Index: Doc/Extra/Core/lang_createtrigger.html ================================================================== --- Doc/Extra/Core/lang_createtrigger.html +++ Doc/Extra/Core/lang_createtrigger.html @@ -287,12 +287,18 @@
-
+ Search for:
@@ -55,11 +56,11 @@ } function div_off(nm){document.getElementById(nm).style.display="none";} window.onbeforeunload = function(e){div_off("submenu");} /* Disable the Search feature if we are not operating from CGI, since */ /* Search is accomplished using CGI and will not work without it. */ -if( !location.origin.match(/http/) ){ +if( !location.origin.match || !location.origin.match(/http/) ){ document.getElementById("search_menubutton").style.display = "none"; } /* Used by the Hide/Show button beside syntax diagrams, to toggle the */ function hideorshow(btn,obj){ var x = document.getElementById(obj); Index: Doc/Extra/Provider/dbfactorysupport.html ================================================================== --- Doc/Extra/Provider/dbfactorysupport.html +++ Doc/Extra/Provider/dbfactorysupport.html @@ -83,11 +83,11 @@ <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.105.0, Culture=neutral, + Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139"/> </DbProviderFactories> </system.data> </configuration> Index: Doc/Extra/Provider/version.html ================================================================== --- Doc/Extra/Provider/version.html +++ Doc/Extra/Provider/version.html @@ -41,10 +41,21 @@

Version History

+

1.0.105.2 - June 12, 2017

+ +

1.0.105.1 - May 15, 2017

+

1.0.105.0 - April 9, 2017

Index: Doc/SQLite.NET.chm ================================================================== --- Doc/SQLite.NET.chm +++ Doc/SQLite.NET.chm cannot compute difference between binary files Index: Doc/buildChm.tcl ================================================================== --- Doc/buildChm.tcl +++ Doc/buildChm.tcl @@ -421,10 +421,13 @@ {"(System\.Data\.SQLite~System\.Data\.SQLite\.SQLiteModule\.Dispose)\.html"} set patterns(.html,8) \ {"(System\.Data\.SQLite~System\.Data\.SQLite\.SQLiteVirtualTableCursor\.Dispose)\.html"} +set patterns(.html,9) \ + {"(System\.Data\.SQLite~System\.Data\.SQLite\.ISQLiteManagedModule\.[^(]+)\((?:[^)]+)\)\.html"} + set subSpecs(.hhc,1) [readFileAsSubSpec [file join $path SQLite.NET.hhc]] set subSpecs(.hhp,1) {Default topic=Provider\welcome.html} set subSpecs(.hhp,2) {"Provider\welcome.html","Provider\welcome.html",,,,,} @@ -434,10 +437,11 @@ set subSpecs(.html,4) {"\1~Overloads.html"} set subSpecs(.html,5) {"\1~Overloads.html"} set subSpecs(.html,6) {"\1~Overloads.html"} set subSpecs(.html,7) {"\1~Overloads.html"} set subSpecs(.html,8) {"\1~Overloads.html"} +set subSpecs(.html,9) {"\1.html"} ############################################################################### set fileNames [list \ [file join $temporaryPath SQLite.NET.hhp] \ Index: Doc/sync.eagle ================================================================== --- Doc/sync.eagle +++ Doc/sync.eagle @@ -52,10 +52,11 @@ [file join images syntax analyze-stmt.gif] \ [file join images syntax attach-stmt.gif] \ [file join images syntax begin-stmt.gif] \ [file join images syntax column-constraint.gif] \ [file join images syntax column-def.gif] \ + [file join images syntax column-name-list.gif] \ [file join images syntax comment-syntax.gif] \ [file join images syntax commit-stmt.gif] \ [file join images syntax common-table-expression.gif] \ [file join images syntax compound-operator.gif] \ [file join images syntax compound-select-stmt.gif] \ @@ -111,10 +112,11 @@ [file join syntax analyze-stmt.html] \ [file join syntax attach-stmt.html] \ [file join syntax begin-stmt.html] \ [file join syntax column-constraint.html] \ [file join syntax column-def.html] \ + [file join syntax column-name-list.html] \ [file join syntax comment-syntax.html] \ [file join syntax commit-stmt.html] \ [file join syntax common-table-expression.html] \ [file join syntax compound-operator.html] \ [file join syntax compound-select-stmt.html] \ Index: NuGet/SQLite.Beta.nuspec ================================================================== --- NuGet/SQLite.Beta.nuspec +++ NuGet/SQLite.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Beta System.Data.SQLite (x86/x64) Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. This package includes support for LINQ and Entity Framework 6. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.Core.Beta.nuspec ================================================================== --- NuGet/SQLite.Core.Beta.nuspec +++ NuGet/SQLite.Core.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core.Beta System.Data.SQLite Core (x86/x64) Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Core.MSIL.Beta.nuspec ================================================================== --- NuGet/SQLite.Core.MSIL.Beta.nuspec +++ NuGet/SQLite.Core.MSIL.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core.MSIL.Beta System.Data.SQLite (MSIL) Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Core.MSIL.Test.nuspec ================================================================== --- NuGet/SQLite.Core.MSIL.Test.nuspec +++ NuGet/SQLite.Core.MSIL.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core.MSIL.Test System.Data.SQLite (MSIL) Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Core.MSIL.nuspec ================================================================== --- NuGet/SQLite.Core.MSIL.nuspec +++ NuGet/SQLite.Core.MSIL.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core.MSIL System.Data.SQLite Core (MSIL) - 1.0.105.0 + 1.0.105.2 SQLite Development Team An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Core.Test.nuspec ================================================================== --- NuGet/SQLite.Core.Test.nuspec +++ NuGet/SQLite.Core.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core.Test System.Data.SQLite Core (x86/x64) Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Core.nuspec ================================================================== --- NuGet/SQLite.Core.nuspec +++ NuGet/SQLite.Core.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Core System.Data.SQLite Core (x86/x64) - 1.0.105.0 + 1.0.105.2 SQLite Development Team The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.EF6.Beta.nuspec ================================================================== --- NuGet/SQLite.EF6.Beta.nuspec +++ NuGet/SQLite.EF6.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.EF6.Beta System.Data.SQLite EF6 Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. Support for Entity Framework 6 using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.EF6.Test.nuspec ================================================================== --- NuGet/SQLite.EF6.Test.nuspec +++ NuGet/SQLite.EF6.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.EF6.Test System.Data.SQLite EF6 Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. Support for Entity Framework 6 using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.EF6.nuspec ================================================================== --- NuGet/SQLite.EF6.nuspec +++ NuGet/SQLite.EF6.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.EF6 System.Data.SQLite EF6 - 1.0.105.0 + 1.0.105.2 SQLite Development Team Support for Entity Framework 6 using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Linq.Beta.nuspec ================================================================== --- NuGet/SQLite.Linq.Beta.nuspec +++ NuGet/SQLite.Linq.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Linq.Beta System.Data.SQLite LINQ Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. Support for LINQ using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Linq.Test.nuspec ================================================================== --- NuGet/SQLite.Linq.Test.nuspec +++ NuGet/SQLite.Linq.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Linq.Test System.Data.SQLite LINQ Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. Support for LINQ using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.Linq.nuspec ================================================================== --- NuGet/SQLite.Linq.nuspec +++ NuGet/SQLite.Linq.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Linq System.Data.SQLite LINQ - 1.0.105.0 + 1.0.105.2 SQLite Development Team Support for LINQ using System.Data.SQLite. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png Index: NuGet/SQLite.MSIL.Beta.nuspec ================================================================== --- NuGet/SQLite.MSIL.Beta.nuspec +++ NuGet/SQLite.MSIL.Beta.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.MSIL.Beta System.Data.SQLite (MSIL) Beta - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a "beta" package and is not intended for production use. This is a legacy package; if possible, please use either the "System.Data.SQLite.Beta" or "System.Data.SQLite.Core.Beta" package instead. An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.MSIL.Test.nuspec ================================================================== --- NuGet/SQLite.MSIL.Test.nuspec +++ NuGet/SQLite.MSIL.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.MSIL.Test System.Data.SQLite (MSIL) Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. This is a legacy package; if possible, please use either the "System.Data.SQLite.Test" or "System.Data.SQLite.Core.Test" package instead. An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.MSIL.nuspec ================================================================== --- NuGet/SQLite.MSIL.nuspec +++ NuGet/SQLite.MSIL.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.MSIL System.Data.SQLite (MSIL) - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead. An ADO.NET provider for SQLite (managed-only). en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.Test.nuspec ================================================================== --- NuGet/SQLite.Test.nuspec +++ NuGet/SQLite.Test.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite.Test System.Data.SQLite (x86/x64) Test - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a pre-release package and is not intended for production use. The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. This package includes support for LINQ and Entity Framework 6. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.nuspec ================================================================== --- NuGet/SQLite.nuspec +++ NuGet/SQLite.nuspec @@ -9,11 +9,11 @@ --> System.Data.SQLite System.Data.SQLite (x86/x64) - 1.0.105.0 + 1.0.105.2 SQLite Development Team The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. This package includes support for LINQ and Entity Framework 6. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -20,50 +20,50 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.x64.nuspec ================================================================== --- NuGet/SQLite.x64.nuspec +++ NuGet/SQLite.x64.nuspec @@ -8,11 +8,11 @@ * --> System.Data.SQLite.x64 - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead. The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x64. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -19,35 +19,35 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: NuGet/SQLite.x86.nuspec ================================================================== --- NuGet/SQLite.x86.nuspec +++ NuGet/SQLite.x86.nuspec @@ -8,11 +8,11 @@ * --> System.Data.SQLite.x86 - 1.0.105.0 + 1.0.105.2 SQLite Development Team This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead. The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x86. en-US https://system.data.sqlite.org/ https://system.data.sqlite.org/images/sqlite128.png @@ -19,35 +19,35 @@ https://www.sqlite.org/copyright.html sqlite database ado.net provider interop Public Domain - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Index: SQLite.Designer/AssemblyInfo.cs ================================================================== --- SQLite.Designer/AssemblyInfo.cs +++ SQLite.Designer/AssemblyInfo.cs @@ -41,7 +41,7 @@ // 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.105.0")] -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +[assembly: AssemblyFileVersion("1.0.105.2")] Index: SQLite.Designer/source.extension.vsixmanifest ================================================================== --- SQLite.Designer/source.extension.vsixmanifest +++ SQLite.Designer/source.extension.vsixmanifest @@ -1,11 +1,11 @@ System.Data.SQLite Designer https://system.data.sqlite.org/ - 1.0.105.0 + 1.0.105.2 ADO.NET Data Designer for SQLite 1033 false Index: SQLite.Interop/props/SQLite.Interop.2005.vsprops ================================================================== --- SQLite.Interop/props/SQLite.Interop.2005.vsprops +++ SQLite.Interop/props/SQLite.Interop.2005.vsprops @@ -27,16 +27,16 @@ Value="1.0" PerformEnvironmentSet="true" /> 2010 105 1.0 - 1.0.105.0 - 1,0,105,0 + 1.0.105.2 + 1,0,105,2 src\core INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1 INTEROP_PLACEHOLDER=1;INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_FTS5_EXTENSION=1;INTEROP_PERCENTILE_EXTENSION=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1;INTEROP_JSON1_EXTENSION=1;INTEROP_SHA1_EXTENSION=1 Index: SQLite.Interop/props/SQLite.Interop.2012.props ================================================================== --- SQLite.Interop/props/SQLite.Interop.2012.props +++ SQLite.Interop/props/SQLite.Interop.2012.props @@ -10,12 +10,12 @@ 2012 105 1.0 - 1.0.105.0 - 1,0,105,0 + 1.0.105.2 + 1,0,105,2 src\core INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1 INTEROP_PLACEHOLDER=1;INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_FTS5_EXTENSION=1;INTEROP_PERCENTILE_EXTENSION=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1;INTEROP_JSON1_EXTENSION=1;INTEROP_SHA1_EXTENSION=1 Index: SQLite.Interop/props/SQLite.Interop.2013.props ================================================================== --- SQLite.Interop/props/SQLite.Interop.2013.props +++ SQLite.Interop/props/SQLite.Interop.2013.props @@ -10,12 +10,12 @@ 2013 105 1.0 - 1.0.105.0 - 1,0,105,0 + 1.0.105.2 + 1,0,105,2 src\core INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1 INTEROP_PLACEHOLDER=1;INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_FTS5_EXTENSION=1;INTEROP_PERCENTILE_EXTENSION=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1;INTEROP_JSON1_EXTENSION=1;INTEROP_SHA1_EXTENSION=1 Index: SQLite.Interop/props/SQLite.Interop.2015.props ================================================================== --- SQLite.Interop/props/SQLite.Interop.2015.props +++ SQLite.Interop/props/SQLite.Interop.2015.props @@ -10,12 +10,12 @@ 2015 105 1.0 - 1.0.105.0 - 1,0,105,0 + 1.0.105.2 + 1,0,105,2 src\core INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1 INTEROP_PLACEHOLDER=1;INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1;INTEROP_VIRTUAL_TABLE=1;INTEROP_FTS5_EXTENSION=1;INTEROP_PERCENTILE_EXTENSION=1;INTEROP_TOTYPE_EXTENSION=1;INTEROP_REGEXP_EXTENSION=1;INTEROP_JSON1_EXTENSION=1;INTEROP_SHA1_EXTENSION=1 Index: SQLite.Interop/props/sqlite3.props ================================================================== --- SQLite.Interop/props/sqlite3.props +++ SQLite.Interop/props/sqlite3.props @@ -7,12 +7,12 @@ * Released to the public domain, use at your own risk! * --> - 3.18.0.0 - 3,18,0,0 + 3.19.3.0 + 3,19,3,0 _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_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1;SQLITE_ENABLE_API_ARMOR=1;SQLITE_ENABLE_DBSTAT_VTAB=1 SQLITE_PLACEHOLDER=1;SQLITE_HAS_CODEC=1 SQLITE_OMIT_WAL=1 HAVE_ERRNO_H=1;SQLITE_MSVC_LOCALTIME_API=1 SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1;SQLITE_ENABLE_EXPENSIVE_ASSERT=1 Index: SQLite.Interop/props/sqlite3.vsprops ================================================================== --- SQLite.Interop/props/sqlite3.vsprops +++ SQLite.Interop/props/sqlite3.vsprops @@ -12,16 +12,16 @@ Version="8.00" Name="sqlite3" > r[P1] */ -#define OP_Le 39 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 40 /* same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseNotEq 42 /* same as TK_ESCAPE */ -#define OP_BitAnd 43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_Last 53 -#define OP_BitNot 54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ -#define OP_IfSmaller 55 -#define OP_SorterSort 56 -#define OP_Sort 57 -#define OP_Rewind 58 -#define OP_IdxLE 59 /* synopsis: key=r[P3@P4] */ -#define OP_IdxGT 60 /* synopsis: key=r[P3@P4] */ -#define OP_IdxLT 61 /* synopsis: key=r[P3@P4] */ -#define OP_IdxGE 62 /* synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 63 /* synopsis: r[P3]=rowset(P1) */ -#define OP_RowSetTest 64 /* synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 65 -#define OP_FkIfZero 66 /* synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IfPos 67 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 68 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ -#define OP_DecrJumpZero 69 /* synopsis: if (--r[P1])==0 goto P2 */ -#define OP_IncrVacuum 70 -#define OP_VNext 71 -#define OP_Init 72 /* synopsis: Start at P2 */ -#define OP_Return 73 -#define OP_EndCoroutine 74 -#define OP_HaltIfNull 75 /* synopsis: if r[P3]=null halt */ -#define OP_Halt 76 -#define OP_Integer 77 /* synopsis: r[P2]=P1 */ -#define OP_Int64 78 /* synopsis: r[P2]=P4 */ -#define OP_String 79 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 80 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 81 /* synopsis: r[P1]=NULL */ -#define OP_Blob 82 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 83 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 84 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 85 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 86 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 87 /* synopsis: r[P2]=r[P1] */ -#define OP_ResultRow 88 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 89 -#define OP_Function0 90 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_Function 91 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_AddImm 92 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 93 +#define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ +#define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */ +#define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */ +#define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */ +#define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */ +#define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */ +#define OP_NotFound 29 /* synopsis: key=r[P3@P4] */ +#define OP_Found 30 /* synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */ +#define OP_NotExists 32 /* synopsis: intkey=r[P3] */ +#define OP_Last 33 +#define OP_IfSmaller 34 +#define OP_SorterSort 35 +#define OP_Sort 36 +#define OP_Rewind 37 +#define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */ +#define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */ +#define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */ +#define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */ +#define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 44 +#define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IncrVacuum 49 +#define OP_VNext 50 +#define OP_Init 51 /* synopsis: Start at P2 */ +#define OP_Return 52 +#define OP_EndCoroutine 53 +#define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 55 +#define OP_Integer 56 /* synopsis: r[P2]=P1 */ +#define OP_Int64 57 /* synopsis: r[P2]=P4 */ +#define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_Null 59 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 60 /* synopsis: r[P1]=NULL */ +#define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */ +#define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 68 +#define OP_Function0 69 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ +#define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ +#define OP_Function 72 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_AddImm 73 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 74 +#define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]=r[P1] */ +#define OP_ElseNotEq 83 /* same as TK_ESCAPE */ +#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_Cast 94 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 95 -#define OP_Compare 96 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ +#define OP_Permutation 96 #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_Column 98 /* synopsis: r[P3]=PX */ -#define OP_Affinity 99 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 100 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 101 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 102 -#define OP_SetCookie 103 -#define OP_ReopenIdx 104 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 105 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 106 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 109 -#define OP_SequenceTest 110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 111 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 112 -#define OP_ColumnsUsed 113 -#define OP_Sequence 114 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 115 /* synopsis: r[P2]=rowid */ -#define OP_Insert 116 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_InsertInt 117 /* synopsis: intkey=P3 data=r[P2] */ -#define OP_Delete 118 -#define OP_ResetCount 119 -#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 121 /* synopsis: r[P2]=data */ -#define OP_RowData 122 /* synopsis: r[P2]=data */ -#define OP_Rowid 123 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 124 -#define OP_SorterInsert 125 /* synopsis: key=r[P2] */ -#define OP_IdxInsert 126 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */ -#define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */ -#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */ -#define OP_Destroy 130 -#define OP_Clear 131 +#define OP_Compare 98 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_Column 99 /* synopsis: r[P3]=PX */ +#define OP_Affinity 100 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 102 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 103 +#define OP_SetCookie 104 +#define OP_ReopenIdx 105 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 106 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 107 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 108 +#define OP_OpenAutoindex 109 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 110 /* synopsis: nColumn=P2 */ +#define OP_SorterOpen 111 +#define OP_SequenceTest 112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 113 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 114 +#define OP_ColumnsUsed 115 +#define OP_Sequence 116 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 117 /* synopsis: r[P2]=rowid */ +#define OP_Insert 118 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_InsertInt 119 /* synopsis: intkey=P3 data=r[P2] */ +#define OP_Delete 120 +#define OP_ResetCount 121 +#define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 123 /* synopsis: r[P2]=data */ +#define OP_RowData 124 /* synopsis: r[P2]=data */ +#define OP_Rowid 125 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 126 +#define OP_SorterInsert 127 /* synopsis: key=r[P2] */ +#define OP_IdxInsert 128 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 129 /* synopsis: key=r[P2@P3] */ +#define OP_Seek 130 /* synopsis: Move P3 to P1.rowid */ +#define OP_IdxRowid 131 /* synopsis: r[P2]=rowid */ #define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_ResetSorter 133 -#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */ -#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */ -#define OP_SqlExec 136 -#define OP_ParseSchema 137 -#define OP_LoadAnalysis 138 -#define OP_DropTable 139 -#define OP_DropIndex 140 -#define OP_DropTrigger 141 -#define OP_IntegrityCk 142 -#define OP_RowSetAdd 143 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 144 -#define OP_FkCounter 145 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 146 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggStep0 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggFinal 150 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 151 -#define OP_TableLock 152 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 153 -#define OP_VCreate 154 -#define OP_VDestroy 155 -#define OP_VOpen 156 -#define OP_VColumn 157 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 158 -#define OP_Pagecount 159 -#define OP_MaxPgcnt 160 -#define OP_CursorHint 161 -#define OP_Noop 162 -#define OP_Explain 163 +#define OP_Destroy 133 +#define OP_Clear 134 +#define OP_ResetSorter 135 +#define OP_CreateIndex 136 /* synopsis: r[P2]=root iDb=P1 */ +#define OP_CreateTable 137 /* synopsis: r[P2]=root iDb=P1 */ +#define OP_SqlExec 138 +#define OP_ParseSchema 139 +#define OP_LoadAnalysis 140 +#define OP_DropTable 141 +#define OP_DropIndex 142 +#define OP_DropTrigger 143 +#define OP_IntegrityCk 144 +#define OP_RowSetAdd 145 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 146 +#define OP_FkCounter 147 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 148 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggStep0 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep 151 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggFinal 152 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 153 +#define OP_TableLock 154 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 155 +#define OP_VCreate 156 +#define OP_VDestroy 157 +#define OP_VOpen 158 +#define OP_VColumn 159 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 160 +#define OP_Pagecount 161 +#define OP_MaxPgcnt 162 +#define OP_CursorHint 163 +#define OP_Noop 164 +#define OP_Explain 165 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ @@ -12903,37 +12915,37 @@ #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ /* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\ -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x09,\ -/* 24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\ -/* 32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\ -/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23,\ -/* 64 */ 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\ -/* 72 */ 0x01, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\ -/* 80 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\ -/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\ -/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\ +/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\ +/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ +/* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\ +/* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\ +/* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\ +/* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\ +/* 72 */ 0x00, 0x02, 0x02, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +/* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\ +/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x02, 0x12,\ +/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\ -/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\ -/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\ -/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -/* 160 */ 0x10, 0x00, 0x00, 0x00,} +/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04,\ +/* 128 */ 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\ +/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\ +/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ -#define SQLITE_MX_JUMP_OPCODE 72 /* Maximum JUMP opcode */ +#define SQLITE_MX_JUMP_OPCODE 83 /* Maximum JUMP opcode */ /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ /* @@ -15209,10 +15221,11 @@ ** of the result column in the form: DATABASE.TABLE.COLUMN. This later ** form is used for name resolution with nested FROM clauses. */ struct ExprList { int nExpr; /* Number of expressions on the list */ + int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ @@ -15224,11 +15237,11 @@ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; int iConstExprReg; /* Register in which Expr value is cached */ } u; - } *a; /* Alloc a power of two greater or equal to nExpr */ + } a[1]; /* One slot for each expression in the list */ }; /* ** An instance of this structure is used by the parser to record both ** the parse tree for an expression and the span of input text for an @@ -16081,18 +16094,21 @@ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ int walkerDepth; /* Number of subqueries */ u8 eCode; /* A small processing code */ union { /* Extra data for callback */ - NameContext *pNC; /* Naming context */ - int n; /* A counter */ - int iCur; /* A cursor number */ - SrcList *pSrcList; /* FROM clause */ - struct SrcCount *pSrcCount; /* Counting column references */ - struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ - int *aiCol; /* array of column indexes */ - struct IdxCover *pIdxCover; /* Check for index coverage */ + NameContext *pNC; /* Naming context */ + int n; /* A counter */ + int iCur; /* A cursor number */ + SrcList *pSrcList; /* FROM clause */ + struct SrcCount *pSrcCount; /* Counting column references */ + struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ + int *aiCol; /* array of column indexes */ + struct IdxCover *pIdxCover; /* Check for index coverage */ + struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ + ExprList *pGroupBy; /* GROUP BY clause */ + struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */ } u; }; /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); @@ -16242,10 +16258,11 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); SQLITE_PRIVATE int sqlite3MallocSize(void*); SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); SQLITE_PRIVATE void *sqlite3ScratchMalloc(int); SQLITE_PRIVATE void sqlite3ScratchFree(void*); SQLITE_PRIVATE void *sqlite3PageMalloc(int); @@ -16557,10 +16574,11 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); @@ -17266,13 +17284,20 @@ ** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options. ** ** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** SQLITE_USE_URI symbol defined. +** +** URI filenames are enabled by default if SQLITE_HAS_CODEC is +** enabled. */ #ifndef SQLITE_USE_URI -# define SQLITE_USE_URI 0 +# ifdef SQLITE_HAS_CODEC +# define SQLITE_USE_URI 1 +# else +# define SQLITE_USE_URI 0 +# endif #endif /* EVIDENCE-OF: R-38720-18127 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. @@ -18092,11 +18117,11 @@ /* ** Internally, the vdbe manipulates nearly all SQL values as Mem ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ -struct Mem { +struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ @@ -18194,15 +18219,15 @@ ** of this structure. All such structures associated with a single VM ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed ** when the VM is halted (if not before). */ struct AuxData { - int iOp; /* Instruction number of OP_Function opcode */ - int iArg; /* Index of function argument. */ + int iAuxOp; /* Instruction number of OP_Function opcode */ + int iAuxArg; /* Index of function argument. */ void *pAux; /* Aux data pointer */ - void (*xDelete)(void *); /* Destructor for the aux data */ - AuxData *pNext; /* Next element in list */ + void (*xDeleteAux)(void*); /* Destructor for the aux data */ + AuxData *pNextAux; /* Next element in list */ }; /* ** The "context" argument for an installable function. A pointer to an ** instance of this structure is the first argument to the routines used @@ -19222,12 +19247,14 @@ if( p->validYMD ) return; if( !p->validJD ){ p->Y = 2000; p->M = 1; p->D = 1; + }else if( !validJulianDay(p->iJD) ){ + datetimeError(p); + return; }else{ - assert( validJulianDay(p->iJD) ); Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); A = Z + 1 + A - (A/4); B = A + 1524; C = (int)((B - 122.1)/365.25); @@ -24659,15 +24686,16 @@ *db->pnBytesFreed += sqlite3DbMallocSize(db,p); } /* ** Free memory that might be associated with a particular database -** connection. +** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op. +** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL. */ -SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( p==0 ) return; + assert( p!=0 ); if( db ){ if( db->pnBytesFreed ){ measureAllocationSize(db, p); return; } @@ -24686,10 +24714,14 @@ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); sqlite3_free(p); +} +SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p ) sqlite3DbFreeNN(db, p); } /* ** Change the size of an existing memory allocation */ @@ -26379,19 +26411,24 @@ ** Generate a human-readable explanation of an expression tree. */ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ const char *zBinOp = 0; /* Binary operator */ const char *zUniOp = 0; /* Unary operator */ - char zFlgs[30]; + char zFlgs[60]; pView = sqlite3TreeViewPush(pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); sqlite3TreeViewPop(pView); return; } if( pExpr->flags ){ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags); + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x iRJT=%d", + pExpr->flags, pExpr->iRightJoinTable); + }else{ + sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags); + } }else{ zFlgs[0] = 0; } switch( pExpr->op ){ case TK_AGG_COLUMN: { @@ -26605,10 +26642,15 @@ } case TK_SELECT_COLUMN: { sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); break; + } + case TK_IF_NULL_ROW: { + sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; } default: { sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; } @@ -28325,10 +28367,11 @@ }else{ return 0; } } #endif + if( !sqlite3Isdigit(zNum[0]) ) return 0; while( zNum[0]=='0' ) zNum++; for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; } @@ -29488,151 +29531,153 @@ /* 18 */ "Jump" OpHelp(""), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), /* 20 */ "Once" OpHelp(""), /* 21 */ "If" OpHelp(""), /* 22 */ "IfNot" OpHelp(""), - /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 27 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), - /* 28 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 31 */ "Found" OpHelp("key=r[P3@P4]"), - /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 33 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 34 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 35 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 36 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 37 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 38 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 39 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 40 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 42 */ "ElseNotEq" OpHelp(""), - /* 43 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 44 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 45 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 47 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 48 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 49 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 50 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 51 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 52 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 53 */ "Last" OpHelp(""), - /* 54 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), - /* 55 */ "IfSmaller" OpHelp(""), - /* 56 */ "SorterSort" OpHelp(""), - /* 57 */ "Sort" OpHelp(""), - /* 58 */ "Rewind" OpHelp(""), - /* 59 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 60 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 61 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 62 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 63 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), - /* 64 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), - /* 65 */ "Program" OpHelp(""), - /* 66 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 67 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 68 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), - /* 69 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), - /* 70 */ "IncrVacuum" OpHelp(""), - /* 71 */ "VNext" OpHelp(""), - /* 72 */ "Init" OpHelp("Start at P2"), - /* 73 */ "Return" OpHelp(""), - /* 74 */ "EndCoroutine" OpHelp(""), - /* 75 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), - /* 76 */ "Halt" OpHelp(""), - /* 77 */ "Integer" OpHelp("r[P2]=P1"), - /* 78 */ "Int64" OpHelp("r[P2]=P4"), - /* 79 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 80 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 81 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 82 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 83 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 84 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 85 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 86 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 87 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 88 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 89 */ "CollSeq" OpHelp(""), - /* 90 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), - /* 91 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), - /* 92 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 93 */ "RealAffinity" OpHelp(""), + /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 30 */ "Found" OpHelp("key=r[P3@P4]"), + /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 32 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 33 */ "Last" OpHelp(""), + /* 34 */ "IfSmaller" OpHelp(""), + /* 35 */ "SorterSort" OpHelp(""), + /* 36 */ "Sort" OpHelp(""), + /* 37 */ "Rewind" OpHelp(""), + /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 44 */ "Program" OpHelp(""), + /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 49 */ "IncrVacuum" OpHelp(""), + /* 50 */ "VNext" OpHelp(""), + /* 51 */ "Init" OpHelp("Start at P2"), + /* 52 */ "Return" OpHelp(""), + /* 53 */ "EndCoroutine" OpHelp(""), + /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 55 */ "Halt" OpHelp(""), + /* 56 */ "Integer" OpHelp("r[P2]=P1"), + /* 57 */ "Int64" OpHelp("r[P2]=P4"), + /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 68 */ "CollSeq" OpHelp(""), + /* 69 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), + /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), + /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), + /* 72 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), + /* 73 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 74 */ "RealAffinity" OpHelp(""), + /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 81 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 83 */ "ElseNotEq" OpHelp(""), + /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 94 */ "Cast" OpHelp("affinity(r[P1])"), - /* 95 */ "Permutation" OpHelp(""), - /* 96 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), + /* 96 */ "Permutation" OpHelp(""), /* 97 */ "String8" OpHelp("r[P2]='P4'"), - /* 98 */ "Column" OpHelp("r[P3]=PX"), - /* 99 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 100 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 101 */ "Count" OpHelp("r[P2]=count()"), - /* 102 */ "ReadCookie" OpHelp(""), - /* 103 */ "SetCookie" OpHelp(""), - /* 104 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 105 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 106 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 107 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 108 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 109 */ "SorterOpen" OpHelp(""), - /* 110 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 111 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 112 */ "Close" OpHelp(""), - /* 113 */ "ColumnsUsed" OpHelp(""), - /* 114 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 115 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 116 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 117 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), - /* 118 */ "Delete" OpHelp(""), - /* 119 */ "ResetCount" OpHelp(""), - /* 120 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 121 */ "SorterData" OpHelp("r[P2]=data"), - /* 122 */ "RowData" OpHelp("r[P2]=data"), - /* 123 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 124 */ "NullRow" OpHelp(""), - /* 125 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 126 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"), - /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 130 */ "Destroy" OpHelp(""), - /* 131 */ "Clear" OpHelp(""), + /* 98 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 99 */ "Column" OpHelp("r[P3]=PX"), + /* 100 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 102 */ "Count" OpHelp("r[P2]=count()"), + /* 103 */ "ReadCookie" OpHelp(""), + /* 104 */ "SetCookie" OpHelp(""), + /* 105 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 106 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 107 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 108 */ "OpenDup" OpHelp(""), + /* 109 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 110 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 111 */ "SorterOpen" OpHelp(""), + /* 112 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 113 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 114 */ "Close" OpHelp(""), + /* 115 */ "ColumnsUsed" OpHelp(""), + /* 116 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 117 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 118 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 119 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), + /* 120 */ "Delete" OpHelp(""), + /* 121 */ "ResetCount" OpHelp(""), + /* 122 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 123 */ "SorterData" OpHelp("r[P2]=data"), + /* 124 */ "RowData" OpHelp("r[P2]=data"), + /* 125 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 126 */ "NullRow" OpHelp(""), + /* 127 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 128 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 129 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 130 */ "Seek" OpHelp("Move P3 to P1.rowid"), + /* 131 */ "IdxRowid" OpHelp("r[P2]=rowid"), /* 132 */ "Real" OpHelp("r[P2]=P4"), - /* 133 */ "ResetSorter" OpHelp(""), - /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), - /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), - /* 136 */ "SqlExec" OpHelp(""), - /* 137 */ "ParseSchema" OpHelp(""), - /* 138 */ "LoadAnalysis" OpHelp(""), - /* 139 */ "DropTable" OpHelp(""), - /* 140 */ "DropIndex" OpHelp(""), - /* 141 */ "DropTrigger" OpHelp(""), - /* 142 */ "IntegrityCk" OpHelp(""), - /* 143 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 144 */ "Param" OpHelp(""), - /* 145 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 146 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 147 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 148 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 149 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 150 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 151 */ "Expire" OpHelp(""), - /* 152 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 153 */ "VBegin" OpHelp(""), - /* 154 */ "VCreate" OpHelp(""), - /* 155 */ "VDestroy" OpHelp(""), - /* 156 */ "VOpen" OpHelp(""), - /* 157 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 158 */ "VRename" OpHelp(""), - /* 159 */ "Pagecount" OpHelp(""), - /* 160 */ "MaxPgcnt" OpHelp(""), - /* 161 */ "CursorHint" OpHelp(""), - /* 162 */ "Noop" OpHelp(""), - /* 163 */ "Explain" OpHelp(""), + /* 133 */ "Destroy" OpHelp(""), + /* 134 */ "Clear" OpHelp(""), + /* 135 */ "ResetSorter" OpHelp(""), + /* 136 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), + /* 137 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), + /* 138 */ "SqlExec" OpHelp(""), + /* 139 */ "ParseSchema" OpHelp(""), + /* 140 */ "LoadAnalysis" OpHelp(""), + /* 141 */ "DropTable" OpHelp(""), + /* 142 */ "DropIndex" OpHelp(""), + /* 143 */ "DropTrigger" OpHelp(""), + /* 144 */ "IntegrityCk" OpHelp(""), + /* 145 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 146 */ "Param" OpHelp(""), + /* 147 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 148 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 149 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 150 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 151 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 152 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 153 */ "Expire" OpHelp(""), + /* 154 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 155 */ "VBegin" OpHelp(""), + /* 156 */ "VCreate" OpHelp(""), + /* 157 */ "VDestroy" OpHelp(""), + /* 158 */ "VOpen" OpHelp(""), + /* 159 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 160 */ "VRename" OpHelp(""), + /* 161 */ "Pagecount" OpHelp(""), + /* 162 */ "MaxPgcnt" OpHelp(""), + /* 163 */ "CursorHint" OpHelp(""), + /* 164 */ "Noop" OpHelp(""), + /* 165 */ "Explain" OpHelp(""), }; return azName[i]; } #endif @@ -45243,21 +45288,20 @@ } zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); sqlite3EndBenignMalloc(); if( zBulk ){ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; - int i; - for(i=0; iszPage]; pX->page.pBuf = zBulk; pX->page.pExtra = &pX[1]; pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; pCache->pFree = pX; zBulk += pCache->szAlloc; - } + }while( --nBulk ); } return pCache->pFree!=0; } /* @@ -46169,11 +46213,11 @@ */ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ int nFree = 0; assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); assert( sqlite3_mutex_notheld(pcache1.mutex) ); - if( sqlite3GlobalConfig.nPage==0 ){ + if( sqlite3GlobalConfig.pPage==0 ){ PgHdr1 *p; pcache1EnterMutex(&pcache1.grp); while( (nReq<0 || nFreeisAnchor==0 @@ -49129,10 +49173,15 @@ Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ char *aData; /* Temporary storage for the page */ sqlite3_file *jfd; /* The file descriptor for the journal file */ int isSynced; /* True if journal page is synced */ +#ifdef SQLITE_HAS_CODEC + /* The jrnlEnc flag is true if Journal pages should be passed through + ** the codec. It is false for pure in-memory journals. */ + const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0); +#endif assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ @@ -49252,18 +49301,38 @@ && isSynced ){ i64 ofst = (pgno-1)*(i64)pPager->pageSize; testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); assert( !pagerUseWal(pPager) ); + + /* Write the data read from the journal back into the database file. + ** This is usually safe even for an encrypted database - as the data + ** was encrypted before it was written to the journal file. The exception + ** is if the data was just read from an in-memory sub-journal. In that + ** case it must be encrypted here before it is copied into the database + ** file. */ +#ifdef SQLITE_HAS_CODEC + if( !jrnlEnc ){ + CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData); + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); + }else +#endif rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } if( pPager->pBackup ){ - CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); +#ifdef SQLITE_HAS_CODEC + if( jrnlEnc ){ + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData); + }else +#endif sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); - CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData); } }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential ** problem. When the page is next fetched by the b-tree layer, it @@ -49311,11 +49380,13 @@ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } /* Decode the page just read from disk */ - CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); +#if SQLITE_HAS_CODEC + if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); } +#endif sqlite3PcacheRelease(pPg); } return rc; } @@ -51323,12 +51394,17 @@ ** write the journal record into the file. */ if( rc==SQLITE_OK ){ void *pData = pPg->pData; i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; - - CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); + +#if SQLITE_HAS_CODEC + if( !pPager->subjInMemory ){ + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); + }else +#endif + pData2 = pData; PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); rc = write32bits(pPager->sjfd, offset, pPg->pgno); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); } @@ -58476,14 +58552,14 @@ /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ i8 iPage; /* Index of current page in apPage */ u8 curIntKey; /* Value of apPage[0]->intKey */ - struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ - void *padding1; /* Make object size a multiple of 16 */ - u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ + u16 ix; /* Current index for apPage[iPage] */ + u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ + struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ + MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ }; /* ** Legal values for BtCursor.curFlags */ @@ -59455,10 +59531,11 @@ ** rowid iRow is being replaced or deleted. In this case invalidate ** only those incrblob cursors open on that specific row. */ static void invalidateIncrblobCursors( Btree *pBtree, /* The database file to check */ + Pgno pgnoRoot, /* The table that might be changing */ i64 iRow, /* The rowid that might be changing */ int isClearTable /* True if all rows are being deleted */ ){ BtCursor *p; if( pBtree->hasIncrblobCur==0 ) return; @@ -59465,20 +59542,20 @@ assert( sqlite3BtreeHoldsMutex(pBtree) ); pBtree->hasIncrblobCur = 0; for(p=pBtree->pBt->pCursor; p; p=p->pNext){ if( (p->curFlags & BTCF_Incrblob)!=0 ){ pBtree->hasIncrblobCur = 1; - if( isClearTable || p->info.nKey==iRow ){ + if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){ p->eState = CURSOR_INVALID; } } } } #else /* Stub function when INCRBLOB is omitted */ - #define invalidateIncrblobCursors(x,y,z) + #define invalidateIncrblobCursors(w,x,y,z) #endif /* SQLITE_OMIT_INCRBLOB */ /* ** Set bit pgno of the BtShared.pHasContent bitvec. This is called ** when a page that previously contained data becomes a free-list leaf @@ -63272,21 +63349,21 @@ #ifndef NDEBUG static void assertCellInfo(BtCursor *pCur){ CellInfo info; int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); - btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); + btreeParseCell(pCur->apPage[iPage], pCur->ix, &info); assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); } #else #define assertCellInfo(x) #endif static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ int iPage = pCur->iPage; pCur->curFlags |= BTCF_ValidNKey; - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); + btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info); }else{ assertCellInfo(pCur); } } @@ -63489,11 +63566,11 @@ #endif assert( pPage ); assert( eOp==0 || eOp==1 ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->aiIdx[pCur->iPage]nCell ); + assert( pCur->ixnCell ); assert( cursorHoldsMutex(pCur) ); getCellInfo(pCur); aPayload = pCur->info.pPayload; assert( offset+amt <= pCur->info.nPayload ); @@ -63676,11 +63753,11 @@ */ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } /* ** This variant of sqlite3BtreePayload() works even if the cursor has not @@ -63738,11 +63815,11 @@ u32 amt; assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); if( pCur->info.nLocalinfo.nLocal; @@ -63789,12 +63866,12 @@ if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ return SQLITE_CORRUPT_BKPT; } pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->iPage++; - pCur->aiIdx[pCur->iPage] = 0; + pCur->aiIdx[pCur->iPage++] = pCur->ix; + pCur->ix = 0; return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], pCur, pCur->curPagerFlags); } #ifdef SQLITE_DEBUG @@ -63838,10 +63915,11 @@ pCur->apPage[pCur->iPage]->pgno ); testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->ix = pCur->aiIdx[pCur->iPage-1]; releasePageNotNull(pCur->apPage[pCur->iPage--]); } /* ** Move the cursor to point to the root page of its b-tree structure. @@ -63919,11 +63997,11 @@ if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ return SQLITE_CORRUPT_BKPT; } skip_init: - pCur->aiIdx[0] = 0; + pCur->ix = 0; pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); pRoot = pCur->apPage[0]; if( pRoot->nCell>0 ){ @@ -63953,12 +64031,12 @@ MemPage *pPage; assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ - assert( pCur->aiIdx[pCur->iPage]nCell ); - pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage])); + assert( pCur->ixnCell ); + pgno = get4byte(findCell(pPage, pCur->ix)); rc = moveToChild(pCur, pgno); } return rc; } @@ -63979,15 +64057,15 @@ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - pCur->aiIdx[pCur->iPage] = pPage->nCell; + pCur->ix = pPage->nCell; rc = moveToChild(pCur, pgno); if( rc ) return rc; } - pCur->aiIdx[pCur->iPage] = pPage->nCell-1; + pCur->ix = pPage->nCell-1; assert( pCur->info.nSize==0 ); assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); return SQLITE_OK; } @@ -64031,11 +64109,11 @@ ** to the last entry in the b-tree. */ int ii; for(ii=0; iiiPage; ii++){ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); } - assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 ); + assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 ); assert( pCur->apPage[pCur->iPage]->leaf ); #endif return SQLITE_OK; } @@ -64178,11 +64256,11 @@ assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; assert( biasRight==0 || biasRight==1 ); idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( xRecordCompare==0 ){ for(;;){ i64 nCellKey; pCell = findCellPastPtr(pPage, idx); if( pPage->intKeyLeaf ){ @@ -64197,11 +64275,11 @@ }else if( nCellKey>intKey ){ upr = idx-1; if( lwr>upr ){ c = +1; break; } }else{ assert( nCellKey==intKey ); - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( !pPage->leaf ){ lwr = idx; goto moveto_next_layer; }else{ pCur->curFlags |= BTCF_ValidNKey; @@ -64266,11 +64344,11 @@ pCellKey = sqlite3Malloc( nCell+18 ); if( pCellKey==0 ){ rc = SQLITE_NOMEM_BKPT; goto moveto_finish; } - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); pCur->curFlags &= ~BTCF_ValidOvfl; if( rc ){ sqlite3_free(pCellKey); goto moveto_finish; @@ -64288,11 +64366,11 @@ upr = idx-1; }else{ assert( c==0 ); *pRes = 0; rc = SQLITE_OK; - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; goto moveto_finish; } if( lwr>upr ) break; assert( lwr+upr>=0 ); @@ -64300,12 +64378,12 @@ } } assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - pCur->aiIdx[pCur->iPage] = (u16)idx; + assert( pCur->ixapPage[pCur->iPage]->nCell ); + pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; goto moveto_finish; } moveto_next_layer: @@ -64312,11 +64390,11 @@ if( lwr>=pPage->nCell ){ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); }else{ chldPg = get4byte(findCell(pPage, lwr)); } - pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->ix = (u16)lwr; rc = moveToChild(pCur, chldPg); if( rc ) break; } moveto_finish: pCur->info.nSize = 0; @@ -64413,11 +64491,11 @@ pCur->skipNext = 0; } } pPage = pCur->apPage[pCur->iPage]; - idx = ++pCur->aiIdx[pCur->iPage]; + idx = ++pCur->ix; assert( pPage->isInit ); /* If the database file is corrupt, it is possible for the value of idx ** to be invalid here. This can only occur if a second cursor modifies ** the page while cursor pCur is holding a reference to it. Which can @@ -64437,11 +64515,11 @@ pCur->eState = CURSOR_INVALID; return SQLITE_OK; } moveToParent(pCur); pPage = pCur->apPage[pCur->iPage]; - }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); + }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ return sqlite3BtreeNext(pCur, pRes); }else{ return SQLITE_OK; } @@ -64461,12 +64539,12 @@ pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); *pRes = 0; if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes); pPage = pCur->apPage[pCur->iPage]; - if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){ - pCur->aiIdx[pCur->iPage]--; + if( (++pCur->ix)>=pPage->nCell ){ + pCur->ix--; return btreeNext(pCur, pRes); } if( pPage->leaf ){ return SQLITE_OK; }else{ @@ -64526,16 +64604,16 @@ } pPage = pCur->apPage[pCur->iPage]; assert( pPage->isInit ); if( !pPage->leaf ){ - int idx = pCur->aiIdx[pCur->iPage]; + int idx = pCur->ix; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); if( rc ) return rc; rc = moveToRightmost(pCur); }else{ - while( pCur->aiIdx[pCur->iPage]==0 ){ + while( pCur->ix==0 ){ if( pCur->iPage==0 ){ pCur->eState = CURSOR_INVALID; *pRes = 1; return SQLITE_OK; } @@ -64542,11 +64620,11 @@ moveToParent(pCur); } assert( pCur->info.nSize==0 ); assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); - pCur->aiIdx[pCur->iPage]--; + pCur->ix--; pPage = pCur->apPage[pCur->iPage]; if( pPage->intKey && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, pRes); }else{ rc = SQLITE_OK; @@ -64561,16 +64639,16 @@ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); *pRes = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); pCur->info.nSize = 0; if( pCur->eState!=CURSOR_VALID - || pCur->aiIdx[pCur->iPage]==0 + || pCur->ix==0 || pCur->apPage[pCur->iPage]->leaf==0 ){ return btreePrevious(pCur, pRes); } - pCur->aiIdx[pCur->iPage]--; + pCur->ix--; return SQLITE_OK; } /* ** Allocate a new page from the database file. @@ -66888,12 +66966,12 @@ assert( balance_deeper_called==0 ); VVA_ONLY( balance_deeper_called++ ); rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ pCur->iPage = 1; + pCur->ix = 0; pCur->aiIdx[0] = 0; - pCur->aiIdx[1] = 0; assert( pCur->apPage[1]->nOverflow ); } }else{ break; } @@ -67066,11 +67144,11 @@ if( pCur->pKeyInfo==0 ){ assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced */ - invalidateIncrblobCursors(p, pX->nKey, 0); + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing ** to a row with the same key as the new entry being inserted. */ assert( (flags & BTREE_SAVEPOSITION)==0 || ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); @@ -67078,13 +67156,10 @@ /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ loc = 0; - }else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0 - && pCur->info.nKey==pX->nKey-1 ){ - loc = -1; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ @@ -67118,11 +67193,11 @@ assert( newCell!=0 ); rc = fillInCell(pPage, newCell, pX, &szNew); if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); - idx = pCur->aiIdx[pCur->iPage]; + idx = pCur->ix; if( loc==0 ){ CellInfo info; assert( idxnCell ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ @@ -67131,26 +67206,33 @@ oldCell = findCell(pPage, idx); if( !pPage->leaf ){ memcpy(newCell, oldCell, 4); } rc = clearCell(pPage, oldCell, &info); - if( info.nSize==szNew && info.nLocal==info.nPayload ){ + if( info.nSize==szNew && info.nLocal==info.nPayload + && (!ISAUTOVACUUM || szNewminLocal) + ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just - ** calling dropCell() and insertCell(). */ + ** calling dropCell() and insertCell(). + ** + ** This optimization cannot be used on an autovacuum database if the + ** new entry uses overflow pages, as the insertCell() call below is + ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; memcpy(oldCell, newCell, szNew); return SQLITE_OK; } dropCell(pPage, idx, info.nSize, &rc); if( rc ) goto end_insert; }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); - idx = ++pCur->aiIdx[pCur->iPage]; + idx = ++pCur->ix; + pCur->curFlags &= ~BTCF_ValidNKey; }else{ assert( pPage->leaf ); } insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); assert( pPage->nOverflow==0 || rc==SQLITE_OK ); @@ -67242,16 +67324,16 @@ assert( pBt->inTransaction==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); assert( pCur->eState==CURSOR_VALID ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; - iCellIdx = pCur->aiIdx[iCellDepth]; + iCellIdx = pCur->ix; pPage = pCur->apPage[iCellDepth]; pCell = findCell(pPage, iCellIdx); /* If the bPreserve flag is set to true, then the cursor position must ** be preserved following this delete operation. If the current delete @@ -67296,11 +67378,11 @@ } /* If this is a delete operation to remove a row from a table b-tree, ** invalidate any incrblob cursors open on the row being deleted. */ if( pCur->pKeyInfo==0 ){ - invalidateIncrblobCursors(p, pCur->info.nKey, 0); + invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); } /* Make the page containing the entry to be deleted writable. Then free any ** overflow pages associated with the entry and finally remove the cell ** itself from within the page. */ @@ -67364,11 +67446,11 @@ assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ pCur->skipNext = -1; - pCur->aiIdx[iCellDepth] = pPage->nCell-1; + pCur->ix = pPage->nCell-1; }else{ pCur->skipNext = 1; } }else{ rc = moveToRoot(pCur); @@ -67623,11 +67705,11 @@ if( SQLITE_OK==rc ){ /* Invalidate all incrblob cursors open on table iTable (assuming iTable ** is the root of a table b-tree - if it is not, the following call is ** a no-op). */ - invalidateIncrblobCursors(p, 0, 1); + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); return rc; } @@ -67877,20 +67959,20 @@ /* All pages of the b-tree have been visited. Return successfully. */ *pnEntry = nEntry; return moveToRoot(pCur); } moveToParent(pCur); - }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); + }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell ); - pCur->aiIdx[pCur->iPage]++; + pCur->ix++; pPage = pCur->apPage[pCur->iPage]; } /* Descend to the child node of the cell that the cursor currently ** points at. This is the right-child if (iIdx==pPage->nCell). */ - iIdx = pCur->aiIdx[pCur->iPage]; + iIdx = pCur->ix; if( iIdx==pPage->nCell ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); }else{ rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); } @@ -68271,10 +68353,11 @@ if( pPage->intKey ){ if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){ checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey); } maxKey = info.nKey; + keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */ } /* Check the content overflow list */ if( info.nPayload>info.nLocal ){ int nPage; /* Number of pages on the overflow chain */ @@ -69656,10 +69739,14 @@ assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); + /* Cannot be both MEM_Null and some other type */ + assert( (p->flags & MEM_Null)==0 || + (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 ); + /* The szMalloc field holds the correct memory allocation size */ assert( p->szMalloc==0 || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); /* If p holds a string or blob, the Mem.z must point to exactly @@ -69741,30 +69828,28 @@ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); testcase( bPreserve && pMem->z==0 ); assert( pMem->szMalloc==0 || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); - if( pMem->szMallocszMalloc>0 && pMem->z==pMem->zMalloc ){ - pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); - bPreserve = 0; - }else{ - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); - pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); - } - if( pMem->zMalloc==0 ){ - sqlite3VdbeMemSetNull(pMem); - pMem->z = 0; - pMem->szMalloc = 0; - return SQLITE_NOMEM_BKPT; - }else{ - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); - } - } - - if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ + if( n<32 ) n = 32; + if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + bPreserve = 0; + }else{ + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + pMem->szMalloc = 0; + return SQLITE_NOMEM_BKPT; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + } + + if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( (pMem->flags&MEM_Dyn)!=0 ){ assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); pMem->xDel((void *)(pMem->z)); @@ -69957,11 +70042,11 @@ ctx.pOut = &t; ctx.pMem = pMem; ctx.pFunc = pFunc; pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); rc = ctx.isError; } return rc; } @@ -70008,11 +70093,11 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ if( VdbeMemDynamic(p) ){ vdbeMemClearExternAndSetNull(p); } if( p->szMalloc ){ - sqlite3DbFree(p->db, p->zMalloc); + sqlite3DbFreeNN(p->db, p->zMalloc); p->szMalloc = 0; } p->z = 0; } @@ -70036,11 +70121,11 @@ /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. ** If the double is out of range of a 64-bit signed integer then ** return the closest available 64-bit signed integer. */ -static i64 doubleToInt64(double r){ +static SQLITE_NOINLINE i64 doubleToInt64(double r){ #ifdef SQLITE_OMIT_FLOATING_POINT /* When floating-point is omitted, double and int64 are the same thing */ return r; #else /* @@ -70072,10 +70157,15 @@ ** it into an integer and return that. If pMem represents an ** an SQL-NULL value, return 0. ** ** If pMem represents a string value, its encoding might be changed. */ +static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){ + i64 value = 0; + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + return value; +} SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ int flags; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem->flags; @@ -70082,14 +70172,12 @@ if( flags & MEM_Int ){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); }else if( flags & (MEM_Str|MEM_Blob) ){ - i64 value = 0; assert( pMem->z || pMem->n==0 ); - sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); - return value; + return memIntValue(pMem); }else{ return 0; } } @@ -70097,22 +70185,25 @@ ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ +static SQLITE_NOINLINE double memRealValue(Mem *pMem){ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + double val = (double)0; + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); + return val; +} SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ return pMem->u.r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - double val = (double)0; - sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); - return val; + return memRealValue(pMem); }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } } @@ -70733,11 +70824,11 @@ for(i=0; iaMem[i].flags = MEM_Null; pRec->aMem[i].db = db; } }else{ - sqlite3DbFree(db, pRec); + sqlite3DbFreeNN(db, pRec); pRec = 0; } } if( pRec==0 ) return 0; p->ppRec[0] = pRec; @@ -70845,11 +70936,11 @@ } if( apVal ){ for(i=0; ipKeyInfo); - sqlite3DbFree(db, pRec); + sqlite3DbFreeNN(db, pRec); } } #endif /* ifdef SQLITE_ENABLE_STAT4 */ /* @@ -71295,11 +71386,11 @@ ** Free an sqlite3_value object */ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ if( !v ) return; sqlite3VdbeMemRelease((Mem *)v); - sqlite3DbFree(((Mem*)v)->db, v); + sqlite3DbFreeNN(((Mem*)v)->db, v); } /* ** The sqlite3ValueBytes() routine returns the number of bytes in the ** sqlite3_value object assuming that it uses the encoding "enc". @@ -72138,11 +72229,11 @@ ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - sqlite3DbFree(db, pDef); + sqlite3DbFreeNN(db, pDef); } } static void vdbeFreeOpArray(sqlite3 *, Op *, int); @@ -72149,15 +72240,15 @@ /* ** Delete a P4 value if necessary. */ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ freeEphemeralFunction(db, p->pFunc); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); switch( p4type ){ case P4_FUNCCTX: { @@ -72206,18 +72297,18 @@ ** nOp entries. */ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ if( aOp ){ Op *pOp; - for(pOp=aOp; pOp<&aOp[nOp]; pOp++){ + for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); #endif } + sqlite3DbFreeNN(db, aOp); } - sqlite3DbFree(db, aOp); } /* ** Link the SubProgram object passed as the second argument into the linked ** list at Vdbe.pSubProgram. This list is used to delete all sub-program @@ -72886,11 +72977,11 @@ testcase( p->flags & MEM_Frame ); testcase( p->flags & MEM_RowSet ); if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ - sqlite3DbFree(db, p->zMalloc); + sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; } p->flags = MEM_Undefined; }while( (++p)db, pCx); break; } case CURTYPE_BTREE: { - if( pCx->pBtx ){ - sqlite3BtreeClose(pCx->pBtx); + if( pCx->isEphemeral ){ + if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx); /* The pCx->pCursor will be close automatically, if it exists, by ** the call above. */ }else{ assert( pCx->uc.pCursor!=0 ); sqlite3BtreeCloseCursor(pCx->uc.pCursor); @@ -74257,11 +74348,10 @@ } fclose(out); } } #endif - p->iCurrentTime = 0; p->magic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } /* @@ -74296,20 +74386,22 @@ */ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ while( *pp ){ AuxData *pAux = *pp; if( (iOp<0) - || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg)))) + || (pAux->iAuxOp==iOp + && pAux->iAuxArg>=0 + && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg)))) ){ - testcase( pAux->iArg==31 ); - if( pAux->xDelete ){ - pAux->xDelete(pAux->pAux); + testcase( pAux->iAuxArg==31 ); + if( pAux->xDeleteAux ){ + pAux->xDeleteAux(pAux->pAux); } - *pp = pAux->pNext; + *pp = pAux->pNextAux; sqlite3DbFree(db, pAux); }else{ - pp= &pAux->pNext; + pp= &pAux->pNextAux; } } } /* @@ -74367,11 +74459,11 @@ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } p->magic = VDBE_MAGIC_DEAD; p->db = 0; - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } /* ** The cursor "p" has a pending seek operation that has not yet been ** carried out. Seek the cursor now. If an error occurs, return @@ -75926,11 +76018,11 @@ int i; for(i=0; iaMem[i]; if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -75993,11 +76085,11 @@ if( preupdate.aNew ){ int i; for(i=0; inField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - sqlite3DbFree(db, preupdate.aNew); + sqlite3DbFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of vdbeaux.c *********************************************/ @@ -76806,10 +76898,16 @@ } /* ** Return the auxiliary data pointer, if any, for the iArg'th argument to ** the user-function defined by pCtx. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then access a cache of +** auxiliary data pointers that is available to all functions within a +** single prepared statement. The iArg values must match. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); @@ -76816,21 +76914,28 @@ #if SQLITE_ENABLE_STAT3_OR_STAT4 if( pCtx->pVdbe==0 ) return 0; #else assert( pCtx->pVdbe!=0 ); #endif - for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ - if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + return pAuxData->pAux; + } } - - return (pAuxData ? pAuxData->pAux : 0); + return 0; } /* ** Set the auxiliary data pointer and delete function, for the iArg'th ** argument to the user-function defined by pCtx. Any previous value is ** deleted by calling the delete function specified when it was set. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then make the data available +** to all functions within the current prepared statement using iArg as an +** access code. */ SQLITE_API void sqlite3_set_auxdata( sqlite3_context *pCtx, int iArg, void *pAux, @@ -76838,37 +76943,38 @@ ){ AuxData *pAuxData; Vdbe *pVdbe = pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - if( iArg<0 ) goto failed; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( pVdbe==0 ) goto failed; #else assert( pVdbe!=0 ); #endif - for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ - if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + break; + } } if( pAuxData==0 ){ pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); if( !pAuxData ) goto failed; - pAuxData->iOp = pCtx->iOp; - pAuxData->iArg = iArg; - pAuxData->pNext = pVdbe->pAuxData; + pAuxData->iAuxOp = pCtx->iOp; + pAuxData->iAuxArg = iArg; + pAuxData->pNextAux = pVdbe->pAuxData; pVdbe->pAuxData = pAuxData; if( pCtx->fErrorOrAux==0 ){ pCtx->isError = 0; pCtx->fErrorOrAux = 1; } - }else if( pAuxData->xDelete ){ - pAuxData->xDelete(pAuxData->pAux); + }else if( pAuxData->xDeleteAux ){ + pAuxData->xDeleteAux(pAuxData->pAux); } pAuxData->pAux = pAux; - pAuxData->xDelete = xDelete; + pAuxData->xDeleteAux = xDelete; return; failed: if( xDelete ){ xDelete(pAux); @@ -78579,10 +78685,11 @@ } static void registerTrace(int iReg, Mem *p){ printf("REG[%d] = ", iReg); memTracePrint(p); printf("\n"); + sqlite3VdbeCheckMemInvariants(p); } #endif #ifdef SQLITE_DEBUG # define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) @@ -78945,11 +79052,11 @@ case OP_Goto: { /* jump */ jump_to_p2_and_check_for_interrupt: pOp = &aOp[pOp->p2 - 1]; /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, - ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon + ** OP_VNext, or OP_SorterNext) all jump here upon ** completion. Check to see if sqlite3_interrupt() has been called ** or if the progress callback needs to be invoked. ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this @@ -79333,11 +79440,11 @@ ** previously copied using OP_SCopy, the copies will continue to be valid. */ case OP_SoftNull: { assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); pOut = &aMem[pOp->p1]; - pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; + pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null; break; } /* Opcode: Blob P1 P2 * P4 * ** Synopsis: r[P2]=P4 (len=P1) @@ -79676,11 +79783,10 @@ type1 = numericType(pIn1); pIn2 = &aMem[pOp->p2]; type2 = numericType(pIn2); pOut = &aMem[pOp->p3]; flags = pIn1->flags | pIn2->flags; - if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; if( (type1 & type2 & MEM_Int)!=0 ){ iA = pIn1->u.i; iB = pIn2->u.i; bIntint = 1; switch( pOp->opcode ){ @@ -79700,10 +79806,12 @@ break; } } pOut->u.i = iB; MemSetTypeFlag(pOut, MEM_Int); + }else if( (flags & MEM_Null)!=0 ){ + goto arithmetic_result_is_null; }else{ bIntint = 0; fp_math: rA = sqlite3VdbeRealValue(pIn1); rB = sqlite3VdbeRealValue(pIn2); @@ -79747,11 +79855,11 @@ break; } /* Opcode: CollSeq P1 * * P4 ** -** P4 is a pointer to a CollSeq struct. If the next call to a user function +** P4 is a pointer to a CollSeq object. If the next call to a user function ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will ** be returned. This is used by the built-in min(), max() and nullif() ** functions. ** ** If P1 is not zero, then it is a register that a subsequent min() or @@ -80028,15 +80136,15 @@ ** Synopsis: affinity(r[P1]) ** ** Force the value in register P1 to be the type defined by P2. ** **
    -**
  • TEXT -**
  • BLOB -**
  • NUMERIC -**
  • INTEGER -**
  • REAL +**
  • P2=='A' → BLOB +**
  • P2=='B' → TEXT +**
  • P2=='C' → NUMERIC +**
  • P2=='D' → INTEGER +**
  • P2=='E' → REAL **
** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_Cast: { /* in1 */ @@ -80610,10 +80718,28 @@ if( (pIn1->flags & MEM_Null)==0 ){ goto jump_to_p2; } break; } + +/* Opcode: IfNullRow P1 P2 P3 * * +** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2 +** +** Check the cursor P1 to see if it is currently pointing at a NULL row. +** If it is, then set register P3 to NULL and jump immediately to P2. +** If P1 is not on a NULL row, then fall through without making any +** changes. +*/ +case OP_IfNullRow: { /* jump */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + if( p->apCsr[pOp->p1]->nullRow ){ + sqlite3VdbeMemSetNull(aMem + pOp->p3); + goto jump_to_p2; + } + break; +} /* Opcode: Column P1 P2 P3 P4 P5 ** Synopsis: r[P3]=PX ** ** Interpret the data that cursor P1 points to as a structure built using @@ -80622,20 +80748,20 @@ ** from this record. If there are less that (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is stored in register P3. ** -** If the column contains fewer than P2 fields, then extract a NULL. Or, +** If the record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. ** -** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { @@ -80886,28 +81012,28 @@ /* Opcode: Affinity P1 P2 * P4 * ** Synopsis: affinity(r[P1@P2]) ** ** Apply affinities to a range of P2 registers starting with P1. ** -** P4 is a string that is P2 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth +** P4 is a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th ** memory cell in the range. */ case OP_Affinity: { const char *zAffinity; /* The affinity to be applied */ - char cAff; /* A single character of affinity */ zAffinity = pOp->p4.z; assert( zAffinity!=0 ); + assert( pOp->p2>0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; - while( (cAff = *(zAffinity++))!=0 ){ + do{ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); - applyAffinity(pIn1, cAff, encoding); + applyAffinity(pIn1, *(zAffinity++), encoding); pIn1++; - } + }while( zAffinity[0] ); break; } /* Opcode: MakeRecord P1 P2 P3 P4 * ** Synopsis: r[P3]=mkrec(r[P1@P2]) @@ -80914,12 +81040,12 @@ ** ** Convert P2 registers beginning with P1 into the [record format] ** use as a data record in a database table or as a key ** in an index. The OP_Column opcode can decode the record later. ** -** P4 may be a string that is P2 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth +** P4 may be a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th ** field of the index key. ** ** The mapping from character to affinity is given by the SQLITE_AFF_ ** macros defined in sqliteInt.h. ** @@ -81074,11 +81200,10 @@ pOut->flags = MEM_Blob; if( nZero ){ pOut->u.nZero = nZero; pOut->flags |= MEM_Zero; } - pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); break; } @@ -81703,10 +81828,41 @@ sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); if( rc ) goto abort_due_to_error; break; } + +/* Opcode: OpenDup P1 P2 * * * +** +** Open a new cursor P1 that points to the same ephemeral table as +** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral +** opcode. Only ephemeral cursors may be duplicated. +** +** Duplicate ephemeral cursors are used for self-joins of materialized views. +*/ +case OP_OpenDup: { + VdbeCursor *pOrig; /* The original cursor to be duplicated */ + VdbeCursor *pCx; /* The new cursor */ + + pOrig = p->apCsr[pOp->p2]; + assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */ + + pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->isEphemeral = 1; + pCx->pKeyInfo = pOrig->pKeyInfo; + pCx->isTable = pOrig->isTable; + rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR, + pCx->pKeyInfo, pCx->uc.pCursor); + /* The sqlite3BtreeCursor() routine can only fail for the first cursor + ** opened for a database. Since there is already an open cursor when this + ** opcode is run, the sqlite3BtreeCursor() cannot fail */ + assert( rc==SQLITE_OK ); + break; +} + /* Opcode: OpenEphemeral P1 P2 * P4 P5 ** Synopsis: nColumn=P2 ** ** Open a new cursor P1 to a transient table. @@ -82239,14 +82395,16 @@ } #endif pIdxKey = &r; pFree = 0; }else{ + assert( pIn3->flags & MEM_Blob ); + rc = ExpandBlob(pIn3); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc ) goto no_mem; pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; - assert( pIn3->flags & MEM_Blob ); - (void)ExpandBlob(pIn3); sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } pIdxKey->default_rc = 0; takeJump = 0; if( pOp->opcode==OP_NoConflict ){ @@ -82259,11 +82417,11 @@ break; } } } rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); - if( pFree ) sqlite3DbFree(db, pFree); + if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pC->seekResult = res; alreadyExists = (res==0); @@ -83569,14 +83727,21 @@ ** ** If AUTOVACUUM is enabled then it is possible that another root page ** might be moved into the newly deleted root page in order to keep all ** root pages contiguous at the beginning of the database. The former ** value of the root page that moved - its value before the move occurred - -** is stored in register P2. If no page -** movement was required (because the table being dropped was already -** the last one in the database) then a zero is stored in register P2. -** If AUTOVACUUM is disabled then a zero is stored in register P2. +** is stored in register P2. If no page movement was required (because the +** table being dropped was already the last one in the database) then a +** zero is stored in register P2. If AUTOVACUUM is disabled then a zero +** is stored in register P2. +** +** This opcode throws an error if there are any active reader VMs when +** it is invoked. This is done to avoid the difficulty associated with +** updating existing cursors when a root page is moved in an AUTOVACUUM +** database. This error is thrown even if the database is not an AUTOVACUUM +** db in order to avoid introducing an incompatibility between autovacuum +** and non-autovacuum modes. ** ** See also: Clear */ case OP_Destroy: { /* out2 */ int iMoved; @@ -83777,11 +83942,11 @@ db->init.busy = 1; initData.rc = SQLITE_OK; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_OK ) rc = initData.rc; - sqlite3DbFree(db, zSql); + sqlite3DbFreeNN(db, zSql); db->init.busy = 0; } } if( rc ){ sqlite3ResetAllSchemasOfConnection(db); @@ -83905,11 +84070,11 @@ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: RowSetAdd P1 P2 * * * ** Synopsis: rowset(P1)=r[P2] ** -** Insert the integer value held by register P2 into a boolean index +** Insert the integer value held by register P2 into a RowSet object ** held in register P1. ** ** An assertion fails if P2 is not an integer. */ case OP_RowSetAdd: { /* in1, in2 */ @@ -83925,12 +84090,13 @@ } /* Opcode: RowSetRead P1 P2 P3 * * ** Synopsis: r[P3]=rowset(P1) ** -** Extract the smallest value from boolean index P1 and put that value into -** register P3. Or, if boolean index P1 is initially empty, leave P3 +** Extract the smallest value from the RowSet object in P1 +** and put that value into register P3. +** Or, if RowSet object P1 is initially empty, leave P3 ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, in1, out3 */ i64 val; @@ -83957,19 +84123,18 @@ ** contains a RowSet object and that RowSet object contains ** the value held in P3, jump to register P2. Otherwise, insert the ** integer in P3 into the RowSet and continue on to the ** next opcode. ** -** The RowSet object is optimized for the case where successive sets -** of integers, where each set contains no duplicates. Each set -** of values is identified by a unique P4 value. The first set -** must have P4==0, the final set P4=-1. P4 must be either -1 or -** non-negative. For non-negative values of P4 only the lower 4 -** bits are significant. +** The RowSet object is optimized for the case where sets of integers +** are inserted in distinct phases, which each set contains no duplicates. +** Each set is identified by a unique P4 value. The first set +** must have P4==0, the final set must have P4==-1, and for all other sets +** must have P4>0. ** ** This allows optimizations: (a) when P4==0 there is no need to test -** the rowset object for P3, as it is guaranteed not to contain it, +** the RowSet object for P3, as it is guaranteed not to contain it, ** (b) when P4==-1 there is no need to insert the value, as it will ** never be tested for, and (c) when a value that is part of set X is ** inserted, there is no need to search to see if the same value was ** previously inserted as part of set X (only if it was previously ** inserted as part of some other set). @@ -86705,41 +86870,40 @@ int res; /* Return value */ assert( (s1>0 && s1<7) || s1==8 || s1==9 ); assert( (s2>0 && s2<7) || s2==8 || s2==9 ); - if( s1>7 && s2>7 ){ - res = s1 - s2; - }else{ - if( s1==s2 ){ - if( (*v1 ^ *v2) & 0x80 ){ - /* The two values have different signs */ - res = (*v1 & 0x80) ? -1 : +1; - }else{ - /* The two values have the same sign. Compare using memcmp(). */ - static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 }; - int i; - res = 0; - for(i=0; i7 ){ - res = +1; - }else if( s1>7 ){ - res = -1; - }else{ - res = s1 - s2; - } - assert( res!=0 ); - - if( res>0 ){ - if( *v1 & 0x80 ) res = -1; - }else{ - if( *v2 & 0x80 ) res = +1; - } + if( s1==s2 ){ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 }; + const u8 n = aLen[s1]; + int i; + res = 0; + for(i=0; i7 && s2>7 ){ + res = s1 - s2; + }else{ + if( s2>7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; + }else{ + res = s1 - s2; + } + assert( res!=0 ); + + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; } } if( res==0 ){ if( pTask->pSorter->pKeyInfo->nField>1 ){ @@ -90790,11 +90954,11 @@ if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ + if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){ return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); return sqlite3ExprAffinity( @@ -91084,11 +91248,10 @@ }else{ return 1; } } -#ifndef SQLITE_OMIT_SUBQUERY /* ** Return a pointer to a subexpression of pVector that is the i-th ** column of the vector (numbered starting with 0). The caller must ** ensure that i is within range. ** @@ -91112,13 +91275,11 @@ return pVector->x.pList->a[i].pExpr; } } return pVector; } -#endif /* !defined(SQLITE_OMIT_SUBQUERY) */ -#ifndef SQLITE_OMIT_SUBQUERY /* ** Compute and return a new Expr object which when passed to ** sqlite3ExprCode() will generate all necessary code to compute ** the iField-th column of the vector expression pVector. ** @@ -91172,11 +91333,10 @@ if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; pRet = sqlite3ExprDup(pParse->db, pVector, 0); } return pRet; } -#endif /* !define(SQLITE_OMIT_SUBQUERY) */ /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate ** it. Return the register in which the result is stored (or, if the ** sub-select returns more than one column, the first in an array @@ -91688,11 +91848,11 @@ if( pExpr==0 ) return; assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); z = pExpr->u.zToken; assert( z!=0 ); assert( z[0]!=0 ); - assert( n==sqlite3Strlen30(z) ); + assert( n==(u32)sqlite3Strlen30(z) ); if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); x = (ynVar)(++pParse->nVar); }else{ @@ -91770,11 +91930,11 @@ sqlite3ExprListDelete(db, p->x.pList); } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } } SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } @@ -92037,19 +92197,15 @@ struct ExprList_item *pItem, *pOldItem; int i; Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, + sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) ); if( pNew==0 ) return 0; - pNew->nExpr = i = p->nExpr; - if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} - pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) ); - if( pItem==0 ){ - sqlite3DbFree(db, pNew); - return 0; - } + pNew->nAlloc = pNew->nExpr = p->nExpr; + pItem = pNew->a; pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); @@ -92136,11 +92292,11 @@ pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = p->nId; pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ - sqlite3DbFree(db, pNew); + sqlite3DbFreeNN(db, pNew); return 0; } /* Note that because the size of the allocation for p->a[] is not ** necessarily a power of two, sqlite3IdListAppend() may not be called ** on the duplicate created by this function. */ @@ -92207,35 +92363,33 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ + struct ExprList_item *pItem; sqlite3 *db = pParse->db; assert( db!=0 ); if( pList==0 ){ pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } pList->nExpr = 0; - pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0])); - if( pList->a==0 ) goto no_mem; - }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - struct ExprList_item *a; - assert( pList->nExpr>0 ); - a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); - if( a==0 ){ + pList->nAlloc = 1; + }else if( pList->nExpr==pList->nAlloc ){ + ExprList *pNew; + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0])); + if( pNew==0 ){ goto no_mem; } - pList->a = a; - } - assert( pList->a!=0 ); - if( 1 ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr++]; - memset(pItem, 0, sizeof(*pItem)); - pItem->pExpr = pExpr; - } + pList = pNew; + pList->nAlloc *= 2; + } + pItem = &pList->a[pList->nExpr++]; + memset(pItem, 0, sizeof(*pItem)); + pItem->pExpr = pExpr; return pList; no_mem: /* Avoid leaking memory if malloc has failed. */ sqlite3ExprDelete(db, pExpr); @@ -92288,24 +92442,23 @@ pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; pColumns->a[i].zName = 0; } } - if( pExpr->op==TK_SELECT ){ - if( pList && pList->a[iFirst].pExpr ){ - Expr *pFirst = pList->a[iFirst].pExpr; - assert( pFirst->op==TK_SELECT_COLUMN ); - - /* Store the SELECT statement in pRight so it will be deleted when - ** sqlite3ExprListDelete() is called */ - pFirst->pRight = pExpr; - pExpr = 0; - - /* Remember the size of the LHS in iTable so that we can check that - ** the RHS and LHS sizes match during code generation. */ - pFirst->iTable = pColumns->nId; - } + if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){ + Expr *pFirst = pList->a[iFirst].pExpr; + assert( pFirst!=0 ); + assert( pFirst->op==TK_SELECT_COLUMN ); + + /* Store the SELECT statement in pRight so it will be deleted when + ** sqlite3ExprListDelete() is called */ + pFirst->pRight = pExpr; + pExpr = 0; + + /* Remember the size of the LHS in iTable so that we can check that + ** the RHS and LHS sizes match during code generation. */ + pFirst->iTable = pColumns->nId; } vector_append_error: sqlite3ExprDelete(db, pExpr); sqlite3IdListDelete(db, pColumns); @@ -92395,20 +92548,20 @@ /* ** Delete an entire expression list. */ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ - int i; - struct ExprList_item *pItem; - assert( pList->a!=0 || pList->nExpr==0 ); - for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + assert( pList->nExpr>0 ); + do{ sqlite3ExprDelete(db, pItem->pExpr); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zSpan); - } - sqlite3DbFree(db, pList->a); - sqlite3DbFree(db, pList); + pItem++; + }while( --i>0 ); + sqlite3DbFreeNN(db, pList); } SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } @@ -92483,14 +92636,16 @@ testcase( pExpr->op==TK_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); testcase( pExpr->op==TK_AGG_COLUMN ); if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ return WRC_Continue; - }else{ - pWalker->eCode = 0; - return WRC_Abort; } + /* Fall through */ + case TK_IF_NULL_ROW: + testcase( pExpr->op==TK_IF_NULL_ROW ); + pWalker->eCode = 0; + return WRC_Abort; case TK_VARIABLE: if( pWalker->eCode==5 ){ /* Silently convert bound parameters that appear inside of CREATE ** statements into a NULL when parsing the CREATE statement text out ** of the sqlite_master table */ @@ -92554,10 +92709,69 @@ */ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } + +/* +** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). +*/ +static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ + ExprList *pGroupBy = pWalker->u.pGroupBy; + int i; + + /* Check if pExpr is identical to any GROUP BY term. If so, consider + ** it constant. */ + for(i=0; inExpr; i++){ + Expr *p = pGroupBy->a[i].pExpr; + if( sqlite3ExprCompare(pExpr, p, -1)<2 ){ + CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p); + if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){ + return WRC_Prune; + } + } + } + + /* Check if pExpr is a sub-select. If so, consider it variable. */ + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + return exprNodeIsConstant(pWalker, pExpr); +} + +/* +** Walk the expression tree passed as the first argument. Return non-zero +** if the expression consists entirely of constants or copies of terms +** in pGroupBy that sort with the BINARY collation sequence. +** +** This routine is used to determine if a term of the HAVING clause can +** be promoted into the WHERE clause. In order for such a promotion to work, +** the value of the HAVING clause term must be the same for all members of +** a "group". The requirement that the GROUP BY term must be BINARY +** assumes that no other collating sequence will have a finer-grained +** grouping than binary. In other words (A=B COLLATE binary) implies +** A=B in every other collating sequence. The requirement that the +** GROUP BY be BINARY is stricter than necessary. It would also work +** to promote HAVING clauses that use the same alternative collating +** sequence as the GROUP BY term, but that is much harder to check, +** alternative collating sequences are uncommon, and this is only an +** optimization, so we take the easy way out and simply require the +** GROUP BY to use the BINARY collating sequence. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 1; + w.xExprCallback = exprNodeIsConstantOrGroupBy; + w.u.pGroupBy = pGroupBy; + w.pParse = pParse; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + /* ** Walk an expression tree. Return non-zero if the expression is constant ** or a function call with constant arguments. Return and 0 if there ** are any variables. ** @@ -93931,10 +94145,14 @@ Table *pTab, /* The table containing the value */ int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ int iCol, /* Index of the column to extract */ int regOut /* Extract the value into this register */ ){ + if( pTab==0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); + return; + } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); }else{ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; int x = iCol; @@ -94087,11 +94305,15 @@ if( nResult==1 ){ iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); }else{ *piFreeable = 0; if( p->op==TK_SELECT ){ +#if SQLITE_OMIT_SUBQUERY + iResult = 0; +#else iResult = sqlite3CodeSubselect(pParse, p, 0, 0); +#endif }else{ int i; iResult = pParse->nMem+1; pParse->nMem += nResult; for(i=0; iiTable); + sqlite3ExprCachePush(pParse); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + sqlite3ExprCachePop(pParse); + sqlite3VdbeJumpHere(v, addrINR); + sqlite3VdbeChangeP3(v, addrINR, inReg); + break; + } /* ** Form A: ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END ** @@ -99401,10 +99634,22 @@ } if( db->xAuth==0 ){ return SQLITE_OK; } + + /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the + ** callback are either NULL pointers or zero-terminated strings that + ** contain additional details about the action to be authorized. + ** + ** The following testcase() macros show that any of the 3rd through 6th + ** parameters can be either NULL or a string. */ + testcase( zArg1==0 ); + testcase( zArg2==0 ); + testcase( zArg3==0 ); + testcase( pParse->zAuthContext==0 ); + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext #ifdef SQLITE_USER_AUTHENTICATION ,db->auth.zAuthUser #endif ); @@ -103072,11 +103317,11 @@ if( pList==0 ) return; for(i=0; inId; i++){ sqlite3DbFree(db, pList->a[i].zName); } sqlite3DbFree(db, pList->a); - sqlite3DbFree(db, pList); + sqlite3DbFreeNN(db, pList); } /* ** Return the index in pList of the identifier named zId. Return -1 ** if not found. @@ -103262,11 +103507,11 @@ sqlite3DeleteTable(db, pItem->pTab); sqlite3SelectDelete(db, pItem->pSelect); sqlite3ExprDelete(db, pItem->pOn); sqlite3IdListDelete(db, pItem->pUsing); } - sqlite3DbFree(db, pList); + sqlite3DbFreeNN(db, pList); } /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of @@ -104736,11 +104981,18 @@ #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Prior to version 3.6.5, ** this optimization caused the row change count (the value returned by - ** API function sqlite3_count_changes) to be set incorrectly. */ + ** API function sqlite3_count_changes) to be set incorrectly. + ** + ** The "rcauth==SQLITE_OK" terms is the + ** IMPLEMENATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and + ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but + ** the truncate optimization is disabled and all rows are deleted + ** individually. + */ if( rcauth==SQLITE_OK && pWhere==0 && !bComplex && !IsVirtual(pTab) #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -108246,42 +108498,57 @@ ** entry in the aChange[] array is set to -1. If the column is modified, ** the value is 0 or greater. Parameter chngRowid is set to true if the ** UPDATE statement modifies the rowid fields of the table. ** ** If any foreign key processing will be required, this function returns -** true. If there is no foreign key related processing, this function -** returns false. +** non-zero. If there is no foreign key related processing, this function +** returns zero. +** +** For an UPDATE, this function returns 2 if: +** +** * There are any FKs for which pTab is the child and the parent table, or +** * the UPDATE modifies one or more parent keys for which the action is +** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). +** +** Or, assuming some other foreign key processing is required, 1. */ SQLITE_PRIVATE int sqlite3FkRequired( Parse *pParse, /* Parse context */ Table *pTab, /* Table being modified */ int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ + int eRet = 0; if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !aChange ){ /* A DELETE operation. Foreign key processing is required if the ** table in question is either the child or parent table for any ** foreign key constraint. */ - return (sqlite3FkReferences(pTab) || pTab->pFKey); + eRet = (sqlite3FkReferences(pTab) || pTab->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ FKey *p; /* Check if any child key columns are being modified. */ for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2; + if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ + eRet = 1; + } } /* Check if any parent key columns are being modified. */ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1; + if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ + if( p->aAction[1]!=OE_None ) return 2; + eRet = 1; + } } } } - return 0; + return eRet; } /* ** This function is called when an UPDATE or DELETE operation is being ** compiled on table pTab, which is the parent table of foreign-key pFKey. @@ -112787,11 +113054,11 @@ /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif {/* zName: */ "optimize", /* ePragTyp: */ PragTyp_OPTIMIZE, - /* ePragFlg: */ PragFlg_Result1, + /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "page_count", /* ePragTyp: */ PragTyp_PAGE_COUNT, @@ -114287,37 +114554,41 @@ if( pParent ){ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); assert( x==0 ); } addrOk = sqlite3VdbeMakeLabel(v); - if( pParent && pIdx==0 ){ - int iKey = pFK->aCol[0].iFrom; - assert( iKey>=0 && iKeynCol ); - if( iKey!=pTab->iPKey ){ - sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); - sqlite3ColumnDefault(v, pTab, iKey, regRow); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); - }else{ - sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); - } - sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v); + + /* Generate code to read the child key values into registers + ** regRow..regRow+n. If any of the child key values are NULL, this + ** row cannot cause an FK violation. Jump directly to addrOk in + ** this case. */ + for(j=0; jnCol; j++){ + int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; + sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); + } + + /* Generate code to query the parent index for a matching parent + ** key. If a match is found, jump to addrOk. */ + if( pIdx ){ + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, + sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + VdbeCoverage(v); + }else if( pParent ){ + int jmp = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); - sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + assert( pFK->nCol==1 ); + } + + /* Generate code to report an FK violation to the caller. */ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); }else{ - for(j=0; jnCol; j++){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, - aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); - } - if( pParent ){ - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, - sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); - VdbeCoverage(v); - } - } - sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); + sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); + } sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1); sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); sqlite3VdbeResolveLabel(v, addrOk); sqlite3DbFree(db, aiCols); } @@ -114499,29 +114770,32 @@ integrityCheckResultRow(v, 3); sqlite3VdbeJumpHere(v, jmp2); } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ - int addrCkFault = sqlite3VdbeMakeLabel(v); - int addrCkOk = sqlite3VdbeMakeLabel(v); - ExprList *pCheck = pTab->pCheck; - char *zErr; - int k; - pParse->iSelfTab = iDataCur; - sqlite3ExprCachePush(pParse); - for(k=pCheck->nExpr-1; k>0; k--){ - sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); - } - sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, - SQLITE_JUMPIFNULL); - sqlite3VdbeResolveLabel(v, addrCkFault); - zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", - pTab->zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v, 3); - sqlite3VdbeResolveLabel(v, addrCkOk); - sqlite3ExprCachePop(pParse); + ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); + if( db->mallocFailed==0 ){ + int addrCkFault = sqlite3VdbeMakeLabel(v); + int addrCkOk = sqlite3VdbeMakeLabel(v); + char *zErr; + int k; + pParse->iSelfTab = iDataCur; + sqlite3ExprCachePush(pParse); + for(k=pCheck->nExpr-1; k>0; k--){ + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + } + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + SQLITE_JUMPIFNULL); + sqlite3VdbeResolveLabel(v, addrCkFault); + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v, 3); + sqlite3VdbeResolveLabel(v, addrCkOk); + sqlite3ExprCachePop(pParse); + } + sqlite3ExprListDelete(db, pCheck); } /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(v); @@ -116321,11 +116595,11 @@ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); sqlite3ExprDelete(db, p->pOffset); if( p->pWith ) sqlite3WithDelete(db, p->pWith); - if( bFree ) sqlite3DbFree(db, p); + if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } } @@ -116357,18 +116631,17 @@ Expr *pLimit, /* LIMIT value. NULL means not used */ Expr *pOffset /* OFFSET value. NULL means no offset */ ){ Select *pNew; Select standin; - sqlite3 *db = pParse->db; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); if( pNew==0 ){ - assert( db->mallocFailed ); + assert( pParse->db->mallocFailed ); pNew = &standin; } if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0)); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0)); } pNew->pEList = pEList; pNew->op = TK_SELECT; pNew->selFlags = selFlags; pNew->iLimit = 0; @@ -116377,11 +116650,11 @@ pNew->zSelName[0] = 0; #endif pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; - if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; @@ -116388,13 +116661,13 @@ pNew->pPrior = 0; pNew->pNext = 0; pNew->pLimit = pLimit; pNew->pOffset = pOffset; pNew->pWith = 0; - assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); - if( db->mallocFailed ) { - clearSelect(db, pNew, pNew!=&standin); + assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 ); + if( pParse->db->mallocFailed ) { + clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); } assert( pNew!=&standin ); @@ -117300,11 +117573,11 @@ */ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) sqlite3DbFree(p->db, p); + if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); } } /* ** Make a new pointer to a KeyInfo object @@ -117775,10 +118048,11 @@ Vdbe *v = pParse->pVdbe; int i; NameContext sNC; sNC.pSrcList = pTabList; sNC.pParse = pParse; + sNC.pNext = 0; for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; const char *zType; #ifdef SQLITE_ENABLE_COLUMN_METADATA const char *zOrigDb = 0; @@ -117798,10 +118072,23 @@ #endif sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); } #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ } + +/* +** Return the Table objecct in the SrcList that has cursor iCursor. +** Or return NULL if no such Table object exists in the SrcList. +*/ +static Table *tableWithCursor(SrcList *pList, int iCursor){ + int j; + for(j=0; jnSrc; j++){ + if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab; + } + return 0; +} + /* ** Generate code that will tell the VDBE the names of columns ** in the result set. This information is used to provide the ** azCol[] values in the callback. @@ -117810,11 +118097,12 @@ Parse *pParse, /* Parser context */ SrcList *pTabList, /* List of tables */ ExprList *pEList /* Expressions defining the result set */ ){ Vdbe *v = pParse->pVdbe; - int i, j; + int i; + Table *pTab; sqlite3 *db = pParse->db; int fullNames, shortNames; #ifndef SQLITE_OMIT_EXPLAIN /* If this is an EXPLAIN, skip this step */ @@ -117835,19 +118123,15 @@ p = pEList->a[i].pExpr; if( NEVER(p==0) ) continue; if( pEList->a[i].zName ){ char *zName = pEList->a[i].zName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); - }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){ - Table *pTab; + }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) + && (pTab = tableWithCursor(pTabList, p->iTable))!=0 + ){ char *zCol; int iCol = p->iColumn; - for(j=0; ALWAYS(jnSrc); j++){ - if( pTabList->a[j].iCursor==p->iTable ) break; - } - assert( jnSrc ); - pTab = pTabList->a[j].pTab; if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ zCol = "rowid"; }else{ @@ -117925,11 +118209,11 @@ Table *pTab; /* Table associated with this expression */ while( pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ + if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; pTab = pColExpr->pTab; if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; @@ -119145,11 +119429,11 @@ if( j==nOrderBy ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); if( pNew==0 ) return SQLITE_NOMEM_BKPT; pNew->flags |= EP_IntValue; pNew->u.iValue = i; - pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; } } } @@ -119379,13 +119663,28 @@ return pParse->nErr!=0; } #endif #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + +/* An instance of the SubstContext object describes an substitution edit +** to be performed on a parse tree. +** +** All references to columns in table iTable are to be replaced by corresponding +** expressions in pEList. +*/ +typedef struct SubstContext { + Parse *pParse; /* The parsing context */ + int iTable; /* Replace references to this table */ + int iNewTable; /* New table number */ + int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + ExprList *pEList; /* Replacement expressions */ +} SubstContext; + /* Forward Declarations */ -static void substExprList(Parse*, ExprList*, int, ExprList*); -static void substSelect(Parse*, Select *, int, ExprList*, int); +static void substExprList(SubstContext*, ExprList*); +static void substSelect(SubstContext*, Select*, int); /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th ** entry in pEList. (But leave references to the ROWID column @@ -119392,33 +119691,42 @@ ** unchanged.) ** ** This routine is part of the flattening procedure. A subquery ** whose result set is defined by pEList appears as entry in the ** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine make the necessary +** FORM clause entry is iTable. This routine makes the necessary ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ static Expr *substExpr( - Parse *pParse, /* Report errors here */ - Expr *pExpr, /* Expr in which substitution occurs */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute expressions */ + SubstContext *pSubst, /* Description of the substitution */ + Expr *pExpr /* Expr in which substitution occurs */ ){ - sqlite3 *db = pParse->db; if( pExpr==0 ) return 0; - if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ + if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){ + pExpr->iRightJoinTable = pSubst->iNewTable; + } + if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){ if( pExpr->iColumn<0 ){ pExpr->op = TK_NULL; }else{ Expr *pNew; - Expr *pCopy = pEList->a[pExpr->iColumn].pExpr; - assert( pEList!=0 && pExpr->iColumnnExpr ); + Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; + Expr ifNullRow; + assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); assert( pExpr->pLeft==0 && pExpr->pRight==0 ); if( sqlite3ExprIsVector(pCopy) ){ - sqlite3VectorErrorMsg(pParse, pCopy); + sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ + sqlite3 *db = pSubst->pParse->db; + if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){ + memset(&ifNullRow, 0, sizeof(ifNullRow)); + ifNullRow.op = TK_IF_NULL_ROW; + ifNullRow.pLeft = pCopy; + ifNullRow.iTable = pSubst->iNewTable; + pCopy = &ifNullRow; + } pNew = sqlite3ExprDup(db, pCopy, 0); if( pNew && (pExpr->flags & EP_FromJoin) ){ pNew->iRightJoinTable = pExpr->iRightJoinTable; pNew->flags |= EP_FromJoin; } @@ -119425,55 +119733,54 @@ sqlite3ExprDelete(db, pExpr); pExpr = pNew; } } }else{ - pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList); - pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList); + if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ + pExpr->iTable = pSubst->iNewTable; + } + pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); + pExpr->pRight = substExpr(pSubst, pExpr->pRight); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1); + substSelect(pSubst, pExpr->x.pSelect, 1); }else{ - substExprList(pParse, pExpr->x.pList, iTable, pEList); + substExprList(pSubst, pExpr->x.pList); } } return pExpr; } static void substExprList( - Parse *pParse, /* Report errors here */ - ExprList *pList, /* List to scan and in which to make substitutes */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute values */ + SubstContext *pSubst, /* Description of the substitution */ + ExprList *pList /* List to scan and in which to make substitutes */ ){ int i; if( pList==0 ) return; for(i=0; inExpr; i++){ - pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList); + pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr); } } static void substSelect( - Parse *pParse, /* Report errors here */ - Select *p, /* SELECT statement in which to make substitutions */ - int iTable, /* Table to be replaced */ - ExprList *pEList, /* Substitute values */ - int doPrior /* Do substitutes on p->pPrior too */ + SubstContext *pSubst, /* Description of the substitution */ + Select *p, /* SELECT statement in which to make substitutions */ + int doPrior /* Do substitutes on p->pPrior too */ ){ SrcList *pSrc; struct SrcList_item *pItem; int i; if( !p ) return; do{ - substExprList(pParse, p->pEList, iTable, pEList); - substExprList(pParse, p->pGroupBy, iTable, pEList); - substExprList(pParse, p->pOrderBy, iTable, pEList); - p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList); - p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList); + substExprList(pSubst, p->pEList); + substExprList(pSubst, p->pGroupBy); + substExprList(pSubst, p->pOrderBy); + p->pHaving = substExpr(pSubst, p->pHaving); + p->pWhere = substExpr(pSubst, p->pWhere); pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(pParse, pItem->pSelect, iTable, pEList, 1); + substSelect(pSubst, pItem->pSelect, 1); if( pItem->fg.isTabFunc ){ - substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList); + substExprList(pSubst, pItem->u1.pFuncArg); } } }while( doPrior && (p = p->pPrior)!=0 ); } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ @@ -119512,12 +119819,13 @@ ** (2) The subquery is not an aggregate or (2a) the outer query is not a join ** and (2b) the outer query does not use subqueries other than the one ** FROM-clause subquery that is a candidate for flattening. (2b is ** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) ** -** (3) The subquery is not the right operand of a left outer join -** (Originally ticket #306. Strengthened by ticket #3300) +** (3) The subquery is not the right operand of a LEFT JOIN +** or the subquery is not itself a join and the outer query is not +** an aggregate. ** ** (4) The subquery is not DISTINCT. ** ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT ** sub-queries that were excluded from this optimization. Restriction @@ -119525,11 +119833,11 @@ ** ** (6) The subquery does not use aggregates or the outer query is not ** DISTINCT. ** ** (7) The subquery has a FROM clause. TODO: For subqueries without -** A FROM clause, consider adding a FROM close with the special +** A FROM clause, consider adding a FROM clause with the special ** table sqlite_once that consists of a single row containing a ** single NULL. ** ** (8) The subquery does not use LIMIT or the outer query is not a join. ** @@ -119631,10 +119939,12 @@ Select *pSub1; /* Pointer to the rightmost select in sub-query */ SrcList *pSrc; /* The FROM clause of the outer query */ SrcList *pSubSrc; /* The FROM clause of the subquery */ ExprList *pList; /* The result set of the outer query */ int iParent; /* VDBE cursor number of the pSub result set temp table */ + int iNewParent = -1;/* Replacement table for iParent */ + int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ struct SrcList_item *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; @@ -119657,11 +119967,11 @@ || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 ){ return 0; /* Restriction (2b) */ } } - + pSubSrc = pSub->pSrc; assert( pSubSrc ); /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET ** because they could be computed at compile-time. But when LIMIT and OFFSET @@ -119695,45 +120005,43 @@ } if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ return 0; /* Restriction (23) */ } - /* OBSOLETE COMMENT 1: - ** Restriction 3: If the subquery is a join, make sure the subquery is - ** not used as the right operand of an outer join. Examples of why this - ** is not allowed: + /* + ** If the subquery is the right operand of a LEFT JOIN, then the + ** subquery may not be a join itself. Example of why this is not allowed: ** ** t1 LEFT OUTER JOIN (t2 JOIN t3) ** ** If we flatten the above, we would get ** ** (t1 LEFT OUTER JOIN t2) JOIN t3 ** ** which is not at all the same thing. ** - ** OBSOLETE COMMENT 2: - ** Restriction 12: If the subquery is the right operand of a left outer - ** join, make sure the subquery has no WHERE clause. - ** An examples of why this is not allowed: - ** - ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) - ** - ** If we flatten the above, we would get - ** - ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 - ** - ** But the t2.x>0 test will always fail on a NULL row of t2, which - ** effectively converts the OUTER JOIN into an INNER JOIN. - ** - ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: - ** Ticket #3300 shows that flattening the right term of a LEFT JOIN - ** is fraught with danger. Best to avoid the whole thing. If the - ** subquery is the right term of a LEFT JOIN, then do not flatten. + ** If the subquery is the right operand of a LEFT JOIN, then the outer + ** query cannot be an aggregate. This is an artifact of the way aggregates + ** are processed - there is not mechanism to determine if the LEFT JOIN + ** table should be all-NULL. + ** + ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ - return 0; + isLeftJoin = 1; + if( pSubSrc->nSrc>1 || isAgg ){ + return 0; /* Restriction (3) */ + } } +#ifdef SQLITE_EXTRA_IFNULLROW + else if( iFrom>0 && !isAgg ){ + /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for + ** every reference to any result column from subquery in a join, even though + ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */ + isLeftJoin = -1; + } +#endif /* Restriction 17: If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries ** that make up the compound SELECT are allowed to be aggregate or distinct ** queries. @@ -119937,10 +120245,11 @@ */ for(i=0; ia[i+iFrom].pUsing); assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); pSrc->a[i+iFrom] = pSubSrc->a[i]; + iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } pSrc->a[iFrom].fg.jointype = jointype; /* Now begin substituting subquery result set expressions for @@ -119982,10 +120291,13 @@ assert( pSub->pPrior==0 ); pParent->pOrderBy = pOrderBy; pSub->pOrderBy = 0; } pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); + if( isLeftJoin>0 ){ + setJoinExpr(pWhere, iNewParent); + } if( subqueryIsAgg ){ assert( pParent->pHaving==0 ); pParent->pHaving = pParent->pWhere; pParent->pWhere = pWhere; pParent->pHaving = sqlite3ExprAnd(db, @@ -119995,11 +120307,17 @@ pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); }else{ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); } if( db->mallocFailed==0 ){ - substSelect(pParse, pParent, iParent, pSub->pEList, 0); + SubstContext x; + x.pParse = pParse; + x.iTable = iParent; + x.iNewTable = iNewParent; + x.isLeftJoin = isLeftJoin; + x.pEList = pSub->pEList; + substSelect(&x, pParent, 0); } /* The flattened query is distinct if either the inner or the ** outer query is distinct. */ @@ -120098,12 +120416,18 @@ } if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */ if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; while( pSubq ){ + SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); - pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList); + x.pParse = pParse; + x.iTable = iCursor; + x.iNewTable = iCursor; + x.isLeftJoin = 0; + x.pEList = pSubq->pEList; + pNew = substExpr(&x, pNew); pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); pSubq = pSubq->pPrior; } } return nChng; @@ -121090,10 +121414,107 @@ } } #else # define explainSimpleCount(a,b,c) #endif + +/* +** Context object for havingToWhereExprCb(). +*/ +struct HavingToWhereCtx { + Expr **ppWhere; + ExprList *pGroupBy; +}; + +/* +** sqlite3WalkExpr() callback used by havingToWhere(). +** +** If the node passed to the callback is a TK_AND node, return +** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. +** +** Otherwise, return WRC_Prune. In this case, also check if the +** sub-expression matches the criteria for being moved to the WHERE +** clause. If so, add it to the WHERE clause and replace the sub-expression +** within the HAVING expression with a constant "1". +*/ +static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op!=TK_AND ){ + struct HavingToWhereCtx *p = pWalker->u.pHavingCtx; + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){ + sqlite3 *db = pWalker->pParse->db; + Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); + if( pNew ){ + Expr *pWhere = *(p->ppWhere); + SWAP(Expr, *pNew, *pExpr); + pNew = sqlite3ExprAnd(db, pWhere, pNew); + *(p->ppWhere) = pNew; + } + } + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Transfer eligible terms from the HAVING clause of a query, which is +** processed after grouping, to the WHERE clause, which is processed before +** grouping. For example, the query: +** +** SELECT * FROM WHERE a=? GROUP BY b HAVING b=? AND c=? +** +** can be rewritten as: +** +** SELECT * FROM WHERE a=? AND b=? GROUP BY b HAVING c=? +** +** A term of the HAVING expression is eligible for transfer if it consists +** entirely of constants and expressions that are also GROUP BY terms that +** use the "BINARY" collation sequence. +*/ +static void havingToWhere( + Parse *pParse, + ExprList *pGroupBy, + Expr *pHaving, + Expr **ppWhere +){ + struct HavingToWhereCtx sCtx; + Walker sWalker; + + sCtx.ppWhere = ppWhere; + sCtx.pGroupBy = pGroupBy; + + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = havingToWhereExprCb; + sWalker.u.pHavingCtx = &sCtx; + sqlite3WalkExpr(&sWalker, pHaving); +} + +/* +** Check to see if the pThis entry of pTabList is a self-join of a prior view. +** If it is, then return the SrcList_item for the prior view. If it is not, +** then return 0. +*/ +static struct SrcList_item *isSelfJoinView( + SrcList *pTabList, /* Search for self-joins in this FROM clause */ + struct SrcList_item *pThis /* Search for prior reference to this subquery */ +){ + struct SrcList_item *pItem; + for(pItem = pTabList->a; pItempSelect==0 ) continue; + if( pItem->fg.viaCoroutine ) continue; + if( pItem->zName==0 ) continue; + if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue; + if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; + if( sqlite3ExprCompare(pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) ){ + /* The view was modified by some other optimization such as + ** pushDownWhereTerms() */ + continue; + } + return pItem; + } + return 0; +} /* ** Generate code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. @@ -121230,17 +121651,42 @@ #endif return rc; } #endif - /* Generate code for all sub-queries in the FROM clause + /* For each term in the FROM clause, do two things: + ** (1) Authorized unreferenced tables + ** (2) Generate code for all sub-queries */ -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; inSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; - Select *pSub = pItem->pSelect; + Select *pSub; + + /* Issue SQLITE_READ authorizations with a fake column name for any tables that + ** are referenced but from which no values are extracted. Examples of where these + ** kinds of null SQLITE_READ authorizations would occur: + ** + ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" + ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" + ** + ** The fake column name is an empty string. It is possible for a table to + ** have a column named by the empty string, in which case there is no way to + ** distinguish between an unreferenced table and an actual reference to the + ** "" column. The original design was for the fake column name to be a NULL, + ** which would be unambiguous. But legacy authorization callbacks might + ** assume the column name is non-NULL and segfault. The use of an empty string + ** for the fake column name seems safer. + */ + if( pItem->colUsed==0 ){ + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + } + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + /* Generate code for all sub-queries in the FROM clause + */ + pSub = pItem->pSelect; 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 @@ -121247,10 +121693,14 @@ ** 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->fg.viaCoroutine==0 ){ + /* The subroutine that manifests the view might be a one-time routine, + ** or it might need to be rerun on each iteration because it + ** encodes a correlated subquery. */ + testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once ); sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); } continue; } @@ -121321,10 +121771,12 @@ ** is a register allocated to hold the subroutine return address */ int topAddr; int onceAddr = 0; int retAddr; + struct SrcList_item *pPrior; + assert( pItem->addrFillSub==0 ); pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; if( pItem->fg.isCorrelated==0 ){ @@ -121334,24 +121786,29 @@ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); } - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); - sqlite3Select(pParse, pSub, &dest); + pPrior = isSelfJoinView(pTabList, pItem); + if( pPrior ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + }else{ + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + sqlite3Select(pParse, pSub, &dest); + } pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); +#endif } -#endif /* Various elements of the SELECT copied into local variables for ** convenience */ pEList = p->pEList; pWhere = p->pWhere; @@ -121555,10 +122012,15 @@ sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; sAggInfo.pGroupBy = pGroupBy; sqlite3ExprAnalyzeAggList(&sNC, pEList); sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); if( pHaving ){ + if( pGroupBy ){ + assert( pWhere==p->pWhere ); + havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere); + pWhere = p->pWhere; + } sqlite3ExprAnalyzeAggregates(&sNC, pHaving); } sAggInfo.nAccumulator = sAggInfo.nColumn; for(i=0; ipIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ + if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; }else{ reg = 0; for(i=0; inKeyCol; i++){ @@ -123922,11 +124384,11 @@ ** is the column index supplied by the user. */ assert( regNew==regNewRowid+1 ); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, - OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP), + OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP), regNewRowid ); if( eOnePass==ONEPASS_MULTI ){ assert( hasFK==0 && chngKey==0 ); sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); @@ -123933,11 +124395,11 @@ } if( !pParse->nested ){ sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else - if( hasFK || chngKey ){ + if( hasFK>1 || chngKey ){ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif if( bReplace || chngKey ){ sqlite3VdbeJumpHere(v, addr1); @@ -125576,11 +126038,11 @@ /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; pTab = pExpr->pTab; - if( NEVER(pTab==0) ) return pDef; + if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; @@ -125911,10 +126373,11 @@ union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ u16 nBtm; /* Size of BTM vector */ u16 nTop; /* Size of TOP vector */ + u16 nIdxCol; /* Index column used for ORDER BY */ Index *pIndex; /* Index used, or NULL */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u8 needFree; /* True if sqlite3_free(idxStr) is needed */ @@ -126204,10 +126667,11 @@ struct WhereInfo { Parse *pParse; /* Parsing and code generating context */ SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ + Expr *pWhere; /* The complete WHERE clause */ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ @@ -127363,10 +127827,73 @@ }else{ assert( nReg==1 ); sqlite3ExprCode(pParse, p, iReg); } } + +/* An instance of the IdxExprTrans object carries information about a +** mapping from an expression on table columns into a column in an index +** down through the Walker. +*/ +typedef struct IdxExprTrans { + Expr *pIdxExpr; /* The index expression */ + int iTabCur; /* The cursor of the corresponding table */ + int iIdxCur; /* The cursor for the index */ + int iIdxCol; /* The column for the index */ +} IdxExprTrans; + +/* The walker node callback used to transform matching expressions into +** a reference to an index column for an index on an expression. +** +** If pExpr matches, then transform it into a reference to the index column +** that contains the value of pExpr. +*/ +static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr->op = TK_COLUMN; + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + pExpr->pTab = 0; + return WRC_Prune; + }else{ + return WRC_Continue; + } +} + +/* +** For an indexes on expression X, locate every instance of expression X in pExpr +** and change that subexpression into a reference to the appropriate column of +** the index. +*/ +static void whereIndexExprTrans( + Index *pIdx, /* The Index */ + int iTabCur, /* Cursor of the table that is being indexed */ + int iIdxCur, /* Cursor of the index itself */ + WhereInfo *pWInfo /* Transform expressions in this WHERE clause */ +){ + int iIdxCol; /* Column number of the index */ + ExprList *aColExpr; /* Expressions that are indexed */ + Walker w; + IdxExprTrans x; + aColExpr = pIdx->aColExpr; + if( aColExpr==0 ) return; /* Not an index on expressions */ + memset(&w, 0, sizeof(w)); + w.xExprCallback = whereIndexExprTransNode; + w.u.pIdxTrans = &x; + x.iTabCur = iTabCur; + x.iIdxCur = iIdxCur; + for(iIdxCol=0; iIdxColnExpr; iIdxCol++){ + if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue; + assert( aColExpr->a[iIdxCol].pExpr!=0 ); + x.iIdxCol = iIdxCol; + x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; + sqlite3WalkExpr(&w, pWInfo->pWhere); + sqlite3WalkExprList(&w, pWInfo->pOrderBy); + sqlite3WalkExprList(&w, pWInfo->pResultSet); + } +} /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. */ @@ -127391,10 +127918,12 @@ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ int iReleaseReg = 0; /* Temp register to free before returning */ + Index *pIdx = 0; /* Index used by loop (if any) */ + int loopAgain; /* True if constraint generator loop should repeat */ pParse = pWInfo->pParse; v = pParse->pVdbe; pWC = &pWInfo->sWC; db = pParse->db; @@ -127716,11 +128245,10 @@ WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ int startEq; /* True if range start uses ==, >= or <= */ int endEq; /* True if range end uses ==, >= or <= */ int start_constraints; /* Start of range is constrained */ int nConstraint; /* Number of constraint terms */ - Index *pIdx; /* The index we will be using */ int iIdxCur; /* The VDBE cursor for the index */ int nExtraReg = 0; /* Number of extra registers needed */ int op; /* Instruction opcode */ char *zStartAff; /* Affinity for start of range constraint */ char *zEndAff = 0; /* Affinity for end of range constraint */ @@ -127944,10 +128472,17 @@ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); } sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } + + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. + */ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; }else if( bRev ){ @@ -127960,10 +128495,11 @@ if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; }else{ assert( pLevel->p5==0 ); } + if( omitTable ) pIdx = 0; }else #ifndef SQLITE_OMIT_OR_OPTIMIZATION if( pLoop->wsFlags & WHERE_MULTI_OR ){ /* Case 5: Two or more separately indexed terms connected by OR @@ -128277,47 +128813,60 @@ pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); #endif /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. + ** + ** This loop may run either once (pIdx==0) or twice (pIdx!=0). If + ** it is run twice, then the first iteration codes those sub-expressions + ** that can be computed using columns from pIdx only (without seeking + ** the main table cursor). */ - for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ - Expr *pE; - int skipLikeAddr = 0; - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ - testcase( pWInfo->untestedTerms==0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); - pWInfo->untestedTerms = 1; - continue; - } - pE = pTerm->pExpr; - assert( pE!=0 ); - if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ - continue; - } - if( pTerm->wtFlags & TERM_LIKECOND ){ - /* If the TERM_LIKECOND flag is set, that means that the range search - ** is sufficient to guarantee that the LIKE operator is true, so we - ** can skip the call to the like(A,B) function. But this only works - ** for strings. So do not skip the call to the function on the pass - ** that compares BLOBs. */ + do{ + loopAgain = 0; + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + Expr *pE; + int skipLikeAddr = 0; + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + testcase( pWInfo->untestedTerms==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); + pWInfo->untestedTerms = 1; + continue; + } + pE = pTerm->pExpr; + assert( pE!=0 ); + if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ + continue; + } + if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + loopAgain = 1; + continue; + } + if( pTerm->wtFlags & TERM_LIKECOND ){ + /* If the TERM_LIKECOND flag is set, that means that the range search + ** is sufficient to guarantee that the LIKE operator is true, so we + ** can skip the call to the like(A,B) function. But this only works + ** for strings. So do not skip the call to the function on the pass + ** that compares BLOBs. */ #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS - continue; + continue; #else - u32 x = pLevel->iLikeRepCntr; - assert( x>0 ); - skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1)); - VdbeCoverage(v); + u32 x = pLevel->iLikeRepCntr; + assert( x>0 ); + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1)); + VdbeCoverage(v); #endif + } + sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); + pTerm->wtFlags |= TERM_CODED; } - sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); - if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); - pTerm->wtFlags |= TERM_CODED; - } + pIdx = 0; + }while( loopAgain ); /* Insert code to test for implied constraints based on transitivity ** of the "==" operator. ** ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" @@ -129206,31 +129755,50 @@ /* ** Expression pExpr is one operand of a comparison operator that might ** be useful for indexing. This routine checks to see if pExpr appears ** in any index. Return TRUE (1) if pExpr is an indexed term and return -** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor -** number of the table that is indexed and *piColumn to the column number +** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor +** number of the table that is indexed and aiCurCol[1] to the column number ** of the column that is indexed, or XN_EXPR (-2) if an expression is being ** indexed. ** ** If pExpr is a TK_COLUMN column reference, then this routine always returns ** true even if that particular column is not indexed, because the column ** might be added to an automatic index later. */ -static int exprMightBeIndexed( +static SQLITE_NOINLINE int exprMightBeIndexed2( SrcList *pFrom, /* The FROM clause */ - int op, /* The specific comparison operator */ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ - Expr *pExpr, /* An operand of a comparison operator */ - int *piCur, /* Write the referenced table cursor number here */ - int *piColumn /* Write the referenced table column number here */ + int *aiCurCol, /* Write the referenced table cursor and column here */ + Expr *pExpr /* An operand of a comparison operator */ ){ Index *pIdx; int i; int iCur; - + for(i=0; mPrereq>1; i++, mPrereq>>=1){} + iCur = pFrom->a[i].iCursor; + for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr==0 ) continue; + for(i=0; inKeyCol; i++){ + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; + if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ + aiCurCol[0] = iCur; + aiCurCol[1] = XN_EXPR; + return 1; + } + } + } + return 0; +} +static int exprMightBeIndexed( + SrcList *pFrom, /* The FROM clause */ + Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ + int *aiCurCol, /* Write the referenced table cursor & column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int op /* The specific comparison operator */ +){ /* If this expression is a vector to the left or right of a ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ pExpr = pExpr->x.pList->a[0].pExpr; } if( pExpr->op==TK_COLUMN ){ - *piCur = pExpr->iTable; - *piColumn = pExpr->iColumn; + aiCurCol[0] = pExpr->iTable; + aiCurCol[1] = pExpr->iColumn; return 1; } if( mPrereq==0 ) return 0; /* No table references */ if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */ - for(i=0; mPrereq>1; i++, mPrereq>>=1){} - iCur = pFrom->a[i].iCursor; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->aColExpr==0 ) continue; - for(i=0; inKeyCol; i++){ - if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ - *piCur = iCur; - *piColumn = XN_EXPR; - return 1; - } - } - } - return 0; + return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -129337,11 +129892,11 @@ pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(op) ){ - int iCur, iColumn; + int aiCurCol[2]; Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; if( pTerm->iField>0 ){ @@ -129348,18 +129903,18 @@ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; } - if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){ - pTerm->leftCursor = iCur; - pTerm->u.leftColumn = iColumn; + if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ + pTerm->leftCursor = aiCurCol[0]; + pTerm->u.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight - && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn) + && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op) ){ WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ assert( pTerm->iField==0 ); @@ -129385,12 +129940,12 @@ }else{ pDup = pExpr; pNew = pTerm; } exprCommute(pParse, pDup); - pNew->leftCursor = iCur; - pNew->u.leftColumn = iColumn; + pNew->leftCursor = aiCurCol[0]; + pNew->u.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; } @@ -129745,15 +130300,15 @@ */ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ Bitmask mask; if( p==0 ) return 0; if( p->op==TK_COLUMN ){ - mask = sqlite3WhereGetMask(pMaskSet, p->iTable); - return mask; + return sqlite3WhereGetMask(pMaskSet, p->iTable); } + mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; assert( !ExprHasProperty(p, EP_TokenOnly) ); - mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0; + if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); if( ExprHasProperty(p, EP_xIsSelect) ){ mask |= exprSelectUsage(pMaskSet, p->x.pSelect); }else if( p->x.pList ){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); @@ -131618,21 +132173,21 @@ sqlite3_free(p->u.vtab.idxStr); p->u.vtab.needFree = 0; p->u.vtab.idxStr = 0; }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ sqlite3DbFree(db, p->u.btree.pIndex->zColAff); - sqlite3DbFree(db, p->u.btree.pIndex); + sqlite3DbFreeNN(db, p->u.btree.pIndex); p->u.btree.pIndex = 0; } } } /* ** Deallocate internal memory used by a WhereLoop object */ static void whereLoopClear(sqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); whereLoopClearUnion(db, p); whereLoopInit(p); } /* @@ -131643,11 +132198,11 @@ if( p->nLSlot>=n ) return SQLITE_OK; n = (n+7)&~7; paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); if( paNew==0 ) return SQLITE_NOMEM_BKPT; memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); p->aLTerm = paNew; p->nLSlot = n; return SQLITE_OK; } @@ -131673,11 +132228,11 @@ /* ** Delete a WhereLoop object */ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ whereLoopClear(db, p); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } /* ** Free a WhereInfo structure */ @@ -131694,11 +132249,11 @@ while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } - sqlite3DbFree(db, pWInfo); + sqlite3DbFreeNN(db, pWInfo); } } /* ** Return TRUE if all of the following are true: @@ -133085,11 +133640,11 @@ pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); } } if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFree(pParse->db, p); + sqlite3DbFreeNN(pParse->db, p); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* @@ -133269,11 +133824,11 @@ whereLoopClear(db, pNew); return rc; } /* -** Examine a WherePath (with the addition of the extra WhereLoop of the 5th +** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY ** (or GROUP BY) without requiring a separate sort operation. Return N: ** ** N>0: N terms of the ORDER BY clause are satisfied ** N==0: No terms of the ORDER BY clause are satisfied @@ -133364,10 +133919,12 @@ pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ if( pLoop->u.vtab.isOrdered ) obSat = obDone; break; + }else{ + pLoop->u.btree.nIdxCol = 0; } iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; /* Mark off any ORDER BY term X that is a column in the table of ** the current loop for which there is term in the WHERE @@ -133509,10 +134066,11 @@ if( iColumn>=0 ){ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( !pColl ) pColl = db->pDfltColl; if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; } + pLoop->u.btree.nIdxCol = j+1; isMatch = 1; break; } if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ /* Make sure the sort order is compatible in an ORDER BY clause. @@ -133940,11 +134498,11 @@ nFrom = nTo; } if( nFrom==0 ){ sqlite3ErrorMsg(pParse, "no query solution"); - sqlite3DbFree(db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_ERROR; } /* Find the lowest cost path. pFrom will be left pointing to that path */ pFrom = aFrom; @@ -134016,11 +134574,11 @@ pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ - sqlite3DbFree(db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_OK; } /* ** Most queries use only a single table (they are not joins) and have @@ -134094,11 +134652,12 @@ } } if( pLoop->wsFlags ){ pLoop->nOut = (LogEst)1; pWInfo->a[0].pWLoop = pLoop; - pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); + assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] ); + pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ pWInfo->a[0].iTabCur = iCur; pWInfo->nRowOut = 1; if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; @@ -134278,10 +134837,11 @@ goto whereBeginError; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; + pWInfo->pWhere = pWhere; pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); pWInfo->wctrlFlags = wctrlFlags; @@ -134588,10 +135148,11 @@ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIx); if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 + && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", pIx->zName)); #ifdef SQLITE_ENABLE_COLUMN_USED_MASK @@ -134676,18 +135237,47 @@ sqlite3ExprCacheClear(pParse); for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; pLevel = &pWInfo->a[i]; pLoop = pLevel->pWLoop; - sqlite3VdbeResolveLabel(v, pLevel->addrCont); if( pLevel->op!=OP_Noop ){ +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + int addrSeek = 0; + Index *pIdx; + int n; + if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + && (pLoop->wsFlags & WHERE_INDEXED)!=0 + && (pIdx = pLoop->u.btree.pIndex)->hasStat1 + && (n = pLoop->u.btree.nIdxCol)>0 + && pIdx->aiRowLogEst[n]>=36 + ){ + int r1 = pParse->nMem+1; + int j, op; + for(j=0; jiIdxCur, j, r1+j); + } + pParse->nMem += n+1; + op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT; + addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n); + VdbeCoverageIf(v, op==OP_SeekLT); + VdbeCoverageIf(v, op==OP_SeekGT); + sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); + } +#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ + /* The common case: Advance to the next row */ + sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); +#endif + }else{ + sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; int j; sqlite3VdbeResolveLabel(v, pLevel->addrNxt); @@ -134806,10 +135396,12 @@ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; + }else if( pOp->opcode==OP_IfNullRow ){ + pOp->p1 = pLevel->iIdxCur; } } } } @@ -135115,11 +135707,11 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned char #define YYNOCODE 252 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 96 +#define YYWILDCARD 69 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; Expr* yy72; @@ -135222,419 +135814,419 @@ ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1567) +#define YY_ACTTAB_COUNT (1566) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100, - /* 10 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98, - /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95, - /* 30 */ 94, 94, 94, 93, 351, 325, 976, 976, 824, 824, - /* 40 */ 826, 946, 354, 99, 100, 90, 978, 978, 853, 856, - /* 50 */ 845, 845, 97, 97, 98, 98, 98, 98, 338, 96, - /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, - /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 976, 976, - /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100, - /* 90 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98, - /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95, - /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325, - /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90, - /* 130 */ 978, 978, 853, 856, 845, 845, 97, 97, 98, 98, - /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94, - /* 150 */ 94, 94, 93, 351, 957, 957, 325, 268, 428, 413, - /* 160 */ 411, 61, 752, 752, 99, 100, 90, 978, 978, 853, - /* 170 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 60, - /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 190 */ 351, 325, 270, 329, 273, 277, 958, 959, 250, 99, - /* 200 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97, - /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95, - /* 220 */ 95, 94, 94, 94, 93, 351, 325, 937, 1326, 698, - /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 978, 978, 853, - /* 240 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 347, - /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 260 */ 351, 325, 937, 1327, 384, 699, 1327, 381, 379, 99, - /* 270 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97, - /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95, - /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178, - /* 300 */ 833, 935, 373, 700, 99, 100, 90, 978, 978, 853, - /* 310 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 375, - /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 330 */ 351, 325, 1275, 946, 354, 818, 935, 739, 739, 99, - /* 340 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97, - /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95, - /* 360 */ 95, 94, 94, 94, 93, 351, 325, 968, 227, 92, - /* 370 */ 89, 178, 373, 300, 99, 100, 90, 978, 978, 853, - /* 380 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 920, - /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99, - /* 410 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97, - /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95, - /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 957, - /* 440 */ 957, 158, 25, 422, 99, 100, 90, 978, 978, 853, - /* 450 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 450, - /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 470 */ 351, 443, 224, 224, 420, 957, 957, 961, 325, 52, - /* 480 */ 52, 958, 959, 176, 415, 78, 99, 100, 90, 978, - /* 490 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98, - /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94, - /* 510 */ 94, 93, 351, 325, 428, 418, 298, 958, 959, 961, - /* 520 */ 81, 99, 88, 90, 978, 978, 853, 856, 845, 845, - /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96, - /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 842, - /* 550 */ 842, 854, 857, 996, 318, 343, 379, 100, 90, 978, - /* 560 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98, - /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94, - /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340, - /* 590 */ 928, 52, 52, 90, 978, 978, 853, 856, 845, 845, - /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96, - /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445, - /* 620 */ 846, 3, 1202, 361, 360, 378, 344, 813, 957, 957, - /* 630 */ 1299, 86, 445, 729, 3, 212, 169, 287, 405, 282, - /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245, - /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83, - /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246, - /* 670 */ 958, 959, 194, 455, 670, 402, 399, 398, 448, 243, - /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224, - /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427, - /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452, - /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1270, - /* 720 */ 1270, 23, 957, 957, 86, 445, 397, 3, 228, 429, - /* 730 */ 894, 824, 824, 826, 827, 19, 203, 720, 52, 52, - /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229, - /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85, - /* 760 */ 352, 352, 120, 157, 958, 959, 58, 976, 409, 355, - /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86, - /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96, - /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, - /* 800 */ 832, 120, 452, 451, 813, 886, 819, 83, 84, 976, - /* 810 */ 813, 132, 410, 919, 85, 352, 352, 132, 407, 789, - /* 820 */ 957, 957, 92, 89, 178, 916, 448, 262, 370, 261, - /* 830 */ 82, 913, 80, 262, 370, 261, 776, 824, 824, 826, - /* 840 */ 827, 19, 933, 434, 96, 96, 96, 96, 95, 95, - /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 957, - /* 860 */ 957, 819, 958, 959, 120, 92, 89, 178, 944, 2, - /* 870 */ 917, 964, 268, 1, 975, 76, 445, 762, 3, 708, - /* 880 */ 900, 900, 387, 957, 957, 757, 918, 371, 740, 778, - /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450, - /* 900 */ 24, 958, 959, 83, 84, 369, 957, 957, 177, 226, - /* 910 */ 85, 352, 352, 884, 315, 314, 313, 215, 311, 10, - /* 920 */ 10, 683, 448, 349, 348, 958, 959, 908, 777, 157, - /* 930 */ 120, 957, 957, 337, 776, 416, 711, 310, 450, 434, - /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 958, 959, - /* 950 */ 907, 832, 792, 452, 451, 9, 9, 819, 10, 10, - /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171, - /* 970 */ 170, 167, 339, 958, 959, 247, 984, 702, 702, 450, - /* 980 */ 715, 233, 686, 982, 888, 983, 182, 913, 824, 824, - /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10, - /* 1000 */ 10, 888, 890, 749, 957, 957, 916, 268, 985, 198, - /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825, - /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91, - /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 1040 */ 351, 157, 810, 371, 382, 359, 958, 959, 358, 268, - /* 1050 */ 450, 917, 368, 324, 824, 824, 826, 450, 709, 450, - /* 1060 */ 264, 380, 888, 450, 876, 746, 253, 918, 255, 433, - /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12, - /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162, - /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450, - /* 1100 */ 709, 1209, 450, 132, 450, 39, 39, 450, 40, 40, - /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28, - /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450, - /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767, - /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47, - /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172, - /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122, - /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 897, 56, 56, - /* 1180 */ 450, 896, 35, 35, 450, 267, 450, 817, 450, 817, - /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817, - /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119, - /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111, - /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 911, - /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331, - /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 936, 197, - /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436, - /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 932, - /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202, - /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 883, - /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74, - /* 1300 */ 726, 727, 785, 783, 879, 202, 999, 208, 893, 892, - /* 1310 */ 893, 892, 694, 816, 763, 116, 774, 1289, 431, 432, - /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289, - /* 1330 */ 679, 883, 681, 951, 291, 218, 293, 7, 316, 828, - /* 1340 */ 173, 805, 259, 364, 252, 910, 376, 713, 295, 435, - /* 1350 */ 308, 168, 954, 993, 135, 400, 990, 284, 881, 880, - /* 1360 */ 205, 927, 925, 59, 333, 62, 144, 156, 130, 72, - /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383, - /* 1380 */ 67, 895, 140, 141, 142, 148, 389, 812, 775, 266, - /* 1390 */ 219, 190, 154, 391, 912, 875, 271, 406, 191, 322, - /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421, - /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346, - /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 966, 239, - /* 1430 */ 769, 102, 861, 438, 426, 240, 424, 442, 73, 213, - /* 1440 */ 688, 238, 22, 453, 952, 214, 217, 216, 454, 677, - /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166, - /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 891, - /* 1470 */ 327, 889, 811, 328, 134, 128, 136, 138, 743, 258, - /* 1480 */ 906, 184, 143, 129, 909, 186, 63, 64, 145, 187, - /* 1490 */ 905, 65, 8, 66, 13, 188, 202, 898, 265, 149, - /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396, - /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131, - /* 1520 */ 830, 859, 70, 751, 16, 414, 755, 4, 174, 220, - /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 874, - /* 1540 */ 860, 858, 915, 863, 914, 207, 206, 941, 163, 437, - /* 1550 */ 947, 942, 164, 209, 1002, 441, 862, 165, 210, 829, - /* 1560 */ 695, 87, 312, 211, 1291, 1290, 309, + /* 0 */ 325, 411, 343, 752, 752, 203, 946, 354, 976, 98, + /* 10 */ 98, 98, 98, 91, 96, 96, 96, 96, 95, 95, + /* 20 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 813, + /* 30 */ 978, 978, 98, 98, 98, 98, 20, 96, 96, 96, + /* 40 */ 96, 95, 95, 94, 94, 94, 93, 351, 92, 89, + /* 50 */ 178, 99, 100, 90, 853, 856, 845, 845, 97, 97, + /* 60 */ 98, 98, 98, 98, 351, 96, 96, 96, 96, 95, + /* 70 */ 95, 94, 94, 94, 93, 351, 325, 340, 976, 262, + /* 80 */ 365, 251, 212, 169, 287, 405, 282, 404, 199, 791, + /* 90 */ 242, 412, 21, 957, 379, 280, 93, 351, 792, 95, + /* 100 */ 95, 94, 94, 94, 93, 351, 978, 978, 96, 96, + /* 110 */ 96, 96, 95, 95, 94, 94, 94, 93, 351, 813, + /* 120 */ 329, 242, 412, 913, 832, 913, 132, 99, 100, 90, + /* 130 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98, + /* 140 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94, + /* 150 */ 93, 351, 325, 825, 349, 348, 120, 819, 120, 75, + /* 160 */ 52, 52, 957, 958, 959, 760, 984, 146, 361, 262, + /* 170 */ 370, 261, 957, 982, 961, 983, 92, 89, 178, 371, + /* 180 */ 230, 371, 978, 978, 817, 361, 360, 101, 824, 824, + /* 190 */ 826, 384, 24, 964, 381, 428, 413, 369, 985, 380, + /* 200 */ 985, 708, 325, 99, 100, 90, 853, 856, 845, 845, + /* 210 */ 97, 97, 98, 98, 98, 98, 373, 96, 96, 96, + /* 220 */ 96, 95, 95, 94, 94, 94, 93, 351, 957, 132, + /* 230 */ 897, 450, 978, 978, 896, 60, 94, 94, 94, 93, + /* 240 */ 351, 957, 958, 959, 961, 103, 361, 957, 385, 334, + /* 250 */ 702, 52, 52, 99, 100, 90, 853, 856, 845, 845, + /* 260 */ 97, 97, 98, 98, 98, 98, 698, 96, 96, 96, + /* 270 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 455, + /* 280 */ 670, 450, 227, 61, 157, 243, 344, 114, 701, 888, + /* 290 */ 147, 832, 957, 373, 747, 957, 320, 957, 958, 959, + /* 300 */ 194, 10, 10, 402, 399, 398, 888, 890, 978, 978, + /* 310 */ 762, 171, 170, 157, 397, 337, 957, 958, 959, 702, + /* 320 */ 825, 310, 153, 957, 819, 321, 82, 23, 80, 99, + /* 330 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98, + /* 340 */ 98, 98, 894, 96, 96, 96, 96, 95, 95, 94, + /* 350 */ 94, 94, 93, 351, 325, 824, 824, 826, 277, 231, + /* 360 */ 300, 957, 958, 959, 957, 958, 959, 888, 194, 25, + /* 370 */ 450, 402, 399, 398, 957, 355, 300, 450, 957, 74, + /* 380 */ 450, 1, 397, 132, 978, 978, 957, 224, 224, 813, + /* 390 */ 10, 10, 957, 958, 959, 968, 132, 52, 52, 415, + /* 400 */ 52, 52, 739, 739, 339, 99, 100, 90, 853, 856, + /* 410 */ 845, 845, 97, 97, 98, 98, 98, 98, 790, 96, + /* 420 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, + /* 430 */ 325, 789, 428, 418, 706, 428, 427, 1270, 1270, 262, + /* 440 */ 370, 261, 957, 957, 958, 959, 757, 957, 958, 959, + /* 450 */ 450, 756, 450, 734, 713, 957, 958, 959, 443, 711, + /* 460 */ 978, 978, 734, 394, 92, 89, 178, 447, 447, 447, + /* 470 */ 51, 51, 52, 52, 439, 778, 700, 92, 89, 178, + /* 480 */ 172, 99, 100, 90, 853, 856, 845, 845, 97, 97, + /* 490 */ 98, 98, 98, 98, 198, 96, 96, 96, 96, 95, + /* 500 */ 95, 94, 94, 94, 93, 351, 325, 428, 408, 916, + /* 510 */ 699, 957, 958, 959, 92, 89, 178, 224, 224, 157, + /* 520 */ 241, 221, 419, 299, 776, 917, 416, 375, 450, 415, + /* 530 */ 58, 324, 737, 737, 920, 379, 978, 978, 379, 777, + /* 540 */ 449, 918, 363, 740, 296, 686, 9, 9, 52, 52, + /* 550 */ 234, 330, 234, 256, 417, 741, 280, 99, 100, 90, + /* 560 */ 853, 856, 845, 845, 97, 97, 98, 98, 98, 98, + /* 570 */ 450, 96, 96, 96, 96, 95, 95, 94, 94, 94, + /* 580 */ 93, 351, 325, 423, 72, 450, 833, 120, 368, 450, + /* 590 */ 10, 10, 5, 301, 203, 450, 177, 976, 253, 420, + /* 600 */ 255, 776, 200, 175, 233, 10, 10, 842, 842, 36, + /* 610 */ 36, 1299, 978, 978, 729, 37, 37, 349, 348, 425, + /* 620 */ 203, 260, 776, 976, 232, 937, 1326, 876, 338, 1326, + /* 630 */ 422, 854, 857, 99, 100, 90, 853, 856, 845, 845, + /* 640 */ 97, 97, 98, 98, 98, 98, 268, 96, 96, 96, + /* 650 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 846, + /* 660 */ 450, 985, 818, 985, 1209, 450, 916, 976, 720, 350, + /* 670 */ 350, 350, 935, 177, 450, 937, 1327, 254, 198, 1327, + /* 680 */ 12, 12, 917, 403, 450, 27, 27, 250, 978, 978, + /* 690 */ 118, 721, 162, 976, 38, 38, 268, 176, 918, 776, + /* 700 */ 433, 1275, 946, 354, 39, 39, 317, 998, 325, 99, + /* 710 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98, + /* 720 */ 98, 98, 935, 96, 96, 96, 96, 95, 95, 94, + /* 730 */ 94, 94, 93, 351, 450, 330, 450, 358, 978, 978, + /* 740 */ 717, 317, 936, 341, 900, 900, 387, 673, 674, 675, + /* 750 */ 275, 996, 318, 999, 40, 40, 41, 41, 268, 99, + /* 760 */ 100, 90, 853, 856, 845, 845, 97, 97, 98, 98, + /* 770 */ 98, 98, 450, 96, 96, 96, 96, 95, 95, 94, + /* 780 */ 94, 94, 93, 351, 325, 450, 356, 450, 999, 450, + /* 790 */ 692, 331, 42, 42, 791, 270, 450, 273, 450, 228, + /* 800 */ 450, 298, 450, 792, 450, 28, 28, 29, 29, 31, + /* 810 */ 31, 450, 817, 450, 978, 978, 43, 43, 44, 44, + /* 820 */ 45, 45, 11, 11, 46, 46, 893, 78, 893, 268, + /* 830 */ 268, 105, 105, 47, 47, 99, 100, 90, 853, 856, + /* 840 */ 845, 845, 97, 97, 98, 98, 98, 98, 450, 96, + /* 850 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, + /* 860 */ 325, 450, 117, 450, 749, 158, 450, 696, 48, 48, + /* 870 */ 229, 919, 450, 928, 450, 415, 450, 335, 450, 245, + /* 880 */ 450, 33, 33, 49, 49, 450, 50, 50, 246, 817, + /* 890 */ 978, 978, 34, 34, 122, 122, 123, 123, 124, 124, + /* 900 */ 56, 56, 268, 81, 249, 35, 35, 197, 196, 195, + /* 910 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97, + /* 920 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95, + /* 930 */ 95, 94, 94, 94, 93, 351, 450, 696, 450, 817, + /* 940 */ 978, 978, 975, 884, 106, 106, 268, 886, 268, 944, + /* 950 */ 2, 892, 268, 892, 336, 716, 53, 53, 107, 107, + /* 960 */ 325, 99, 100, 90, 853, 856, 845, 845, 97, 97, + /* 970 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95, + /* 980 */ 95, 94, 94, 94, 93, 351, 450, 746, 450, 742, + /* 990 */ 978, 978, 715, 267, 108, 108, 446, 331, 332, 133, + /* 1000 */ 223, 175, 301, 225, 386, 933, 104, 104, 121, 121, + /* 1010 */ 325, 99, 88, 90, 853, 856, 845, 845, 97, 97, + /* 1020 */ 98, 98, 98, 98, 817, 96, 96, 96, 96, 95, + /* 1030 */ 95, 94, 94, 94, 93, 351, 450, 347, 450, 167, + /* 1040 */ 978, 978, 932, 815, 372, 319, 202, 202, 374, 263, + /* 1050 */ 395, 202, 74, 208, 726, 727, 119, 119, 112, 112, + /* 1060 */ 325, 407, 100, 90, 853, 856, 845, 845, 97, 97, + /* 1070 */ 98, 98, 98, 98, 450, 96, 96, 96, 96, 95, + /* 1080 */ 95, 94, 94, 94, 93, 351, 450, 757, 450, 345, + /* 1090 */ 978, 978, 756, 278, 111, 111, 74, 719, 718, 709, + /* 1100 */ 286, 883, 754, 1289, 257, 77, 109, 109, 110, 110, + /* 1110 */ 908, 285, 810, 90, 853, 856, 845, 845, 97, 97, + /* 1120 */ 98, 98, 98, 98, 911, 96, 96, 96, 96, 95, + /* 1130 */ 95, 94, 94, 94, 93, 351, 86, 445, 450, 3, + /* 1140 */ 1202, 450, 745, 132, 352, 120, 689, 86, 445, 785, + /* 1150 */ 3, 767, 202, 377, 448, 352, 907, 120, 55, 55, + /* 1160 */ 450, 57, 57, 828, 879, 448, 450, 208, 450, 709, + /* 1170 */ 450, 883, 237, 434, 436, 120, 440, 429, 362, 120, + /* 1180 */ 54, 54, 132, 450, 434, 832, 52, 52, 26, 26, + /* 1190 */ 30, 30, 382, 132, 409, 444, 832, 694, 264, 390, + /* 1200 */ 116, 269, 272, 32, 32, 83, 84, 120, 274, 120, + /* 1210 */ 120, 276, 85, 352, 452, 451, 83, 84, 819, 730, + /* 1220 */ 714, 428, 430, 85, 352, 452, 451, 120, 120, 819, + /* 1230 */ 378, 218, 281, 828, 783, 816, 86, 445, 410, 3, + /* 1240 */ 763, 774, 431, 432, 352, 302, 303, 823, 697, 824, + /* 1250 */ 824, 826, 827, 19, 448, 691, 680, 679, 681, 951, + /* 1260 */ 824, 824, 826, 827, 19, 289, 159, 291, 293, 7, + /* 1270 */ 316, 173, 259, 434, 805, 364, 252, 910, 376, 713, + /* 1280 */ 295, 435, 168, 993, 400, 832, 284, 881, 880, 205, + /* 1290 */ 954, 308, 927, 86, 445, 990, 3, 925, 333, 144, + /* 1300 */ 130, 352, 72, 135, 59, 83, 84, 761, 137, 366, + /* 1310 */ 802, 448, 85, 352, 452, 451, 139, 226, 819, 140, + /* 1320 */ 156, 62, 315, 314, 313, 215, 311, 367, 393, 683, + /* 1330 */ 434, 185, 141, 912, 142, 160, 148, 812, 875, 383, + /* 1340 */ 189, 67, 832, 180, 389, 248, 895, 775, 219, 824, + /* 1350 */ 824, 826, 827, 19, 247, 190, 266, 154, 391, 271, + /* 1360 */ 191, 192, 83, 84, 682, 406, 733, 182, 322, 85, + /* 1370 */ 352, 452, 451, 732, 183, 819, 342, 132, 181, 711, + /* 1380 */ 731, 421, 76, 445, 705, 3, 323, 704, 283, 724, + /* 1390 */ 352, 771, 703, 966, 723, 71, 204, 6, 288, 290, + /* 1400 */ 448, 772, 770, 769, 79, 292, 824, 824, 826, 827, + /* 1410 */ 19, 294, 297, 438, 346, 442, 102, 861, 753, 434, + /* 1420 */ 238, 426, 73, 305, 239, 304, 326, 240, 424, 306, + /* 1430 */ 307, 832, 213, 688, 22, 952, 453, 214, 216, 217, + /* 1440 */ 454, 677, 115, 676, 671, 125, 126, 235, 127, 669, + /* 1450 */ 327, 83, 84, 359, 353, 244, 166, 328, 85, 352, + /* 1460 */ 452, 451, 134, 179, 819, 357, 113, 891, 811, 889, + /* 1470 */ 136, 128, 138, 743, 258, 184, 906, 143, 145, 63, + /* 1480 */ 64, 65, 66, 129, 909, 905, 187, 186, 8, 13, + /* 1490 */ 188, 265, 898, 149, 202, 824, 824, 826, 827, 19, + /* 1500 */ 388, 987, 150, 161, 285, 685, 392, 396, 151, 722, + /* 1510 */ 193, 68, 14, 401, 279, 15, 69, 236, 831, 830, + /* 1520 */ 131, 859, 751, 70, 16, 414, 755, 4, 784, 220, + /* 1530 */ 222, 174, 152, 437, 779, 201, 17, 77, 74, 18, + /* 1540 */ 874, 860, 858, 915, 863, 914, 207, 206, 941, 163, + /* 1550 */ 210, 942, 209, 164, 441, 862, 165, 211, 829, 695, + /* 1560 */ 87, 312, 309, 947, 1291, 1290, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28, - /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48, - /* 30 */ 49, 50, 51, 52, 53, 19, 55, 55, 132, 133, - /* 40 */ 134, 1, 2, 27, 28, 29, 30, 31, 32, 33, - /* 50 */ 34, 35, 36, 37, 38, 39, 40, 41, 187, 43, - /* 60 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 70 */ 47, 48, 49, 50, 51, 52, 53, 61, 97, 97, - /* 80 */ 19, 49, 50, 51, 52, 53, 70, 26, 27, 28, - /* 90 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - /* 100 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48, - /* 110 */ 49, 50, 51, 52, 53, 144, 145, 146, 147, 19, - /* 120 */ 16, 22, 92, 172, 173, 52, 53, 27, 28, 29, - /* 130 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - /* 140 */ 40, 41, 81, 43, 44, 45, 46, 47, 48, 49, - /* 150 */ 50, 51, 52, 53, 55, 56, 19, 152, 207, 208, - /* 160 */ 115, 24, 117, 118, 27, 28, 29, 30, 31, 32, - /* 170 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 79, - /* 180 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 190 */ 53, 19, 88, 157, 90, 23, 97, 98, 193, 27, - /* 200 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 210 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47, - /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 172, - /* 230 */ 23, 26, 119, 120, 27, 28, 29, 30, 31, 32, - /* 240 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 187, - /* 250 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 260 */ 53, 19, 22, 23, 228, 23, 26, 231, 152, 27, - /* 270 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 280 */ 38, 39, 40, 41, 172, 43, 44, 45, 46, 47, - /* 290 */ 48, 49, 50, 51, 52, 53, 19, 221, 222, 223, - /* 300 */ 23, 96, 152, 172, 27, 28, 29, 30, 31, 32, - /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152, - /* 320 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 330 */ 53, 19, 0, 1, 2, 23, 96, 190, 191, 27, - /* 340 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 350 */ 38, 39, 40, 41, 238, 43, 44, 45, 46, 47, - /* 360 */ 48, 49, 50, 51, 52, 53, 19, 185, 218, 221, - /* 370 */ 222, 223, 152, 152, 27, 28, 29, 30, 31, 32, - /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 241, - /* 390 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 400 */ 53, 19, 152, 168, 169, 170, 22, 190, 191, 27, - /* 410 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 420 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47, - /* 430 */ 48, 49, 50, 51, 52, 53, 19, 19, 218, 55, - /* 440 */ 56, 24, 22, 152, 27, 28, 29, 30, 31, 32, - /* 450 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152, - /* 460 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 470 */ 53, 250, 194, 195, 56, 55, 56, 55, 19, 172, - /* 480 */ 173, 97, 98, 152, 206, 138, 27, 28, 29, 30, - /* 490 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - /* 500 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50, - /* 510 */ 51, 52, 53, 19, 207, 208, 152, 97, 98, 97, - /* 520 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35, - /* 530 */ 36, 37, 38, 39, 40, 41, 181, 43, 44, 45, - /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 30, - /* 550 */ 31, 32, 33, 247, 248, 19, 152, 28, 29, 30, - /* 560 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - /* 570 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50, - /* 580 */ 51, 52, 53, 19, 168, 169, 170, 238, 19, 53, - /* 590 */ 152, 172, 173, 29, 30, 31, 32, 33, 34, 35, - /* 600 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45, - /* 610 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 20, - /* 620 */ 101, 22, 23, 169, 170, 56, 207, 85, 55, 56, - /* 630 */ 23, 19, 20, 26, 22, 99, 100, 101, 102, 103, - /* 640 */ 104, 105, 238, 152, 152, 210, 47, 48, 112, 152, - /* 650 */ 108, 109, 110, 54, 55, 56, 221, 222, 223, 47, - /* 660 */ 48, 119, 120, 172, 173, 66, 54, 55, 56, 152, - /* 670 */ 97, 98, 99, 148, 149, 102, 103, 104, 66, 154, - /* 680 */ 23, 156, 83, 26, 230, 152, 113, 152, 163, 194, - /* 690 */ 195, 92, 92, 30, 95, 83, 97, 98, 207, 208, - /* 700 */ 101, 206, 179, 180, 92, 172, 173, 95, 152, 97, - /* 710 */ 98, 188, 99, 101, 219, 102, 103, 104, 152, 119, - /* 720 */ 120, 196, 55, 56, 19, 20, 113, 22, 193, 163, - /* 730 */ 11, 132, 133, 134, 135, 136, 24, 65, 172, 173, - /* 740 */ 207, 208, 250, 152, 132, 133, 134, 135, 136, 193, - /* 750 */ 78, 84, 47, 48, 49, 98, 199, 152, 86, 54, - /* 760 */ 55, 56, 196, 152, 97, 98, 209, 55, 163, 244, - /* 770 */ 107, 66, 152, 207, 208, 164, 175, 172, 173, 19, - /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43, - /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97, - /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175, - /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110, - /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134, - /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48, - /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55, - /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147, - /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179, - /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124, - /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152, - /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5, - /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172, - /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152, - /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83, - /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98, - /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173, - /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47, - /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152, - /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133, - /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172, - /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30, - /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97, - /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42, - /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152, - /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152, - /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75, - /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172, - /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24, - /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152, - /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173, - /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172, - /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152, - /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213, - /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172, - /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26, - /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173, - /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173, - /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152, - /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152, - /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173, - /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173, - /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163, - /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167, - /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108, - /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163, - /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23, - /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26, - /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55, - /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26, - /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132, - /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191, - /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210, - /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97, - /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227, - /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175, - /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130, - /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159, - /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235, - /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177, - /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125, - /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53, - /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229, - /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25, - /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151, - /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22, - /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23, - /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16, - /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122, - /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80, - /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79, - /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68, - /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23, - /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23, - /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24, - /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23, - /* 1560 */ 23, 22, 15, 122, 122, 122, 23, -}; -#define YY_SHIFT_USE_DFLT (1567) + /* 0 */ 19, 115, 19, 117, 118, 24, 1, 2, 27, 79, + /* 10 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + /* 20 */ 90, 91, 92, 93, 94, 144, 145, 146, 147, 58, + /* 30 */ 49, 50, 79, 80, 81, 82, 22, 84, 85, 86, + /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 221, 222, + /* 50 */ 223, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 60 */ 79, 80, 81, 82, 94, 84, 85, 86, 87, 88, + /* 70 */ 89, 90, 91, 92, 93, 94, 19, 94, 97, 108, + /* 80 */ 109, 110, 99, 100, 101, 102, 103, 104, 105, 32, + /* 90 */ 119, 120, 78, 27, 152, 112, 93, 94, 41, 88, + /* 100 */ 89, 90, 91, 92, 93, 94, 49, 50, 84, 85, + /* 110 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 58, + /* 120 */ 157, 119, 120, 163, 68, 163, 65, 70, 71, 72, + /* 130 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + /* 140 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 150 */ 93, 94, 19, 97, 88, 89, 196, 101, 196, 26, + /* 160 */ 172, 173, 96, 97, 98, 210, 100, 22, 152, 108, + /* 170 */ 109, 110, 27, 107, 27, 109, 221, 222, 223, 219, + /* 180 */ 238, 219, 49, 50, 152, 169, 170, 54, 132, 133, + /* 190 */ 134, 228, 232, 171, 231, 207, 208, 237, 132, 237, + /* 200 */ 134, 179, 19, 70, 71, 72, 73, 74, 75, 76, + /* 210 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86, + /* 220 */ 87, 88, 89, 90, 91, 92, 93, 94, 27, 65, + /* 230 */ 30, 152, 49, 50, 34, 52, 90, 91, 92, 93, + /* 240 */ 94, 96, 97, 98, 97, 22, 230, 27, 48, 217, + /* 250 */ 27, 172, 173, 70, 71, 72, 73, 74, 75, 76, + /* 260 */ 77, 78, 79, 80, 81, 82, 172, 84, 85, 86, + /* 270 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 148, + /* 280 */ 149, 152, 218, 24, 152, 154, 207, 156, 172, 152, + /* 290 */ 22, 68, 27, 152, 163, 27, 164, 96, 97, 98, + /* 300 */ 99, 172, 173, 102, 103, 104, 169, 170, 49, 50, + /* 310 */ 90, 88, 89, 152, 113, 186, 96, 97, 98, 96, + /* 320 */ 97, 160, 57, 27, 101, 164, 137, 196, 139, 70, + /* 330 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 340 */ 81, 82, 11, 84, 85, 86, 87, 88, 89, 90, + /* 350 */ 91, 92, 93, 94, 19, 132, 133, 134, 23, 218, + /* 360 */ 152, 96, 97, 98, 96, 97, 98, 230, 99, 22, + /* 370 */ 152, 102, 103, 104, 27, 244, 152, 152, 27, 26, + /* 380 */ 152, 22, 113, 65, 49, 50, 27, 194, 195, 58, + /* 390 */ 172, 173, 96, 97, 98, 185, 65, 172, 173, 206, + /* 400 */ 172, 173, 190, 191, 186, 70, 71, 72, 73, 74, + /* 410 */ 75, 76, 77, 78, 79, 80, 81, 82, 175, 84, + /* 420 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 430 */ 19, 175, 207, 208, 23, 207, 208, 119, 120, 108, + /* 440 */ 109, 110, 27, 96, 97, 98, 116, 96, 97, 98, + /* 450 */ 152, 121, 152, 179, 180, 96, 97, 98, 250, 106, + /* 460 */ 49, 50, 188, 19, 221, 222, 223, 168, 169, 170, + /* 470 */ 172, 173, 172, 173, 250, 124, 172, 221, 222, 223, + /* 480 */ 26, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 490 */ 79, 80, 81, 82, 50, 84, 85, 86, 87, 88, + /* 500 */ 89, 90, 91, 92, 93, 94, 19, 207, 208, 12, + /* 510 */ 23, 96, 97, 98, 221, 222, 223, 194, 195, 152, + /* 520 */ 199, 23, 19, 225, 26, 28, 152, 152, 152, 206, + /* 530 */ 209, 164, 190, 191, 241, 152, 49, 50, 152, 124, + /* 540 */ 152, 44, 219, 46, 152, 21, 172, 173, 172, 173, + /* 550 */ 183, 107, 185, 16, 163, 58, 112, 70, 71, 72, + /* 560 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + /* 570 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 580 */ 93, 94, 19, 207, 130, 152, 23, 196, 64, 152, + /* 590 */ 172, 173, 22, 152, 24, 152, 98, 27, 61, 96, + /* 600 */ 63, 26, 211, 212, 186, 172, 173, 49, 50, 172, + /* 610 */ 173, 23, 49, 50, 26, 172, 173, 88, 89, 186, + /* 620 */ 24, 238, 124, 27, 238, 22, 23, 103, 187, 26, + /* 630 */ 152, 73, 74, 70, 71, 72, 73, 74, 75, 76, + /* 640 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86, + /* 650 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 101, + /* 660 */ 152, 132, 23, 134, 140, 152, 12, 97, 36, 168, + /* 670 */ 169, 170, 69, 98, 152, 22, 23, 140, 50, 26, + /* 680 */ 172, 173, 28, 51, 152, 172, 173, 193, 49, 50, + /* 690 */ 22, 59, 24, 97, 172, 173, 152, 152, 44, 124, + /* 700 */ 46, 0, 1, 2, 172, 173, 22, 23, 19, 70, + /* 710 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 720 */ 81, 82, 69, 84, 85, 86, 87, 88, 89, 90, + /* 730 */ 91, 92, 93, 94, 152, 107, 152, 193, 49, 50, + /* 740 */ 181, 22, 23, 111, 108, 109, 110, 7, 8, 9, + /* 750 */ 16, 247, 248, 69, 172, 173, 172, 173, 152, 70, + /* 760 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 770 */ 81, 82, 152, 84, 85, 86, 87, 88, 89, 90, + /* 780 */ 91, 92, 93, 94, 19, 152, 242, 152, 69, 152, + /* 790 */ 166, 167, 172, 173, 32, 61, 152, 63, 152, 193, + /* 800 */ 152, 152, 152, 41, 152, 172, 173, 172, 173, 172, + /* 810 */ 173, 152, 152, 152, 49, 50, 172, 173, 172, 173, + /* 820 */ 172, 173, 172, 173, 172, 173, 132, 138, 134, 152, + /* 830 */ 152, 172, 173, 172, 173, 70, 71, 72, 73, 74, + /* 840 */ 75, 76, 77, 78, 79, 80, 81, 82, 152, 84, + /* 850 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 860 */ 19, 152, 22, 152, 195, 24, 152, 27, 172, 173, + /* 870 */ 193, 193, 152, 152, 152, 206, 152, 217, 152, 152, + /* 880 */ 152, 172, 173, 172, 173, 152, 172, 173, 152, 152, + /* 890 */ 49, 50, 172, 173, 172, 173, 172, 173, 172, 173, + /* 900 */ 172, 173, 152, 138, 152, 172, 173, 108, 109, 110, + /* 910 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 920 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, + /* 930 */ 89, 90, 91, 92, 93, 94, 152, 97, 152, 152, + /* 940 */ 49, 50, 26, 193, 172, 173, 152, 152, 152, 146, + /* 950 */ 147, 132, 152, 134, 217, 181, 172, 173, 172, 173, + /* 960 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 970 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, + /* 980 */ 89, 90, 91, 92, 93, 94, 152, 193, 152, 193, + /* 990 */ 49, 50, 181, 193, 172, 173, 166, 167, 245, 246, + /* 1000 */ 211, 212, 152, 22, 217, 152, 172, 173, 172, 173, + /* 1010 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 1020 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, + /* 1030 */ 89, 90, 91, 92, 93, 94, 152, 187, 152, 123, + /* 1040 */ 49, 50, 23, 23, 23, 26, 26, 26, 23, 23, + /* 1050 */ 23, 26, 26, 26, 7, 8, 172, 173, 172, 173, + /* 1060 */ 19, 90, 71, 72, 73, 74, 75, 76, 77, 78, + /* 1070 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88, + /* 1080 */ 89, 90, 91, 92, 93, 94, 152, 116, 152, 217, + /* 1090 */ 49, 50, 121, 23, 172, 173, 26, 100, 101, 27, + /* 1100 */ 101, 27, 23, 122, 152, 26, 172, 173, 172, 173, + /* 1110 */ 152, 112, 163, 72, 73, 74, 75, 76, 77, 78, + /* 1120 */ 79, 80, 81, 82, 163, 84, 85, 86, 87, 88, + /* 1130 */ 89, 90, 91, 92, 93, 94, 19, 20, 152, 22, + /* 1140 */ 23, 152, 163, 65, 27, 196, 163, 19, 20, 23, + /* 1150 */ 22, 213, 26, 19, 37, 27, 152, 196, 172, 173, + /* 1160 */ 152, 172, 173, 27, 23, 37, 152, 26, 152, 97, + /* 1170 */ 152, 97, 210, 56, 163, 196, 163, 163, 100, 196, + /* 1180 */ 172, 173, 65, 152, 56, 68, 172, 173, 172, 173, + /* 1190 */ 172, 173, 152, 65, 163, 163, 68, 23, 152, 234, + /* 1200 */ 26, 152, 152, 172, 173, 88, 89, 196, 152, 196, + /* 1210 */ 196, 152, 95, 96, 97, 98, 88, 89, 101, 152, + /* 1220 */ 152, 207, 208, 95, 96, 97, 98, 196, 196, 101, + /* 1230 */ 96, 233, 152, 97, 152, 152, 19, 20, 207, 22, + /* 1240 */ 152, 152, 152, 191, 27, 152, 152, 152, 152, 132, + /* 1250 */ 133, 134, 135, 136, 37, 152, 152, 152, 152, 152, + /* 1260 */ 132, 133, 134, 135, 136, 210, 197, 210, 210, 198, + /* 1270 */ 150, 184, 239, 56, 201, 214, 214, 201, 239, 180, + /* 1280 */ 214, 227, 198, 38, 176, 68, 175, 175, 175, 122, + /* 1290 */ 155, 200, 159, 19, 20, 40, 22, 159, 159, 22, + /* 1300 */ 70, 27, 130, 243, 240, 88, 89, 90, 189, 18, + /* 1310 */ 201, 37, 95, 96, 97, 98, 192, 5, 101, 192, + /* 1320 */ 220, 240, 10, 11, 12, 13, 14, 159, 18, 17, + /* 1330 */ 56, 158, 192, 201, 192, 220, 189, 189, 201, 159, + /* 1340 */ 158, 137, 68, 31, 45, 33, 236, 159, 159, 132, + /* 1350 */ 133, 134, 135, 136, 42, 158, 235, 22, 177, 159, + /* 1360 */ 158, 158, 88, 89, 159, 107, 174, 55, 177, 95, + /* 1370 */ 96, 97, 98, 174, 62, 101, 47, 65, 66, 106, + /* 1380 */ 174, 125, 19, 20, 174, 22, 177, 176, 174, 182, + /* 1390 */ 27, 216, 174, 174, 182, 107, 159, 22, 215, 215, + /* 1400 */ 37, 216, 216, 216, 137, 215, 132, 133, 134, 135, + /* 1410 */ 136, 215, 159, 177, 94, 177, 129, 224, 205, 56, + /* 1420 */ 226, 126, 128, 203, 229, 204, 114, 229, 127, 202, + /* 1430 */ 201, 68, 25, 162, 26, 13, 161, 153, 153, 6, + /* 1440 */ 151, 151, 178, 151, 151, 165, 165, 178, 165, 4, + /* 1450 */ 249, 88, 89, 141, 3, 142, 22, 249, 95, 96, + /* 1460 */ 97, 98, 246, 15, 101, 67, 16, 23, 120, 23, + /* 1470 */ 131, 111, 123, 20, 16, 125, 1, 123, 131, 78, + /* 1480 */ 78, 78, 78, 111, 96, 1, 122, 35, 5, 22, + /* 1490 */ 107, 140, 53, 53, 26, 132, 133, 134, 135, 136, + /* 1500 */ 43, 60, 107, 24, 112, 20, 19, 52, 22, 29, + /* 1510 */ 105, 22, 22, 52, 23, 22, 22, 52, 23, 23, + /* 1520 */ 39, 23, 116, 26, 22, 26, 23, 22, 96, 23, + /* 1530 */ 23, 122, 22, 24, 124, 35, 35, 26, 26, 35, + /* 1540 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22, + /* 1550 */ 122, 23, 26, 22, 24, 23, 22, 122, 23, 23, + /* 1560 */ 22, 15, 23, 1, 122, 122, +}; +#define YY_SHIFT_USE_DFLT (1566) #define YY_SHIFT_COUNT (455) -#define YY_SHIFT_MIN (-94) -#define YY_SHIFT_MAX (1549) +#define YY_SHIFT_MIN (-114) +#define YY_SHIFT_MAX (1562) static const short yy_shift_ofst[] = { - /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19, - /* 10 */ 16, 16, 100, 760, 760, 760, 760, 760, 760, 760, - /* 20 */ 876, 876, 573, 542, 719, 600, 61, 137, 172, 207, - /* 30 */ 242, 277, 312, 347, 382, 417, 459, 459, 459, 459, - /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, - /* 50 */ 459, 459, 459, 494, 459, 529, 564, 564, 705, 760, - /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746, - /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73, - /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99, - /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949, - /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113, - /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922, - /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949, - /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949, - /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949, - /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118, - /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418, - /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882, - /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238, - /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239, - /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238, - /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290, - /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304, - /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280, - /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414, - /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567, - /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104, - /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273, - /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177, - /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452, - /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479, - /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367, - /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429, - /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491, - /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498, - /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475, - /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517, - /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527, - /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436, - /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549, + /* 0 */ 5, 1117, 1312, 1128, 1274, 1274, 1274, 1274, 61, -19, + /* 10 */ 57, 57, 183, 1274, 1274, 1274, 1274, 1274, 1274, 1274, + /* 20 */ 66, 66, 201, -29, 331, 318, 133, 259, 335, 411, + /* 30 */ 487, 563, 639, 689, 765, 841, 891, 891, 891, 891, + /* 40 */ 891, 891, 891, 891, 891, 891, 891, 891, 891, 891, + /* 50 */ 891, 891, 891, 941, 891, 991, 1041, 1041, 1217, 1274, + /* 60 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, + /* 70 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, + /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, + /* 90 */ 1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, + /* 100 */ 1274, 1274, 1274, 1274, -70, -47, -47, -47, -47, -47, + /* 110 */ 24, 11, 146, 296, 524, 444, 529, 529, 296, 3, + /* 120 */ 2, -30, 1566, 1566, 1566, -17, -17, -17, 145, 145, + /* 130 */ 497, 497, 265, 603, 653, 296, 296, 296, 296, 296, + /* 140 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + /* 150 */ 296, 296, 296, 296, 296, 701, 1078, 147, 147, 2, + /* 160 */ 164, 164, 164, 164, 164, 164, 1566, 1566, 1566, 223, + /* 170 */ 56, 56, 268, 269, 220, 347, 351, 415, 359, 296, + /* 180 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + /* 190 */ 296, 296, 296, 296, 296, 632, 632, 632, 296, 296, + /* 200 */ 498, 296, 296, 296, 570, 296, 296, 654, 296, 296, + /* 210 */ 296, 296, 296, 296, 296, 296, 296, 296, 636, 200, + /* 220 */ 596, 596, 596, 575, -114, 971, 740, 454, 503, 503, + /* 230 */ 1134, 454, 1134, 353, 588, 628, 762, 503, 189, 762, + /* 240 */ 762, 916, 330, 668, 1245, 1167, 1167, 1255, 1255, 1167, + /* 250 */ 1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172, + /* 260 */ 1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167, + /* 270 */ 1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258, + /* 280 */ 1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288, + /* 290 */ 1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267, + /* 300 */ 1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407, + /* 310 */ 1408, 1422, 1422, 1433, 1433, 1433, 1433, 1566, 1566, 1566, + /* 320 */ 1566, 1566, 1566, 1566, 1566, 558, 537, 684, 719, 734, + /* 330 */ 799, 840, 1019, 14, 1020, 1021, 1025, 1026, 1027, 1070, + /* 340 */ 1072, 997, 1047, 999, 1079, 1126, 1074, 1141, 694, 819, + /* 350 */ 1174, 1136, 981, 1445, 1451, 1434, 1313, 1448, 1398, 1450, + /* 360 */ 1444, 1446, 1348, 1339, 1360, 1349, 1453, 1350, 1458, 1475, + /* 370 */ 1354, 1347, 1401, 1402, 1403, 1404, 1372, 1388, 1452, 1364, + /* 380 */ 1484, 1483, 1467, 1383, 1351, 1439, 1468, 1440, 1441, 1457, + /* 390 */ 1395, 1479, 1485, 1487, 1392, 1405, 1486, 1455, 1489, 1490, + /* 400 */ 1491, 1493, 1461, 1480, 1494, 1465, 1481, 1495, 1496, 1498, + /* 410 */ 1497, 1406, 1502, 1503, 1505, 1499, 1409, 1506, 1507, 1432, + /* 420 */ 1500, 1510, 1410, 1511, 1501, 1512, 1504, 1517, 1511, 1518, + /* 430 */ 1519, 1520, 1521, 1522, 1524, 1533, 1525, 1527, 1509, 1526, + /* 440 */ 1528, 1531, 1530, 1526, 1532, 1534, 1535, 1536, 1538, 1428, + /* 450 */ 1435, 1442, 1443, 1539, 1546, 1562, }; -#define YY_REDUCE_USE_DFLT (-130) +#define YY_REDUCE_USE_DFLT (-174) #define YY_REDUCE_COUNT (324) -#define YY_REDUCE_MIN (-129) -#define YY_REDUCE_MAX (1300) +#define YY_REDUCE_MIN (-173) +#define YY_REDUCE_MAX (1293) static const short yy_reduce_ofst[] = { - /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435, - /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790, - /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76, - /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898, - /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950, - /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984, - /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021, - /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062, - /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76, - /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76, - /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220, - /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620, - /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047, - /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808, - /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57, - /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438, - /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908, - /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101, - /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171, - /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102, - /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130, - /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183, - /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205, - /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193, - /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231, - /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232, - /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201, - /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215, - /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278, - /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228, - /* 320 */ 1288, 1291, 1276, 1277, 1295, + /* 0 */ -119, 1014, 131, 1031, -12, 225, 228, 300, -40, -45, + /* 10 */ 243, 256, 293, 129, 218, 418, 79, 376, 433, 298, + /* 20 */ 16, 137, 367, 323, -38, 391, -173, -173, -173, -173, + /* 30 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, + /* 40 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173, + /* 50 */ -173, -173, -173, -173, -173, -173, -173, -173, 374, 437, + /* 60 */ 443, 508, 513, 522, 532, 582, 584, 620, 633, 635, + /* 70 */ 637, 644, 646, 648, 650, 652, 659, 661, 696, 709, + /* 80 */ 711, 714, 720, 722, 724, 726, 728, 733, 772, 784, + /* 90 */ 786, 822, 834, 836, 884, 886, 922, 934, 936, 986, + /* 100 */ 989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173, + /* 110 */ -173, -173, -173, 544, -37, 274, 299, 501, 161, -173, + /* 120 */ 193, -173, -173, -173, -173, 22, 22, 22, 64, 141, + /* 130 */ 212, 342, 208, 504, 504, 132, 494, 606, 677, 678, + /* 140 */ 750, 794, 796, -58, 32, 383, 660, 737, 386, 787, + /* 150 */ 800, 441, 872, 224, 850, 803, 949, 624, 830, 669, + /* 160 */ 961, 979, 983, 1011, 1013, 1032, 753, 789, 321, 94, + /* 170 */ 116, 304, 375, 210, 388, 392, 478, 545, 649, 721, + /* 180 */ 727, 736, 752, 795, 853, 952, 958, 1004, 1040, 1046, + /* 190 */ 1049, 1050, 1056, 1059, 1067, 559, 774, 811, 1068, 1080, + /* 200 */ 938, 1082, 1083, 1088, 962, 1089, 1090, 1052, 1093, 1094, + /* 210 */ 1095, 388, 1096, 1103, 1104, 1105, 1106, 1107, 965, 998, + /* 220 */ 1055, 1057, 1058, 938, 1069, 1071, 1120, 1073, 1061, 1062, + /* 230 */ 1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112, + /* 240 */ 1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139, + /* 250 */ 1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132, + /* 260 */ 1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189, + /* 270 */ 1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206, + /* 280 */ 1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183, + /* 290 */ 1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194, + /* 300 */ 1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271, + /* 310 */ 1275, 1284, 1285, 1289, 1290, 1292, 1293, 1201, 1208, 1216, + /* 320 */ 1280, 1281, 1264, 1269, 1283, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1280, 1270, 1270, 1270, 1202, 1202, 1202, 1202, 1270, 1096, /* 10 */ 1125, 1125, 1254, 1332, 1332, 1332, 1332, 1332, 1332, 1201, /* 20 */ 1332, 1332, 1332, 1332, 1270, 1100, 1131, 1332, 1332, 1332, @@ -135700,104 +136292,77 @@ */ #ifdef YYFALLBACK static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ - 55, /* EXPLAIN => ID */ - 55, /* QUERY => ID */ - 55, /* PLAN => ID */ - 55, /* BEGIN => ID */ + 27, /* EXPLAIN => ID */ + 27, /* QUERY => ID */ + 27, /* PLAN => ID */ + 27, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 55, /* DEFERRED => ID */ - 55, /* IMMEDIATE => ID */ - 55, /* EXCLUSIVE => ID */ + 27, /* DEFERRED => ID */ + 27, /* IMMEDIATE => ID */ + 27, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 55, /* END => ID */ - 55, /* ROLLBACK => ID */ - 55, /* SAVEPOINT => ID */ - 55, /* RELEASE => ID */ + 27, /* END => ID */ + 27, /* ROLLBACK => ID */ + 27, /* SAVEPOINT => ID */ + 27, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ - 55, /* IF => ID */ + 27, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ - 55, /* TEMP => ID */ + 27, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ - 55, /* WITHOUT => ID */ + 27, /* WITHOUT => ID */ 0, /* COMMA => nothing */ - 0, /* OR => nothing */ - 0, /* AND => nothing */ - 0, /* IS => nothing */ - 55, /* MATCH => ID */ - 55, /* LIKE_KW => ID */ - 0, /* BETWEEN => nothing */ - 0, /* IN => nothing */ - 0, /* ISNULL => nothing */ - 0, /* NOTNULL => nothing */ - 0, /* NE => nothing */ - 0, /* EQ => nothing */ - 0, /* GT => nothing */ - 0, /* LE => nothing */ - 0, /* LT => nothing */ - 0, /* GE => nothing */ - 0, /* ESCAPE => nothing */ - 0, /* BITAND => nothing */ - 0, /* BITOR => nothing */ - 0, /* LSHIFT => nothing */ - 0, /* RSHIFT => nothing */ - 0, /* PLUS => nothing */ - 0, /* MINUS => nothing */ - 0, /* STAR => nothing */ - 0, /* SLASH => nothing */ - 0, /* REM => nothing */ - 0, /* CONCAT => nothing */ - 0, /* COLLATE => nothing */ - 0, /* BITNOT => nothing */ 0, /* ID => nothing */ - 0, /* INDEXED => nothing */ - 55, /* ABORT => ID */ - 55, /* ACTION => ID */ - 55, /* AFTER => ID */ - 55, /* ANALYZE => ID */ - 55, /* ASC => ID */ - 55, /* ATTACH => ID */ - 55, /* BEFORE => ID */ - 55, /* BY => ID */ - 55, /* CASCADE => ID */ - 55, /* CAST => ID */ - 55, /* COLUMNKW => ID */ - 55, /* CONFLICT => ID */ - 55, /* DATABASE => ID */ - 55, /* DESC => ID */ - 55, /* DETACH => ID */ - 55, /* EACH => ID */ - 55, /* FAIL => ID */ - 55, /* FOR => ID */ - 55, /* IGNORE => ID */ - 55, /* INITIALLY => ID */ - 55, /* INSTEAD => ID */ - 55, /* NO => ID */ - 55, /* KEY => ID */ - 55, /* OF => ID */ - 55, /* OFFSET => ID */ - 55, /* PRAGMA => ID */ - 55, /* RAISE => ID */ - 55, /* RECURSIVE => ID */ - 55, /* REPLACE => ID */ - 55, /* RESTRICT => ID */ - 55, /* ROW => ID */ - 55, /* TRIGGER => ID */ - 55, /* VACUUM => ID */ - 55, /* VIEW => ID */ - 55, /* VIRTUAL => ID */ - 55, /* WITH => ID */ - 55, /* REINDEX => ID */ - 55, /* RENAME => ID */ - 55, /* CTIME_KW => ID */ + 27, /* ABORT => ID */ + 27, /* ACTION => ID */ + 27, /* AFTER => ID */ + 27, /* ANALYZE => ID */ + 27, /* ASC => ID */ + 27, /* ATTACH => ID */ + 27, /* BEFORE => ID */ + 27, /* BY => ID */ + 27, /* CASCADE => ID */ + 27, /* CAST => ID */ + 27, /* COLUMNKW => ID */ + 27, /* CONFLICT => ID */ + 27, /* DATABASE => ID */ + 27, /* DESC => ID */ + 27, /* DETACH => ID */ + 27, /* EACH => ID */ + 27, /* FAIL => ID */ + 27, /* FOR => ID */ + 27, /* IGNORE => ID */ + 27, /* INITIALLY => ID */ + 27, /* INSTEAD => ID */ + 27, /* LIKE_KW => ID */ + 27, /* MATCH => ID */ + 27, /* NO => ID */ + 27, /* KEY => ID */ + 27, /* OF => ID */ + 27, /* OFFSET => ID */ + 27, /* PRAGMA => ID */ + 27, /* RAISE => ID */ + 27, /* RECURSIVE => ID */ + 27, /* REPLACE => ID */ + 27, /* RESTRICT => ID */ + 27, /* ROW => ID */ + 27, /* TRIGGER => ID */ + 27, /* VACUUM => ID */ + 27, /* VIEW => ID */ + 27, /* VIRTUAL => ID */ + 27, /* WITH => ID */ + 27, /* REINDEX => ID */ + 27, /* RENAME => ID */ + 27, /* CTIME_KW => ID */ }; #endif /* YYFALLBACK */ /* The following structure represents a single element of the ** parser's stack. Information stored includes: @@ -135885,29 +136450,29 @@ "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", "TABLE", "CREATE", "IF", "NOT", "EXISTS", "TEMP", "LP", "RP", - "AS", "WITHOUT", "COMMA", "OR", - "AND", "IS", "MATCH", "LIKE_KW", - "BETWEEN", "IN", "ISNULL", "NOTNULL", - "NE", "EQ", "GT", "LE", - "LT", "GE", "ESCAPE", "BITAND", - "BITOR", "LSHIFT", "RSHIFT", "PLUS", - "MINUS", "STAR", "SLASH", "REM", - "CONCAT", "COLLATE", "BITNOT", "ID", - "INDEXED", "ABORT", "ACTION", "AFTER", - "ANALYZE", "ASC", "ATTACH", "BEFORE", - "BY", "CASCADE", "CAST", "COLUMNKW", - "CONFLICT", "DATABASE", "DESC", "DETACH", - "EACH", "FAIL", "FOR", "IGNORE", - "INITIALLY", "INSTEAD", "NO", "KEY", - "OF", "OFFSET", "PRAGMA", "RAISE", - "RECURSIVE", "REPLACE", "RESTRICT", "ROW", - "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", - "WITH", "REINDEX", "RENAME", "CTIME_KW", - "ANY", "STRING", "JOIN_KW", "CONSTRAINT", + "AS", "WITHOUT", "COMMA", "ID", + "ABORT", "ACTION", "AFTER", "ANALYZE", + "ASC", "ATTACH", "BEFORE", "BY", + "CASCADE", "CAST", "COLUMNKW", "CONFLICT", + "DATABASE", "DESC", "DETACH", "EACH", + "FAIL", "FOR", "IGNORE", "INITIALLY", + "INSTEAD", "LIKE_KW", "MATCH", "NO", + "KEY", "OF", "OFFSET", "PRAGMA", + "RAISE", "RECURSIVE", "REPLACE", "RESTRICT", + "ROW", "TRIGGER", "VACUUM", "VIEW", + "VIRTUAL", "WITH", "REINDEX", "RENAME", + "CTIME_KW", "ANY", "OR", "AND", + "IS", "BETWEEN", "IN", "ISNULL", + "NOTNULL", "NE", "EQ", "GT", + "LE", "LT", "GE", "ESCAPE", + "BITAND", "BITOR", "LSHIFT", "RSHIFT", + "PLUS", "MINUS", "STAR", "SLASH", + "REM", "CONCAT", "COLLATE", "BITNOT", + "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR", "ON", "INSERT", "DELETE", "UPDATE", "SET", "DEFERRABLE", "FOREIGN", "DROP", "UNION", "ALL", "EXCEPT", "INTERSECT", "SELECT", @@ -139380,11 +139945,11 @@ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */ + yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ #endif assert( zSql!=0 ); mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->nVdbeActive==0 ){ @@ -139393,11 +139958,11 @@ pParse->rc = SQLITE_OK; pParse->zTail = zSql; assert( pzErrMsg!=0 ); /* sqlite3ParserTrace(stdout, "parser: "); */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - pEngine = zSpace; + pEngine = &sEngine; sqlite3ParserInit(pEngine); #else pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ sqlite3OomFault(db); @@ -139502,11 +140067,11 @@ sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->pVList); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; pParse->pAinc = p->pNext; - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(db, p); @@ -142996,20 +143561,22 @@ sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } #endif #if defined(SQLITE_HAS_CODEC) if( rc==SQLITE_OK ){ - const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey"); - if( zHexKey && zHexKey[0] ){ + const char *zKey; + if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){ u8 iByte; int i; - char zKey[40]; - for(i=0, iByte=0; i=0 ); return 5; } /* ** Return the number of bytes required to encode v as a varint @@ -146457,69 +147026,70 @@ struct Fts4Option *pOp = &aFts4Opt[iOpt]; if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ break; } } - if( iOpt==SizeofArray(aFts4Opt) ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); - rc = SQLITE_ERROR; - }else{ - switch( iOpt ){ - case 0: /* MATCHINFO */ - if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); - rc = SQLITE_ERROR; - } - bNoDocsize = 1; - break; - - case 1: /* PREFIX */ - sqlite3_free(zPrefix); - zPrefix = zVal; - zVal = 0; - break; - - case 2: /* COMPRESS */ - sqlite3_free(zCompress); - zCompress = zVal; - zVal = 0; - break; - - case 3: /* UNCOMPRESS */ - sqlite3_free(zUncompress); - zUncompress = zVal; - zVal = 0; - break; - - case 4: /* ORDER */ - if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) - && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) - ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); - rc = SQLITE_ERROR; - } - bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); - break; - - case 5: /* CONTENT */ - sqlite3_free(zContent); - zContent = zVal; - zVal = 0; - break; - - case 6: /* LANGUAGEID */ - assert( iOpt==6 ); - sqlite3_free(zLanguageid); - zLanguageid = zVal; - zVal = 0; - break; - - case 7: /* NOTINDEXED */ - azNotindexed[nNotindexed++] = zVal; - zVal = 0; - break; - } + switch( iOpt ){ + case 0: /* MATCHINFO */ + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); + rc = SQLITE_ERROR; + } + bNoDocsize = 1; + break; + + case 1: /* PREFIX */ + sqlite3_free(zPrefix); + zPrefix = zVal; + zVal = 0; + break; + + case 2: /* COMPRESS */ + sqlite3_free(zCompress); + zCompress = zVal; + zVal = 0; + break; + + case 3: /* UNCOMPRESS */ + sqlite3_free(zUncompress); + zUncompress = zVal; + zVal = 0; + break; + + case 4: /* ORDER */ + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) + ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); + rc = SQLITE_ERROR; + } + bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); + break; + + case 5: /* CONTENT */ + sqlite3_free(zContent); + zContent = zVal; + zVal = 0; + break; + + case 6: /* LANGUAGEID */ + assert( iOpt==6 ); + sqlite3_free(zLanguageid); + zLanguageid = zVal; + zVal = 0; + break; + + case 7: /* NOTINDEXED */ + azNotindexed[nNotindexed++] = zVal; + zVal = 0; + break; + + default: + assert( iOpt==SizeofArray(aFts4Opt) ); + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); + rc = SQLITE_ERROR; + break; } sqlite3_free(zVal); } } @@ -147084,11 +147654,12 @@ zCsr += fts3GetVarint32(zCsr, &nPrefix); } isFirstTerm = 0; zCsr += fts3GetVarint32(zCsr, &nSuffix); - if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){ + assert( nPrefix>=0 && nSuffix>=0 ); + if( &zCsr[nSuffix]>zEnd ){ rc = FTS_CORRUPT_VTAB; goto finish_scan; } if( nPrefix+nSuffix>nAlloc ){ char *zNew; @@ -147894,11 +148465,11 @@ bWritten = 1; } fts3ColumnlistCopy(0, &p); } - while( ppVtab; /* The column value supplied by SQLite must be in range. */ assert( iCol>=0 && iCol<=p->nColumn+2 ); - if( iCol==p->nColumn+1 ){ - /* This call is a request for the "docid" column. Since "docid" is an - ** alias for "rowid", use the xRowid() method to obtain the value. - */ - sqlite3_result_int64(pCtx, pCsr->iPrevId); - }else if( iCol==p->nColumn ){ - /* The extra column whose name is the same as the table. - ** Return a blob which is a pointer to the cursor. */ - sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); - }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ - sqlite3_result_int64(pCtx, pCsr->iLangid); - }else{ - /* The requested column is either a user column (one that contains - ** indexed data), or the language-id column. */ - rc = fts3CursorSeek(0, pCsr); - - if( rc==SQLITE_OK ){ - if( iCol==p->nColumn+2 ){ - int iLangid = 0; - if( p->zLanguageid ){ - iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1); - } - sqlite3_result_int(pCtx, iLangid); - }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){ + switch( iCol-p->nColumn ){ + case 0: + /* The special 'table-name' column */ + sqlite3_result_blob(pCtx, &pCsr, sizeof(Fts3Cursor*), SQLITE_TRANSIENT); + sqlite3_result_subtype(pCtx, SQLITE_BLOB); + break; + + case 1: + /* The docid column */ + sqlite3_result_int64(pCtx, pCsr->iPrevId); + break; + + case 2: + if( pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); + break; + }else if( p->zLanguageid==0 ){ + sqlite3_result_int(pCtx, 0); + break; + }else{ + iCol = p->nColumn; + /* fall-through */ + } + + default: + /* A user column. Or, if this is a full-table scan, possibly the + ** language-id column. Seek the cursor. */ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } - } + break; } assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); return rc; } @@ -148680,21 +149256,15 @@ ** if an error occurs. */ static int fts3SetHasStat(Fts3Table *p){ int rc = SQLITE_OK; if( p->bHasStat==2 ){ - const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'"; - char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName); - if( zSql ){ - sqlite3_stmt *pStmt = 0; - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - if( rc==SQLITE_OK ){ - int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); - rc = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat; - } - sqlite3_free(zSql); + char *zTbl = sqlite3_mprintf("%s_stat", p->zName); + if( zTbl ){ + int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0); + sqlite3_free(zTbl); + p->bHasStat = (res==SQLITE_OK); }else{ rc = SQLITE_NOMEM; } } return rc; @@ -148797,22 +149367,20 @@ sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ - Fts3Cursor *pRet; - if( sqlite3_value_type(pVal)!=SQLITE_BLOB - || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) - ){ + int rc = SQLITE_OK; + if( sqlite3_value_subtype(pVal)==SQLITE_BLOB ){ + *ppCsr = *(Fts3Cursor**)sqlite3_value_blob(pVal); + }else{ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); sqlite3_free(zErr); - return SQLITE_ERROR; + rc = SQLITE_ERROR; } - memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); - *ppCsr = pRet; - return SQLITE_OK; + return rc; } /* ** Implementation of the snippet() function for FTS3 */ @@ -149195,11 +149763,11 @@ rc = sqlite3Fts3ExprInitTestInterface(db); } #endif /* Create the virtual table wrapper around the hash-table and overload - ** the two scalar functions. If this is successful, register the + ** the four scalar functions. If this is successful, register the ** module with sqlite. */ if( SQLITE_OK==rc && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) @@ -149778,11 +150346,11 @@ /* This is only called if it is guaranteed that the phrase has at least ** one incremental token. In which case the bIncr flag is set. */ assert( p->bIncr==1 ); - if( p->nToken==1 && p->bIncr ){ + if( p->nToken==1 ){ rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, &pDL->iDocid, &pDL->pList, &pDL->nList ); if( pDL->pList==0 ) bEof = 1; }else{ @@ -150011,10 +150579,11 @@ ** of data that will fit on a single leaf page of an intkey table in ** this database, then the average docsize is 1. Otherwise, it is 1 plus ** the number of overflow pages consumed by a record B bytes in size. */ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ + int rc = SQLITE_OK; if( pCsr->nRowAvg==0 ){ /* The average document size, which is required to calculate the cost ** of each doclist, has not yet been determined. Read the required ** data from the %_stat table to calculate it. ** @@ -150023,11 +150592,10 @@ ** The first varint is the number of documents currently stored in ** the table. The following nCol varints contain the total amount of ** data stored in all rows of each column of the table, from left ** to right. */ - int rc; Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; sqlite3_stmt *pStmt; sqlite3_int64 nDoc = 0; sqlite3_int64 nByte = 0; const char *pEnd; @@ -150050,15 +150618,14 @@ pCsr->nDoc = nDoc; pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); assert( pCsr->nRowAvg>0 ); rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ) return rc; } *pnPage = pCsr->nRowAvg; - return SQLITE_OK; + return rc; } /* ** This function is called to select the tokens (if any) that will be ** deferred. The array aTC[] has already been populated when this is @@ -150404,11 +150971,12 @@ } } pExpr->iDocid = pLeft->iDocid; pExpr->bEof = (pLeft->bEof || pRight->bEof); if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ - if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){ + assert( pRight->eType==FTSQUERY_PHRASE ); + if( pRight->pPhrase->doclist.aAll ){ Fts3Doclist *pDl = &pRight->pPhrase->doclist; while( *pRc==SQLITE_OK && pRight->bEof==0 ){ memset(pDl->pList, 0, pDl->nList); fts3EvalNextRow(pCsr, pRight, pRc); } @@ -150433,11 +151001,11 @@ assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ fts3EvalNextRow(pCsr, pLeft, pRc); - }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){ + }else if( pLeft->bEof || iCmp>0 ){ fts3EvalNextRow(pCsr, pRight, pRc); }else{ fts3EvalNextRow(pCsr, pLeft, pRc); fts3EvalNextRow(pCsr, pRight, pRc); } @@ -150525,55 +151093,51 @@ ** left-hand child may be either a phrase or a NEAR node. There are ** no exceptions to this - it's the way the parser in fts3_expr.c works. */ if( *pRc==SQLITE_OK && pExpr->eType==FTSQUERY_NEAR - && pExpr->bEof==0 && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) ){ Fts3Expr *p; int nTmp = 0; /* Bytes of temp space */ char *aTmp; /* Temp space for PoslistNearMerge() */ /* Allocate temporary working space. */ for(p=pExpr; p->pLeft; p=p->pLeft){ + assert( p->pRight->pPhrase->doclist.nList>0 ); 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; - - 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); - } + 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); + } + } + + sqlite3_free(aTmp); } return res; } @@ -166676,16 +167240,40 @@ , pRtree->zDb, pRtree->zName, zNewName , pRtree->zDb, pRtree->zName, zNewName , pRtree->zDb, pRtree->zName, zNewName ); if( zSql ){ + nodeBlobReset(pRtree); rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } +/* +** The xSavepoint method. +** +** This module does not need to do anything to support savepoints. However, +** it uses this hook to close any open blob handle. This is done because a +** DROP TABLE command - which fortunately always opens a savepoint - cannot +** succeed if there are any open blob handles. i.e. if the blob handle were +** not closed here, the following would fail: +** +** BEGIN; +** INSERT INTO rtree... +** DROP TABLE ; -- Would fail with SQLITE_LOCKED +** COMMIT; +*/ +static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ + Rtree *pRtree = (Rtree *)pVtab; + int iwt = pRtree->inWrTrans; + UNUSED_PARAMETER(iSavepoint); + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + pRtree->inWrTrans = iwt; + return SQLITE_OK; +} /* ** This function populates the pRtree->nRowEst variable with an estimate ** of the number of rows in the virtual table. If possible, this is based ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. @@ -166728,11 +167316,11 @@ return rc; } static sqlite3_module rtreeModule = { - 0, /* iVersion */ + 2, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ rtreeDisconnect, /* xDisconnect - Disconnect from a table */ rtreeDestroy, /* xDestroy - Drop a table */ @@ -166748,11 +167336,11 @@ rtreeEndTransaction, /* xSync - sync transaction */ rtreeEndTransaction, /* xCommit - commit transaction */ rtreeEndTransaction, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ - 0, /* xSavepoint */ + rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ }; static int rtreeSqlInit( @@ -178905,10 +179493,11 @@ #ifndef SQLITE_AMALGAMATION /* Unsigned integer types. These are already defined in the sqliteInt.h, ** but the definitions need to be repeated for separate compilation. */ typedef sqlite3_uint64 u64; typedef unsigned int u32; + typedef unsigned short int u16; typedef unsigned char u8; #endif /* Objects */ typedef struct JsonString JsonString; @@ -178984,12 +179573,23 @@ JsonNode *aNode; /* Array of nodes containing the parse */ const char *zJson; /* Original JSON string */ u32 *aUp; /* Index of parent of each node */ u8 oom; /* Set to true if out of memory */ u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ + int nJson; /* Length of the zJson string in bytes */ }; +/* +** Maximum nesting depth of JSON for this implementation. +** +** This limit is needed to avoid a stack overflow in the recursive +** descent parser. A depth of 2000 is far deeper than any sane JSON +** should go. +*/ +#define JSON_MAX_DEPTH 2000 + /************************************************************************** ** Utility routines for dealing with JsonString objects **************************************************************************/ /* Set the JsonString object to an empty string @@ -179216,10 +179816,18 @@ pParse->nNode = 0; pParse->nAlloc = 0; sqlite3_free(pParse->aUp); pParse->aUp = 0; } + +/* +** Free a JsonParse object that was obtained from sqlite3_malloc(). +*/ +static void jsonParseFree(JsonParse *pParse){ + jsonParseReset(pParse); + sqlite3_free(pParse); +} /* ** Convert the JsonNode pNode into a pure JSON string and ** append to pOut. Subsubstructure is also included. Return ** the number of JsonNode objects that are encoded. @@ -179542,35 +180150,39 @@ char c; u32 j; int iThis; int x; JsonNode *pNode; - while( safe_isspace(pParse->zJson[i]) ){ i++; } - if( (c = pParse->zJson[i])=='{' ){ + const char *z = pParse->zJson; + while( safe_isspace(z[i]) ){ i++; } + if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); if( x<0 ){ + pParse->iDepth--; if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } if( pParse->oom ) return -1; pNode = &pParse->aNode[pParse->nNode-1]; if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - if( pParse->zJson[j]!=':' ) return -1; + while( safe_isspace(z[j]) ){ j++; } + if( z[j]!=':' ) return -1; j++; x = jsonParseValue(pParse, j); + pParse->iDepth--; if( x<0 ) return -1; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!='}' ) return -1; break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; @@ -179578,19 +180190,21 @@ }else if( c=='[' ){ /* Parse array */ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); + pParse->iDepth--; if( x<0 ){ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!=']' ) return -1; break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; @@ -179598,75 +180212,83 @@ }else if( c=='"' ){ /* Parse string */ u8 jnFlags = 0; j = i+1; for(;;){ - c = pParse->zJson[j]; - if( c==0 ) return -1; + c = z[j]; + if( (c & ~0x1f)==0 ){ + /* Control characters are not allowed in strings */ + return -1; + } if( c=='\\' ){ - c = pParse->zJson[++j]; + c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){ + || (c=='u' && jsonIs4Hex(z+j+1)) ){ jnFlags = JNODE_ESCAPE; }else{ return -1; } }else if( c=='"' ){ break; } j++; } - jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]); + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; return j+1; }else if( c=='n' - && strncmp(pParse->zJson+i,"null",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"null",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_NULL, 0, 0); return i+4; }else if( c=='t' - && strncmp(pParse->zJson+i,"true",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"true",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); return i+4; }else if( c=='f' - && strncmp(pParse->zJson+i,"false",5)==0 - && !safe_isalnum(pParse->zJson[i+5]) ){ + && strncmp(z+i,"false",5)==0 + && !safe_isalnum(z[i+5]) ){ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); return i+5; }else if( c=='-' || (c>='0' && c<='9') ){ /* Parse number */ u8 seenDP = 0; u8 seenE = 0; + assert( '-' < '0' ); + if( c<='0' ){ + j = c=='-' ? i+1 : i; + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; + } j = i+1; for(;; j++){ - c = pParse->zJson[j]; + c = z[j]; if( c>='0' && c<='9' ) continue; if( c=='.' ){ - if( pParse->zJson[j-1]=='-' ) return -1; + if( z[j-1]=='-' ) return -1; if( seenDP ) return -1; seenDP = 1; continue; } if( c=='e' || c=='E' ){ - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; if( seenE ) return -1; seenDP = seenE = 1; - c = pParse->zJson[j+1]; + c = z[j+1]; if( c=='+' || c=='-' ){ j++; - c = pParse->zJson[j+1]; + c = z[j+1]; } if( c<'0' || c>'9' ) return -1; continue; } break; } - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, - j - i, &pParse->zJson[i]); + j - i, &z[i]); return j; }else if( c=='}' ){ return -2; /* End of {...} */ }else if( c==']' ){ return -3; /* End of [...] */ @@ -179694,10 +180316,11 @@ if( zJson==0 ) return 1; pParse->zJson = zJson; i = jsonParseValue(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ + assert( pParse->iDepth==0 ); while( safe_isspace(zJson[i]) ) i++; if( zJson[i] ) i = -1; } if( i<=0 ){ if( pCtx!=0 ){ @@ -179752,10 +180375,53 @@ return SQLITE_NOMEM; } jsonParseFillInParentage(pParse, 0, 0); return SQLITE_OK; } + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) + +/* +** Obtain a complete parse of the JSON found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the JSON again and return the new parse, +** and also register the new parse so that it will be available for +** future sqlite3_get_auxdata() calls. +*/ +static JsonParse *jsonParseCached( + sqlite3_context *pCtx, + sqlite3_value **argv +){ + const char *zJson = (const char*)sqlite3_value_text(argv[0]); + int nJson = sqlite3_value_bytes(argv[0]); + JsonParse *p; + if( zJson==0 ) return 0; + p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); + if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ + p->nErr = 0; + return p; /* The cached entry matches, so return it */ + } + p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); + if( p==0 ){ + sqlite3_result_error_nomem(pCtx); + return 0; + } + memset(p, 0, sizeof(*p)); + p->zJson = (char*)&p[1]; + memcpy((char*)p->zJson, zJson, nJson+1); + if( jsonParse(p, pCtx, p->zJson) ){ + sqlite3_free(p); + return 0; + } + p->nJson = nJson; + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); +} /* ** Compare the OBJECT label at pNode against zKey,nKey. Return true on ** a match. */ @@ -180118,33 +180784,34 @@ static void jsonArrayLengthFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ sqlite3_int64 n = 0; u32 i; JsonNode *pNode; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + p = jsonParseCached(ctx, argv); + if( p==0 ) return; + assert( p->nNode ); if( argc==2 ){ const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(&x, zPath, 0, ctx); + pNode = jsonLookup(p, zPath, 0, ctx); }else{ - pNode = x.aNode; + pNode = p->aNode; } if( pNode==0 ){ - x.nErr = 1; - }else if( pNode->eType==JSON_ARRAY ){ + return; + } + if( pNode->eType==JSON_ARRAY ){ assert( (pNode->jnFlags & JNODE_APPEND)==0 ); for(i=1; i<=pNode->n; n++){ i += jsonNodeSize(&pNode[i]); } } - if( x.nErr==0 ) sqlite3_result_int64(ctx, n); - jsonParseReset(&x); + sqlite3_result_int64(ctx, n); } /* ** json_extract(JSON, PATH, ...) ** @@ -180156,24 +180823,25 @@ static void jsonExtractFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ JsonNode *pNode; const char *zPath; JsonString jx; int i; if( argc<2 ) return; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + p = jsonParseCached(ctx, argv); + if( p==0 ) return; jsonInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=1; inErr ) break; if( argc>2 ){ jsonAppendSeparator(&jx); if( pNode ){ jsonRenderNode(pNode, &jx, 0); }else{ @@ -180187,18 +180855,17 @@ jsonAppendChar(&jx, ']'); jsonResult(&jx); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } jsonReset(&jx); - jsonParseReset(&x); } /* This is the RFC 7396 MergePatch algorithm. */ static JsonNode *jsonMergePatch( JsonParse *pParse, /* The JSON parser that contains the TARGET */ - int iTarget, /* Node of the TARGET in pParse */ + u32 iTarget, /* Node of the TARGET in pParse */ JsonNode *pPatch /* The PATCH */ ){ u32 i, j; u32 iRoot; JsonNode *pTarget; @@ -182203,13 +182870,13 @@ i64 iDocid /* Docid to add or remove data from */ ); /* ** Flush any data stored in the in-memory hash tables to the database. -** If the bCommit flag is true, also close any open blob handles. +** Also close any open blob handles. */ -static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit); +static int sqlite3Fts5IndexSync(Fts5Index *p); /* ** Discard any data stored in the in-memory hash tables. Do not write it ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data @@ -182375,11 +183042,11 @@ static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol); static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg); static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow); -static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit); +static int sqlite3Fts5StorageSync(Fts5Storage *p); static int sqlite3Fts5StorageRollback(Fts5Storage *p); static int sqlite3Fts5StorageConfigValue( Fts5Storage *p, const char*, sqlite3_value*, int ); @@ -182411,10 +183078,11 @@ }; /* Parse a MATCH expression. */ static int sqlite3Fts5ExprNew( Fts5Config *pConfig, + int iCol, /* Column on LHS of MATCH operator */ const char *zExpr, Fts5Expr **ppNew, char **pzErr ); @@ -182495,11 +183163,11 @@ static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); -static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); +static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*); static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); /* @@ -182552,16 +183220,16 @@ #define FTS5_OR 1 #define FTS5_AND 2 #define FTS5_NOT 3 #define FTS5_TERM 4 #define FTS5_COLON 5 -#define FTS5_LP 6 -#define FTS5_RP 7 -#define FTS5_MINUS 8 -#define FTS5_LCP 9 -#define FTS5_RCP 10 -#define FTS5_STRING 11 +#define FTS5_MINUS 6 +#define FTS5_LCP 7 +#define FTS5_RCP 8 +#define FTS5_STRING 9 +#define FTS5_LP 10 +#define FTS5_RP 11 #define FTS5_COMMA 12 #define FTS5_PLUS 13 #define FTS5_STAR 14 /* @@ -182693,20 +183361,20 @@ #endif #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse -#define fts5YYNSTATE 29 -#define fts5YYNRULE 26 -#define fts5YY_MAX_SHIFT 28 -#define fts5YY_MIN_SHIFTREDUCE 45 -#define fts5YY_MAX_SHIFTREDUCE 70 -#define fts5YY_MIN_REDUCE 71 -#define fts5YY_MAX_REDUCE 96 -#define fts5YY_ERROR_ACTION 97 -#define fts5YY_ACCEPT_ACTION 98 -#define fts5YY_NO_ACTION 99 +#define fts5YYNSTATE 33 +#define fts5YYNRULE 27 +#define fts5YY_MAX_SHIFT 32 +#define fts5YY_MIN_SHIFTREDUCE 50 +#define fts5YY_MAX_SHIFTREDUCE 76 +#define fts5YY_MIN_REDUCE 77 +#define fts5YY_MAX_REDUCE 103 +#define fts5YY_ERROR_ACTION 104 +#define fts5YY_ACCEPT_ACTION 105 +#define fts5YY_NO_ACTION 106 /************* End control #defines *******************************************/ /* Define the fts5yytestcase() macro to be a no-op if is not already defined ** otherwise. ** @@ -182774,54 +183442,58 @@ ** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for ** shifting non-terminals after a reduce. ** fts5yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define fts5YY_ACTTAB_COUNT (85) +#define fts5YY_ACTTAB_COUNT (98) static const fts5YYACTIONTYPE fts5yy_action[] = { - /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15, - /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5, - /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53, - /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68, - /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27, - /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21, - /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59, - /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69, - /* 80 */ 25, 66, 8, 14, 2, + /* 0 */ 105, 19, 63, 6, 26, 66, 65, 24, 24, 17, + /* 10 */ 63, 6, 26, 16, 65, 54, 24, 18, 63, 6, + /* 20 */ 26, 10, 65, 12, 24, 75, 59, 63, 6, 26, + /* 30 */ 13, 65, 75, 24, 20, 63, 6, 26, 74, 65, + /* 40 */ 56, 24, 27, 63, 6, 26, 73, 65, 21, 24, + /* 50 */ 23, 15, 30, 11, 1, 64, 22, 25, 9, 65, + /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77, + /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12, + /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32, + /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14, }; static const fts5YYCODETYPE fts5yy_lookahead[] = { - /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17, - /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19, - /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20, - /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26, - /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21, - /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24, - /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11, - /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14, - /* 80 */ 13, 11, 5, 11, 3, + /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17, + /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19, + /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20, + /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22, + /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24, + /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22, + /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0, + /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9, + /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25, + /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9, }; -#define fts5YY_SHIFT_USE_DFLT (85) -#define fts5YY_SHIFT_COUNT (28) +#define fts5YY_SHIFT_USE_DFLT (98) +#define fts5YY_SHIFT_COUNT (32) #define fts5YY_SHIFT_MIN (0) -#define fts5YY_SHIFT_MAX (81) +#define fts5YY_SHIFT_MAX (90) static const unsigned char fts5yy_shift_ofst[] = { - /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1, - /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63, - /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81, + /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14, + /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69, + /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87, + /* 30 */ 88, 39, 71, }; -#define fts5YY_REDUCE_USE_DFLT (-17) -#define fts5YY_REDUCE_COUNT (14) -#define fts5YY_REDUCE_MIN (-16) -#define fts5YY_REDUCE_MAX (54) +#define fts5YY_REDUCE_USE_DFLT (-18) +#define fts5YY_REDUCE_COUNT (16) +#define fts5YY_REDUCE_MIN (-17) +#define fts5YY_REDUCE_MAX (67) static const signed char fts5yy_reduce_ofst[] = { - /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13, - /* 10 */ 13, 22, 54, 13, 51, + /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17, + /* 10 */ 67, 12, 12, 12, 20, 27, 35, }; static const fts5YYACTIONTYPE fts5yy_default[] = { - /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96, - /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97, - /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72, + /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104, + /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104, + /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104, + /* 30 */ 104, 97, 104, }; /********** End of lemon-generated parsing tables *****************************/ /* The next table maps tokens (terminal symbols) into fallback tokens. ** If a construct like the following: @@ -182923,49 +183595,50 @@ #ifndef NDEBUG /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ static const char *const fts5yyTokenName[] = { "$", "OR", "AND", "NOT", - "TERM", "COLON", "LP", "RP", - "MINUS", "LCP", "RCP", "STRING", + "TERM", "COLON", "MINUS", "LCP", + "RCP", "STRING", "LP", "RP", "COMMA", "PLUS", "STAR", "error", "input", "expr", "cnearset", "exprlist", - "nearset", "colset", "colsetlist", "nearphrases", + "colset", "colsetlist", "nearset", "nearphrases", "phrase", "neardist_opt", "star_opt", }; #endif /* NDEBUG */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. */ static const char *const fts5yyRuleName[] = { /* 0 */ "input ::= expr", - /* 1 */ "expr ::= expr AND expr", - /* 2 */ "expr ::= expr OR expr", - /* 3 */ "expr ::= expr NOT expr", - /* 4 */ "expr ::= LP expr RP", - /* 5 */ "expr ::= exprlist", - /* 6 */ "exprlist ::= cnearset", - /* 7 */ "exprlist ::= exprlist cnearset", - /* 8 */ "cnearset ::= nearset", - /* 9 */ "cnearset ::= colset COLON nearset", - /* 10 */ "colset ::= MINUS LCP colsetlist RCP", - /* 11 */ "colset ::= LCP colsetlist RCP", - /* 12 */ "colset ::= STRING", - /* 13 */ "colset ::= MINUS STRING", - /* 14 */ "colsetlist ::= colsetlist STRING", - /* 15 */ "colsetlist ::= STRING", - /* 16 */ "nearset ::= phrase", - /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP", - /* 18 */ "nearphrases ::= phrase", - /* 19 */ "nearphrases ::= nearphrases phrase", - /* 20 */ "neardist_opt ::=", - /* 21 */ "neardist_opt ::= COMMA STRING", - /* 22 */ "phrase ::= phrase PLUS STRING star_opt", - /* 23 */ "phrase ::= STRING star_opt", - /* 24 */ "star_opt ::= STAR", - /* 25 */ "star_opt ::=", + /* 1 */ "colset ::= MINUS LCP colsetlist RCP", + /* 2 */ "colset ::= LCP colsetlist RCP", + /* 3 */ "colset ::= STRING", + /* 4 */ "colset ::= MINUS STRING", + /* 5 */ "colsetlist ::= colsetlist STRING", + /* 6 */ "colsetlist ::= STRING", + /* 7 */ "expr ::= expr AND expr", + /* 8 */ "expr ::= expr OR expr", + /* 9 */ "expr ::= expr NOT expr", + /* 10 */ "expr ::= colset COLON LP expr RP", + /* 11 */ "expr ::= LP expr RP", + /* 12 */ "expr ::= exprlist", + /* 13 */ "exprlist ::= cnearset", + /* 14 */ "exprlist ::= exprlist cnearset", + /* 15 */ "cnearset ::= nearset", + /* 16 */ "cnearset ::= colset COLON nearset", + /* 17 */ "nearset ::= phrase", + /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP", + /* 19 */ "nearphrases ::= phrase", + /* 20 */ "nearphrases ::= nearphrases phrase", + /* 21 */ "neardist_opt ::=", + /* 22 */ "neardist_opt ::= COMMA STRING", + /* 23 */ "phrase ::= phrase PLUS STRING star_opt", + /* 24 */ "phrase ::= STRING star_opt", + /* 25 */ "star_opt ::= STAR", + /* 26 */ "star_opt ::=", }; #endif /* NDEBUG */ #if fts5YYSTACKDEPTH<=0 @@ -183091,21 +183764,21 @@ case 19: /* exprlist */ { sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); } break; - case 20: /* nearset */ + case 20: /* colset */ + case 21: /* colsetlist */ +{ + sqlite3_free((fts5yypminor->fts5yy11)); +} + break; + case 22: /* nearset */ case 23: /* nearphrases */ { sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); } - break; - case 21: /* colset */ - case 22: /* colsetlist */ -{ - sqlite3_free((fts5yypminor->fts5yy11)); -} break; case 24: /* phrase */ { sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); } @@ -183360,27 +184033,28 @@ static const struct { fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } fts5yyRuleInfo[] = { { 16, 1 }, + { 20, 4 }, + { 20, 3 }, + { 20, 1 }, + { 20, 2 }, + { 21, 2 }, + { 21, 1 }, { 17, 3 }, { 17, 3 }, { 17, 3 }, + { 17, 5 }, { 17, 3 }, { 17, 1 }, { 19, 1 }, { 19, 2 }, { 18, 1 }, { 18, 3 }, - { 21, 4 }, - { 21, 3 }, - { 21, 1 }, - { 21, 2 }, - { 22, 2 }, { 22, 1 }, - { 20, 1 }, - { 20, 5 }, + { 22, 5 }, { 23, 1 }, { 23, 2 }, { 25, 0 }, { 25, 2 }, { 24, 4 }, @@ -183451,132 +184125,139 @@ /********** Begin reduce actions **********************************************/ fts5YYMINORTYPE fts5yylhsminor; case 0: /* input ::= expr */ { sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); } break; - case 1: /* expr ::= expr AND expr */ -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 2: /* expr ::= expr OR expr */ -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 3: /* expr ::= expr NOT expr */ -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 4: /* expr ::= LP expr RP */ -{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;} - break; - case 5: /* expr ::= exprlist */ - case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6); -{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;} - fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 7: /* exprlist ::= exprlist cnearset */ -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); -} - fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 8: /* cnearset ::= nearset */ -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); -} - fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 9: /* cnearset ::= colset COLON nearset */ -{ - sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11); - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); -} - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 10: /* colset ::= MINUS LCP colsetlist RCP */ -{ - fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); -} - break; - case 11: /* colset ::= LCP colsetlist RCP */ -{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; } - break; - case 12: /* colset ::= STRING */ -{ - fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); -} - fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; - break; - case 13: /* colset ::= MINUS STRING */ -{ - fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); - fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); -} - break; - case 14: /* colsetlist ::= colsetlist STRING */ -{ - fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); } - fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11; - break; - case 15: /* colsetlist ::= STRING */ -{ - fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); -} - fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; - break; - case 16: /* nearset ::= phrase */ -{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } - fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; - break; - case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */ + case 1: /* colset ::= MINUS LCP colsetlist RCP */ +{ + fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); +} + break; + case 2: /* colset ::= LCP colsetlist RCP */ +{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; } + break; + case 3: /* colset ::= STRING */ +{ + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); +} + fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; + break; + case 4: /* colset ::= MINUS STRING */ +{ + fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); + fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); +} + break; + case 5: /* colsetlist ::= colsetlist STRING */ +{ + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); } + fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11; + break; + case 6: /* colsetlist ::= STRING */ +{ + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); +} + fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; + break; + case 7: /* expr ::= expr AND expr */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 8: /* expr ::= expr OR expr */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 9: /* expr ::= expr NOT expr */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 10: /* expr ::= colset COLON LP expr RP */ +{ + sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11); + fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24; +} + fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 11: /* expr ::= LP expr RP */ +{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;} + break; + case 12: /* expr ::= exprlist */ + case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13); +{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;} + fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 14: /* exprlist ::= exprlist cnearset */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); +} + fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 15: /* cnearset ::= nearset */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); +} + fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 16: /* cnearset ::= colset COLON nearset */ +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); + sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11); +} + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 17: /* nearset ::= phrase */ +{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } + fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; + break; + case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */ { sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0); sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0); fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46; } fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 18: /* nearphrases ::= phrase */ + case 19: /* nearphrases ::= phrase */ { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 19: /* nearphrases ::= nearphrases phrase */ + case 20: /* nearphrases ::= nearphrases phrase */ { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53); } fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 20: /* neardist_opt ::= */ + case 21: /* neardist_opt ::= */ { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; } break; - case 21: /* neardist_opt ::= COMMA STRING */ + case 22: /* neardist_opt ::= COMMA STRING */ { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; } break; - case 22: /* phrase ::= phrase PLUS STRING star_opt */ + case 23: /* phrase ::= phrase PLUS STRING star_opt */ { fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; - case 23: /* phrase ::= STRING star_opt */ + case 24: /* phrase ::= STRING star_opt */ { fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; - case 24: /* star_opt ::= STAR */ + case 25: /* star_opt ::= STAR */ { fts5yymsp[0].minor.fts5yy4 = 1; } break; - case 25: /* star_opt ::= */ + case 26: /* star_opt ::= */ { fts5yymsp[1].minor.fts5yy4 = 0; } break; default: break; /********** End reduce actions ************************************************/ @@ -184614,13 +185295,15 @@ Fts5Buffer *pBuf, u32 nData, const u8 *pData ){ assert_nc( *pRc || nData>=0 ); - if( fts5BufferGrow(pRc, pBuf, nData) ) return; - memcpy(&pBuf->p[pBuf->n], pData, nData); - pBuf->n += nData; + if( nData ){ + if( fts5BufferGrow(pRc, pBuf, nData) ) return; + memcpy(&pBuf->p[pBuf->n], pData, nData); + pBuf->n += nData; + } } /* ** Append the nul-terminated string zStr to the buffer pBuf. This function ** ensures that the byte following the buffer data is set to 0x00, even @@ -184793,12 +185476,12 @@ static void *sqlite3Fts5MallocZero(int *pRc, int nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ pRet = sqlite3_malloc(nByte); - if( pRet==0 && nByte>0 ){ - *pRc = SQLITE_NOMEM; + if( pRet==0 ){ + if( nByte>0 ) *pRc = SQLITE_NOMEM; }else{ memset(pRet, 0, nByte); } } return pRet; @@ -186115,10 +186798,11 @@ static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); } static void fts5ParseFree(void *p){ sqlite3_free(p); } static int sqlite3Fts5ExprNew( Fts5Config *pConfig, /* FTS5 Configuration */ + int iCol, const char *zExpr, /* Expression text */ Fts5Expr **ppNew, char **pzErr ){ Fts5Parse sParse; @@ -186138,10 +186822,22 @@ do { t = fts5ExprGetToken(&sParse, &z, &token); sqlite3Fts5Parser(pEngine, t, token, &sParse); }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); + + /* If the LHS of the MATCH expression was a user column, apply the + ** implicit column-filter. */ + if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ + int n = sizeof(Fts5Colset); + Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); + if( pColset ){ + pColset->nCol = 1; + pColset->aiCol[0] = iCol; + sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); + } + } assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); if( pNew==0 ){ @@ -187788,29 +188484,114 @@ } return pRet; } +/* +** If argument pOrig is NULL, or if (*pRc) is set to anything other than +** SQLITE_OK when this function is called, NULL is returned. +** +** Otherwise, a copy of (*pOrig) is made into memory obtained from +** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation +** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. +*/ +static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ + Fts5Colset *pRet; + if( pOrig ){ + int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); + if( pRet ){ + memcpy(pRet, pOrig, nByte); + } + }else{ + pRet = 0; + } + return pRet; +} + +/* +** Remove from colset pColset any columns that are not also in colset pMerge. +*/ +static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){ + int iIn = 0; /* Next input in pColset */ + int iMerge = 0; /* Next input in pMerge */ + int iOut = 0; /* Next output slot in pColset */ + + while( iInnCol && iMergenCol ){ + int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge]; + if( iDiff==0 ){ + pColset->aiCol[iOut++] = pMerge->aiCol[iMerge]; + iMerge++; + iIn++; + }else if( iDiff>0 ){ + iMerge++; + }else{ + iIn++; + } + } + pColset->nCol = iOut; +} + +/* +** Recursively apply colset pColset to expression node pNode and all of +** its decendents. If (*ppFree) is not NULL, it contains a spare copy +** of pColset. This function may use the spare copy and set (*ppFree) to +** zero, or it may create copies of pColset using fts5CloneColset(). +*/ +static void fts5ParseSetColset( + Fts5Parse *pParse, + Fts5ExprNode *pNode, + Fts5Colset *pColset, + Fts5Colset **ppFree +){ + if( pParse->rc==SQLITE_OK ){ + assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING + || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR + || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF + ); + if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){ + Fts5ExprNearset *pNear = pNode->pNear; + if( pNear->pColset ){ + fts5MergeColset(pNear->pColset, pColset); + if( pNear->pColset->nCol==0 ){ + pNode->eType = FTS5_EOF; + pNode->xNext = 0; + } + }else if( *ppFree ){ + pNear->pColset = pColset; + *ppFree = 0; + }else{ + pNear->pColset = fts5CloneColset(&pParse->rc, pColset); + } + }else{ + int i; + assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 ); + for(i=0; inChild; i++){ + fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree); + } + } + } +} + +/* +** Apply colset pColset to expression node pExpr and all of its descendents. +*/ static void sqlite3Fts5ParseSetColset( Fts5Parse *pParse, - Fts5ExprNearset *pNear, + Fts5ExprNode *pExpr, Fts5Colset *pColset ){ + Fts5Colset *pFree = pColset; if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){ pParse->rc = SQLITE_ERROR; pParse->zErr = sqlite3_mprintf( "fts5: column queries are not supported (detail=none)" ); - sqlite3_free(pColset); - return; - } - - if( pNear ){ - pNear->pColset = pColset; - }else{ - sqlite3_free(pColset); - } + }else{ + fts5ParseSetColset(pParse, pExpr, pColset, &pFree); + } + sqlite3_free(pFree); } static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ switch( pNode->eType ){ case FTS5_STRING: { @@ -188260,11 +189041,11 @@ zExpr = (const char*)sqlite3_value_text(apVal[0]); rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr); + rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; if( pExpr->pRoot->xNext==0 ){ zText = sqlite3_mprintf(""); @@ -188657,13 +189438,14 @@ Fts5HashEntry **aSlot; /* Array of hash slots */ }; /* ** Each entry in the hash table is represented by an object of the -** following type. Each object, its key (zKey[]) and its current data -** are stored in a single memory allocation. The position list data -** immediately follows the key data in memory. +** following type. Each object, its key (a nul-terminated string) and +** its current data are stored in a single memory allocation. The +** key immediately follows the object in memory. The position list +** data immediately follows the key data in memory. ** ** The data that follows the key is in a similar, but not identical format ** to the doclist data stored in the database. It is: ** ** * Rowid, as a varint @@ -188683,24 +189465,24 @@ Fts5HashEntry *pScanNext; /* Next entry in sorted order */ int nAlloc; /* Total size of allocation */ int iSzPoslist; /* Offset of space for 4-byte poslist size */ int nData; /* Total bytes of data (incl. structure) */ - int nKey; /* Length of zKey[] in bytes */ + int nKey; /* Length of key in bytes */ u8 bDel; /* Set delete-flag @ iSzPoslist */ u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ - char zKey[8]; /* Nul-terminated entry key */ }; /* -** Size of Fts5HashEntry without the zKey[] array. +** Eqivalent to: +** +** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } */ -#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8) - +#define fts5EntryKey(p) ( ((char *)(&(p)[1])) ) /* ** Allocate a new hash table. */ @@ -188794,11 +189576,11 @@ for(i=0; inSlot; i++){ while( apOld[i] ){ int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; - iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey)); + iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), strlen(fts5EntryKey(p))); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } } @@ -188865,22 +189647,24 @@ bNew = (pHash->eDetail==FTS5_DETAIL_FULL); /* Attempt to locate an existing hash entry */ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken); for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ - if( p->zKey[0]==bByte + char *zKey = fts5EntryKey(p); + if( zKey[0]==bByte && p->nKey==nToken - && memcmp(&p->zKey[1], pToken, nToken)==0 + && memcmp(&zKey[1], pToken, nToken)==0 ){ break; } } /* If an existing hash entry cannot be found, create a new one. */ if( p==0 ){ /* Figure out how much space to allocate */ - int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64; + char *zKey; + int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; if( nByte<128 ) nByte = 128; /* Grow the Fts5Hash.aSlot[] array if necessary. */ if( (pHash->nEntry*2)>=pHash->nSlot ){ int rc = fts5HashResize(pHash); @@ -188889,18 +189673,19 @@ } /* Allocate new Fts5HashEntry and add it to the hash table. */ p = (Fts5HashEntry*)sqlite3_malloc(nByte); if( !p ) return SQLITE_NOMEM; - memset(p, 0, FTS5_HASHENTRYSIZE); + memset(p, 0, sizeof(Fts5HashEntry)); p->nAlloc = nByte; - p->zKey[0] = bByte; - memcpy(&p->zKey[1], pToken, nToken); - assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) ); + zKey = fts5EntryKey(p); + zKey[0] = bByte; + memcpy(&zKey[1], pToken, nToken); + assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); p->nKey = nToken; - p->zKey[nToken+1] = '\0'; - p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE; + zKey[nToken+1] = '\0'; + p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); p->pHashNext = pHash->aSlot[iHash]; pHash->aSlot[iHash] = p; pHash->nEntry++; /* Add the first rowid field to the hash-entry */ @@ -189014,13 +189799,15 @@ }else if( p2==0 ){ *ppOut = p1; p1 = 0; }else{ int i = 0; - while( p1->zKey[i]==p2->zKey[i] ) i++; + char *zKey1 = fts5EntryKey(p1); + char *zKey2 = fts5EntryKey(p2); + while( zKey1[i]==zKey2[i] ) i++; - if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){ + if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ /* p2 is smaller */ *ppOut = p2; ppOut = &p2->pScanNext; p2 = p2->pScanNext; }else{ @@ -189059,11 +189846,11 @@ memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot); for(iSlot=0; iSlotnSlot; iSlot++){ Fts5HashEntry *pIter; for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ - if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){ + if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){ Fts5HashEntry *pEntry = pIter; pEntry->pScanNext = 0; for(i=0; ap[i]; i++){ pEntry = fts5HashEntryMerge(pEntry, ap[i]); ap[i] = 0; @@ -189092,20 +189879,22 @@ const char *pTerm, int nTerm, /* Query term */ const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */ int *pnDoclist /* OUT: Size of doclist in bytes */ ){ unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm); + char *zKey; Fts5HashEntry *p; for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ - if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break; + zKey = fts5EntryKey(p); + if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break; } if( p ){ fts5HashAddPoslistSize(pHash, p); - *ppDoclist = (const u8*)&p->zKey[nTerm+1]; - *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1); + *ppDoclist = (const u8*)&zKey[nTerm+1]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); }else{ *ppDoclist = 0; *pnDoclist = 0; } @@ -189134,15 +189923,16 @@ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ - int nTerm = (int)strlen(p->zKey); + char *zKey = fts5EntryKey(p); + int nTerm = (int)strlen(zKey); fts5HashAddPoslistSize(pHash, p); - *pzTerm = p->zKey; - *ppDoclist = (const u8*)&p->zKey[nTerm+1]; - *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1); + *pzTerm = zKey; + *ppDoclist = (const u8*)&zKey[nTerm+1]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); }else{ *pzTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } @@ -189776,11 +190566,10 @@ sqlite3_blob *pReader = p->pReader; p->pReader = 0; sqlite3_blob_close(pReader); } } - /* ** Retrieve a record from the %_data table. ** ** If an error occurs, NULL is returned and an error left in the @@ -192028,11 +192817,12 @@ Fts5Iter *pIter, int *pbNewTerm /* OUT: True if *might* be new term */ ){ assert( pIter->bSkipEmpty ); if( p->rc==SQLITE_OK ){ - do { + *pbNewTerm = 0; + do{ int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; int bNewTerm = 0; assert( p->rc==SQLITE_OK ); @@ -192041,12 +192831,10 @@ || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg) ){ fts5MultiIterAdvanced(p, pIter, iFirst, 1); fts5MultiIterSetEof(pIter); *pbNewTerm = 1; - }else{ - *pbNewTerm = 0; } fts5AssertMultiIterSetup(p, pIter); }while( fts5MultiIterIsEmpty(p, pIter) ); } @@ -192308,27 +193096,27 @@ } return p - (*pa); } -static int fts5IndexExtractColset ( +static void fts5IndexExtractColset( + int *pRc, Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ Fts5Buffer *pBuf /* Output buffer */ ){ - int rc = SQLITE_OK; - int i; - - fts5BufferZero(pBuf); - for(i=0; inCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); + if( *pRc==SQLITE_OK ){ + int i; + fts5BufferZero(pBuf); + for(i=0; inCol; i++){ + const u8 *pSub = pPos; + int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); + if( nSub ){ + fts5BufferAppendBlob(pRc, pBuf, nSub, pSub); + } } } - return rc; } /* ** xSetOutputs callback used by detail=none tables. */ @@ -192448,12 +193236,13 @@ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; if( pColset->nCol==1 ){ pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); pIter->base.pData = a; }else{ + int *pRc = &pIter->pIndex->rc; fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); + fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist); pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } }else{ /* The data is distributed over two or more pages. Copy it into the @@ -192994,13 +193783,10 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 }; Fts5PageWriter *pPage = &pWriter->writer; i64 iRowid; -static int nCall = 0; -nCall++; - assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) ); /* Set the szLeaf header field. */ assert( 0==fts5GetU16(&pPage->buf.p[2]) ); fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n); @@ -193345,10 +194131,11 @@ Fts5StructureSegment *pSeg; /* Output segment */ Fts5Buffer term; int bOldest; /* True if the output segment is the oldest */ int eDetail = p->pConfig->eDetail; const int flags = FTS5INDEX_QUERY_NOOUTPUT; + int bTermWritten = 0; /* True if current term already output */ assert( iLvlnLevel ); assert( pLvl->nMerge<=pLvl->nSeg ); memset(&writer, 0, sizeof(Fts5SegWriter)); @@ -193398,22 +194185,26 @@ Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int nPos; /* position-list size field value */ int nTerm; const u8 *pTerm; - /* Check for key annihilation. */ - if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue; - pTerm = fts5MultiIterTerm(pIter, &nTerm); if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){ if( pnRem && writer.nLeafWritten>nRem ){ break; } + fts5BufferSet(&p->rc, &term, nTerm, pTerm); + bTermWritten =0; + } + /* Check for key annihilation. */ + if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue; + + if( p->rc==SQLITE_OK && bTermWritten==0 ){ /* This is a new term. Append a term to the output segment. */ fts5WriteAppendTerm(p, &writer, nTerm, pTerm); - fts5BufferSet(&p->rc, &term, nTerm, pTerm); + bTermWritten = 1; } /* Append the rowid to the output */ /* WRITEPOSLISTSIZE */ fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter)); @@ -194241,11 +195032,11 @@ pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = doclist.n; - memcpy(pData->p, doclist.p, doclist.n); + if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } fts5BufferFree(&doclist); } @@ -194280,14 +195071,14 @@ } /* ** Commit data to disk. */ -static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){ +static int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - if( bCommit ) fts5CloseReader(p); + fts5CloseReader(p); return fts5IndexReturn(p); } /* ** Discard any data stored in the in-memory hash tables. Do not write it @@ -194480,11 +195271,11 @@ /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ - memcpy(&buf.p[1], pToken, nToken); + if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be ** satisfied by scanning multiple terms in the main index. @@ -194529,11 +195320,11 @@ if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } if( p->rc ){ - sqlite3Fts5IterClose(&pRet->base); + sqlite3Fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; fts5CloseReader(p); } *ppIter = &pRet->base; @@ -196147,10 +196938,11 @@ ** Costs are not modified by the ORDER BY clause. */ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; + const int nCol = pConfig->nCol; int idxFlags = 0; /* Parameter passed through to xFilter() */ int bHasMatch; int iNext; int i; @@ -196172,28 +196964,38 @@ FTS5_BI_ROWID_GE, 0, 0, -1}, }; int aColMap[3]; aColMap[0] = -1; - aColMap[1] = pConfig->nCol; - aColMap[2] = pConfig->nCol+1; + aColMap[1] = nCol; + aColMap[2] = nCol+1; /* Set idxFlags flags for all WHERE clause terms that will be used. */ for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; - int j; - for(j=0; jiColumn==aColMap[pC->iCol] && p->op & pC->op ){ - if( p->usable ){ + int iCol = p->iColumn; + + if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol) + || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol) + ){ + /* A MATCH operator or equivalent */ + if( p->usable ){ + idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16); + aConstraint[0].iConsIndex = i; + }else{ + /* As there exists an unusable MATCH constraint this is an + ** unusable plan. Set a prohibitively high cost. */ + pInfo->estimatedCost = 1e50; + return SQLITE_OK; + } + }else{ + int j; + for(j=1; jiCol] && p->op & pC->op && p->usable ){ pC->iConsIndex = i; idxFlags |= pC->fts5op; - }else if( j==0 ){ - /* As there exists an unusable MATCH constraint this is an - ** unusable plan. Set a prohibitively high cost. */ - pInfo->estimatedCost = 1e50; - return SQLITE_OK; } } } } @@ -196764,10 +197566,11 @@ sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ + int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; UNUSED_PARAM(zUnused); UNUSED_PARAM(nVal); @@ -196794,10 +197597,12 @@ if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++]; + iCol = (idxNum>>16); + assert( iCol>=0 && iCol<=pConfig->nCol ); assert( iVal==nVal ); bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0); pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0); /* Set the cursor upper and lower rowid limits. Only some strategies @@ -196840,11 +197645,11 @@ ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]); }else{ char **pzErr = &pTab->base.zErrMsg; - rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr); + rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr); if( rc==SQLITE_OK ){ if( bOrderByRank ){ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ @@ -197220,11 +198025,11 @@ int rc; Fts5Table *pTab = (Fts5Table*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg; fts5TripCursors(pTab); - rc = sqlite3Fts5StorageSync(pTab->pStorage, 1); + rc = sqlite3Fts5StorageSync(pTab->pStorage); pTab->pConfig->pzErrmsg = 0; return rc; } /* @@ -198031,11 +198836,11 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* ** The xRelease() method. ** @@ -198044,11 +198849,11 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* ** The xRollbackTo() method. ** @@ -198255,11 +199060,11 @@ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b", -1, SQLITE_TRANSIENT); } static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { /* iVersion */ 2, @@ -198591,11 +199396,11 @@ } } static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ Fts5Config *pConfig = pStorage->pConfig; - int rc = sqlite3Fts5StorageSync(pStorage, 1); + int rc = sqlite3Fts5StorageSync(pStorage); fts5StorageRenameOne(pConfig, &rc, "data", zName); fts5StorageRenameOne(pConfig, &rc, "idx", zName); fts5StorageRenameOne(pConfig, &rc, "config", zName); if( pConfig->bColumnsize ){ @@ -199454,19 +200259,19 @@ } /* ** Flush any data currently held in-memory to disk. */ -static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){ +static int sqlite3Fts5StorageSync(Fts5Storage *p){ int rc = SQLITE_OK; i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - if( bCommit ) p->bTotalsValid = 0; + p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexSync(p->pIndex, bCommit); + rc = sqlite3Fts5IndexSync(p->pIndex); } sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); return rc; } Index: SQLite.Interop/src/core/sqlite3.h ================================================================== --- SQLite.Interop/src/core/sqlite3.h +++ SQLite.Interop/src/core/sqlite3.h @@ -119,13 +119,13 @@ ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.18.0" -#define SQLITE_VERSION_NUMBER 3018000 -#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37" +#define SQLITE_VERSION "3.19.3" +#define SQLITE_VERSION_NUMBER 3019003 +#define SQLITE_SOURCE_ID "2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** @@ -855,11 +855,11 @@ ** of 25 milliseconds before the first retry and with the delay increasing ** by an additional 25 milliseconds with each subsequent retry. This ** opcode allows these two values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two -** integers where the first integer i the new retry count and the second +** integers where the first integer is the new retry count and the second ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** @@ -2209,13 +2209,10 @@ ** that are started after the running statement count reaches zero are ** not effected by the sqlite3_interrupt(). ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** If the database connection closes while [sqlite3_interrupt()] -** is running then bad things will likely happen. */ SQLITE_API void sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -2674,10 +2671,11 @@ SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** METHOD: sqlite3 +** KEYWORDS: {authorizer callback} ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], @@ -2701,20 +2699,26 @@ ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter ** to the callback is an integer [SQLITE_COPY | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters -** to the callback are zero-terminated strings that contain additional -** details about the action to be authorized. +** to the callback are either NULL pointers or zero-terminated strings +** that contain additional details about the action to be authorized. +** Applications must always be prepared to encounter a NULL pointer in any +** of the third through the sixth parameters of the authorization callback. ** ** ^If the action code is [SQLITE_READ] ** and the callback returns [SQLITE_IGNORE] then the ** [prepared statement] statement is constructed to substitute ** a NULL value in place of the table column that would have ** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] ** return can be used to deny an untrusted user access to individual ** columns of a table. +** ^When a table is referenced by a [SELECT] but no column values are +** extracted from that table (for example in a query like +** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback +** is invoked once for that table with a column name that is an empty string. ** ^If the action code is [SQLITE_DELETE] and the callback returns ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the ** [truncate optimization] is disabled and all rows are deleted individually. ** ** An authorizer is used when [sqlite3_prepare | preparing] @@ -3703,11 +3707,11 @@ ** Unprotected sqlite3_value objects may only be used with ** [sqlite3_result_value()] and [sqlite3_bind_value()]. ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ -typedef struct Mem sqlite3_value; +typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object ** ** The context in which an SQL function executes is stored in an @@ -4757,14 +4761,15 @@ ** metadata associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata -** associated by the sqlite3_set_auxdata() function with the Nth argument -** value to the application-defined function. ^If there is no metadata -** associated with the function argument, this sqlite3_get_auxdata() interface +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument +** value to the application-defined function. ^N is zero for the left-most +** function argument. ^If there is no metadata +** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th ** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent @@ -4790,10 +4795,14 @@ ** sqlite3_set_auxdata() has been called. ** ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ +** +** The value of the N parameter to these interfaces should be non-negative. +** Future enhancements may make use of negative N values to define new +** kinds of function caching behavior. ** ** These routines must be called from the same thread in which ** the SQL function is running. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); @@ -9385,11 +9394,11 @@ ** ** As well as the regular sqlite3changegroup_add() and ** sqlite3changegroup_output() functions, also available are the streaming ** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). */ -int sqlite3changegroup_new(sqlite3_changegroup **pp); +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); /* ** CAPI3REF: Add A Changeset To A Changegroup ** ** Add all changes within the changeset (or patchset) in buffer pData (size @@ -9462,11 +9471,11 @@ ** function returns SQLITE_NOMEM. In all cases, if an error occurs the ** final contents of the changegroup is undefined. ** ** If no error occurs, SQLITE_OK is returned. */ -int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup ** ** Obtain a buffer containing a changeset (or patchset) representing the @@ -9488,20 +9497,20 @@ ** is returned and the output variables are set to the size of and a ** pointer to the output buffer, respectively. In this case it is the ** responsibility of the caller to eventually free the buffer using a ** call to sqlite3_free(). */ -int sqlite3changegroup_output( +SQLITE_API int sqlite3changegroup_output( sqlite3_changegroup*, int *pnData, /* OUT: Size of output buffer in bytes */ void **ppData /* OUT: Pointer to output buffer */ ); /* ** CAPI3REF: Delete A Changegroup Object */ -void sqlite3changegroup_delete(sqlite3_changegroup*); +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database ** ** Apply a changeset to a database. This function attempts to update the @@ -9886,15 +9895,15 @@ SQLITE_API int sqlite3session_patchset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -int sqlite3changegroup_add_strm(sqlite3_changegroup*, +SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); -int sqlite3changegroup_output_strm(sqlite3_changegroup*, +SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); Index: SQLite.Interop/src/ext/fts5.c ================================================================== --- SQLite.Interop/src/ext/fts5.c +++ SQLite.Interop/src/ext/fts5.c @@ -1037,13 +1037,13 @@ i64 iDocid /* Docid to add or remove data from */ ); /* ** Flush any data stored in the in-memory hash tables to the database. -** If the bCommit flag is true, also close any open blob handles. +** Also close any open blob handles. */ -static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit); +static int sqlite3Fts5IndexSync(Fts5Index *p); /* ** Discard any data stored in the in-memory hash tables. Do not write it ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data @@ -1209,11 +1209,11 @@ static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol); static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg); static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow); -static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit); +static int sqlite3Fts5StorageSync(Fts5Storage *p); static int sqlite3Fts5StorageRollback(Fts5Storage *p); static int sqlite3Fts5StorageConfigValue( Fts5Storage *p, const char*, sqlite3_value*, int ); @@ -1245,10 +1245,11 @@ }; /* Parse a MATCH expression. */ static int sqlite3Fts5ExprNew( Fts5Config *pConfig, + int iCol, /* Column on LHS of MATCH operator */ const char *zExpr, Fts5Expr **ppNew, char **pzErr ); @@ -1329,11 +1330,11 @@ static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); -static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); +static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*); static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); /* @@ -1387,16 +1388,16 @@ #define FTS5_OR 1 #define FTS5_AND 2 #define FTS5_NOT 3 #define FTS5_TERM 4 #define FTS5_COLON 5 -#define FTS5_LP 6 -#define FTS5_RP 7 -#define FTS5_MINUS 8 -#define FTS5_LCP 9 -#define FTS5_RCP 10 -#define FTS5_STRING 11 +#define FTS5_MINUS 6 +#define FTS5_LCP 7 +#define FTS5_RCP 8 +#define FTS5_STRING 9 +#define FTS5_LP 10 +#define FTS5_RP 11 #define FTS5_COMMA 12 #define FTS5_PLUS 13 #define FTS5_STAR 14 #line 1 "fts5parse.c" @@ -1531,20 +1532,20 @@ #endif #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse -#define fts5YYNSTATE 29 -#define fts5YYNRULE 26 -#define fts5YY_MAX_SHIFT 28 -#define fts5YY_MIN_SHIFTREDUCE 45 -#define fts5YY_MAX_SHIFTREDUCE 70 -#define fts5YY_MIN_REDUCE 71 -#define fts5YY_MAX_REDUCE 96 -#define fts5YY_ERROR_ACTION 97 -#define fts5YY_ACCEPT_ACTION 98 -#define fts5YY_NO_ACTION 99 +#define fts5YYNSTATE 33 +#define fts5YYNRULE 27 +#define fts5YY_MAX_SHIFT 32 +#define fts5YY_MIN_SHIFTREDUCE 50 +#define fts5YY_MAX_SHIFTREDUCE 76 +#define fts5YY_MIN_REDUCE 77 +#define fts5YY_MAX_REDUCE 103 +#define fts5YY_ERROR_ACTION 104 +#define fts5YY_ACCEPT_ACTION 105 +#define fts5YY_NO_ACTION 106 /************* End control #defines *******************************************/ /* Define the fts5yytestcase() macro to be a no-op if is not already defined ** otherwise. ** @@ -1612,54 +1613,58 @@ ** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for ** shifting non-terminals after a reduce. ** fts5yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define fts5YY_ACTTAB_COUNT (85) +#define fts5YY_ACTTAB_COUNT (98) static const fts5YYACTIONTYPE fts5yy_action[] = { - /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15, - /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5, - /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53, - /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68, - /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27, - /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21, - /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59, - /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69, - /* 80 */ 25, 66, 8, 14, 2, + /* 0 */ 105, 19, 63, 6, 26, 66, 65, 24, 24, 17, + /* 10 */ 63, 6, 26, 16, 65, 54, 24, 18, 63, 6, + /* 20 */ 26, 10, 65, 12, 24, 75, 59, 63, 6, 26, + /* 30 */ 13, 65, 75, 24, 20, 63, 6, 26, 74, 65, + /* 40 */ 56, 24, 27, 63, 6, 26, 73, 65, 21, 24, + /* 50 */ 23, 15, 30, 11, 1, 64, 22, 25, 9, 65, + /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77, + /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12, + /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32, + /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14, }; static const fts5YYCODETYPE fts5yy_lookahead[] = { - /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17, - /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19, - /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20, - /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26, - /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21, - /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24, - /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11, - /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14, - /* 80 */ 13, 11, 5, 11, 3, + /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17, + /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19, + /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20, + /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22, + /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24, + /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22, + /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0, + /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9, + /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25, + /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9, }; -#define fts5YY_SHIFT_USE_DFLT (85) -#define fts5YY_SHIFT_COUNT (28) +#define fts5YY_SHIFT_USE_DFLT (98) +#define fts5YY_SHIFT_COUNT (32) #define fts5YY_SHIFT_MIN (0) -#define fts5YY_SHIFT_MAX (81) +#define fts5YY_SHIFT_MAX (90) static const unsigned char fts5yy_shift_ofst[] = { - /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1, - /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63, - /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81, + /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14, + /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69, + /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87, + /* 30 */ 88, 39, 71, }; -#define fts5YY_REDUCE_USE_DFLT (-17) -#define fts5YY_REDUCE_COUNT (14) -#define fts5YY_REDUCE_MIN (-16) -#define fts5YY_REDUCE_MAX (54) +#define fts5YY_REDUCE_USE_DFLT (-18) +#define fts5YY_REDUCE_COUNT (16) +#define fts5YY_REDUCE_MIN (-17) +#define fts5YY_REDUCE_MAX (67) static const signed char fts5yy_reduce_ofst[] = { - /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13, - /* 10 */ 13, 22, 54, 13, 51, + /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17, + /* 10 */ 67, 12, 12, 12, 20, 27, 35, }; static const fts5YYACTIONTYPE fts5yy_default[] = { - /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96, - /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97, - /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72, + /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104, + /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104, + /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104, + /* 30 */ 104, 97, 104, }; /********** End of lemon-generated parsing tables *****************************/ /* The next table maps tokens (terminal symbols) into fallback tokens. ** If a construct like the following: @@ -1761,49 +1766,50 @@ #ifndef NDEBUG /* For tracing shifts, the names of all terminals and nonterminals ** are required. The following table supplies these names */ static const char *const fts5yyTokenName[] = { "$", "OR", "AND", "NOT", - "TERM", "COLON", "LP", "RP", - "MINUS", "LCP", "RCP", "STRING", + "TERM", "COLON", "MINUS", "LCP", + "RCP", "STRING", "LP", "RP", "COMMA", "PLUS", "STAR", "error", "input", "expr", "cnearset", "exprlist", - "nearset", "colset", "colsetlist", "nearphrases", + "colset", "colsetlist", "nearset", "nearphrases", "phrase", "neardist_opt", "star_opt", }; #endif /* NDEBUG */ #ifndef NDEBUG /* For tracing reduce actions, the names of all rules are required. */ static const char *const fts5yyRuleName[] = { /* 0 */ "input ::= expr", - /* 1 */ "expr ::= expr AND expr", - /* 2 */ "expr ::= expr OR expr", - /* 3 */ "expr ::= expr NOT expr", - /* 4 */ "expr ::= LP expr RP", - /* 5 */ "expr ::= exprlist", - /* 6 */ "exprlist ::= cnearset", - /* 7 */ "exprlist ::= exprlist cnearset", - /* 8 */ "cnearset ::= nearset", - /* 9 */ "cnearset ::= colset COLON nearset", - /* 10 */ "colset ::= MINUS LCP colsetlist RCP", - /* 11 */ "colset ::= LCP colsetlist RCP", - /* 12 */ "colset ::= STRING", - /* 13 */ "colset ::= MINUS STRING", - /* 14 */ "colsetlist ::= colsetlist STRING", - /* 15 */ "colsetlist ::= STRING", - /* 16 */ "nearset ::= phrase", - /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP", - /* 18 */ "nearphrases ::= phrase", - /* 19 */ "nearphrases ::= nearphrases phrase", - /* 20 */ "neardist_opt ::=", - /* 21 */ "neardist_opt ::= COMMA STRING", - /* 22 */ "phrase ::= phrase PLUS STRING star_opt", - /* 23 */ "phrase ::= STRING star_opt", - /* 24 */ "star_opt ::= STAR", - /* 25 */ "star_opt ::=", + /* 1 */ "colset ::= MINUS LCP colsetlist RCP", + /* 2 */ "colset ::= LCP colsetlist RCP", + /* 3 */ "colset ::= STRING", + /* 4 */ "colset ::= MINUS STRING", + /* 5 */ "colsetlist ::= colsetlist STRING", + /* 6 */ "colsetlist ::= STRING", + /* 7 */ "expr ::= expr AND expr", + /* 8 */ "expr ::= expr OR expr", + /* 9 */ "expr ::= expr NOT expr", + /* 10 */ "expr ::= colset COLON LP expr RP", + /* 11 */ "expr ::= LP expr RP", + /* 12 */ "expr ::= exprlist", + /* 13 */ "exprlist ::= cnearset", + /* 14 */ "exprlist ::= exprlist cnearset", + /* 15 */ "cnearset ::= nearset", + /* 16 */ "cnearset ::= colset COLON nearset", + /* 17 */ "nearset ::= phrase", + /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP", + /* 19 */ "nearphrases ::= phrase", + /* 20 */ "nearphrases ::= nearphrases phrase", + /* 21 */ "neardist_opt ::=", + /* 22 */ "neardist_opt ::= COMMA STRING", + /* 23 */ "phrase ::= phrase PLUS STRING star_opt", + /* 24 */ "phrase ::= STRING star_opt", + /* 25 */ "star_opt ::= STAR", + /* 26 */ "star_opt ::=", }; #endif /* NDEBUG */ #if fts5YYSTACKDEPTH<=0 @@ -1921,43 +1927,43 @@ /********* Begin destructor definitions ***************************************/ case 16: /* input */ { #line 83 "fts5parse.y" (void)pParse; -#line 525 "fts5parse.c" +#line 530 "fts5parse.c" } break; case 17: /* expr */ case 18: /* cnearset */ case 19: /* exprlist */ { #line 89 "fts5parse.y" sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); -#line 534 "fts5parse.c" +#line 539 "fts5parse.c" } break; - case 20: /* nearset */ + case 20: /* colset */ + case 21: /* colsetlist */ +{ +#line 93 "fts5parse.y" + sqlite3_free((fts5yypminor->fts5yy11)); +#line 547 "fts5parse.c" +} + break; + case 22: /* nearset */ case 23: /* nearphrases */ { -#line 143 "fts5parse.y" +#line 148 "fts5parse.y" sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); -#line 542 "fts5parse.c" -} - break; - case 21: /* colset */ - case 22: /* colsetlist */ -{ -#line 119 "fts5parse.y" - sqlite3_free((fts5yypminor->fts5yy11)); -#line 550 "fts5parse.c" +#line 555 "fts5parse.c" } break; case 24: /* phrase */ { -#line 174 "fts5parse.y" +#line 179 "fts5parse.y" sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); -#line 557 "fts5parse.c" +#line 562 "fts5parse.c" } break; /********* End destructor definitions *****************************************/ default: break; /* If no destructor action specified: do nothing */ } @@ -2135,11 +2141,11 @@ ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ #line 36 "fts5parse.y" sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow"); -#line 739 "fts5parse.c" +#line 744 "fts5parse.c" /******** End %stack_overflow code ********************************************/ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ } /* @@ -2210,27 +2216,28 @@ static const struct { fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } fts5yyRuleInfo[] = { { 16, 1 }, + { 20, 4 }, + { 20, 3 }, + { 20, 1 }, + { 20, 2 }, + { 21, 2 }, + { 21, 1 }, { 17, 3 }, { 17, 3 }, { 17, 3 }, + { 17, 5 }, { 17, 3 }, { 17, 1 }, { 19, 1 }, { 19, 2 }, { 18, 1 }, { 18, 3 }, - { 21, 4 }, - { 21, 3 }, - { 21, 1 }, - { 21, 2 }, - { 22, 2 }, { 22, 1 }, - { 20, 1 }, - { 20, 5 }, + { 22, 5 }, { 23, 1 }, { 23, 2 }, { 25, 0 }, { 25, 2 }, { 24, 4 }, @@ -2301,183 +2308,192 @@ /********** Begin reduce actions **********************************************/ fts5YYMINORTYPE fts5yylhsminor; case 0: /* input ::= expr */ #line 82 "fts5parse.y" { sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); } -#line 905 "fts5parse.c" - break; - case 1: /* expr ::= expr AND expr */ -#line 92 "fts5parse.y" -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} -#line 912 "fts5parse.c" - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 2: /* expr ::= expr OR expr */ -#line 95 "fts5parse.y" -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} -#line 920 "fts5parse.c" - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 3: /* expr ::= expr NOT expr */ -#line 98 "fts5parse.y" -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); -} -#line 928 "fts5parse.c" - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 4: /* expr ::= LP expr RP */ -#line 102 "fts5parse.y" -{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;} -#line 934 "fts5parse.c" - break; - case 5: /* expr ::= exprlist */ - case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6); -#line 103 "fts5parse.y" -{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;} -#line 940 "fts5parse.c" - fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 7: /* exprlist ::= exprlist cnearset */ -#line 106 "fts5parse.y" -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); -} -#line 948 "fts5parse.c" - fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 8: /* cnearset ::= nearset */ -#line 110 "fts5parse.y" -{ - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); -} -#line 956 "fts5parse.c" - fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 9: /* cnearset ::= colset COLON nearset */ -#line 113 "fts5parse.y" -{ - sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11); - fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); -} -#line 965 "fts5parse.c" - fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; - break; - case 10: /* colset ::= MINUS LCP colsetlist RCP */ -#line 123 "fts5parse.y" +#line 911 "fts5parse.c" + break; + case 1: /* colset ::= MINUS LCP colsetlist RCP */ +#line 97 "fts5parse.y" { fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); } -#line 973 "fts5parse.c" +#line 918 "fts5parse.c" break; - case 11: /* colset ::= LCP colsetlist RCP */ -#line 126 "fts5parse.y" + case 2: /* colset ::= LCP colsetlist RCP */ +#line 100 "fts5parse.y" { fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; } -#line 978 "fts5parse.c" +#line 923 "fts5parse.c" break; - case 12: /* colset ::= STRING */ -#line 127 "fts5parse.y" + case 3: /* colset ::= STRING */ +#line 101 "fts5parse.y" { fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); } -#line 985 "fts5parse.c" +#line 930 "fts5parse.c" fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; - case 13: /* colset ::= MINUS STRING */ -#line 130 "fts5parse.y" + case 4: /* colset ::= MINUS STRING */ +#line 104 "fts5parse.y" { fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); } -#line 994 "fts5parse.c" +#line 939 "fts5parse.c" break; - case 14: /* colsetlist ::= colsetlist STRING */ -#line 135 "fts5parse.y" + case 5: /* colsetlist ::= colsetlist STRING */ +#line 109 "fts5parse.y" { fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); } -#line 1000 "fts5parse.c" +#line 945 "fts5parse.c" fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; - case 15: /* colsetlist ::= STRING */ -#line 137 "fts5parse.y" + case 6: /* colsetlist ::= STRING */ +#line 111 "fts5parse.y" { fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); } -#line 1008 "fts5parse.c" +#line 953 "fts5parse.c" fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; - case 16: /* nearset ::= phrase */ -#line 146 "fts5parse.y" -{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } + case 7: /* expr ::= expr AND expr */ +#line 115 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} +#line 961 "fts5parse.c" + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 8: /* expr ::= expr OR expr */ +#line 118 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} +#line 969 "fts5parse.c" + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 9: /* expr ::= expr NOT expr */ +#line 121 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); +} +#line 977 "fts5parse.c" + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 10: /* expr ::= colset COLON LP expr RP */ +#line 125 "fts5parse.y" +{ + sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11); + fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24; +} +#line 986 "fts5parse.c" + fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 11: /* expr ::= LP expr RP */ +#line 129 "fts5parse.y" +{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;} +#line 992 "fts5parse.c" + break; + case 12: /* expr ::= exprlist */ + case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13); +#line 130 "fts5parse.y" +{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;} +#line 998 "fts5parse.c" + fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 14: /* exprlist ::= exprlist cnearset */ +#line 133 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); +} +#line 1006 "fts5parse.c" + fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 15: /* cnearset ::= nearset */ +#line 137 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); +} #line 1014 "fts5parse.c" + fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 16: /* cnearset ::= colset COLON nearset */ +#line 140 "fts5parse.y" +{ + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); + sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11); +} +#line 1023 "fts5parse.c" + fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; + break; + case 17: /* nearset ::= phrase */ +#line 151 "fts5parse.y" +{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } +#line 1029 "fts5parse.c" fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */ -#line 147 "fts5parse.y" + case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */ +#line 152 "fts5parse.y" { sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0); sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0); fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46; } -#line 1024 "fts5parse.c" +#line 1039 "fts5parse.c" fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 18: /* nearphrases ::= phrase */ -#line 153 "fts5parse.y" + case 19: /* nearphrases ::= phrase */ +#line 158 "fts5parse.y" { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } -#line 1032 "fts5parse.c" +#line 1047 "fts5parse.c" fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 19: /* nearphrases ::= nearphrases phrase */ -#line 156 "fts5parse.y" + case 20: /* nearphrases ::= nearphrases phrase */ +#line 161 "fts5parse.y" { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53); } -#line 1040 "fts5parse.c" +#line 1055 "fts5parse.c" fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; - case 20: /* neardist_opt ::= */ -#line 163 "fts5parse.y" + case 21: /* neardist_opt ::= */ +#line 168 "fts5parse.y" { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; } -#line 1046 "fts5parse.c" +#line 1061 "fts5parse.c" break; - case 21: /* neardist_opt ::= COMMA STRING */ -#line 164 "fts5parse.y" + case 22: /* neardist_opt ::= COMMA STRING */ +#line 169 "fts5parse.y" { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; } -#line 1051 "fts5parse.c" +#line 1066 "fts5parse.c" break; - case 22: /* phrase ::= phrase PLUS STRING star_opt */ -#line 176 "fts5parse.y" + case 23: /* phrase ::= phrase PLUS STRING star_opt */ +#line 181 "fts5parse.y" { fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } -#line 1058 "fts5parse.c" +#line 1073 "fts5parse.c" fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; - case 23: /* phrase ::= STRING star_opt */ -#line 179 "fts5parse.y" + case 24: /* phrase ::= STRING star_opt */ +#line 184 "fts5parse.y" { fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } -#line 1066 "fts5parse.c" +#line 1081 "fts5parse.c" fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; - case 24: /* star_opt ::= STAR */ -#line 188 "fts5parse.y" + case 25: /* star_opt ::= STAR */ +#line 193 "fts5parse.y" { fts5yymsp[0].minor.fts5yy4 = 1; } -#line 1072 "fts5parse.c" +#line 1087 "fts5parse.c" break; - case 25: /* star_opt ::= */ -#line 189 "fts5parse.y" + case 26: /* star_opt ::= */ +#line 194 "fts5parse.y" { fts5yymsp[1].minor.fts5yy4 = 0; } -#line 1077 "fts5parse.c" +#line 1092 "fts5parse.c" break; default: break; /********** End reduce actions ************************************************/ }; @@ -2538,11 +2554,11 @@ UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */ sqlite3Fts5ParseError( pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p ); -#line 1142 "fts5parse.c" +#line 1157 "fts5parse.c" /************ End %syntax_error code ******************************************/ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } /* @@ -3518,13 +3534,15 @@ Fts5Buffer *pBuf, u32 nData, const u8 *pData ){ assert_nc( *pRc || nData>=0 ); - if( fts5BufferGrow(pRc, pBuf, nData) ) return; - memcpy(&pBuf->p[pBuf->n], pData, nData); - pBuf->n += nData; + if( nData ){ + if( fts5BufferGrow(pRc, pBuf, nData) ) return; + memcpy(&pBuf->p[pBuf->n], pData, nData); + pBuf->n += nData; + } } /* ** Append the nul-terminated string zStr to the buffer pBuf. This function ** ensures that the byte following the buffer data is set to 0x00, even @@ -3697,12 +3715,12 @@ static void *sqlite3Fts5MallocZero(int *pRc, int nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ pRet = sqlite3_malloc(nByte); - if( pRet==0 && nByte>0 ){ - *pRc = SQLITE_NOMEM; + if( pRet==0 ){ + if( nByte>0 ) *pRc = SQLITE_NOMEM; }else{ memset(pRet, 0, nByte); } } return pRet; @@ -5021,10 +5039,11 @@ static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); } static void fts5ParseFree(void *p){ sqlite3_free(p); } static int sqlite3Fts5ExprNew( Fts5Config *pConfig, /* FTS5 Configuration */ + int iCol, const char *zExpr, /* Expression text */ Fts5Expr **ppNew, char **pzErr ){ Fts5Parse sParse; @@ -5044,10 +5063,22 @@ do { t = fts5ExprGetToken(&sParse, &z, &token); sqlite3Fts5Parser(pEngine, t, token, &sParse); }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); + + /* If the LHS of the MATCH expression was a user column, apply the + ** implicit column-filter. */ + if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ + int n = sizeof(Fts5Colset); + Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); + if( pColset ){ + pColset->nCol = 1; + pColset->aiCol[0] = iCol; + sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); + } + } assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); if( pNew==0 ){ @@ -6694,29 +6725,114 @@ } return pRet; } +/* +** If argument pOrig is NULL, or if (*pRc) is set to anything other than +** SQLITE_OK when this function is called, NULL is returned. +** +** Otherwise, a copy of (*pOrig) is made into memory obtained from +** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation +** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. +*/ +static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ + Fts5Colset *pRet; + if( pOrig ){ + int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); + if( pRet ){ + memcpy(pRet, pOrig, nByte); + } + }else{ + pRet = 0; + } + return pRet; +} + +/* +** Remove from colset pColset any columns that are not also in colset pMerge. +*/ +static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){ + int iIn = 0; /* Next input in pColset */ + int iMerge = 0; /* Next input in pMerge */ + int iOut = 0; /* Next output slot in pColset */ + + while( iInnCol && iMergenCol ){ + int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge]; + if( iDiff==0 ){ + pColset->aiCol[iOut++] = pMerge->aiCol[iMerge]; + iMerge++; + iIn++; + }else if( iDiff>0 ){ + iMerge++; + }else{ + iIn++; + } + } + pColset->nCol = iOut; +} + +/* +** Recursively apply colset pColset to expression node pNode and all of +** its decendents. If (*ppFree) is not NULL, it contains a spare copy +** of pColset. This function may use the spare copy and set (*ppFree) to +** zero, or it may create copies of pColset using fts5CloneColset(). +*/ +static void fts5ParseSetColset( + Fts5Parse *pParse, + Fts5ExprNode *pNode, + Fts5Colset *pColset, + Fts5Colset **ppFree +){ + if( pParse->rc==SQLITE_OK ){ + assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING + || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR + || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF + ); + if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){ + Fts5ExprNearset *pNear = pNode->pNear; + if( pNear->pColset ){ + fts5MergeColset(pNear->pColset, pColset); + if( pNear->pColset->nCol==0 ){ + pNode->eType = FTS5_EOF; + pNode->xNext = 0; + } + }else if( *ppFree ){ + pNear->pColset = pColset; + *ppFree = 0; + }else{ + pNear->pColset = fts5CloneColset(&pParse->rc, pColset); + } + }else{ + int i; + assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 ); + for(i=0; inChild; i++){ + fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree); + } + } + } +} + +/* +** Apply colset pColset to expression node pExpr and all of its descendents. +*/ static void sqlite3Fts5ParseSetColset( Fts5Parse *pParse, - Fts5ExprNearset *pNear, + Fts5ExprNode *pExpr, Fts5Colset *pColset ){ + Fts5Colset *pFree = pColset; if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){ pParse->rc = SQLITE_ERROR; pParse->zErr = sqlite3_mprintf( "fts5: column queries are not supported (detail=none)" ); - sqlite3_free(pColset); - return; - } - - if( pNear ){ - pNear->pColset = pColset; - }else{ - sqlite3_free(pColset); - } + }else{ + fts5ParseSetColset(pParse, pExpr, pColset, &pFree); + } + sqlite3_free(pFree); } static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ switch( pNode->eType ){ case FTS5_STRING: { @@ -7166,11 +7282,11 @@ zExpr = (const char*)sqlite3_value_text(apVal[0]); rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr); + rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; if( pExpr->pRoot->xNext==0 ){ zText = sqlite3_mprintf(""); @@ -7564,13 +7680,14 @@ Fts5HashEntry **aSlot; /* Array of hash slots */ }; /* ** Each entry in the hash table is represented by an object of the -** following type. Each object, its key (zKey[]) and its current data -** are stored in a single memory allocation. The position list data -** immediately follows the key data in memory. +** following type. Each object, its key (a nul-terminated string) and +** its current data are stored in a single memory allocation. The +** key immediately follows the object in memory. The position list +** data immediately follows the key data in memory. ** ** The data that follows the key is in a similar, but not identical format ** to the doclist data stored in the database. It is: ** ** * Rowid, as a varint @@ -7590,24 +7707,24 @@ Fts5HashEntry *pScanNext; /* Next entry in sorted order */ int nAlloc; /* Total size of allocation */ int iSzPoslist; /* Offset of space for 4-byte poslist size */ int nData; /* Total bytes of data (incl. structure) */ - int nKey; /* Length of zKey[] in bytes */ + int nKey; /* Length of key in bytes */ u8 bDel; /* Set delete-flag @ iSzPoslist */ u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ - char zKey[8]; /* Nul-terminated entry key */ }; /* -** Size of Fts5HashEntry without the zKey[] array. +** Eqivalent to: +** +** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } */ -#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8) - +#define fts5EntryKey(p) ( ((char *)(&(p)[1])) ) /* ** Allocate a new hash table. */ @@ -7701,11 +7818,11 @@ for(i=0; inSlot; i++){ while( apOld[i] ){ int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; - iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey)); + iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), strlen(fts5EntryKey(p))); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } } @@ -7772,22 +7889,24 @@ bNew = (pHash->eDetail==FTS5_DETAIL_FULL); /* Attempt to locate an existing hash entry */ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken); for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ - if( p->zKey[0]==bByte + char *zKey = fts5EntryKey(p); + if( zKey[0]==bByte && p->nKey==nToken - && memcmp(&p->zKey[1], pToken, nToken)==0 + && memcmp(&zKey[1], pToken, nToken)==0 ){ break; } } /* If an existing hash entry cannot be found, create a new one. */ if( p==0 ){ /* Figure out how much space to allocate */ - int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64; + char *zKey; + int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; if( nByte<128 ) nByte = 128; /* Grow the Fts5Hash.aSlot[] array if necessary. */ if( (pHash->nEntry*2)>=pHash->nSlot ){ int rc = fts5HashResize(pHash); @@ -7796,18 +7915,19 @@ } /* Allocate new Fts5HashEntry and add it to the hash table. */ p = (Fts5HashEntry*)sqlite3_malloc(nByte); if( !p ) return SQLITE_NOMEM; - memset(p, 0, FTS5_HASHENTRYSIZE); + memset(p, 0, sizeof(Fts5HashEntry)); p->nAlloc = nByte; - p->zKey[0] = bByte; - memcpy(&p->zKey[1], pToken, nToken); - assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) ); + zKey = fts5EntryKey(p); + zKey[0] = bByte; + memcpy(&zKey[1], pToken, nToken); + assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); p->nKey = nToken; - p->zKey[nToken+1] = '\0'; - p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE; + zKey[nToken+1] = '\0'; + p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); p->pHashNext = pHash->aSlot[iHash]; pHash->aSlot[iHash] = p; pHash->nEntry++; /* Add the first rowid field to the hash-entry */ @@ -7921,13 +8041,15 @@ }else if( p2==0 ){ *ppOut = p1; p1 = 0; }else{ int i = 0; - while( p1->zKey[i]==p2->zKey[i] ) i++; + char *zKey1 = fts5EntryKey(p1); + char *zKey2 = fts5EntryKey(p2); + while( zKey1[i]==zKey2[i] ) i++; - if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){ + if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ /* p2 is smaller */ *ppOut = p2; ppOut = &p2->pScanNext; p2 = p2->pScanNext; }else{ @@ -7966,11 +8088,11 @@ memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot); for(iSlot=0; iSlotnSlot; iSlot++){ Fts5HashEntry *pIter; for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ - if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){ + if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){ Fts5HashEntry *pEntry = pIter; pEntry->pScanNext = 0; for(i=0; ap[i]; i++){ pEntry = fts5HashEntryMerge(pEntry, ap[i]); ap[i] = 0; @@ -7999,20 +8121,22 @@ const char *pTerm, int nTerm, /* Query term */ const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */ int *pnDoclist /* OUT: Size of doclist in bytes */ ){ unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm); + char *zKey; Fts5HashEntry *p; for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ - if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break; + zKey = fts5EntryKey(p); + if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break; } if( p ){ fts5HashAddPoslistSize(pHash, p); - *ppDoclist = (const u8*)&p->zKey[nTerm+1]; - *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1); + *ppDoclist = (const u8*)&zKey[nTerm+1]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); }else{ *ppDoclist = 0; *pnDoclist = 0; } @@ -8041,15 +8165,16 @@ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ - int nTerm = (int)strlen(p->zKey); + char *zKey = fts5EntryKey(p); + int nTerm = (int)strlen(zKey); fts5HashAddPoslistSize(pHash, p); - *pzTerm = p->zKey; - *ppDoclist = (const u8*)&p->zKey[nTerm+1]; - *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1); + *pzTerm = zKey; + *ppDoclist = (const u8*)&zKey[nTerm+1]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); }else{ *pzTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } @@ -8684,11 +8809,10 @@ sqlite3_blob *pReader = p->pReader; p->pReader = 0; sqlite3_blob_close(pReader); } } - /* ** Retrieve a record from the %_data table. ** ** If an error occurs, NULL is returned and an error left in the @@ -10936,11 +11060,12 @@ Fts5Iter *pIter, int *pbNewTerm /* OUT: True if *might* be new term */ ){ assert( pIter->bSkipEmpty ); if( p->rc==SQLITE_OK ){ - do { + *pbNewTerm = 0; + do{ int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; int bNewTerm = 0; assert( p->rc==SQLITE_OK ); @@ -10949,12 +11074,10 @@ || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg) ){ fts5MultiIterAdvanced(p, pIter, iFirst, 1); fts5MultiIterSetEof(pIter); *pbNewTerm = 1; - }else{ - *pbNewTerm = 0; } fts5AssertMultiIterSetup(p, pIter); }while( fts5MultiIterIsEmpty(p, pIter) ); } @@ -11216,27 +11339,27 @@ } return p - (*pa); } -static int fts5IndexExtractColset ( +static void fts5IndexExtractColset( + int *pRc, Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ Fts5Buffer *pBuf /* Output buffer */ ){ - int rc = SQLITE_OK; - int i; - - fts5BufferZero(pBuf); - for(i=0; inCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); + if( *pRc==SQLITE_OK ){ + int i; + fts5BufferZero(pBuf); + for(i=0; inCol; i++){ + const u8 *pSub = pPos; + int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); + if( nSub ){ + fts5BufferAppendBlob(pRc, pBuf, nSub, pSub); + } } } - return rc; } /* ** xSetOutputs callback used by detail=none tables. */ @@ -11356,12 +11479,13 @@ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; if( pColset->nCol==1 ){ pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); pIter->base.pData = a; }else{ + int *pRc = &pIter->pIndex->rc; fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); + fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist); pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } }else{ /* The data is distributed over two or more pages. Copy it into the @@ -11902,13 +12026,10 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 }; Fts5PageWriter *pPage = &pWriter->writer; i64 iRowid; -static int nCall = 0; -nCall++; - assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) ); /* Set the szLeaf header field. */ assert( 0==fts5GetU16(&pPage->buf.p[2]) ); fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n); @@ -12253,10 +12374,11 @@ Fts5StructureSegment *pSeg; /* Output segment */ Fts5Buffer term; int bOldest; /* True if the output segment is the oldest */ int eDetail = p->pConfig->eDetail; const int flags = FTS5INDEX_QUERY_NOOUTPUT; + int bTermWritten = 0; /* True if current term already output */ assert( iLvlnLevel ); assert( pLvl->nMerge<=pLvl->nSeg ); memset(&writer, 0, sizeof(Fts5SegWriter)); @@ -12306,22 +12428,26 @@ Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int nPos; /* position-list size field value */ int nTerm; const u8 *pTerm; - /* Check for key annihilation. */ - if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue; - pTerm = fts5MultiIterTerm(pIter, &nTerm); if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){ if( pnRem && writer.nLeafWritten>nRem ){ break; } + fts5BufferSet(&p->rc, &term, nTerm, pTerm); + bTermWritten =0; + } + /* Check for key annihilation. */ + if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue; + + if( p->rc==SQLITE_OK && bTermWritten==0 ){ /* This is a new term. Append a term to the output segment. */ fts5WriteAppendTerm(p, &writer, nTerm, pTerm); - fts5BufferSet(&p->rc, &term, nTerm, pTerm); + bTermWritten = 1; } /* Append the rowid to the output */ /* WRITEPOSLISTSIZE */ fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter)); @@ -13149,11 +13275,11 @@ pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = doclist.n; - memcpy(pData->p, doclist.p, doclist.n); + if( doclist.n ) memcpy(pData->p, doclist.p, doclist.n); fts5MultiIterNew2(p, pData, bDesc, ppIter); } fts5BufferFree(&doclist); } @@ -13188,14 +13314,14 @@ } /* ** Commit data to disk. */ -static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){ +static int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - if( bCommit ) fts5CloseReader(p); + fts5CloseReader(p); return fts5IndexReturn(p); } /* ** Discard any data stored in the in-memory hash tables. Do not write it @@ -13388,11 +13514,11 @@ /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ - memcpy(&buf.p[1], pToken, nToken); + if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be ** satisfied by scanning multiple terms in the main index. @@ -13437,11 +13563,11 @@ if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } if( p->rc ){ - sqlite3Fts5IterClose(&pRet->base); + sqlite3Fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; fts5CloseReader(p); } *ppIter = &pRet->base; @@ -15056,10 +15182,11 @@ ** Costs are not modified by the ORDER BY clause. */ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; + const int nCol = pConfig->nCol; int idxFlags = 0; /* Parameter passed through to xFilter() */ int bHasMatch; int iNext; int i; @@ -15081,28 +15208,38 @@ FTS5_BI_ROWID_GE, 0, 0, -1}, }; int aColMap[3]; aColMap[0] = -1; - aColMap[1] = pConfig->nCol; - aColMap[2] = pConfig->nCol+1; + aColMap[1] = nCol; + aColMap[2] = nCol+1; /* Set idxFlags flags for all WHERE clause terms that will be used. */ for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; - int j; - for(j=0; jiColumn==aColMap[pC->iCol] && p->op & pC->op ){ - if( p->usable ){ + int iCol = p->iColumn; + + if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol) + || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol) + ){ + /* A MATCH operator or equivalent */ + if( p->usable ){ + idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16); + aConstraint[0].iConsIndex = i; + }else{ + /* As there exists an unusable MATCH constraint this is an + ** unusable plan. Set a prohibitively high cost. */ + pInfo->estimatedCost = 1e50; + return SQLITE_OK; + } + }else{ + int j; + for(j=1; jiCol] && p->op & pC->op && p->usable ){ pC->iConsIndex = i; idxFlags |= pC->fts5op; - }else if( j==0 ){ - /* As there exists an unusable MATCH constraint this is an - ** unusable plan. Set a prohibitively high cost. */ - pInfo->estimatedCost = 1e50; - return SQLITE_OK; } } } } @@ -15673,10 +15810,11 @@ sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ + int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; UNUSED_PARAM(zUnused); UNUSED_PARAM(nVal); @@ -15703,10 +15841,12 @@ if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++]; if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++]; + iCol = (idxNum>>16); + assert( iCol>=0 && iCol<=pConfig->nCol ); assert( iVal==nVal ); bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0); pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0); /* Set the cursor upper and lower rowid limits. Only some strategies @@ -15749,11 +15889,11 @@ ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]); }else{ char **pzErr = &pTab->base.zErrMsg; - rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr); + rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr); if( rc==SQLITE_OK ){ if( bOrderByRank ){ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ @@ -16129,11 +16269,11 @@ int rc; Fts5Table *pTab = (Fts5Table*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg; fts5TripCursors(pTab); - rc = sqlite3Fts5StorageSync(pTab->pStorage, 1); + rc = sqlite3Fts5StorageSync(pTab->pStorage); pTab->pConfig->pzErrmsg = 0; return rc; } /* @@ -16940,11 +17080,11 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* ** The xRelease() method. ** @@ -16953,11 +17093,11 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* ** The xRollbackTo() method. ** @@ -17164,11 +17304,11 @@ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2017-06-08 14:26:16 0ee482a1e0eae22e08edc8978c9733a96603d4509645f348ebf55b579e89636b", -1, SQLITE_TRANSIENT); } static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { /* iVersion */ 2, @@ -17501,11 +17641,11 @@ } } static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ Fts5Config *pConfig = pStorage->pConfig; - int rc = sqlite3Fts5StorageSync(pStorage, 1); + int rc = sqlite3Fts5StorageSync(pStorage); fts5StorageRenameOne(pConfig, &rc, "data", zName); fts5StorageRenameOne(pConfig, &rc, "idx", zName); fts5StorageRenameOne(pConfig, &rc, "config", zName); if( pConfig->bColumnsize ){ @@ -18364,19 +18504,19 @@ } /* ** Flush any data currently held in-memory to disk. */ -static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){ +static int sqlite3Fts5StorageSync(Fts5Storage *p){ int rc = SQLITE_OK; i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - if( bCommit ) p->bTotalsValid = 0; + p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexSync(p->pIndex, bCommit); + rc = sqlite3Fts5IndexSync(p->pIndex); } sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); return rc; } Index: SQLite.Interop/src/ext/json1.c ================================================================== --- SQLite.Interop/src/ext/json1.c +++ SQLite.Interop/src/ext/json1.c @@ -88,10 +88,11 @@ #ifndef SQLITE_AMALGAMATION /* Unsigned integer types. These are already defined in the sqliteInt.h, ** but the definitions need to be repeated for separate compilation. */ typedef sqlite3_uint64 u64; typedef unsigned int u32; + typedef unsigned short int u16; typedef unsigned char u8; #endif /* Objects */ typedef struct JsonString JsonString; @@ -167,12 +168,23 @@ JsonNode *aNode; /* Array of nodes containing the parse */ const char *zJson; /* Original JSON string */ u32 *aUp; /* Index of parent of each node */ u8 oom; /* Set to true if out of memory */ u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ + int nJson; /* Length of the zJson string in bytes */ }; +/* +** Maximum nesting depth of JSON for this implementation. +** +** This limit is needed to avoid a stack overflow in the recursive +** descent parser. A depth of 2000 is far deeper than any sane JSON +** should go. +*/ +#define JSON_MAX_DEPTH 2000 + /************************************************************************** ** Utility routines for dealing with JsonString objects **************************************************************************/ /* Set the JsonString object to an empty string @@ -399,10 +411,18 @@ pParse->nNode = 0; pParse->nAlloc = 0; sqlite3_free(pParse->aUp); pParse->aUp = 0; } + +/* +** Free a JsonParse object that was obtained from sqlite3_malloc(). +*/ +static void jsonParseFree(JsonParse *pParse){ + jsonParseReset(pParse); + sqlite3_free(pParse); +} /* ** Convert the JsonNode pNode into a pure JSON string and ** append to pOut. Subsubstructure is also included. Return ** the number of JsonNode objects that are encoded. @@ -725,35 +745,39 @@ char c; u32 j; int iThis; int x; JsonNode *pNode; - while( safe_isspace(pParse->zJson[i]) ){ i++; } - if( (c = pParse->zJson[i])=='{' ){ + const char *z = pParse->zJson; + while( safe_isspace(z[i]) ){ i++; } + if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); if( x<0 ){ + pParse->iDepth--; if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } if( pParse->oom ) return -1; pNode = &pParse->aNode[pParse->nNode-1]; if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - if( pParse->zJson[j]!=':' ) return -1; + while( safe_isspace(z[j]) ){ j++; } + if( z[j]!=':' ) return -1; j++; x = jsonParseValue(pParse, j); + pParse->iDepth--; if( x<0 ) return -1; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!='}' ) return -1; break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; @@ -761,19 +785,21 @@ }else if( c=='[' ){ /* Parse array */ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); + pParse->iDepth--; if( x<0 ){ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!=']' ) return -1; break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; @@ -781,75 +807,83 @@ }else if( c=='"' ){ /* Parse string */ u8 jnFlags = 0; j = i+1; for(;;){ - c = pParse->zJson[j]; - if( c==0 ) return -1; + c = z[j]; + if( (c & ~0x1f)==0 ){ + /* Control characters are not allowed in strings */ + return -1; + } if( c=='\\' ){ - c = pParse->zJson[++j]; + c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){ + || (c=='u' && jsonIs4Hex(z+j+1)) ){ jnFlags = JNODE_ESCAPE; }else{ return -1; } }else if( c=='"' ){ break; } j++; } - jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]); + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; return j+1; }else if( c=='n' - && strncmp(pParse->zJson+i,"null",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"null",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_NULL, 0, 0); return i+4; }else if( c=='t' - && strncmp(pParse->zJson+i,"true",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"true",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); return i+4; }else if( c=='f' - && strncmp(pParse->zJson+i,"false",5)==0 - && !safe_isalnum(pParse->zJson[i+5]) ){ + && strncmp(z+i,"false",5)==0 + && !safe_isalnum(z[i+5]) ){ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); return i+5; }else if( c=='-' || (c>='0' && c<='9') ){ /* Parse number */ u8 seenDP = 0; u8 seenE = 0; + assert( '-' < '0' ); + if( c<='0' ){ + j = c=='-' ? i+1 : i; + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; + } j = i+1; for(;; j++){ - c = pParse->zJson[j]; + c = z[j]; if( c>='0' && c<='9' ) continue; if( c=='.' ){ - if( pParse->zJson[j-1]=='-' ) return -1; + if( z[j-1]=='-' ) return -1; if( seenDP ) return -1; seenDP = 1; continue; } if( c=='e' || c=='E' ){ - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; if( seenE ) return -1; seenDP = seenE = 1; - c = pParse->zJson[j+1]; + c = z[j+1]; if( c=='+' || c=='-' ){ j++; - c = pParse->zJson[j+1]; + c = z[j+1]; } if( c<'0' || c>'9' ) return -1; continue; } break; } - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, - j - i, &pParse->zJson[i]); + j - i, &z[i]); return j; }else if( c=='}' ){ return -2; /* End of {...} */ }else if( c==']' ){ return -3; /* End of [...] */ @@ -877,10 +911,11 @@ if( zJson==0 ) return 1; pParse->zJson = zJson; i = jsonParseValue(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ + assert( pParse->iDepth==0 ); while( safe_isspace(zJson[i]) ) i++; if( zJson[i] ) i = -1; } if( i<=0 ){ if( pCtx!=0 ){ @@ -935,10 +970,53 @@ return SQLITE_NOMEM; } jsonParseFillInParentage(pParse, 0, 0); return SQLITE_OK; } + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) + +/* +** Obtain a complete parse of the JSON found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the JSON again and return the new parse, +** and also register the new parse so that it will be available for +** future sqlite3_get_auxdata() calls. +*/ +static JsonParse *jsonParseCached( + sqlite3_context *pCtx, + sqlite3_value **argv +){ + const char *zJson = (const char*)sqlite3_value_text(argv[0]); + int nJson = sqlite3_value_bytes(argv[0]); + JsonParse *p; + if( zJson==0 ) return 0; + p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); + if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ + p->nErr = 0; + return p; /* The cached entry matches, so return it */ + } + p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); + if( p==0 ){ + sqlite3_result_error_nomem(pCtx); + return 0; + } + memset(p, 0, sizeof(*p)); + p->zJson = (char*)&p[1]; + memcpy((char*)p->zJson, zJson, nJson+1); + if( jsonParse(p, pCtx, p->zJson) ){ + sqlite3_free(p); + return 0; + } + p->nJson = nJson; + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); +} /* ** Compare the OBJECT label at pNode against zKey,nKey. Return true on ** a match. */ @@ -1301,33 +1379,34 @@ static void jsonArrayLengthFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ sqlite3_int64 n = 0; u32 i; JsonNode *pNode; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + p = jsonParseCached(ctx, argv); + if( p==0 ) return; + assert( p->nNode ); if( argc==2 ){ const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(&x, zPath, 0, ctx); + pNode = jsonLookup(p, zPath, 0, ctx); }else{ - pNode = x.aNode; + pNode = p->aNode; } if( pNode==0 ){ - x.nErr = 1; - }else if( pNode->eType==JSON_ARRAY ){ + return; + } + if( pNode->eType==JSON_ARRAY ){ assert( (pNode->jnFlags & JNODE_APPEND)==0 ); for(i=1; i<=pNode->n; n++){ i += jsonNodeSize(&pNode[i]); } } - if( x.nErr==0 ) sqlite3_result_int64(ctx, n); - jsonParseReset(&x); + sqlite3_result_int64(ctx, n); } /* ** json_extract(JSON, PATH, ...) ** @@ -1339,24 +1418,25 @@ static void jsonExtractFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *p; /* The parse */ JsonNode *pNode; const char *zPath; JsonString jx; int i; if( argc<2 ) return; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + p = jsonParseCached(ctx, argv); + if( p==0 ) return; jsonInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=1; inErr ) break; if( argc>2 ){ jsonAppendSeparator(&jx); if( pNode ){ jsonRenderNode(pNode, &jx, 0); }else{ @@ -1370,18 +1450,17 @@ jsonAppendChar(&jx, ']'); jsonResult(&jx); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } jsonReset(&jx); - jsonParseReset(&x); } /* This is the RFC 7396 MergePatch algorithm. */ static JsonNode *jsonMergePatch( JsonParse *pParse, /* The JSON parser that contains the TARGET */ - int iTarget, /* Node of the TARGET in pParse */ + u32 iTarget, /* Node of the TARGET in pParse */ JsonNode *pPatch /* The PATCH */ ){ u32 i, j; u32 iRoot; JsonNode *pTarget; Index: SQLite.Interop/src/generic/interop.c ================================================================== --- SQLite.Interop/src/generic/interop.c +++ SQLite.Interop/src/generic/interop.c @@ -1044,11 +1044,11 @@ if (prowid) *prowid = pC->lastRowid; } else #endif #if SQLITE_VERSION_NUMBER >= 3010000 - if(pC->uc.pseudoTableReg > 0) + if(pC->eCurType != CURTYPE_BTREE) #else if(pC->pseudoTableReg > 0) #endif { ret = SQLITE_ERROR; @@ -1073,11 +1073,13 @@ { ret = SQLITE_ERROR; break; } #if SQLITE_VERSION_NUMBER >= 3014000 + sqlite3BtreeEnterCursor(pC->uc.pCursor); *prowid = sqlite3BtreeIntegerKey(pC->uc.pCursor); + sqlite3BtreeLeaveCursor(pC->uc.pCursor); #elif SQLITE_VERSION_NUMBER >= 3010000 sqlite3BtreeKeySize(pC->uc.pCursor, prowid); #else sqlite3BtreeKeySize(pC->pCursor, prowid); #endif Index: SQLite.Interop/src/generic/interop.h ================================================================== --- SQLite.Interop/src/generic/interop.h +++ SQLite.Interop/src/generic/interop.h @@ -4,11 +4,11 @@ * Written by Joe Mistachkin. * Released to the public domain, use at your own risk! */ #ifndef INTEROP_VERSION -#define INTEROP_VERSION "1.0.105.0" +#define INTEROP_VERSION "1.0.105.2" #endif #ifndef INTEROP_SOURCE_ID #define INTEROP_SOURCE_ID "0000000000000000000000000000000000000000" #endif Index: System.Data.SQLite.Linq/AssemblyInfo.cs ================================================================== --- System.Data.SQLite.Linq/AssemblyInfo.cs +++ System.Data.SQLite.Linq/AssemblyInfo.cs @@ -51,7 +51,7 @@ // 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.105.0")] -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +[assembly: AssemblyFileVersion("1.0.105.2")] Index: System.Data.SQLite/AssemblyInfo.cs ================================================================== --- System.Data.SQLite/AssemblyInfo.cs +++ System.Data.SQLite/AssemblyInfo.cs @@ -70,9 +70,9 @@ // 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.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] #if !PLATFORM_COMPACTFRAMEWORK -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyFileVersion("1.0.105.2")] #endif Index: System.Data.SQLite/SQLite3.cs ================================================================== --- System.Data.SQLite/SQLite3.cs +++ System.Data.SQLite/SQLite3.cs @@ -56,11 +56,11 @@ "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" + "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" + "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c"; #if !PLATFORM_COMPACTFRAMEWORK - internal const string DesignerVersion = "1.0.105.0"; + internal const string DesignerVersion = "1.0.105.2"; #endif /// /// The opaque pointer returned to us by the sqlite provider /// Index: System.Data.SQLite/SQLiteConnection.cs ================================================================== --- System.Data.SQLite/SQLiteConnection.cs +++ System.Data.SQLite/SQLiteConnection.cs @@ -3048,25 +3048,32 @@ private static bool ShouldUseLegacyConnectionStringParser( SQLiteConnection connection ) { string name = "No_SQLiteConnectionNewParser"; - object value; /* NOT USED */ + object value; if ((connection != null) && connection.TryGetCachedSetting(name, null, out value)) { - return true; + return (value != null); } if ((connection == null) && TryGetLastCachedSetting(name, null, out value)) { - return true; + return (value != null); } - return (UnsafeNativeMethods.GetSettingValue(name, null) != null); + value = UnsafeNativeMethods.GetSettingValue(name, null); + + if (connection != null) + connection.SetCachedSetting(name, value); + else + SetLastCachedSetting(name, value); + + return (value != null); } /// /// Parses a connection string into component parts using the custom /// connection string parser. An exception may be thrown if the syntax @@ -3721,11 +3728,11 @@ bool uri = false; #endif bool fullUri = false; string fileName; - if (Convert.ToInt32(FindKey(opts, "Version", DefaultVersion.ToString()), CultureInfo.InvariantCulture) != DefaultVersion) + if (Convert.ToInt32(FindKey(opts, "Version", SQLiteConvert.ToString(DefaultVersion)), CultureInfo.InvariantCulture) != DefaultVersion) throw new NotSupportedException(HelperMethods.StringFormat(CultureInfo.CurrentCulture, "Only SQLite Version {0} is supported at this time", DefaultVersion)); #if INTEROP_INCLUDE_ZIPVFS bool useZipVfs = false; string zipVfsVersion = FindKey(opts, "ZipVfsVersion", DefaultZipVfsVersion); @@ -3812,16 +3819,16 @@ } try { bool usePooling = SQLiteConvert.ToBoolean(FindKey(opts, "Pooling", GetDefaultPooling().ToString())); - int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", DefaultMaxPoolSize.ToString()), CultureInfo.InvariantCulture); + int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", SQLiteConvert.ToString(DefaultMaxPoolSize)), CultureInfo.InvariantCulture); - _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", DefaultConnectionTimeout.ToString()), CultureInfo.InvariantCulture); - _busyTimeout = Convert.ToInt32(FindKey(opts, "BusyTimeout", DefaultBusyTimeout.ToString()), CultureInfo.InvariantCulture); - _prepareRetries = Convert.ToInt32(FindKey(opts, "PrepareRetries", DefaultPrepareRetries.ToString()), CultureInfo.InvariantCulture); - _progressOps = Convert.ToInt32(FindKey(opts, "ProgressOps", DefaultProgressOps.ToString()), CultureInfo.InvariantCulture); + _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", SQLiteConvert.ToString(DefaultConnectionTimeout)), CultureInfo.InvariantCulture); + _busyTimeout = Convert.ToInt32(FindKey(opts, "BusyTimeout", SQLiteConvert.ToString(DefaultBusyTimeout)), CultureInfo.InvariantCulture); + _prepareRetries = Convert.ToInt32(FindKey(opts, "PrepareRetries", SQLiteConvert.ToString(DefaultPrepareRetries)), CultureInfo.InvariantCulture); + _progressOps = Convert.ToInt32(FindKey(opts, "ProgressOps", SQLiteConvert.ToString(DefaultProgressOps)), CultureInfo.InvariantCulture); enumValue = TryParseEnum(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", DefaultIsolationLevel.ToString()), true); _defaultIsolation = (enumValue is IsolationLevel) ? (IsolationLevel)enumValue : DefaultIsolationLevel; _defaultIsolation = GetEffectiveIsolationLevel(_defaultIsolation); @@ -3918,20 +3925,20 @@ int intValue; if (!fullUri && !isMemory) { - strValue = FindKey(opts, "Page Size", DefaultPageSize.ToString()); + strValue = FindKey(opts, "Page Size", SQLiteConvert.ToString(DefaultPageSize)); intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture); if (intValue != DefaultPageSize) { cmd.CommandText = HelperMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", intValue); cmd.ExecuteNonQuery(); } } - strValue = FindKey(opts, "Max Page Count", DefaultMaxPageCount.ToString()); + strValue = FindKey(opts, "Max Page Count", SQLiteConvert.ToString(DefaultMaxPageCount)); intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture); if (intValue != DefaultMaxPageCount) { cmd.CommandText = HelperMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", intValue); cmd.ExecuteNonQuery(); @@ -3951,11 +3958,11 @@ { cmd.CommandText = HelperMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", strValue); cmd.ExecuteNonQuery(); } - strValue = FindKey(opts, "Cache Size", DefaultCacheSize.ToString()); + strValue = FindKey(opts, "Cache Size", SQLiteConvert.ToString(DefaultCacheSize)); intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture); if (intValue != DefaultCacheSize) { cmd.CommandText = HelperMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", intValue); cmd.ExecuteNonQuery(); @@ -4559,14 +4566,16 @@ return null; } } } + /////////////////////////////////////////////////////////////////////////////////////////////// + /// /// Queries and returns the value of the specified setting, using the /// cached setting names and values for the last connection that used - /// by the method, when available. + /// the method, when available. /// /// /// The name of the setting. /// /// @@ -4594,10 +4603,37 @@ return _lastConnectionInOpen.TryGetCachedSetting( name, @default, out value); } + /////////////////////////////////////////////////////////////////////////////////////////////// + + /// + /// Adds or sets the cached setting specified by + /// to the value specified by using the cached + /// setting names and values for the last connection that used the + /// method, when available. + /// + /// + /// The name of the cached setting to add or replace. + /// + /// + /// The new value of the cached setting. + /// + private static void SetLastCachedSetting( + string name, /* in */ + object value /* in */ + ) + { + if (_lastConnectionInOpen == null) + return; + + _lastConnectionInOpen.SetCachedSetting(name, value); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// /// The default connection flags to be used for all opened connections /// when they are not present in the connection string. /// public static SQLiteConnectionFlags DefaultFlags @@ -4606,11 +4642,14 @@ { string name = "DefaultFlags_SQLiteConnection"; object value; if (!TryGetLastCachedSetting(name, null, out value)) + { value = UnsafeNativeMethods.GetSettingValue(name, null); + SetLastCachedSetting(name, value); + } if (value == null) return FallbackDefaultFlags; object enumValue = TryParseEnum( @@ -4621,18 +4660,23 @@ return FallbackDefaultFlags; } } + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// /// The extra connection flags to be used for all opened connections. /// public static SQLiteConnectionFlags SharedFlags { get { lock (_syncRoot) { return _sharedFlags; } } set { lock (_syncRoot) { _sharedFlags = value; } } } + + /////////////////////////////////////////////////////////////////////////////////////////////// /// /// Returns the state of the connection. /// #if !PLATFORM_COMPACTFRAMEWORK Index: System.Data.SQLite/SQLiteConvert.cs ================================================================== --- System.Data.SQLite/SQLiteConvert.cs +++ System.Data.SQLite/SQLiteConvert.cs @@ -1169,10 +1169,30 @@ if (source is bool) return (bool)source; return ToBoolean(ToStringWithProvider( source, CultureInfo.InvariantCulture)); } + + /////////////////////////////////////////////////////////////////////////// + + /// + /// Converts an integer to a string that can be round-tripped using the + /// invariant culture. + /// + /// + /// The integer value to return the string representation for. + /// + /// + /// The string representation of the specified integer value, using the + /// invariant culture. + /// + internal static string ToString(int value) + { + return value.ToString(CultureInfo.InvariantCulture); + } + + /////////////////////////////////////////////////////////////////////////// /// /// Attempts to convert a into a . /// /// Index: System.Data.SQLite/SQLiteDataReader.cs ================================================================== --- System.Data.SQLite/SQLiteDataReader.cs +++ System.Data.SQLite/SQLiteDataReader.cs @@ -517,17 +517,18 @@ VerifyForGet(); if (_keyInfo == null) return null; - int iRowId = _keyInfo.GetRowIdIndex( - GetDatabaseName(i), GetTableName(i)); + string databaseName = GetDatabaseName(i); + string tableName = GetTableName(i); + int iRowId = _keyInfo.GetRowIdIndex(databaseName, tableName); - if (iRowId == -1) - return null; + if (iRowId != -1) + return GetInt64(iRowId); - return GetInt64(iRowId); + return _keyInfo.GetRowId(databaseName, tableName); } /// /// Retrieves the column as a object. /// This will not work for tables that were created WITHOUT ROWID Index: System.Data.SQLite/SQLiteKeyReader.cs ================================================================== --- System.Data.SQLite/SQLiteKeyReader.cs +++ System.Data.SQLite/SQLiteKeyReader.cs @@ -366,10 +366,37 @@ return -1; } /////////////////////////////////////////////////////////////////////////////////////////////// + internal long? GetRowId( + string databaseName, + string tableName + ) + { + if ((_keyInfo != null) && + (databaseName != null) && + (tableName != null)) + { + for (int i = 0; i < _keyInfo.Length; i++) + { + if (_keyInfo[i].databaseName == databaseName && + _keyInfo[i].tableName == tableName) + { + long rowid = _stmt._sql.GetRowIdForCursor(_stmt, _keyInfo[i].cursor); + + if (rowid != 0) + return rowid; + } + } + } + + return null; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); @@ -440,11 +467,11 @@ internal int Count { get { return (_keyInfo == null) ? 0 : _keyInfo.Length; } } - internal void Sync(int i) + private void Sync(int i) { Sync(); if (_keyInfo[i].cursor == -1) throw new InvalidCastException(); } @@ -451,11 +478,11 @@ /// /// Make sure all the subqueries are open and ready and sync'd with the current rowid /// of the table they're supporting /// - internal void Sync() + private void Sync() { if (_isValid == true) return; KeyQuery last = null; Index: System.Data.SQLite/UnsafeNativeMethods.cs ================================================================== --- System.Data.SQLite/UnsafeNativeMethods.cs +++ System.Data.SQLite/UnsafeNativeMethods.cs @@ -45,10 +45,19 @@ /// and testing purposes. /// internal static class DebugData { #region Private Data +#if DEBUG + /// + /// This lock is used to protect several static fields. + /// + private static readonly object staticSyncRoot = new object(); +#endif + + ///////////////////////////////////////////////////////////////////////// + #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 @@ -68,17 +77,10 @@ ///////////////////////////////////////////////////////////////////////// #region Settings Read Counts (Debug Build Only) #if DEBUG /// - /// This lock is used to protect the static - /// field. - /// - private static readonly object staticSyncRoot = new object(); - - ///////////////////////////////////////////////////////////////////////// - /// /// This dictionary stores the read counts for the runtime configuration /// settings. This information is only recorded when compiled in the /// "Debug" build configuration. /// private static Dictionary settingReadCounts; @@ -91,10 +93,23 @@ /// recorded when compiled in the "Debug" build configuration. /// private static Dictionary settingFileReadCounts; #endif #endregion + + ///////////////////////////////////////////////////////////////////////// + + #region Other Counts (Debug Build Only) +#if DEBUG + /// + /// This dictionary stores miscellaneous counts used for debugging + /// purposes. This information is only recorded when compiled in the + /// "Debug" build configuration. + /// + private static Dictionary otherCounts; +#endif + #endregion #endregion ///////////////////////////////////////////////////////////////////////// #region Public Methods @@ -102,11 +117,11 @@ /// /// Creates dictionaries used to store the read counts for each of /// the runtime configuration settings. These numbers are used for /// debugging and testing purposes only. /// - public static void InitializeSettingReadCounts() + public static void Initialize() { lock (staticSyncRoot) { // // NOTE: Create the dictionaries of statistics that will @@ -116,10 +131,13 @@ if (settingReadCounts == null) settingReadCounts = new Dictionary(); if (settingFileReadCounts == null) settingFileReadCounts = new Dictionary(); + + if (otherCounts == null) + otherCounts = new Dictionary(); } } ///////////////////////////////////////////////////////////////////////// @@ -169,10 +187,36 @@ settingReadCounts.Add(name, 1); } } } } + + ///////////////////////////////////////////////////////////////////////// + + /// + /// Increments the specified counter. + /// + /// + /// The name of the counter being incremented. + /// + public static void IncrementOtherCount( + string name + ) + { + lock (staticSyncRoot) + { + if (otherCounts != null) + { + int count; + + if (otherCounts.TryGetValue(name, out count)) + otherCounts[name] = count + 1; + else + otherCounts.Add(name, 1); + } + } + } #endif #endregion } #endif #endregion @@ -636,10 +680,48 @@ /// or more of the named sub-directories exist within the assembly code /// base. Second, they are used to assist in loading the appropriate /// SQLite interop assembly into the current process. /// private static Dictionary processorArchitecturePlatforms; + + ///////////////////////////////////////////////////////////////////////// + /// + /// This is the cached return value from the + /// method -OR- null if that method + /// has never returned a valid value. + /// + private static string cachedAssemblyDirectory; + + ///////////////////////////////////////////////////////////////////////// + /// + /// When this field is non-zero, it indicates the + /// method was not able to locate a + /// suitable assembly directory. The + /// method will check this + /// field and skips calls into the + /// method whenever it is non-zero. + /// + private static bool noAssemblyDirectory; + + ///////////////////////////////////////////////////////////////////////// + /// + /// This is the cached return value from the + /// method -OR- null if that method + /// has never returned a valid value. + /// + private static string cachedXmlConfigFileName; + + ///////////////////////////////////////////////////////////////////////// + /// + /// When this field is non-zero, it indicates the + /// method was not able to locate a + /// suitable XML configuration file name. The + /// method will check this + /// field and skips calls into the + /// method whenever it is non-zero. + /// + private static bool noXmlConfigFileName; #endregion ///////////////////////////////////////////////////////////////////////// /// /// For now, this method simply calls the Initialize method. @@ -668,14 +750,15 @@ #endif #region Debug Build Only #if DEBUG // - // NOTE: Create the list of statistics that will contain the + // NOTE: Create the lists of statistics that will contain + // various counts used in debugging, including the // number of times each setting value has been read. // - DebugData.InitializeSettingReadCounts(); + DebugData.Initialize(); #endif #endregion lock (staticSyncRoot) { @@ -770,35 +853,114 @@ } } ///////////////////////////////////////////////////////////////////////// /// + /// Resets the cached XML configuration file name value, thus forcing the + /// next call to method to rely + /// upon the method to fetch the + /// XML configuration file name. + /// + private static void ResetCachedXmlConfigFileName() + { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_ResetCachedXmlConfigFileName"); +#endif + #endregion + + lock (staticSyncRoot) + { + cachedXmlConfigFileName = null; + noXmlConfigFileName = false; + } + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Queries and returns the cached XML configuration file name for the + /// assembly containing the managed System.Data.SQLite components, if + /// available. If the cached XML configuration file name value is not + /// available, the method will + /// be used to obtain the XML configuration file name. + /// + /// + /// The XML configuration file name -OR- null if it cannot be determined + /// or does not exist. + /// + private static string GetCachedXmlConfigFileName() + { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_GetCachedXmlConfigFileName"); +#endif + #endregion + + lock (staticSyncRoot) + { + if (cachedXmlConfigFileName != null) + return cachedXmlConfigFileName; + + if (noXmlConfigFileName) + return null; + } + + return GetXmlConfigFileName(); + } + + ///////////////////////////////////////////////////////////////////////// + /// /// Queries and returns the XML configuration file name for the assembly /// containing the managed System.Data.SQLite components. /// /// /// The XML configuration file name -OR- null if it cannot be determined /// or does not exist. /// private static string GetXmlConfigFileName() { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_GetXmlConfigFileName"); +#endif + #endregion + string directory; string fileName; #if !PLATFORM_COMPACTFRAMEWORK directory = AppDomain.CurrentDomain.BaseDirectory; fileName = MaybeCombinePath(directory, XmlConfigFileName); if (File.Exists(fileName)) + { + lock (staticSyncRoot) + { + cachedXmlConfigFileName = fileName; + } + return fileName; + } #endif - directory = GetAssemblyDirectory(); + directory = GetCachedAssemblyDirectory(); fileName = MaybeCombinePath(directory, XmlConfigFileName); if (File.Exists(fileName)) + { + lock (staticSyncRoot) + { + cachedXmlConfigFileName = fileName; + } + return fileName; + } + + lock (staticSyncRoot) + { + noXmlConfigFileName = true; + } return null; } ///////////////////////////////////////////////////////////////////////// @@ -1061,11 +1223,11 @@ string value ) { if (!String.IsNullOrEmpty(value)) { - string directory = GetAssemblyDirectory(); + string directory = GetCachedAssemblyDirectory(); if (!String.IsNullOrEmpty(directory)) { try { @@ -1275,11 +1437,11 @@ #endregion ///////////////////////////////////////////////////////////////////// return GetSettingValueViaXmlConfigFile( - GetXmlConfigFileName(), name, @default, expand); + GetCachedXmlConfigFileName(), name, @default, expand); } ///////////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK @@ -1447,47 +1609,139 @@ } #endif ///////////////////////////////////////////////////////////////////////// /// + /// Resets the cached assembly directory value, thus forcing the next + /// call to method to rely + /// upon the method to fetch the + /// assembly directory. + /// + private static void ResetCachedAssemblyDirectory() + { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_ResetCachedAssemblyDirectory"); +#endif + #endregion + + lock (staticSyncRoot) + { + cachedAssemblyDirectory = null; + noAssemblyDirectory = false; + } + } + + ///////////////////////////////////////////////////////////////////////// + /// + /// Queries and returns the cached directory for the assembly currently + /// being executed, if available. If the cached assembly directory value + /// is not available, the method will + /// be used to obtain the assembly directory. + /// + /// + /// The directory for the assembly currently being executed -OR- null if + /// it cannot be determined. + /// + private static string GetCachedAssemblyDirectory() + { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_GetCachedAssemblyDirectory"); +#endif + #endregion + + lock (staticSyncRoot) + { + if (cachedAssemblyDirectory != null) + return cachedAssemblyDirectory; + + if (noAssemblyDirectory) + return null; + } + + return GetAssemblyDirectory(); + } + + ///////////////////////////////////////////////////////////////////////// + /// /// Queries and returns the directory for the assembly currently being /// executed. /// /// /// The directory for the assembly currently being executed -OR- null if /// it cannot be determined. /// private static string GetAssemblyDirectory() { + #region Debug Build Only +#if DEBUG + DebugData.IncrementOtherCount("Method_GetAssemblyDirectory"); +#endif + #endregion + try { Assembly assembly = Assembly.GetExecutingAssembly(); if (assembly == null) + { + lock (staticSyncRoot) + { + noAssemblyDirectory = true; + } + return null; + } string fileName = null; #if PLATFORM_COMPACTFRAMEWORK AssemblyName assemblyName = assembly.GetName(); if (assemblyName == null) + { + lock (staticSyncRoot) + { + noAssemblyDirectory = true; + } + return null; + } fileName = assemblyName.CodeBase; #else if (!CheckAssemblyCodeBase(assembly, ref fileName)) fileName = assembly.Location; #endif if (String.IsNullOrEmpty(fileName)) + { + lock (staticSyncRoot) + { + noAssemblyDirectory = true; + } + return null; + } string directory = Path.GetDirectoryName(fileName); if (String.IsNullOrEmpty(directory)) + { + lock (staticSyncRoot) + { + noAssemblyDirectory = true; + } + return null; + } + + lock (staticSyncRoot) + { + cachedAssemblyDirectory = directory; + } return directory; } #if !NET_COMPACT_20 && TRACE_SHARED catch (Exception e) @@ -1507,10 +1761,15 @@ { // do nothing. } #endif } + + lock (staticSyncRoot) + { + noAssemblyDirectory = true; + } return null; } #endregion Index: Tests/basic.eagle ================================================================== --- Tests/basic.eagle +++ Tests/basic.eagle @@ -4538,10 +4538,159 @@ } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\ defineConstant.System.Data.SQLite.INTEROP_SHA1_EXTENSION\ System.Data.SQLite SQLiteInterop} -result \ {5578139b470e35a3c231a499d06589215e46e8df\ a27f5e6f85a3872ed2e4e4018c8fd7dfaff052bc}} + +############################################################################### + +runTest {test data-1.86 {connection string integer parsing} -setup { + object import System.Globalization + object import System.Threading + + set culture [object create -alias CultureInfo en-US] + $culture NumberFormat.NegativeSign / + + set savedCulture [object invoke Thread.CurrentThread CurrentCulture] + object invoke Thread.CurrentThread CurrentCulture $culture +} -body { + setupDb [set fileName data-1.86.db] +} -cleanup { + cleanupDb $fileName + + unset -nocomplain db fileName + + catch {object invoke Thread.CurrentThread CurrentCulture $savedCulture} + unset -nocomplain savedCulture culture + + object unimport -importpattern System.Threading + object unimport -importpattern System.Globalization +} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\ +defineConstant.System.Data.SQLite.INTEROP_SHA1_EXTENSION System.Data.SQLite\ +SQLiteInterop} -match regexp -result \ +{^System#Data#SQLite#SQLiteConnection#\d+$}} + +############################################################################### + +reportSQLiteResources $test_channel true + +############################################################################### + +runTest {test data-1.87 {GetSettingValue cached directory/file name} -setup { + moveSystemDataSQLiteDllConfig false +} -body { + object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \ + GetSettingValue setting_for_data-1.87 null + + expr {[getOtherCount Method_ResetCachedAssemblyDirectory] == -1 && \ + [getOtherCount Method_ResetCachedXmlConfigFileName] == -1 && \ + [getOtherCount Method_GetAssemblyDirectory] == 1 && \ + [getOtherCount Method_GetXmlConfigFileName] == 1 && \ + [getOtherCount Method_GetCachedAssemblyDirectory] >= 1 && \ + [getOtherCount Method_GetCachedXmlConfigFileName] >= 1} +} -cleanup { + moveSystemDataSQLiteDllConfig true +} -constraints {eagle command.object monoBug28 System.Data.SQLite\ +buildConfiguration.Debug} -result {True}} + +############################################################################### + +reportSQLiteResources $test_channel true + +############################################################################### + +runTest {test data-1.88 {GetSettingValue cached directory/file name} -setup { + moveSystemDataSQLiteDllConfig false +} -body { + object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \ + GetSettingValue setting_for_data-1.88 null + + object invoke -flags +NonPublic \ + System.Data.SQLite.UnsafeNativeMethods ResetCachedAssemblyDirectory + + object invoke -flags +NonPublic \ + System.Data.SQLite.UnsafeNativeMethods ResetCachedXmlConfigFileName + + object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \ + GetSettingValue setting_for_data-1.88 null + + expr {[getOtherCount Method_ResetCachedAssemblyDirectory] == 1 && \ + [getOtherCount Method_ResetCachedXmlConfigFileName] == 1 && \ + [getOtherCount Method_GetAssemblyDirectory] == 2 && \ + [getOtherCount Method_GetXmlConfigFileName] == 2 && \ + [getOtherCount Method_GetCachedAssemblyDirectory] >= 2 && \ + [getOtherCount Method_GetCachedXmlConfigFileName] >= 2} +} -cleanup { + moveSystemDataSQLiteDllConfig true +} -constraints {eagle command.object monoBug28 System.Data.SQLite\ +buildConfiguration.Debug} -result {True}} + +############################################################################### + +runTest {test data-1.89 {using SQLiteBlob without rowid PK index} -setup { + setupDb [set fileName data-1.89.db] +} -body { + sql execute $db { + CREATE TABLE t1 (x GUID UNIQUE NOT NULL, y BLOB NOT NULL); + INSERT INTO t1 (x, y) VALUES( + '12345678-0000-0000-0000-000000000000', + X'010203040506070809' + ); + INSERT INTO t1 (x, y) VALUES( + '12345679-0000-0000-0000-000000000000', + X'0102030405060708090A0B0C0D0E0F101113' + ); + } + + set sql(1) { \ + SELECT y FROM t1 \ + WHERE x = '12345678-0000-0000-0000-000000000000'; \ + } + + set sql(2) { \ + SELECT y FROM t1 \ + WHERE x = '12345679-0000-0000-0000-000000000000'; \ + } + + set dataReader [sql execute -execute reader -format datareader \ + -behavior +KeyInfo -alias $db $sql(1)] + + while {[$dataReader Read]} { + set blob [object invoke -alias \ + System.Data.SQLite.SQLiteBlob Create $dataReader 0 true] + + lappend result [$blob GetCount] + + $blob Close + } + + $dataReader Close; unset dataReader + + set dataReader [sql execute -execute reader -format datareader \ + -behavior +KeyInfo -alias $db $sql(2)] + + while {[$dataReader Read]} { + set blob [object invoke -alias \ + System.Data.SQLite.SQLiteBlob Create $dataReader 0 true] + + lappend result [$blob GetCount] + + $blob Close + } + + $dataReader Close; unset dataReader + + set result +} -cleanup { + unset -nocomplain blob + unset -nocomplain dataReader + + cleanupDb $fileName + + unset -nocomplain result sql db fileName +} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\ +System.Data.SQLite} -result {9 18}} ############################################################################### reportSQLiteResources $test_channel Index: Tests/tkt-58ed318f2f.eagle ================================================================== --- Tests/tkt-58ed318f2f.eagle +++ Tests/tkt-58ed318f2f.eagle @@ -18,56 +18,10 @@ package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### -proc getSettingReadCount { name {viaFile false} } { - if {[haveConstraint buildConfiguration.Debug] && [catch { - object invoke -flags +NonPublic -alias \ - System.Data.SQLite.DebugData [expr {$viaFile ? \ - "settingFileReadCounts" : "settingReadCounts"}] - } settingReadCounts] == 0} then { - if {[string length $name] > 0} then { - if {[$settingReadCounts TryGetValue $name value]} then { - tputs $::test_channel [appendArgs \ - "---- setting \"" $name "\" was read " $value " times" \ - [expr {$viaFile ? " from the configuration file" : ""}] \n] - - return $value - } - } else { - set nameCount [$settingReadCounts Count] - set valueCount 0 - - object foreach -alias pair $settingReadCounts { - incr valueCount [$pair Value] - - tputs $::test_channel [appendArgs \ - "---- setting \"" [$pair Key] "\" was read " [$pair Value] \ - " times" [expr {$viaFile ? " from the configuration file" : \ - ""}] \n] - } - - return [list $nameCount $valueCount] - } - } - - if {[string length $name] > 0} then { - tputs $::test_channel [appendArgs \ - "---- setting \"" $name "\" was not read" [expr {$viaFile ? \ - " from the configuration file" : ""}] \n] - } else { - tputs $::test_channel [appendArgs \ - "---- no settings were read" [expr {$viaFile ? \ - " from the configuration file" : ""}] \n] - } - - return -1 -} - -############################################################################### - reportSQLiteResources $test_channel true ############################################################################### runTest {test tkt-58ed318f2f-1.1 {standard GetDefaultDbType usage} -setup { @@ -462,17 +416,13 @@ unset -nocomplain counts db fileName } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\ System.Data.SQLite buildConfiguration.Debug} -result {True}} -############################################################################### - -rename getSettingReadCount "" - ############################################################################### reportSQLiteResources $test_channel true ############################################################################### runSQLiteTestEpilogue runTestEpilogue Index: Tests/version.eagle ================================================================== --- Tests/version.eagle +++ Tests/version.eagle @@ -30,11 +30,11 @@ # The revision number is reserved for NuGet package versioning. # set version(major) 1 set version(minor) 0 set version(build) 105; # NOTE: Incremented with each release. -set version(revision) 0 +set version(revision) 2 ############################################################################### # # NOTE: What is the full version of the EntityFramework NuGet package (which Index: lib/System.Data.SQLite/common.eagle ================================================================== --- lib/System.Data.SQLite/common.eagle +++ lib/System.Data.SQLite/common.eagle @@ -2133,15 +2133,23 @@ [sql execute -execute scalar $db $sql [list param1 String $name]] > 0 }] } proc getDbDefaultPageSize {} { - return [executeSql "PRAGMA page_size;" scalar] + if {[catch {executeSql "PRAGMA page_size;" scalar} result] == 0} then { + return $result + } else { + return 0 + } } proc getDbDefaultCacheSize {} { - return [executeSql "PRAGMA cache_size;" scalar] + if {[catch {executeSql "PRAGMA cache_size;" scalar} result] == 0} then { + return $result + } else { + return 0 + } } proc useLegacyDbPageAndCacheSizes { varName } { # # NOTE: Refer to the specified variable (e.g. "db") in the context of our @@ -3205,13 +3213,15 @@ 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] + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to get CLR memory usage, error: " \ + \n\t $result \n] + } } } ######################################################################### @@ -3230,13 +3240,15 @@ # 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] + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed full garbage collection, error: " \ + \n\t $error \n] + } } set now [clock seconds] } while {$start <= $now && $now < $stop} } @@ -3251,13 +3263,15 @@ 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] + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to get CLR memory usage, error: " \ + \n\t $result \n] + } } } } proc getSQLiteHandleCounts { channel {quiet false} } { @@ -3279,13 +3293,15 @@ "---- critical handle count \"" $name "\" is " $value \n] } lappend result $value } else { - tputs $channel [appendArgs \ - "==== WARNING: failed to get critical handle count \"" \ - $name "\", error: " \n\t $value \n] + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to get critical handle count \"" \ + $name "\", error: " \n\t $value \n] + } } } } elseif {!$quiet} then { # # NOTE: The actual handle counts are not available; therefore, just @@ -3371,13 +3387,133 @@ "---- call sqlite3_shutdown()... error: " \n\t $result \n] } } } } + + proc getSettingReadCount { name {viaFile false} } { + if {[haveConstraint buildConfiguration.Debug] && [catch { + object invoke -flags +NonPublic -alias \ + System.Data.SQLite.DebugData [expr {$viaFile ? \ + "settingFileReadCounts" : "settingReadCounts"}] + } settingReadCounts] == 0} then { + if {[string length $name] > 0} then { + if {[$settingReadCounts TryGetValue $name value]} then { + tputs $::test_channel [appendArgs \ + "---- setting \"" $name "\" was read " $value " times" \ + [expr {$viaFile ? " from the configuration file" : ""}] \n] + + return $value + } + } else { + set nameCount [$settingReadCounts Count] + set valueCount 0 + + object foreach -alias pair $settingReadCounts { + incr valueCount [$pair Value] + + tputs $::test_channel [appendArgs \ + "---- setting \"" [$pair Key] "\" was read " [$pair Value] \ + " times" [expr {$viaFile ? " from the configuration file" : \ + ""}] \n] + } + + return [list $nameCount $valueCount] + } + } + + if {[string length $name] > 0} then { + tputs $::test_channel [appendArgs \ + "---- setting \"" $name "\" was not read" [expr {$viaFile ? \ + " from the configuration file" : ""}] \n] + } else { + tputs $::test_channel [appendArgs \ + "---- no settings were read" [expr {$viaFile ? \ + " from the configuration file" : ""}] \n] + } + + return -1 + } + + proc getOtherCount { name } { + if {[haveConstraint buildConfiguration.Debug] && [catch { + object invoke -flags +NonPublic -alias \ + System.Data.SQLite.DebugData otherCounts + } otherCounts] == 0} then { + if {[string length $name] > 0} then { + if {[$otherCounts TryGetValue $name value]} then { + tputs $::test_channel [appendArgs \ + "---- other counter \"" $name "\" has value " $value \n] + + return $value + } + } else { + set nameCount [$otherCounts Count] + set valueCount 0 + + object foreach -alias pair $otherCounts { + incr valueCount [$pair Value] + + tputs $::test_channel [appendArgs \ + "---- other counter \"" [$pair Key] "\" has value " \ + [$pair Value] \n] + } + + return [list $nameCount $valueCount] + } + } + + if {[string length $name] > 0} then { + tputs $::test_channel [appendArgs \ + "---- other counter \"" $name "\" has no value\n"] + } else { + tputs $::test_channel "---- there are no other counters\n" + } + + return -1 + } proc reportSQLiteResources { channel {quiet false} {reset true} {collect true} } { + # + # NOTE: If possible, always reset the cached assembly directory + # and the cached XML configuration file name. + # + if {[haveSQLiteObjectCommand]} then { + if {[catch { + object invoke -flags +NonPublic \ + System.Data.SQLite.UnsafeNativeMethods \ + ResetCachedAssemblyDirectory + } error] == 0} then { + if {!$quiet} then { + tputs $channel "---- reset cached assembly directory\n" + } + } else { + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to reset cached assembly directory, " \ + "error: " \n\t $error \n] + } + } + + if {[catch { + object invoke -flags +NonPublic \ + System.Data.SQLite.UnsafeNativeMethods \ + ResetCachedXmlConfigFileName + } error] == 0} then { + if {!$quiet} then { + tputs $channel "---- reset cached XML configuration file name\n" + } + } else { + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to reset cached XML configuration " \ + "file name, error: " \n\t $error \n] + } + } + } + # # NOTE: If available, report on (and possibly reset) the runtime # configuration statistics. # if {[haveSQLiteObjectCommand] && \ @@ -3405,14 +3541,16 @@ tputs $channel [appendArgs \ "---- reset setting statistics for the previous " \ $nameCount " names and " $valueCount " values read\n"] } } else { - tputs $channel [appendArgs \ - "==== WARNING: failed to reset setting statistics for " \ - "the previous " $nameCount " names and " $valueCount \ - " values read, error: " \n\t $error \n] + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to reset setting statistics for " \ + "the previous " $nameCount " names and " $valueCount \ + " values read, error: " \n\t $error \n] + } } } } if {[catch { @@ -3439,15 +3577,52 @@ "---- reset setting statistics for the previous " \ $nameCount " names and " $valueCount " values read " \ "from the configuration file\n"] } } else { + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to reset setting statistics for " \ + "the previous " $nameCount " names and " $valueCount \ + " values read from the configuration file, error: " \n\t \ + $error \n] + } + } + } + } + + if {[catch { + object invoke -flags +NonPublic -alias \ + System.Data.SQLite.DebugData otherCounts + } otherCounts] == 0} then { + set nameCount [$otherCounts Count] + set valueCount 0 + + object foreach -alias pair $otherCounts { + incr valueCount [$pair Value] + + if {!$quiet} then { tputs $channel [appendArgs \ - "==== WARNING: failed to reset setting statistics for " \ - "the previous " $nameCount " names and " $valueCount \ - " values read from the configuration file, error: " \n\t \ - $error \n] + "---- other counter \"" [$pair Key] "\" has value " \ + [$pair Value] \n] + } + } + + if {$reset} then { + if {[catch {$otherCounts Clear} error] == 0} then { + if {!$quiet} then { + tputs $channel [appendArgs \ + "---- reset other counters for the previous " \ + $nameCount " names and " $valueCount " values\n"] + } + } else { + if {!$quiet} then { + tputs $channel [appendArgs \ + "==== WARNING: failed to reset other counters for " \ + "the previous " $nameCount " names and " $valueCount \ + " values, error: " \n\t $error \n] + } } } } } Index: readme.htm ================================================================== --- readme.htm +++ readme.htm @@ -3,12 +3,12 @@ ADO.NET SQLite Data Provider
-Version 1.0.105.0 - April 9, 2017
-Using SQLite 3.18.0
Originally written by Robert Simpson
+Version 1.0.105.2 - June 12, 2017
+Using SQLite 3.19.3
Originally written by Robert Simpson
Released to the public domain, use at your own risk!
Official provider website: https://system.data.sqlite.org/
Legacy versions: https://sourceforge.net/projects/sqlite-dotnet2/

The current development version can be downloaded from @@ -143,11 +143,11 @@ <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.105.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> + type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.105.2, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> </DbProviderFactories> </system.data> </configuration>

@@ -205,10 +205,25 @@ released versions of System.Data.SQLite.

Version History

+

+ 1.0.105.2 - June 12, 2017 +

+
    +
  • Updated to SQLite 3.19.3.
  • +
  • Fix issues that prevented SQLiteBlob creation from succeeding for tables that did not have an integer primary key.
  • +
+

+ 1.0.105.1 - May 15, 2017 +

+
    +
  • Prevent culture settings from negatively impacting integer connection string defaults.
  • +
  • Make sure the "No_SQLiteConnectionNewParser" and "DefaultFlags_SQLiteConnection" setting values end up being cached.
  • +
  • Cache the XML file name and assembly directory used by the configuration subsystem.
  • +

1.0.105.0 - April 9, 2017

  • Updated to SQLite 3.18.0.
  • Index: test/AssemblyInfo.cs ================================================================== --- test/AssemblyInfo.cs +++ test/AssemblyInfo.cs @@ -36,7 +36,7 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.105.0")] -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +[assembly: AssemblyFileVersion("1.0.105.2")] Index: test/app.config ================================================================== --- test/app.config +++ test/app.config @@ -1,8 +1,8 @@ - + Index: testce/AssemblyInfo.cs ================================================================== --- testce/AssemblyInfo.cs +++ testce/AssemblyInfo.cs @@ -36,7 +36,7 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.105.0")] -// [assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +// [assembly: AssemblyFileVersion("1.0.105.2")] Index: testlinq/2008/LINQ/App.config ================================================================== --- testlinq/2008/LINQ/App.config +++ testlinq/2008/LINQ/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/2010/EF6/App.config ================================================================== --- testlinq/2010/EF6/App.config +++ testlinq/2010/EF6/App.config @@ -4,17 +4,17 @@
    - + - + Index: testlinq/2010/LINQ/App.config ================================================================== --- testlinq/2010/LINQ/App.config +++ testlinq/2010/LINQ/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/2012/EF6/App.config ================================================================== --- testlinq/2012/EF6/App.config +++ testlinq/2012/EF6/App.config @@ -4,17 +4,17 @@
    - + - + Index: testlinq/2012/LINQ/App.config ================================================================== --- testlinq/2012/LINQ/App.config +++ testlinq/2012/LINQ/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/2013/EF6/App.config ================================================================== --- testlinq/2013/EF6/App.config +++ testlinq/2013/EF6/App.config @@ -4,17 +4,17 @@
    - + - + Index: testlinq/2013/LINQ/App.config ================================================================== --- testlinq/2013/LINQ/App.config +++ testlinq/2013/LINQ/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/2015/EF6/App.config ================================================================== --- testlinq/2015/EF6/App.config +++ testlinq/2015/EF6/App.config @@ -4,17 +4,17 @@
    - + - + Index: testlinq/2015/LINQ/App.config ================================================================== --- testlinq/2015/LINQ/App.config +++ testlinq/2015/LINQ/App.config @@ -1,11 +1,11 @@ - + Index: testlinq/Properties/AssemblyInfo.cs ================================================================== --- testlinq/Properties/AssemblyInfo.cs +++ testlinq/Properties/AssemblyInfo.cs @@ -44,7 +44,7 @@ // 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.105.0")] -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +[assembly: AssemblyFileVersion("1.0.105.2")] Index: tools/install/Properties/AssemblyInfo.cs ================================================================== --- tools/install/Properties/AssemblyInfo.cs +++ tools/install/Properties/AssemblyInfo.cs @@ -26,7 +26,7 @@ // Major Version // Minor Version // Build Number // Revision // -[assembly: AssemblyVersion("1.0.105.0")] -[assembly: AssemblyFileVersion("1.0.105.0")] +[assembly: AssemblyVersion("1.0.105.2")] +[assembly: AssemblyFileVersion("1.0.105.2")] Index: www/downloads.wiki ================================================================== --- www/downloads.wiki +++ www/downloads.wiki @@ -1,8 +1,8 @@ Downloads Page -

    System.Data.SQLite Downloads

    +

    System.Data.SQLite Downloads

    @@ -425,11 +425,11 @@
    -

    List of Release Packages

    +

    List of Release Packages

    @@ -441,38 +441,38 @@
      - sqlite-netFx-source-1.0.105.0.zip + sqlite-netFx-source-1.0.105.2.zip
    - (6.02 MiB) + (6.03 MiB)
    This ZIP archive contains all current source code for System.Data.SQLite - 1.0.105.0 (3.18.0) combined into a single archive file. + 1.0.105.2 (3.19.3) combined into a single archive file.
    - (sha1: 698e4a4747bb1d107c60a580c7eec900d6c8db9a) + (sha1: a58bed040da0e9d54ff0c39553ffc6e4babd7591)
      - sqlite-netFx-full-source-1.0.105.0.zip + sqlite-netFx-full-source-1.0.105.2.zip
    - (7.44 MiB) + (7.45 MiB)
    This ZIP archive contains all current source code for System.Data.SQLite - 1.0.105.0 (3.18.0) and the extra files needed to run the unit test suite, + 1.0.105.2 (3.19.3) and the extra files needed to run the unit test suite, combined into a single archive file.
    - (sha1: 7e2622dd66da59c97ba0dad5c8916d48b2820bb6) + (sha1: 92a7d8263dcfd8060e7ab34adf55d030d2903c88)
    @@ -482,19 +482,19 @@
      - sqlite-netFx20-setup-bundle-x86-2005-1.0.105.0.exe + sqlite-netFx20-setup-bundle-x86-2005-1.0.105.2.exe
    (5.41 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2005 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 is included. The .NET Framework 2.0 SP2 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2005. @@ -503,30 +503,30 @@ However, if you do not require the design-time components, please consider downloading the associated "Precompiled Binaries" instead.

    - (sha1: aab5ce1dcdc5b0017d12d4429ff0fe28ea7e9810) + (sha1: 51a0855996baf221f58f27ea6795cd938376fff8)
      - sqlite-netFx20-setup-x86-2005-1.0.105.0.exe + sqlite-netFx20-setup-x86-2005-1.0.105.2.exe
    (5.40 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x86 is included. + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 is included. The .NET Framework 2.0 SP2 is required.
    - (sha1: f37c7f5d6c8780af07b8bdb5a470bbd81a683547) + (sha1: f5e641c52f853aed32771cbbc93f9b2ccd6c115e)
    @@ -536,42 +536,42 @@
      - sqlite-netFx20-setup-bundle-x64-2005-1.0.105.0.exe + sqlite-netFx20-setup-bundle-x64-2005-1.0.105.2.exe
    - (6.04 MiB) + (6.05 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2005 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 is included. The .NET Framework 2.0 SP2 is required.
    - (sha1: 1906178f9c8b4d50b03bd00ef269294d2ca2ffb3) + (sha1: eee3784617b3de0637dc025699402f00e5b3d939)
      - sqlite-netFx20-setup-x64-2005-1.0.105.0.exe + sqlite-netFx20-setup-x64-2005-1.0.105.2.exe
    - (6.03 MiB) + (6.04 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x64 is included. + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 is included. The .NET Framework 2.0 SP2 is required.
    - (sha1: 8f124abc0a8258e4906fd7c23d75c3d9a75a4a91) + (sha1: d56b3068f3163602f455fc9a6ffabf3ef86e31f0)
    @@ -581,19 +581,19 @@
      - sqlite-netFx35-setup-bundle-x86-2008-1.0.105.0.exe + sqlite-netFx35-setup-bundle-x86-2008-1.0.105.2.exe
    (7.44 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2008 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 is included. The .NET Framework 3.5 SP1 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2008. @@ -602,30 +602,30 @@ However, if you do not require the design-time components, please consider downloading the associated "Precompiled Binaries" instead.

    - (sha1: 99ef3b89442672411a29f59a2baca2770f8b4f1f) + (sha1: e397ad5f1d575bb2bb40b23f0834261c9bcf69d0)
      - sqlite-netFx35-setup-x86-2008-1.0.105.0.exe + sqlite-netFx35-setup-x86-2008-1.0.105.2.exe
    (7.43 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2008 SP1 runtime for x86 is included. + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: 7aaa1bccdb9e94b77af75728921e7b2e0f3bd655) + (sha1: 7f1f645cff7c618b6f9def9ccf12a362312410dc)
    @@ -635,42 +635,42 @@
      - sqlite-netFx35-setup-bundle-x64-2008-1.0.105.0.exe + sqlite-netFx35-setup-bundle-x64-2008-1.0.105.2.exe
    (8.21 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2008 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: fd03e6b602ce80c5334333b907f6d1e8ea05219b) + (sha1: 49c5481e8f75184c2719270abff65e16cd1ef7ad)
      - sqlite-netFx35-setup-x64-2008-1.0.105.0.exe + sqlite-netFx35-setup-x64-2008-1.0.105.2.exe
    (8.20 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2008 SP1 runtime for x64 is included. + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 is included. The .NET Framework 3.5 SP1 is required.
    - (sha1: 24d1d38fcfa850d91a45d608150ee9679a8f8686) + (sha1: 71471844acfa21a34836067db1f98783a22b3def)
    @@ -680,19 +680,19 @@
      - sqlite-netFx40-setup-bundle-x86-2010-1.0.105.0.exe + sqlite-netFx40-setup-bundle-x86-2010-1.0.105.2.exe
    - (13.01 MiB) + (13.02 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2010 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 is included. The .NET Framework 4.0 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2010.
    @@ -700,30 +700,30 @@ However, if you do not require the design-time components, please consider downloading the associated "Precompiled Binaries" instead.


    - (sha1: df852d22ccf6b69181e723609f0789e6b6781e07) + (sha1: d86e1f43f3bc3eea0d8ad6230cf90d85c03bcd9a)
      - sqlite-netFx40-setup-x86-2010-1.0.105.0.exe + sqlite-netFx40-setup-x86-2010-1.0.105.2.exe
    - (13.00 MiB) + (13.01 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2010 SP1 runtime for x86 is included. + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 is included. The .NET Framework 4.0 is required.
    - (sha1: 5ee18d080e94ea2d40413e03997e429201bd9df1) + (sha1: bda84aae8dfed30503b197c28bf5bf8c7a9ac9b7)
    @@ -733,41 +733,41 @@
      - sqlite-netFx40-setup-bundle-x64-2010-1.0.105.0.exe + sqlite-netFx40-setup-bundle-x64-2010-1.0.105.2.exe
    (14.29 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2010 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 is included. The .NET Framework 4.0 is required.
    - (sha1: b1e3ada999d40e73c311df63ba7931edf6608f14) + (sha1: 8f825be91342b6e741e62ad69c6b7da0ecb26717)
      - sqlite-netFx40-setup-x64-2010-1.0.105.0.exe + sqlite-netFx40-setup-x64-2010-1.0.105.2.exe
    (14.28 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2010 SP1 runtime for x64 is included. + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 is included. The .NET Framework 4.0 is required.
    - (sha1: 3e84a56548188219820816d198ae348d70a59af3) + (sha1: 4e729bc7c9fe01cc491a15735ad66ec5459781f0)
    @@ -777,19 +777,19 @@
      - sqlite-netFx45-setup-bundle-x86-2012-1.0.105.0.exe + sqlite-netFx45-setup-bundle-x86-2012-1.0.105.2.exe
    (10.44 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2012 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 is included. The .NET Framework 4.5 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2012. @@ -804,30 +804,30 @@ installing the Visual Studio 2012 "flavor" of the Entity Framework 6 Tools for Visual Studio 2012 & 2013.

    - (sha1: b3fecb31ec50f11095854c47d56cf3fe096f52b0) + (sha1: 09d47fef648dcbd846b564f2fba3f113523469ba)
      - sqlite-netFx45-setup-x86-2012-1.0.105.0.exe + sqlite-netFx45-setup-x86-2012-1.0.105.2.exe
    - (10.47 MiB) + (10.48 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x86 is + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 is included. The .NET Framework 4.5 is required.
    - (sha1: fb8bfa089ea81284a11a98e7480c731e605c05b0) + (sha1: 3f302340ae1c639862c87630a871a147b9cb1f0a)
    @@ -837,42 +837,42 @@
      - sqlite-netFx45-setup-bundle-x64-2012-1.0.105.0.exe + sqlite-netFx45-setup-bundle-x64-2012-1.0.105.2.exe
    - (11.10 MiB) + (11.11 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2012 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 is included. The .NET Framework 4.5 is required.
    - (sha1: 7029232b6ced30d3f6ad127fe37be184fb096e03) + (sha1: bf2bc9ad65bcaffb8eb1120b84c5d72426ac2d6c)
      - sqlite-netFx45-setup-x64-2012-1.0.105.0.exe + sqlite-netFx45-setup-x64-2012-1.0.105.2.exe
    (11.17 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x64 is + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 is included. The .NET Framework 4.5 is required.
    - (sha1: 3ac4f00ea1086c851d0199be5d3476c3f7873d76) + (sha1: b5d2b14927771a1749dfa6bd5f7389d7c4c56acd)
    @@ -882,19 +882,19 @@
      - sqlite-netFx451-setup-bundle-x86-2013-1.0.105.0.exe + sqlite-netFx451-setup-bundle-x86-2013-1.0.105.2.exe
    (10.40 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2013 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 is included. The .NET Framework 4.5.1 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2013. @@ -909,30 +909,30 @@ installing the Visual Studio 2013 "flavor" of the Entity Framework 6 Tools for Visual Studio 2012 & 2013.

    - (sha1: 371b9acd8aa1dd51561349799eed94ee5a032898) + (sha1: 7e03f11e9ee7f7b1e6bd643510ed68d433604b31)
      - sqlite-netFx451-setup-x86-2013-1.0.105.0.exe + sqlite-netFx451-setup-x86-2013-1.0.105.2.exe
    (10.43 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x86 is + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 is included. The .NET Framework 4.5.1 is required.
    - (sha1: e95fc3cec587939d1cabcc2b0c39a0107191f37b) + (sha1: 1288f8ae2cac4e7a0739121fbfcefe29377fb6aa)
    @@ -942,42 +942,42 @@
      - sqlite-netFx451-setup-bundle-x64-2013-1.0.105.0.exe + sqlite-netFx451-setup-bundle-x64-2013-1.0.105.2.exe
    - (11.09 MiB) + (11.10 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2013 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 is included. The .NET Framework 4.5.1 is required.
    - (sha1: 30d2e880f4ec97d9843a3eaf1d215cb25e9f7649) + (sha1: 585c5e40058f7b3d1337af04e9e18a5dd7cd3c69)
      - sqlite-netFx451-setup-x64-2013-1.0.105.0.exe + sqlite-netFx451-setup-x64-2013-1.0.105.2.exe
    (11.16 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x64 is + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 is included. The .NET Framework 4.5.1 is required.
    - (sha1: 8dd09e4ed6dff2a88e7a77b4af1b933d1990e07d) + (sha1: bf5d821ebb96359d80fa51c08ff6e8483955b334)
    @@ -987,19 +987,19 @@
      - sqlite-netFx46-setup-bundle-x86-2015-1.0.105.0.exe + sqlite-netFx46-setup-bundle-x86-2015-1.0.105.2.exe
    - (16.93 MiB) + (16.94 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2015 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 is included. The .NET Framework 4.6 is required.
    This is the only setup package that is capable of installing the design-time components for Visual Studio 2015. @@ -1008,30 +1008,30 @@ However, if you do not require the design-time components, please consider downloading the associated "Precompiled Binaries" instead.

    - (sha1: cc12a63845b480ae6766e479c5c78bc26752819c) + (sha1: 6e9711c2d84ecd9695632eb90fc750719ac66fab)
      - sqlite-netFx46-setup-x86-2015-1.0.105.0.exe + sqlite-netFx46-setup-x86-2015-1.0.105.2.exe
    - (17.11 MiB) + (17.12 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x86 is + dependencies for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 is included. The .NET Framework 4.6 is required.
    - (sha1: d8d947b45f579aac78b6a9a373378cc6186a14cf) + (sha1: cb0761146b69e5bed61c38e4bcb86b7b87f3f1b2)
    @@ -1041,42 +1041,42 @@
      - sqlite-netFx46-setup-bundle-x64-2015-1.0.105.0.exe + sqlite-netFx46-setup-bundle-x64-2015-1.0.105.2.exe
    - (17.78 MiB) + (17.80 MiB)
    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.105.0 (3.18.0) package. The Visual C++ 2015 + the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 is included. The .NET Framework 4.6 is required.
    - (sha1: f600bc8a1585f563ec58a5a6f36574ea6baff98c) + (sha1: 3fe173990a49941e56b098b2bd82785464bd75a8)
      - sqlite-netFx46-setup-x64-2015-1.0.105.0.exe + sqlite-netFx46-setup-x64-2015-1.0.105.2.exe
    - (18.02 MiB) + (18.03 MiB)
    This setup package will install all the necessary runtime components and - dependencies for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x64 is + dependencies for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 is included. The .NET Framework 4.6 is required.
    - (sha1: d9f6d63a3234a60c11814e24006ad5d3e9cfac13) + (sha1: e719ba640a371851bcfd19f01d2a9aa2ef29187d)
    @@ -1086,40 +1086,40 @@
      - sqlite-netFx20-binary-bundle-Win32-2005-1.0.105.0.zip + sqlite-netFx20-binary-bundle-Win32-2005-1.0.105.2.zip
    - (1.77 MiB) + (1.78 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x86 and the .NET + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 and the .NET Framework 2.0 SP2 are required.
    - (sha1: 0358d783c2e3817fa86a1e073c09a65e492c7771) + (sha1: 5edddc419a4a17713951a12303ce0c49094d7ad5)
      - sqlite-netFx20-binary-Win32-2005-1.0.105.0.zip + sqlite-netFx20-binary-Win32-2005-1.0.105.2.zip
    - (1.77 MiB) + (1.78 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2005 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 and the .NET Framework 2.0 SP2 are required.
    - (sha1: 4929fbef835434f88ada8bf43fa67ba50954f147) + (sha1: 84209458c00ec6a2ad5602fa8c352a281325a201)
    @@ -1129,40 +1129,40 @@
      - sqlite-netFx20-binary-bundle-x64-2005-1.0.105.0.zip + sqlite-netFx20-binary-bundle-x64-2005-1.0.105.2.zip
    - (2.04 MiB) + (2.05 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x64 and the .NET + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 and the .NET Framework 2.0 SP2 are required.
    - (sha1: 9311735817b5463e9dca1119789abd69a8c8d3d7) + (sha1: 586a318fbb43d1ed897636dd2435e25926a8f14c)
      - sqlite-netFx20-binary-x64-2005-1.0.105.0.zip + sqlite-netFx20-binary-x64-2005-1.0.105.2.zip
    - (2.03 MiB) + (2.04 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2005 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 and the .NET Framework 2.0 SP2 are required.
    - (sha1: c5f4c6df3b1d6e4b9d2df38d190cf5214fb4df63) + (sha1: 3e9869d05285bee6d46dd1817abb895a348100d6)
    @@ -1172,40 +1172,40 @@
      - sqlite-netFx35-binary-bundle-Win32-2008-1.0.105.0.zip + sqlite-netFx35-binary-bundle-Win32-2008-1.0.105.2.zip
    - (2.22 MiB) + (2.23 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) 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.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 and the .NET Framework 3.5 SP1 are required.
    - (sha1: cef9457903093ed4e3e6fe5feefe8f31e7e3096f) + (sha1: 5dcea70e78ca11f081766aa2dd8f28f6c5538187)
      - sqlite-netFx35-binary-Win32-2008-1.0.105.0.zip + sqlite-netFx35-binary-Win32-2008-1.0.105.2.zip
    - (2.21 MiB) + (2.22 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 and the .NET Framework 3.5 SP1 are required.
    - (sha1: c69bb7f9bf40aef1a3f56f1fefb0918ebf175a6b) + (sha1: efce5ee79fd8a5b2c6bbaf47531ed0a9c5407ae9)
    @@ -1215,40 +1215,40 @@
      - sqlite-netFx35-binary-bundle-x64-2008-1.0.105.0.zip + sqlite-netFx35-binary-bundle-x64-2008-1.0.105.2.zip
    - (2.33 MiB) + (2.34 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) 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.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 and the .NET Framework 3.5 SP1 are required.
    - (sha1: 1c9c53d4c87206c90c01c8b8d6915093ff53c324) + (sha1: aede328c84b0daf7396deff87bae494aa3d24244)
      - sqlite-netFx35-binary-x64-2008-1.0.105.0.zip + sqlite-netFx35-binary-x64-2008-1.0.105.2.zip
    (2.33 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 and the .NET Framework 3.5 SP1 are required.
    - (sha1: 86d5f58841519a5e993d8398a311bb4f09a0681c) + (sha1: 740365a07f8b8b35749038e7f8a88711f2aa1a5c)
    @@ -1258,40 +1258,40 @@
      - sqlite-netFx40-binary-bundle-Win32-2010-1.0.105.0.zip + sqlite-netFx40-binary-bundle-Win32-2010-1.0.105.2.zip
    (2.46 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) 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.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 and the .NET Framework 4.0 are required.
    - (sha1: a08700a190a4db2460696e8da216a93576c0971b) + (sha1: a6e0fb2d1cedcbaf365e2420a69104fd359461c3)
      - sqlite-netFx40-binary-Win32-2010-1.0.105.0.zip + sqlite-netFx40-binary-Win32-2010-1.0.105.2.zip
    - (2.45 MiB) + (2.46 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 and the .NET Framework 4.0 are required.
    - (sha1: 171d62499ee93ff082724d0d173979d411b822db) + (sha1: 31c6d486b7e8017cbde144b51389cad1807f4d92)
    @@ -1301,40 +1301,40 @@
      - sqlite-netFx40-binary-bundle-x64-2010-1.0.105.0.zip + sqlite-netFx40-binary-bundle-x64-2010-1.0.105.2.zip
    (2.51 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) 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.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 and the .NET Framework 4.0 are required.
    - (sha1: 60862fc87a8a4e08050403c91b20799e8b57b218) + (sha1: 293b0844189e47256e191a43454fd397a3f779f9)
      - sqlite-netFx40-binary-x64-2010-1.0.105.0.zip + sqlite-netFx40-binary-x64-2010-1.0.105.2.zip
    - (2.50 MiB) + (2.51 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 and the .NET Framework 4.0 are required.
    - (sha1: 62819d1f5dee5ad7392eda5794c6b0fdb12353af) + (sha1: 001860575c4390f13d205fd93c2a4634bba8a082)
    @@ -1344,40 +1344,40 @@
      - sqlite-netFx45-binary-bundle-Win32-2012-1.0.105.0.zip + sqlite-netFx45-binary-bundle-Win32-2012-1.0.105.2.zip
    (2.37 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x86 and + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 and the .NET Framework 4.5 are required.
    - (sha1: f1b72ba60cd643a5bf13c4814b797c10c27536b7) + (sha1: f89b548cfc2f3d29d02fa6bc7dafc18e0b464989)
      - sqlite-netFx45-binary-Win32-2012-1.0.105.0.zip + sqlite-netFx45-binary-Win32-2012-1.0.105.2.zip
    - (2.41 MiB) + (2.42 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2012 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 and the .NET Framework 4.5 are required.
    - (sha1: a3b212bb0bb27a360db1b63871d3130b14e3f375) + (sha1: 31c4df4a4a2ba1331465f387f1debe2b69bd8f3f)
    @@ -1387,40 +1387,40 @@
      - sqlite-netFx45-binary-bundle-x64-2012-1.0.105.0.zip + sqlite-netFx45-binary-bundle-x64-2012-1.0.105.2.zip
    (2.42 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x64 and + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 and the .NET Framework 4.5 are required.
    - (sha1: a56de60f45ad48b9f4f10ed9e24af24fb7a6df94) + (sha1: 27c02e2b946960b6f90baf9c876dd0ca0abbf3cd)
      - sqlite-netFx45-binary-x64-2012-1.0.105.0.zip + sqlite-netFx45-binary-x64-2012-1.0.105.2.zip
    (2.51 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2012 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 and the .NET Framework 4.5 are required.
    - (sha1: 2dc67ea077dfe6f08e6c352dc476606553f2faab) + (sha1: 1f431f94e286841475e7a246cf4fe00c428fcb30)
    @@ -1430,40 +1430,40 @@
      - sqlite-netFx451-binary-bundle-Win32-2013-1.0.105.0.zip + sqlite-netFx451-binary-bundle-Win32-2013-1.0.105.2.zip
    (2.38 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x86 and the + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 and the .NET Framework 4.5.1 are required.
    - (sha1: 73053857b2baf85de8e6249ac5cdb5d1fb76aae4) + (sha1: 5f9aabcf21cf2920379471b24a78755620e68017)
      - sqlite-netFx451-binary-Win32-2013-1.0.105.0.zip + sqlite-netFx451-binary-Win32-2013-1.0.105.2.zip
    - (2.42 MiB) + (2.43 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2013 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 and the .NET Framework 4.5.1 are required.
    - (sha1: 0ddd340a6928713b4ff170ed842d6ba4f45466b9) + (sha1: a79ed2a21886b0edced9372d697f3649f7275551)
    @@ -1473,40 +1473,40 @@
      - sqlite-netFx451-binary-bundle-x64-2013-1.0.105.0.zip + sqlite-netFx451-binary-bundle-x64-2013-1.0.105.2.zip
    - (2.42 MiB) + (2.43 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x64 and the + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 and the .NET Framework 4.5.1 are required.
    - (sha1: 027eb468a70de82e102a9b4a943bda710e6eb7bd) + (sha1: 239905b7b514bff6b6eee9232c33d2f655407710)
      - sqlite-netFx451-binary-x64-2013-1.0.105.0.zip + sqlite-netFx451-binary-x64-2013-1.0.105.2.zip
    - (2.51 MiB) + (2.52 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2013 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 and the .NET Framework 4.5.1 are required.
    - (sha1: 465d30843289381f13e041aaf48610feed4eb692) + (sha1: 2fc6be6822490ea385adc115d57c478e5671a80f)
    @@ -1516,40 +1516,40 @@
      - sqlite-netFx46-binary-bundle-Win32-2015-1.0.105.0.zip + sqlite-netFx46-binary-bundle-Win32-2015-1.0.105.2.zip
    - (2.93 MiB) + (2.94 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x86 and the + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 and the .NET Framework 4.6 are required.
    - (sha1: 8383826dada5c1e9bf51e2e673bf77329ce69aa3) + (sha1: 43bbab20b1d4bab7dcee62baaa8ea74346046592)
      - sqlite-netFx46-binary-Win32-2015-1.0.105.0.zip + sqlite-netFx46-binary-Win32-2015-1.0.105.2.zip
    - (3.16 MiB) + (3.18 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2015 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 and the .NET Framework 4.6 are required.
    - (sha1: c17d4461341e0c62e4429d72330a17cbdca5f1c3) + (sha1: b5d14c7afb4261eee1fd7f728b7ea7a3d3362e1a)
    @@ -1559,40 +1559,40 @@
      - sqlite-netFx46-binary-bundle-x64-2015-1.0.105.0.zip + sqlite-netFx46-binary-bundle-x64-2015-1.0.105.2.zip
    - (2.98 MiB) + (3.00 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x64 and the + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 and the .NET Framework 4.6 are required.
    - (sha1: 79d9a31ede2ad6fa72fd6871c2c0ae17aa34e5a9) + (sha1: d53f68fbef7675ef897030aa2b73bf23867253b4)
      - sqlite-netFx46-binary-x64-2015-1.0.105.0.zip + sqlite-netFx46-binary-x64-2015-1.0.105.2.zip
    - (3.28 MiB) + (3.30 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2015 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 and the .NET Framework 4.6 are required.
    - (sha1: cbbf3e3cfb093c9a6fb357a001c259dc6e4f3d61) + (sha1: b0f6d4727fc349ca28cfab6dfe7084de0a0c3dae)
    @@ -1602,22 +1602,22 @@
      - sqlite-netFx451-binary-Mono-2013-1.0.105.0.zip + sqlite-netFx451-binary-Mono-2013-1.0.105.2.zip
    - (1.21 MiB) + (1.22 MiB)
    This binary package contains all the managed binaries for the Mono - version of the System.Data.SQLite 1.0.105.0 (3.18.0) package. The + version of the System.Data.SQLite 1.0.105.2 (3.19.3) package. The Mono runtime (4.2.3.4 or higher) is required.
    - (sha1: e054c17284fed3c10f74532c70e2a65d08fda717) + (sha1: 01b306cc7c66cdae9b6a6bc2fc119e7f1ff9143a)
    @@ -1627,41 +1627,41 @@
      - sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.105.0.zip + sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.105.2.zip
    (1.97 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x86 is statically + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 is statically linked. The .NET Framework 2.0 SP2 is required.
    - (sha1: b1f25935f7ec3ba8cff7c172374ff2f582e2bc2f) + (sha1: abc6eacbe96b45ce3e5b00faf006865895c152d0)
      - sqlite-netFx20-static-binary-Win32-2005-1.0.105.0.zip + sqlite-netFx20-static-binary-Win32-2005-1.0.105.2.zip
    - (1.96 MiB) + (1.97 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2005 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x86 is statically linked. The .NET Framework 2.0 SP2 is required.
    - (sha1: f2c012a43b53630073fb50d0b18c7f5d0f6d125d) + (sha1: b1c73292b5033b861d8238f0e63947cccc1f290c)
    @@ -1671,41 +1671,41 @@
      - sqlite-netFx20-static-binary-bundle-x64-2005-1.0.105.0.zip + sqlite-netFx20-static-binary-bundle-x64-2005-1.0.105.2.zip
    - (2.18 MiB) + (2.19 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2005 SP1 runtime for x64 is statically + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 is statically linked. The .NET Framework 2.0 SP2 is required.
    - (sha1: f8fb5b9d0c60a8799c4b477fbb313d6e19cd3d2f) + (sha1: caaccb2296fc42e9e1198dce178b8f7edd8e5c58)
      - sqlite-netFx20-static-binary-x64-2005-1.0.105.0.zip + sqlite-netFx20-static-binary-x64-2005-1.0.105.2.zip
    - (2.17 MiB) + (2.18 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2005 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2005 SP1 runtime for x64 is statically linked. The .NET Framework 2.0 SP2 is required.
    - (sha1: 5c34b1fadc936dfc84dc0e7ec9c0e8e9f7d634d6) + (sha1: 3432bda228648fc25ab887f8a7de040f38e02e49)
    @@ -1715,41 +1715,41 @@
      - sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.105.0.zip + sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.105.2.zip
    - (2.42 MiB) + (2.43 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2008 SP1 runtime for x86 is statically + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: 7037d89c13f66050956694db1d6de7955be38933) + (sha1: a188b2ba523abdb243e05c57c41ccba963b9b042)
      - sqlite-netFx35-static-binary-Win32-2008-1.0.105.0.zip + sqlite-netFx35-static-binary-Win32-2008-1.0.105.2.zip
    - (2.41 MiB) + (2.42 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x86 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: 0ed8c711c3ba0fdcda70c3fd913148893929acf9) + (sha1: 81f194eb26cf315d24fcbea179870c3ff14be9e7)
    @@ -1759,41 +1759,41 @@
      - sqlite-netFx35-static-binary-bundle-x64-2008-1.0.105.0.zip + sqlite-netFx35-static-binary-bundle-x64-2008-1.0.105.2.zip
    - (2.49 MiB) + (2.50 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2008 SP1 runtime for x64 is statically + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: c613eb874db578a763c84773b676e49d1934845d) + (sha1: f35554f34bae4f7d4e7c0a038fa3663ad5489dde)
      - sqlite-netFx35-static-binary-x64-2008-1.0.105.0.zip + sqlite-netFx35-static-binary-x64-2008-1.0.105.2.zip
    - (2.48 MiB) + (2.49 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2008 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2008 SP1 runtime for x64 is statically linked. The .NET Framework 3.5 SP1 is required.
    - (sha1: 74f68524fbde2be635df19f53b7c2c2f341eb863) + (sha1: fe2ef88bfd925bdfcf3f92811756b96afabb7d2c)
    @@ -1803,41 +1803,41 @@
      - sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.105.0.zip + sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.105.2.zip
    - (2.65 MiB) + (2.66 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2010 SP1 runtime for x86 is statically + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 90ab3273db757569f53098bf3e5687ff58172554) + (sha1: 863d426bb1fdd2ec2f435598ab9dbbca1a4e5276)
      - sqlite-netFx40-static-binary-Win32-2010-1.0.105.0.zip + sqlite-netFx40-static-binary-Win32-2010-1.0.105.2.zip
    (2.65 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x86 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: 7ab5dce06568236ed3b288059fc8dc26d59c2843) + (sha1: 04a4ae4c48bf9308fc95187f473cad627e20aed4)
    @@ -1847,41 +1847,41 @@
      - sqlite-netFx40-static-binary-bundle-x64-2010-1.0.105.0.zip + sqlite-netFx40-static-binary-bundle-x64-2010-1.0.105.2.zip
    - (2.68 MiB) + (2.69 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2010 SP1 runtime for x64 is statically + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: a970acccfc8398bcc34571747d02fd8ab1ce91b2) + (sha1: e574cf8df0d9a18ef74c2e91106eeb04633cde26)
      - sqlite-netFx40-static-binary-x64-2010-1.0.105.0.zip + sqlite-netFx40-static-binary-x64-2010-1.0.105.2.zip
    (2.68 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2010 SP1 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2010 SP1 runtime for x64 is statically linked. The .NET Framework 4.0 is required.
    - (sha1: e0afff605a94a422de75eccab2da809291af5cbe) + (sha1: 5c79021d15fa22c69baf692c65b9428648f342ee)
    @@ -1891,41 +1891,41 @@
      - sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.105.0.zip + sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.105.2.zip
    - (2.69 MiB) + (2.70 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x86 is + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 is statically linked. The .NET Framework 4.5 is required.
    - (sha1: c28601a1cd90de40026e76bf0065aeca7d75126a) + (sha1: 88f8c39025f3256ccba229c20765146520fdd27e)
      - sqlite-netFx45-static-binary-Win32-2012-1.0.105.0.zip + sqlite-netFx45-static-binary-Win32-2012-1.0.105.2.zip
    - (2.74 MiB) + (2.75 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2012 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x86 is statically linked. The .NET Framework 4.5 is required.
    - (sha1: 1dd055dbbd28201fc3c53ffc556b63803bd89b0b) + (sha1: b268e07d8a1342f66f43a955c788580035c9a05d)
    @@ -1935,41 +1935,41 @@
      - sqlite-netFx45-static-binary-bundle-x64-2012-1.0.105.0.zip + sqlite-netFx45-static-binary-bundle-x64-2012-1.0.105.2.zip
    - (2.67 MiB) + (2.68 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2012 Update 4 runtime for x64 is + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 is statically linked. The .NET Framework 4.5 is required.
    - (sha1: 3f8dd898f927f148bd93d464cb27eb6fb286515a) + (sha1: 1136edf7e0609f09ce92966c971a61b2c81ffb86)
      - sqlite-netFx45-static-binary-x64-2012-1.0.105.0.zip + sqlite-netFx45-static-binary-x64-2012-1.0.105.2.zip
    - (2.76 MiB) + (2.77 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2012 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2012 Update 4 runtime for x64 is statically linked. The .NET Framework 4.5 is required.
    - (sha1: a653d868753ebd50a8cc29b914a13a7245ad59b0) + (sha1: 833d58c4883e66f9d38b5f3fad503092bebe6e35)
    @@ -1979,41 +1979,41 @@
      - sqlite-netFx451-static-binary-bundle-Win32-2013-1.0.105.0.zip + sqlite-netFx451-static-binary-bundle-Win32-2013-1.0.105.2.zip
    (2.72 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x86 is + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 is statically linked. The .NET Framework 4.5.1 is required.
    - (sha1: 9e60b7b5830c6617a0dcf0749c22b322e433853d) + (sha1: 3fded66bf9157d12d4c5d8b88ff30b48289c1bdf)
      - sqlite-netFx451-static-binary-Win32-2013-1.0.105.0.zip + sqlite-netFx451-static-binary-Win32-2013-1.0.105.2.zip
    - (2.76 MiB) + (2.77 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2013 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x86 is statically linked. The .NET Framework 4.5.1 is required.
    - (sha1: d4ac4f5c2d5747db9ce94ee1e58bea03bd0bc60a) + (sha1: 52aedfecbccc4858ce6f0a6bdee6ed6de6a5afb1)
    @@ -2023,41 +2023,41 @@
      - sqlite-netFx451-static-binary-bundle-x64-2013-1.0.105.0.zip + sqlite-netFx451-static-binary-bundle-x64-2013-1.0.105.2.zip
    - (2.71 MiB) + (2.72 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2013 Update 2 runtime for x64 is + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 is statically linked. The .NET Framework 4.5.1 is required.
    - (sha1: a7f5e485e3661211415f07eaa92e9d74dfc1b94c) + (sha1: 98d30eb4829e1ca7f00142ce40d65737375e3eac)
      - sqlite-netFx451-static-binary-x64-2013-1.0.105.0.zip + sqlite-netFx451-static-binary-x64-2013-1.0.105.2.zip
    - (2.80 MiB) + (2.81 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2013 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2013 Update 2 runtime for x64 is statically linked. The .NET Framework 4.5.1 is required.
    - (sha1: 164b82234b24c084ac4bff0855f7d9f104f96e71) + (sha1: 4b1b2ea50af7f2f541047fabca31d8f87c3d6801)
    @@ -2067,41 +2067,41 @@
      - sqlite-netFx46-static-binary-bundle-Win32-2015-1.0.105.0.zip + sqlite-netFx46-static-binary-bundle-Win32-2015-1.0.105.2.zip
    - (3.45 MiB) + (3.46 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x86 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x86 is + the binaries for the x86 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 is statically linked. The .NET Framework 4.6 is required.
    - (sha1: d172250a202e4170741d768e5e1c1773c9ac400a) + (sha1: fe5721af0ce9c9a73f357e94e15cc77271c888b1)
      - sqlite-netFx46-static-binary-Win32-2015-1.0.105.0.zip + sqlite-netFx46-static-binary-Win32-2015-1.0.105.2.zip
    - (3.68 MiB) + (3.70 MiB)
    This binary package contains all the binaries for the x86 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2015 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x86 is statically linked. The .NET Framework 4.6 is required.
    - (sha1: 71252613424f0b89eeea8b6c2562ed2d1ebebece) + (sha1: 665516bf95b60e393b41eeb8bf8d7727c8f26a7c)
    @@ -2111,41 +2111,41 @@
      - sqlite-netFx46-static-binary-bundle-x64-2015-1.0.105.0.zip + sqlite-netFx46-static-binary-bundle-x64-2015-1.0.105.2.zip
    - (3.46 MiB) + (3.48 MiB)
    This binary package features the mixed-mode assembly and contains all - the binaries for the x64 version of the System.Data.SQLite 1.0.105.0 - (3.18.0) package. The Visual C++ 2015 Update 3 runtime for x64 is + the binaries for the x64 version of the System.Data.SQLite 1.0.105.2 + (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 is statically linked. The .NET Framework 4.6 is required.
    - (sha1: 9163268eaeda161c3c53d53424046c13891c3f61) + (sha1: b8a3de1b9623663d1a82c2467ccc4d2a0d984099)
      - sqlite-netFx46-static-binary-x64-2015-1.0.105.0.zip + sqlite-netFx46-static-binary-x64-2015-1.0.105.2.zip
    - (3.77 MiB) + (3.78 MiB)
    This binary package contains all the binaries for the x64 version of the - System.Data.SQLite 1.0.105.0 (3.18.0) package. The Visual C++ 2015 + System.Data.SQLite 1.0.105.2 (3.19.3) package. The Visual C++ 2015 Update 3 runtime for x64 is statically linked. The .NET Framework 4.6 is required.
    - (sha1: e9022720bc2db1189026f6d10e613c4b397ce135) + (sha1: c93f9db87245e1a37587f6043d1ec3f466b9d07f)
    @@ -2155,59 +2155,59 @@
      - sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.105.0.zip + sqlite-netFx35-binary-PocketPC-ARM-2008-1.0.105.2.zip
    (1.35 MiB)
    This binary package contains all the binaries for the PocketPC version - of the System.Data.SQLite 1.0.105.0 (3.18.0) package. The included native + of the System.Data.SQLite 1.0.105.2 (3.19.3) package. The included native binaries should work on all supported ARM versions of Windows CE prior to Windows Embedded Compact 2013. The .NET Compact Framework 3.5 is required.
    - (sha1: cb5ea54af63b11b0ead0daf38264d75db9443276) + (sha1: 4f1efd87249ea4665d033a55cb52f64f49fc194a)
      - sqlite-netFx39-binary-WinCE-ARM-2012-1.0.105.0.zip + sqlite-netFx39-binary-WinCE-ARM-2012-1.0.105.2.zip
    (1.50 MiB)
    This binary package contains all the binaries for the Windows Embedded - Compact 2013 (ARM) version of the System.Data.SQLite 1.0.105.0 (3.18.0) + Compact 2013 (ARM) version of the System.Data.SQLite 1.0.105.2 (3.19.3) package. The .NET Compact Framework 3.9 is required.
    - (sha1: c39c8af1c46250209bd08b111bfadc38b4028f1f) + (sha1: a1cb9ca1fc60e283e046f1970551a1dda9f4c1e0)
      - sqlite-netFx39-binary-WinCE-x86-2012-1.0.105.0.zip + sqlite-netFx39-binary-WinCE-x86-2012-1.0.105.2.zip
    - (1.54 MiB) + (1.55 MiB)
    This binary package contains all the binaries for the Windows Embedded - Compact 2013 (x86) version of the System.Data.SQLite 1.0.105.0 (3.18.0) + Compact 2013 (x86) version of the System.Data.SQLite 1.0.105.2 (3.19.3) package. The .NET Compact Framework 3.9 is required.
    - (sha1: 428601d4f2aaca911860fb31128065a2c651ebe2) + (sha1: 81a86753584035aea5869a14e5bb5336f2047827)
    @@ -2228,18 +2228,18 @@
      - System.Data.SQLite.1.0.105.0.nupkg + System.Data.SQLite.1.0.105.2.nupkg
    (0.00 MiB)
    This NuGet package includes all the binaries for both the x86 and x64 - versions of System.Data.SQLite 1.0.105.0 (3.18.0). The .NET Framework + versions of System.Data.SQLite 1.0.105.2 (3.19.3). The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 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.
    @@ -2253,48 +2253,48 @@ depend on the "System.Data.SQLite.Core", "System.Data.SQLite.Linq", and "System.Data.SQLite.EF6" packages.

    - (sha1: d61ec9cc9568136b7185df3153857da3d4d49f21) + (sha1: 369eaa95c54bd82fd1c44fbe9ddf27ceaa03c893)
      - System.Data.SQLite.Core.1.0.105.0.nupkg + System.Data.SQLite.Core.1.0.105.2.nupkg
    - (7.63 MiB) + (7.67 MiB)
    This NuGet package contains all the binaries for both the x86 and x64 - versions of System.Data.SQLite 1.0.105.0 (3.18.0), except those + versions of System.Data.SQLite 1.0.105.2 (3.19.3), except those needed to support LINQ and Entity Framework 6. The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 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.
    This package does not depend on any other package.
    - (sha1: cc475592d8b146eef99efd8485ce5b46dfb4deda) + (sha1: 9b707a420ee112f246309eef4ab48d77d61a69f6)
      - System.Data.SQLite.Core.MSIL.1.0.105.0.nupkg + System.Data.SQLite.Core.MSIL.1.0.105.2.nupkg
    (1.03 MiB)
    This NuGet package contains the managed binaries for System.Data.SQLite - 1.0.105.0. The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, + 1.0.105.2. The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 is required.
    This package does not depend on any other package.

    @@ -2303,64 +2303,64 @@ assembly "SQLite.Interop.dll" compiled for the processor architecture of the host process being present in a directory in the native library search path.

    - (sha1: 3cb4b3e894fce5b74523f68b2fb85f9037fc284f) + (sha1: 33dcea530a8a549ee4c774b0094a214f2685b7ec)
      - System.Data.SQLite.EF6.1.0.105.0.nupkg + System.Data.SQLite.EF6.1.0.105.2.nupkg
    (0.18 MiB)
    This NuGet package contains just the binaries to support Entity - Framework 6 using System.Data.SQLite 1.0.105.0 (3.18.0). The .NET + Framework 6 using System.Data.SQLite 1.0.105.2 (3.19.3). The .NET Framework 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 is required.
    This package depends on the "EntityFramework" package, version 6.0 or higher.
    - (sha1: 96abc72887e3aba66e8de62e63fe1c6b8eaba8b0) + (sha1: 6767891bea7915d70872298299491be6592142dd)
      - System.Data.SQLite.Linq.1.0.105.0.nupkg + System.Data.SQLite.Linq.1.0.105.2.nupkg
    (0.22 MiB)
    This NuGet package contains just the binaries to support LINQ using - System.Data.SQLite 1.0.105.0 (3.18.0). The .NET Framework 3.5 SP1, 4.0, + System.Data.SQLite 1.0.105.2 (3.19.3). The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 is required.
    This package does not depend on any other package.
    - (sha1: ead25acf9b51b4a9101cc034f0919767ac999e9d) + (sha1: 166af795a47676318cf40f274b5c7b4147184c0e)
      - System.Data.SQLite.MSIL.1.0.105.0.nupkg + System.Data.SQLite.MSIL.1.0.105.2.nupkg
    (0.00 MiB)
    This NuGet package contains the managed binaries for System.Data.SQLite - 1.0.105.0. The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, + 1.0.105.2. The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 is required.
    This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead. @@ -2378,59 +2378,59 @@ depend on the "System.Data.SQLite.Core.MSIL", "System.Data.SQLite.Linq", and "System.Data.SQLite.EF6" packages.

    - (sha1: 417b6981213485251c0a44323294f5332a2aa531) + (sha1: e4f61413ad74ddb5bd253986e688920bd2301f8c)
      - System.Data.SQLite.x86.1.0.105.0.nupkg + System.Data.SQLite.x86.1.0.105.2.nupkg
    - (3.83 MiB) + (3.85 MiB)
    This NuGet package contains all the binaries for the x86 version of - System.Data.SQLite 1.0.105.0 (3.18.0). The .NET Framework 3.5 SP1, + System.Data.SQLite 1.0.105.2 (3.19.3). The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 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.
    This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead.
    - (sha1: a8f9b426439da246b5802eb840d41af37159de34) + (sha1: c9e5cf463cffeae46c1efd40a6e75e53c278c257)
      - System.Data.SQLite.x64.1.0.105.0.nupkg + System.Data.SQLite.x64.1.0.105.2.nupkg
    - (4.35 MiB) + (4.38 MiB)
    This NuGet package contains all the binaries for the x64 version of - System.Data.SQLite 1.0.105.0 (3.18.0). The .NET Framework 3.5 SP1, + System.Data.SQLite 1.0.105.2 (3.19.3). The .NET Framework 3.5 SP1, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, or 4.6.2 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.
    This is a legacy package; if possible, please use either the "System.Data.SQLite" or "System.Data.SQLite.Core" package instead.
    - (sha1: f260a2ed366119f80811335f741ff60204d67232) + (sha1: 4973079c795c1a613b68de414ddd59689e17ab91)
    @@ -2450,11 +2450,11 @@ updates there since April of 2010.
    -

    Build Product Names

    +

    Build Product Names

    Beginning with System.Data.SQLite version 1.0.101.0 (3.12.2), the following templates will be used for the names of the build products: @@ -2558,11 +2558,11 @@ release candidate testing.

-

Canonical Source Code

+

Canonical Source Code

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 Index: www/news.wiki ================================================================== --- www/news.wiki +++ www/news.wiki @@ -29,11 +29,11 @@

  • However, any tickets opened for them will be deleted.
  • -

    Release Rackages

    +

    Release Packages

    • Release packages for non-current releases will be archived.
    • @@ -42,10 +42,25 @@

    Version History

    +

    + 1.0.105.2 - June 12, 2017 +

    +
      +
    • Updated to [https://www.sqlite.org/releaselog/3_19_3.html|SQLite 3.19.3].
    • +
    • Fix issues that prevented SQLiteBlob creation from succeeding for tables that did not have an integer primary key.
    • +
    +

    + 1.0.105.1 - May 15, 2017 +

    +
      +
    • Prevent culture settings from negatively impacting integer connection string defaults.
    • +
    • Make sure the "No_SQLiteConnectionNewParser" and "DefaultFlags_SQLiteConnection" setting values end up being cached.
    • +
    • Cache the XML file name and assembly directory used by the configuration subsystem.
    • +

    1.0.105.0 - April 9, 2017

    • Updated to [https://www.sqlite.org/releaselog/3_18_0.html|SQLite 3.18.0].
    • Index: www/support.wiki ================================================================== --- www/support.wiki +++ www/support.wiki @@ -29,11 +29,11 @@
    • However, any tickets opened for them will be deleted.
    -

    Release Rackages

    +

    Release Packages

    • Release packages for non-current releases will be archived.