Version History
+1.0.99.0 - October XX, 2015 (release scheduled)
+-
+
- Updated to SQLite 3.8.12. +
1.0.98.0 - August 19, 2015
- Updated to SQLite 3.8.11.1.
- Add full support for Visual Studio 2015 and the .NET Framework 4.6.
- Add support for creating custom SQL functions using delegates. Index: Doc/Extra/Provider/welcome.html ================================================================== --- Doc/Extra/Provider/welcome.html +++ Doc/Extra/Provider/welcome.html @@ -158,11 +158,11 @@
- FTS5_TOKENIZE_DOCUMENT - A document is being inserted into +** or removed from the FTS table. The tokenizer is being invoked to +** determine the set of tokens to add to (or delete from) the +** FTS index. +** +**
- FTS5_TOKENIZE_QUERY - A MATCH query is being executed +** against the FTS index. The tokenizer is being called to tokenize +** a bareword or quoted string specified as part of the query. +** +**
- (FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX) - Same as +** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is +** followed by a "*" character, indicating that the last token +** returned by the tokenizer will be treated as a token prefix. +** +**
- FTS5_TOKENIZE_AUX - The tokenizer is being invoked to +** satisfy an fts5_api.xTokenize() request made by an auxiliary +** function. Or an fts5_api.xColumnSize() request made by the same +** on a columnsize=0 database. +**
- By mapping all synonyms to a single token. In this case, the +** In the above example, this means that the tokenizer returns the +** same token for inputs "first" and "1st". Say that token is in +** fact "first", so that when the user inserts the document "I won +** 1st place" entries are added to the index for tokens "i", "won", +** "first" and "place". If the user then queries for '1st + place', +** the tokenizer substitutes "first" for "1st" and the query works +** as expected. +** +**
- By adding multiple synonyms for a single term to the FTS index.
+** In this case, when tokenizing query text, the tokenizer may
+** provide multiple synonyms for a single term within the document.
+** FTS5 then queries the index for each synonym individually. For
+** example, faced with the query:
+**
+**
+** ... MATCH 'first place' +** +** the tokenizer offers both "1st" and "first" as synonyms for the +** first token in the MATCH query and FTS5 effectively runs a query +** similar to: +** +**+** ... MATCH '(first OR 1st) place' +** +** except that, for the purposes of auxiliary functions, the query +** still appears to contain just two phrases - "(first OR 1st)" +** being treated as a single phrase. +** +** - By adding multiple synonyms for a single term to the FTS index. +** Using this method, when tokenizing document text, the tokenizer +** provides multiple synonyms for each token. So that when a +** document such as "I won first place" is tokenized, entries are +** added to the FTS index for "i", "won", "first", "1st" and +** "place". +** +** This way, even if the tokenizer does not provide synonyms +** when tokenizing query text (it should not - to do would be +** inefficient), it doesn't matter if the user queries for +** 'first + place' or '1st + place', as there are entires in the +** FTS index corresponding to both forms of the first token. +**
- Updated to SQLite 3.8.12. +
- Updated to SQLite 3.8.11.1. 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.98.0")] -[assembly: AssemblyFileVersion("1.0.98.0")] +[assembly: AssemblyVersion("1.0.99.0")] +[assembly: AssemblyFileVersion("1.0.99.0")] Index: test/app.config ================================================================== --- test/app.config +++ test/app.config @@ -1,8 +1,8 @@
- Updated to [https://www.sqlite.org/draft/releaselog/3_8_12.html|SQLite 3.8.12]. +
- Updated to [https://www.sqlite.org/releaselog/3_8_11_1.html|SQLite 3.8.11.1].
Distributing the Binaries (Compact Framework)
Both the System.Data.SQLite.DLL and SQLite.Interop.XXX.DLL files must be deployed on the Compact Framework. The XXX is the build number of - the System.Data.SQLite library (e.g. "098"). The + the System.Data.SQLite library (e.g. "099"). The SQLite.Interop.XXX.DLL file is a fully native assembly compiled for the ARM processor, and System.Data.SQLite is the fully-managed Compact Framework assembly.
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.1
+ 1.0.99.0
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.98.0")]
-[assembly: AssemblyFileVersion("1.0.98.0")]
+[assembly: AssemblyVersion("1.0.99.0")]
+[assembly: AssemblyFileVersion("1.0.99.0")]
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.98.0
+ 1.0.99.0
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
@@ -17,26 +17,26 @@
Value="2005"
PerformEnvironmentSet="true"
/>
2010
- 098
+ 099
1.0
- 1.0.98.0
- 1,0,98,0
+ 1.0.99.0
+ 1,0,99,0
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
Index: SQLite.Interop/props/SQLite.Interop.2012.props
==================================================================
--- SQLite.Interop/props/SQLite.Interop.2012.props
+++ SQLite.Interop/props/SQLite.Interop.2012.props
@@ -8,14 +8,14 @@
*
-->
2012
- 098
+ 099
1.0
- 1.0.98.0
- 1,0,98,0
+ 1.0.99.0
+ 1,0,99,0
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
Index: SQLite.Interop/props/SQLite.Interop.2013.props
==================================================================
--- SQLite.Interop/props/SQLite.Interop.2013.props
+++ SQLite.Interop/props/SQLite.Interop.2013.props
@@ -8,14 +8,14 @@
*
-->
2013
- 098
+ 099
1.0
- 1.0.98.0
- 1,0,98,0
+ 1.0.99.0
+ 1,0,99,0
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
Index: SQLite.Interop/props/SQLite.Interop.2015.props
==================================================================
--- SQLite.Interop/props/SQLite.Interop.2015.props
+++ SQLite.Interop/props/SQLite.Interop.2015.props
@@ -8,14 +8,14 @@
*
-->
2015
- 098
+ 099
1.0
- 1.0.98.0
- 1,0,98,0
+ 1.0.99.0
+ 1,0,99,0
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
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.8.11.1
- 3,8,11,1
+ 3.8.12.0
+ 3,8,12,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_FTS5=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=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"
>
=1300
-# if !defined(_WIN32_WCE)
-# include
-# pragma intrinsic(_byteswap_ushort)
-# pragma intrinsic(_byteswap_ulong)
-# else
-# include
+#if !defined(SQLITE_DISABLE_INTRINSIC)
+# if defined(_MSC_VER) && _MSC_VER>=1300
+# if !defined(_WIN32_WCE)
+# include
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# else
+# include
+# endif
# endif
#endif
/*
** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
@@ -10050,16 +10055,20 @@
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*);
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int);
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*);
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
+SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
@@ -10913,10 +10922,11 @@
#define sqlite3_mutex_held(X) ((void)(X),1)
#define sqlite3_mutex_notheld(X) ((void)(X),1)
#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
#define sqlite3MutexInit() SQLITE_OK
#define sqlite3MutexEnd()
+#define sqlite3MemoryBarrier()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X) X
#endif /* defined(SQLITE_MUTEX_OMIT) */
@@ -11333,22 +11343,24 @@
/*
** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF
** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There
** are assert() statements in the code to verify this.
*/
-#define SQLITE_FUNC_ENCMASK 0x003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
-#define SQLITE_FUNC_LIKE 0x004 /* Candidate for the LIKE optimization */
-#define SQLITE_FUNC_CASE 0x008 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM 0x010 /* Ephemeral. Delete with VDBE */
-#define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */
-#define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */
-#define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */
-#define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */
-#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
-#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
-#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
-#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
+#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
+#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
+#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */
+#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */
+#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
+#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
+#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
+#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
+#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
+#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
+#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
+#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
+#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
+ ** single query - might change over time */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
**
@@ -11359,10 +11371,16 @@
** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
+**
+** DFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
+** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions
+** and functions like sqlite_version() that can change, but not during
+** a single query.
**
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
** Used to create an aggregate function definition implemented by
** the C functions xStep and xFinal. The first four parameters
** are interpreted in the same way as the first 4 parameters to
@@ -11380,15 +11398,18 @@
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
+#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
{nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
pArg, 0, xFunc, 0, 0, #zName, 0, 0}
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
(void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
@@ -11428,10 +11449,11 @@
struct Module {
const sqlite3_module *pModule; /* Callback pointers */
const char *zName; /* Name passed to create_module() */
void *pAux; /* pAux passed to create_module() */
void (*xDestroy)(void *); /* Module destructor function */
+ Table *pEpoTab; /* Eponymous table for this module */
};
/*
** information about each column of an SQL table is held in an instance
** of this structure.
@@ -11473,10 +11495,11 @@
/*
** A sort order can be either ASC or DESC.
*/
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
+#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
/*
** Column affinity types.
**
** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
@@ -11579,13 +11602,12 @@
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
-#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
-#endif
+ /* ... also used as column name list in a VIEW */
int tnum; /* Root BTree page for this table */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
@@ -11598,11 +11620,11 @@
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nModuleArg; /* Number of arguments to the module */
- char **azModuleArg; /* Text of all module args. [0] is module name */
+ char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */
VTable *pVTable; /* List of VTable objects. */
#endif
Trigger *pTrigger; /* List of triggers stored in pSchema */
Schema *pSchema; /* Schema that contains this table */
Table *pNextZombie; /* Next on the Parse.pZombieTab list */
@@ -11819,10 +11841,11 @@
Index *pNext; /* The next index associated with the same table */
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
char **azColl; /* Array of collation sequence names for index */
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
+ ExprList *aColExpr; /* Column expressions */
int tnum; /* DB Page containing root of this index */
LogEst szIdxRow; /* Estimated average row size in bytes */
u16 nKeyCol; /* Number of columns forming the key */
u16 nColumn; /* Number of columns stored in the index */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
@@ -12068,13 +12091,14 @@
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
-#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
+#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
+#define EP_Alias 0x400000 /* Is an alias for a result set column */
/*
** Combinations of two or more EP_* flags
*/
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
@@ -12233,24 +12257,31 @@
Table *pTab; /* An SQL table corresponding to zName */
Select *pSelect; /* A SELECT statement used in place of a table name */
int addrFillSub; /* Address of subroutine to manifest a subquery */
int regReturn; /* Register holding return address of addrFillSub */
int regResult; /* Registers holding results of a co-routine */
- u8 jointype; /* Type of join between this able and the previous */
- unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
- unsigned isCorrelated :1; /* True if sub-query is correlated */
- unsigned viaCoroutine :1; /* Implemented as a co-routine */
- unsigned isRecursive :1; /* True for recursive reference in WITH */
+ struct {
+ u8 jointype; /* Type of join between this able and the previous */
+ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
+ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
+ unsigned isTabFunc :1; /* True if table-valued-function syntax */
+ unsigned isCorrelated :1; /* True if sub-query is correlated */
+ unsigned viaCoroutine :1; /* Implemented as a co-routine */
+ unsigned isRecursive :1; /* True for recursive reference in WITH */
+ } fg;
#ifndef SQLITE_OMIT_EXPLAIN
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
#endif
int iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
IdList *pUsing; /* The USING clause of a join */
Bitmask colUsed; /* Bit N (1<" clause */
- Index *pIndex; /* Index structure corresponding to zIndex, if any */
+ union {
+ char *zIndexedBy; /* Identifier from "INDEXED BY " clause */
+ ExprList *pFuncArg; /* Arguments to table-valued-function */
+ } u1;
+ Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
} a[1]; /* One entry for each identifier on the list */
};
/*
** Permitted values of the SrcList.a.jointype field
@@ -12332,10 +12363,11 @@
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */
+#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
@@ -12601,11 +12633,11 @@
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
int ckBase; /* Base register of data during check constraints */
- int iPartIdxTab; /* Table corresponding to a partial index */
+ int iSelfTab; /* Table of an index whose exprs are being coded */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
int nLabel; /* Number of labels used */
int *aLabel; /* Space to hold the labels */
struct yColCache {
@@ -12971,11 +13003,11 @@
With *pOuter; /* Containing WITH clause, or NULL */
struct Cte { /* For each CTE in the WITH clause.... */
char *zName; /* Name of this CTE */
ExprList *pCols; /* List of explicit column names, or NULL */
Select *pSelect; /* The definition of this CTE */
- const char *zErr; /* Error message for circular references */
+ const char *zCteErr; /* Error message for circular references */
} a[1];
};
#ifdef SQLITE_DEBUG
/*
@@ -13118,10 +13150,11 @@
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void);
SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void);
SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int);
SQLITE_PRIVATE int sqlite3MutexInit(void);
SQLITE_PRIVATE int sqlite3MutexEnd(void);
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void);
#endif
SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
SQLITE_PRIVATE void sqlite3StatusUp(int, int);
SQLITE_PRIVATE void sqlite3StatusDown(int, int);
@@ -13185,10 +13218,11 @@
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
@@ -13197,10 +13231,12 @@
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*);
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
@@ -13238,11 +13274,11 @@
SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
+SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
@@ -13268,10 +13304,11 @@
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
+SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
@@ -13298,10 +13335,11 @@
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
@@ -13313,13 +13351,14 @@
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
+SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
+#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
@@ -13487,11 +13526,11 @@
sqlite3PutVarint((A),(B)))
#define getVarint sqlite3GetVarint
#define putVarint sqlite3PutVarint
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
@@ -13559,10 +13598,11 @@
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
+SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -13667,10 +13707,12 @@
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
@@ -16546,18 +16588,18 @@
** external linkage.
*/
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
- FUNCTION(julianday, -1, 0, 0, juliandayFunc ),
- FUNCTION(date, -1, 0, 0, dateFunc ),
- FUNCTION(time, -1, 0, 0, timeFunc ),
- FUNCTION(datetime, -1, 0, 0, datetimeFunc ),
- FUNCTION(strftime, -1, 0, 0, strftimeFunc ),
- FUNCTION(current_time, 0, 0, 0, ctimeFunc ),
- FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
- FUNCTION(current_date, 0, 0, 0, cdateFunc ),
+ DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
+ DFUNCTION(date, -1, 0, 0, dateFunc ),
+ DFUNCTION(time, -1, 0, 0, timeFunc ),
+ DFUNCTION(datetime, -1, 0, 0, datetimeFunc ),
+ DFUNCTION(strftime, -1, 0, 0, strftimeFunc ),
+ DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
+ DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
+ DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
#else
STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc),
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
#endif
@@ -19273,10 +19315,11 @@
pTo->xMutexEnter = pFrom->xMutexEnter;
pTo->xMutexTry = pFrom->xMutexTry;
pTo->xMutexLeave = pFrom->xMutexLeave;
pTo->xMutexHeld = pFrom->xMutexHeld;
pTo->xMutexNotheld = pFrom->xMutexNotheld;
+ sqlite3MemoryBarrier();
pTo->xMutexAlloc = pFrom->xMutexAlloc;
}
rc = sqlite3GlobalConfig.mutex.xMutexInit();
#ifdef SQLITE_DEBUG
@@ -19679,10 +19722,21 @@
}
static int pthreadMutexNotheld(sqlite3_mutex *p){
return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
}
#endif
+
+/*
+** Try to provide a memory barrier operation, needed for initialization only.
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__)
+ __sync_synchronize();
+#endif
+}
/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void){ return SQLITE_OK; }
@@ -20341,10 +20395,23 @@
static int winMutexNotheld(sqlite3_mutex *p){
DWORD tid = GetCurrentThreadId();
return winMutexNotheld2(p, tid);
}
#endif
+
+/*
+** Try to provide a memory barrier operation, needed for initialization only.
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__)
+ __sync_synchronize();
+#else
+ MemoryBarrier();
+#endif
+}
/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
@@ -20695,20 +20762,11 @@
/*
** State information local to the memory allocation subsystem.
*/
static SQLITE_WSD struct Mem0Global {
sqlite3_mutex *mutex; /* Mutex to serialize access */
-
- /*
- ** The alarm callback and its arguments. The mem0.mutex lock will
- ** be held while the callback is running. Recursive calls into
- ** the memory subsystem are allowed, but no new callbacks will be
- ** issued.
- */
- sqlite3_int64 alarmThreshold;
- void (*alarmCallback)(void*, sqlite3_int64,int);
- void *alarmArg;
+ sqlite3_int64 alarmThreshold; /* The soft heap limit */
/*
** Pointers to the end of sqlite3GlobalConfig.pScratch memory
** (so that a range test can be used to determine if an allocation
** being freed came from pScratch) and a pointer to the list of
@@ -20721,11 +20779,11 @@
/*
** True if heap is nearly "full" where "full" is defined by the
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
+} mem0 = { 0, 0, 0, 0, 0, 0 };
#define mem0 GLOBAL(struct Mem0Global, mem0)
/*
** Return the memory allocator mutex. sqlite3_status() needs it.
@@ -20733,78 +20791,86 @@
SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
return mem0.mutex;
}
/*
-** This routine runs when the memory allocator sees that the
-** total memory allocation is about to exceed the soft heap
-** limit.
+** Return the amount of memory currently in use.
*/
-static void softHeapLimitEnforcer(
- void *NotUsed,
- sqlite3_int64 NotUsed2,
- int allocSize
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_release_memory(allocSize);
+static sqlite3_int64 memInUse(void){
+ assert( sqlite3_mutex_held(mem0.mutex) );
+ return sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
}
/*
-** Change the alarm callback
+** Called when the soft heap limit is exceeded for an allocation
+** of nBytes.
*/
-static int sqlite3MemoryAlarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- sqlite3_int64 nUsed;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+static void sqlite3HeapLimitExceeded(int nByte){
+ sqlite3_int64 excess = memInUse() + nByte - mem0.alarmThreshold;
+ sqlite3_mutex_leave(mem0.mutex);
+ sqlite3_release_memory((int)(excess & 0x7fffffff));
sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
- mem0.alarmThreshold = iThreshold;
- nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
- sqlite3_mutex_leave(mem0.mutex);
- return SQLITE_OK;
+}
+#else
+# define sqlite3HeapLimitExceeded(X) /* no-op */
+#endif
+
+/*
+** Check to see if increasing the total memory usage by nNew bytes
+** will exceed the soft heap limit.
+**
+** If the soft heap limit is exceeded, set the mem0.nearlyFull flag
+** and invoke sqlite3HeapLimitExceeded() to try to free up some
+** memory.
+*/
+static void sqlite3CheckSoftHeapLimit(int nNew){
+ assert( sqlite3_mutex_held(mem0.mutex) );
+ if( mem0.alarmThreshold>0 ){
+ if( mem0.alarmThreshold-nNew >= memInUse() ){
+ mem0.nearlyFull = 1;
+ sqlite3HeapLimitExceeded(nNew);
+ }else{
+ mem0.nearlyFull = 0;
+ }
+ }
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3MemoryAlarm.
+** Deprecated external interface. First deprecated 2007-11-05. Changed
+** into a no-op on 2015-09-02.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
- return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
+ return SQLITE_OK;
}
#endif
/*
** Set the soft heap-size limit for the library. Passing a zero or
** negative value indicates no limit.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
- sqlite3_int64 excess;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return -1;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
- sqlite3_mutex_leave(mem0.mutex);
- if( n<0 ) return priorLimit;
if( n>0 ){
- sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
- }else{
- sqlite3MemoryAlarm(0, 0, 0);
+ mem0.alarmThreshold = n;
+ sqlite3CheckSoftHeapLimit(0);
+ }else if( n==0 ){
+ mem0.alarmThreshold = 0;
+ mem0.nearlyFull = 0;
}
- excess = sqlite3_memory_used() - n;
- if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
+ sqlite3_mutex_leave(mem0.mutex);
return priorLimit;
}
SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
@@ -20891,29 +20957,10 @@
sqlite3_int64 res, mx;
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
return mx;
}
-/*
-** Trigger the alarm
-*/
-static void sqlite3MallocAlarm(int nByte){
- void (*xCallback)(void*,sqlite3_int64,int);
- sqlite3_int64 nowUsed;
- void *pArg;
- if( mem0.alarmCallback==0 ) return;
- xCallback = mem0.alarmCallback;
- nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- pArg = mem0.alarmArg;
- mem0.alarmCallback = 0;
- sqlite3_mutex_leave(mem0.mutex);
- xCallback(pArg, nowUsed, nByte);
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
-}
-
/*
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
*/
static int mallocWithAlarm(int n, void **pp){
@@ -20920,23 +20967,15 @@
int nFull;
void *p;
assert( sqlite3_mutex_held(mem0.mutex) );
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
- if( mem0.alarmCallback!=0 ){
- sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- if( nUsed >= mem0.alarmThreshold - nFull ){
- mem0.nearlyFull = 1;
- sqlite3MallocAlarm(nFull);
- }else{
- mem0.nearlyFull = 0;
- }
- }
+ sqlite3CheckSoftHeapLimit(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( p==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nFull);
+ if( p==0 && mem0.alarmThreshold ){
+ sqlite3HeapLimitExceeded(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
}
#endif
if( p ){
nFull = sqlite3MallocSize(p);
@@ -21106,23 +21145,24 @@
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
- if( db==0 ){
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
- return sqlite3MallocSize(p);
- }else{
- assert( sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db, p) ){
- return db->lookaside.sz;
+ if( db==0 || !isLookaside(db,p) ){
+#if SQLITE_DEBUG
+ if( db==0 ){
+ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
- return sqlite3GlobalConfig.m.xSize(p);
}
+#endif
+ return sqlite3GlobalConfig.m.xSize(p);
+ }else{
+ assert( sqlite3_mutex_held(db->mutex) );
+ return db->lookaside.sz;
}
}
SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
@@ -21214,19 +21254,18 @@
pNew = pOld;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
- mem0.alarmThreshold-nDiff ){
- sqlite3MallocAlarm(nDiff);
- }
+ sqlite3CheckSoftHeapLimit(nDiff);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- if( pNew==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm((int)nBytes);
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ if( pNew==0 && mem0.alarmThreshold ){
+ sqlite3HeapLimitExceeded((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
+#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
sqlite3_mutex_leave(mem0.mutex);
@@ -21933,25 +21972,20 @@
break;
}
if( realvalue>0.0 ){
LONGDOUBLE_TYPE scale = 1.0;
while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
- while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
- while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
+ while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
realvalue /= scale;
while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
if( exp>350 ){
- if( prefix=='-' ){
- bufpt = "-Inf";
- }else if( prefix=='+' ){
- bufpt = "+Inf";
- }else{
- bufpt = "Inf";
- }
- length = sqlite3Strlen30(bufpt);
+ bufpt = buf;
+ buf[0] = prefix;
+ memcpy(buf+(prefix!=0),"Inf",4);
+ length = 3+(prefix!=0);
break;
}
}
bufpt = buf;
/*
@@ -22096,27 +22130,28 @@
break;
case etSTRING:
case etDYNSTRING:
if( bArgList ){
bufpt = getTextArg(pArgList);
+ xtype = etSTRING;
}else{
bufpt = va_arg(ap,char*);
}
if( bufpt==0 ){
bufpt = "";
- }else if( xtype==etDYNSTRING && !bArgList ){
+ }else if( xtype==etDYNSTRING ){
zExtra = bufpt;
}
if( precision>=0 ){
for(length=0; lengthetBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
@@ -22527,11 +22562,12 @@
}
#endif
/*
-** variable-argument wrapper around sqlite3VXPrintf().
+** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
+** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
*/
SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
sqlite3VXPrintf(p, bFlags, zFormat, ap);
@@ -22625,94 +22661,104 @@
/*
** Generate a human-readable description of a the Select object.
*/
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
int n = 0;
- pView = sqlite3TreeViewPush(pView, moreToFollow);
- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
- ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
- );
- if( p->pSrc && p->pSrc->nSrc ) n++;
- if( p->pWhere ) n++;
- if( p->pGroupBy ) n++;
- if( p->pHaving ) n++;
- if( p->pOrderBy ) n++;
- if( p->pLimit ) n++;
- if( p->pOffset ) n++;
- if( p->pPrior ) n++;
- sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
- if( p->pSrc && p->pSrc->nSrc ){
- int i;
- pView = sqlite3TreeViewPush(pView, (n--)>0);
- sqlite3TreeViewLine(pView, "FROM");
- for(i=0; ipSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- StrAccum x;
- char zLine[100];
- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
- if( pItem->zDatabase ){
- sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
- }else if( pItem->zName ){
- sqlite3XPrintf(&x, 0, " %s", pItem->zName);
- }
- if( pItem->pTab ){
- sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
- }
- if( pItem->zAlias ){
- sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
- }
- if( pItem->jointype & JT_LEFT ){
- sqlite3XPrintf(&x, 0, " LEFT-JOIN");
- }
- sqlite3StrAccumFinish(&x);
- sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1);
- if( pItem->pSelect ){
- sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
- }
- sqlite3TreeViewPop(pView);
- }
- sqlite3TreeViewPop(pView);
- }
- if( p->pWhere ){
- sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pWhere, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pGroupBy ){
- sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
- }
- if( p->pHaving ){
- sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pHaving, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pOrderBy ){
- sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
- }
- if( p->pLimit ){
- sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pLimit, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pOffset ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pOffset, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pPrior ){
- const char *zOp = "UNION";
- switch( p->op ){
- case TK_ALL: zOp = "UNION ALL"; break;
- case TK_INTERSECT: zOp = "INTERSECT"; break;
- case TK_EXCEPT: zOp = "EXCEPT"; break;
- }
- sqlite3TreeViewItem(pView, zOp, (n--)>0);
- sqlite3TreeViewSelect(pView, p->pPrior, 0);
- sqlite3TreeViewPop(pView);
- }
+ int cnt = 0;
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ do{
+ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
+ ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
+ );
+ if( cnt++ ) sqlite3TreeViewPop(pView);
+ if( p->pPrior ){
+ n = 1000;
+ }else{
+ n = 0;
+ if( p->pSrc && p->pSrc->nSrc ) n++;
+ if( p->pWhere ) n++;
+ if( p->pGroupBy ) n++;
+ if( p->pHaving ) n++;
+ if( p->pOrderBy ) n++;
+ if( p->pLimit ) n++;
+ if( p->pOffset ) n++;
+ }
+ sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
+ if( p->pSrc && p->pSrc->nSrc ){
+ int i;
+ pView = sqlite3TreeViewPush(pView, (n--)>0);
+ sqlite3TreeViewLine(pView, "FROM");
+ for(i=0; ipSrc->nSrc; i++){
+ struct SrcList_item *pItem = &p->pSrc->a[i];
+ StrAccum x;
+ char zLine[100];
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
+ if( pItem->zDatabase ){
+ sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
+ }else if( pItem->zName ){
+ sqlite3XPrintf(&x, 0, " %s", pItem->zName);
+ }
+ if( pItem->pTab ){
+ sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
+ }
+ if( pItem->zAlias ){
+ sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
+ }
+ if( pItem->fg.jointype & JT_LEFT ){
+ sqlite3XPrintf(&x, 0, " LEFT-JOIN");
+ }
+ sqlite3StrAccumFinish(&x);
+ sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1);
+ if( pItem->pSelect ){
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+ }
+ if( pItem->fg.isTabFunc ){
+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+ }
+ sqlite3TreeViewPop(pView);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pWhere ){
+ sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pWhere, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pGroupBy ){
+ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
+ }
+ if( p->pHaving ){
+ sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pHaving, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pOrderBy ){
+ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+ }
+ if( p->pLimit ){
+ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pOffset ){
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pOffset, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pPrior ){
+ const char *zOp = "UNION";
+ switch( p->op ){
+ case TK_ALL: zOp = "UNION ALL"; break;
+ case TK_INTERSECT: zOp = "INTERSECT"; break;
+ case TK_EXCEPT: zOp = "EXCEPT"; break;
+ }
+ sqlite3TreeViewItem(pView, zOp, 1);
+ }
+ p = p->pPrior;
+ }while( p!=0 );
sqlite3TreeViewPop(pView);
}
/*
** Generate a human-readable explanation of an expression tree.
@@ -22783,15 +22829,10 @@
}
case TK_REGISTER: {
sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
break;
}
- case TK_AS: {
- sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
- sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
- break;
- }
case TK_ID: {
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
break;
}
#ifndef SQLITE_OMIT_CAST
@@ -22962,11 +23003,17 @@
if( pList==0 ){
sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
}else{
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; inExpr; i++){
+ int j = pList->a[i].u.x.iOrderByCol;
+ if( j ){
+ sqlite3TreeViewPush(pView, 0);
+ sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
+ }
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, inExpr-1);
+ if( j ) sqlite3TreeViewPop(pView);
}
}
sqlite3TreeViewPop(pView);
}
@@ -24977,15 +25024,12 @@
/*
** Return the number of bytes that will be needed to store the given
** 64-bit integer.
*/
SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
- int i = 0;
- do{
- i++;
- v >>= 7;
- }while( v!=0 && ALWAYS(i<9) );
+ int i;
+ for(i=1; (v >>= 7)!=0; i++){ assert( i<9 ); }
return i;
}
/*
@@ -24994,15 +25038,17 @@
SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
#if SQLITE_BYTEORDER==4321
u32 x;
memcpy(&x,p,4);
return x;
-#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(__GNUC__) && GCC_VERSION>=4003000
u32 x;
memcpy(&x,p,4);
return __builtin_bswap32(x);
-#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
u32 x;
memcpy(&x,p,4);
return _byteswap_ulong(x);
#else
testcase( p[0]&0x80 );
@@ -29103,11 +29149,10 @@
i64 newOffset;
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
assert( id->h>2 );
- cnt &= 0x1ffff;
do{
#if defined(USE_PREAD)
got = osPread(id->h, pBuf, cnt, offset);
SimulateIOError( got = -1 );
#elif defined(USE_PREAD64)
@@ -29320,20 +29365,20 @@
amt -= nCopy;
offset += nCopy;
}
}
#endif
-
- while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
+
+ while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){
amt -= wrote;
offset += wrote;
pBuf = &((char*)pBuf)[wrote];
}
SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 ));
- if( amt>0 ){
+ if( amt>wrote ){
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
/* lastErrno set by seekAndWrite */
return SQLITE_IOERR_WRITE;
}else{
storeLastErrno(pFile, 0); /* not a system error */
@@ -39798,11 +39843,11 @@
** A complete page cache is an instance of this structure.
*/
struct PCache {
PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
PgHdr *pSynced; /* Last synced page in dirty page list */
- int nRef; /* Number of referenced pages */
+ int nRefSum; /* Sum of ref counts over all pages */
int szCache; /* Configured cache size */
int szPage; /* Size of every page in this cache */
int szExtra; /* Size of extra space for each page */
u8 bPurgeable; /* True if pages are on backing store */
u8 eCreate; /* eCreate value for for xFetch() */
@@ -39963,11 +40008,11 @@
/*
** Change the page size for PCache object. The caller must ensure that there
** are no outstanding page references when this function is called.
*/
SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
- assert( pCache->nRef==0 && pCache->pDirty==0 );
+ assert( pCache->nRefSum==0 && pCache->pDirty==0 );
if( pCache->szPage ){
sqlite3_pcache *pNew;
pNew = sqlite3GlobalConfig.pcache2.xCreate(
szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
pCache->bPurgeable
@@ -40130,13 +40175,11 @@
pPgHdr = (PgHdr *)pPage->pExtra;
if( !pPgHdr->pPage ){
return pcacheFetchFinishWithInit(pCache, pgno, pPage);
}
- if( 0==pPgHdr->nRef ){
- pCache->nRef++;
- }
+ pCache->nRefSum++;
pPgHdr->nRef++;
return pPgHdr;
}
/*
@@ -40143,13 +40186,12 @@
** Decrement the reference count on a page. If the page is clean and the
** reference count drops to 0, then it is made eligible for recycling.
*/
SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
assert( p->nRef>0 );
- p->nRef--;
- if( p->nRef==0 ){
- p->pCache->nRef--;
+ p->pCache->nRefSum--;
+ if( (--p->nRef)==0 ){
if( p->flags&PGHDR_CLEAN ){
pcacheUnpin(p);
}else if( p->pDirtyPrev!=0 ){
/* Move the page to the head of the dirty list. */
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
@@ -40161,10 +40203,11 @@
** Increase the reference count of a supplied page by 1.
*/
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
assert(p->nRef>0);
p->nRef++;
+ p->pCache->nRefSum++;
}
/*
** Drop a page from the cache. There must be exactly one reference to the
** page. This function deletes that reference, so after it returns the
@@ -40173,11 +40216,11 @@
SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
assert( p->nRef==1 );
if( p->flags&PGHDR_DIRTY ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
}
- p->pCache->nRef--;
+ p->pCache->nRefSum--;
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
}
/*
** Make sure the page is marked as dirty. If it isn't dirty already,
@@ -40269,15 +40312,15 @@
if( ALWAYS(p->pgno>pgno) ){
assert( p->flags&PGHDR_DIRTY );
sqlite3PcacheMakeClean(p);
}
}
- if( pgno==0 && pCache->nRef ){
+ if( pgno==0 && pCache->nRefSum ){
sqlite3_pcache_page *pPage1;
pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because
- ** pCache->nRef>0 */
+ ** pCache->nRefSum>0 */
memset(pPage1->pBuf, 0, pCache->szPage);
pgno = 1;
}
}
sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
@@ -40379,14 +40422,17 @@
}
return pcacheSortDirtyList(pCache->pDirty);
}
/*
-** Return the total number of referenced pages held by the cache.
+** Return the total number of references to all pages held by the cache.
+**
+** This is not the total number of pages referenced, but the sum of the
+** reference count for all pages.
*/
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
- return pCache->nRef;
+ return pCache->nRefSum;
}
/*
** Return the number of references to the page supplied as an argument.
*/
@@ -40517,11 +40563,11 @@
**
** The third case is a chunk of heap memory (defaulting to 100 pages worth)
** that is allocated when the page cache is created. The size of the local
** bulk allocation can be adjusted using
**
-** sqlite3_config(SQLITE_CONFIG_PCACHE, 0, 0, N).
+** sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, N).
**
** If N is positive, then N pages worth of memory are allocated using a single
** sqlite3Malloc() call and that memory is used for the first N pages allocated.
** Or if N is negative, then -1024*N bytes of memory are allocated and used
** for as many pages as can be accomodated.
@@ -40538,10 +40584,28 @@
typedef struct PCache1 PCache1;
typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
typedef struct PGroup PGroup;
+
+/*
+** Each cache entry is represented by an instance of the following
+** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
+** PgHdr1.pCache->szPage bytes is allocated directly before this structure
+** in memory.
+*/
+struct PgHdr1 {
+ sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
+ unsigned int iKey; /* Key value (page number) */
+ u8 isPinned; /* Page in use, not on the LRU list */
+ u8 isBulkLocal; /* This page from bulk local storage */
+ u8 isAnchor; /* This is the PGroup.lru element */
+ PgHdr1 *pNext; /* Next in hash table chain */
+ PCache1 *pCache; /* Cache that currently owns this page */
+ PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
+ PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
+};
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure. A PGroup is an instance of
** the following object.
@@ -40567,11 +40631,11 @@
sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */
unsigned int nMaxPage; /* Sum of nMax for purgeable caches */
unsigned int nMinPage; /* Sum of nMin for purgeable caches */
unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */
unsigned int nCurrentPage; /* Number of purgeable pages allocated */
- PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
+ PgHdr1 lru; /* The beginning and end of the LRU list */
};
/* Each page cache is an instance of the following object. Every
** open database file (including each in-memory database and each
** temporary or transient database) has a single page cache which
@@ -40605,27 +40669,10 @@
PgHdr1 **apHash; /* Hash table for fast lookup by key */
PgHdr1 *pFree; /* List of unused pcache-local pages */
void *pBulk; /* Bulk memory used by pcache-local */
};
-/*
-** Each cache entry is represented by an instance of the following
-** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
-** PgHdr1.pCache->szPage bytes is allocated directly before this structure
-** in memory.
-*/
-struct PgHdr1 {
- sqlite3_pcache_page page;
- unsigned int iKey; /* Key value (page number) */
- u8 isPinned; /* Page in use, not on the LRU list */
- u8 isBulkLocal; /* This page from bulk local storage */
- PgHdr1 *pNext; /* Next in hash table chain */
- PCache1 *pCache; /* Cache that currently owns this page */
- PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
- PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
-};
-
/*
** Free slots in the allocator used to divide up the global page cache
** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism.
*/
struct PgFreeslot {
@@ -40681,10 +40728,11 @@
# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1
#endif
/******************************************************************************/
/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
+
/*
** This function is called during initialization if a static buffer is
** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
** verb to sqlite3_config(). Parameter pBuf points to an allocation large
@@ -40741,10 +40789,11 @@
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;
}
}
@@ -40844,11 +40893,11 @@
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
/*
** Allocate a new page object initially associated with cache pCache.
*/
-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
+static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
PgHdr1 *p = 0;
void *pPg;
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
@@ -40862,10 +40911,11 @@
** this mutex is not held. */
assert( pcache1.separateCache==0 );
assert( pCache->pGroup==&pcache1.grp );
pcache1LeaveMutex(pCache->pGroup);
#endif
+ if( benignMalloc ) sqlite3BeginBenignMalloc();
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
pPg = pcache1Alloc(pCache->szPage);
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
if( !pPg || !p ){
pcache1Free(pPg);
@@ -40874,17 +40924,19 @@
}
#else
pPg = pcache1Alloc(pCache->szAlloc);
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
+ if( benignMalloc ) sqlite3EndBenignMalloc();
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
if( pPg==0 ) return 0;
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
p->isBulkLocal = 0;
+ p->isAnchor = 0;
}
if( pCache->bPurgeable ){
pCache->pGroup->nCurrentPage++;
}
return p;
@@ -41007,26 +41059,20 @@
PCache1 *pCache;
assert( pPage!=0 );
assert( pPage->isPinned==0 );
pCache = pPage->pCache;
- assert( pPage->pLruNext || pPage==pCache->pGroup->pLruTail );
- assert( pPage->pLruPrev || pPage==pCache->pGroup->pLruHead );
+ assert( pPage->pLruNext );
+ assert( pPage->pLruPrev );
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
- if( pPage->pLruPrev ){
- pPage->pLruPrev->pLruNext = pPage->pLruNext;
- }else{
- pCache->pGroup->pLruHead = pPage->pLruNext;
- }
- if( pPage->pLruNext ){
- pPage->pLruNext->pLruPrev = pPage->pLruPrev;
- }else{
- pCache->pGroup->pLruTail = pPage->pLruPrev;
- }
+ pPage->pLruPrev->pLruNext = pPage->pLruNext;
+ pPage->pLruNext->pLruPrev = pPage->pLruPrev;
pPage->pLruNext = 0;
pPage->pLruPrev = 0;
pPage->isPinned = 1;
+ assert( pPage->isAnchor==0 );
+ assert( pCache->pGroup->lru.isAnchor==1 );
pCache->nRecyclable--;
return pPage;
}
@@ -41055,13 +41101,15 @@
** If there are currently more than nMaxPage pages allocated, try
** to recycle pages to reduce the number allocated to nMaxPage.
*/
static void pcache1EnforceMaxPage(PCache1 *pCache){
PGroup *pGroup = pCache->pGroup;
+ PgHdr1 *p;
assert( sqlite3_mutex_held(pGroup->mutex) );
- while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
- PgHdr1 *p = pGroup->pLruTail;
+ while( pGroup->nCurrentPage>pGroup->nMaxPage
+ && (p=pGroup->lru.pLruPrev)->isAnchor==0
+ ){
assert( p->pCache->pGroup==pGroup );
assert( p->isPinned==0 );
pcache1PinPage(p);
pcache1RemoveFromHash(p, 1);
}
@@ -41191,10 +41239,14 @@
pGroup = (PGroup*)&pCache[1];
pGroup->mxPinned = 10;
}else{
pGroup = &pcache1.grp;
}
+ if( pGroup->lru.isAnchor==0 ){
+ pGroup->lru.isAnchor = 1;
+ pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
+ }
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
@@ -41298,15 +41350,15 @@
if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
assert( pCache->nHash>0 && pCache->apHash );
/* Step 4. Try to recycle a page. */
if( pCache->bPurgeable
- && pGroup->pLruTail
+ && !pGroup->lru.pLruPrev->isAnchor
&& ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache))
){
PCache1 *pOther;
- pPage = pGroup->pLruTail;
+ pPage = pGroup->lru.pLruPrev;
assert( pPage->isPinned==0 );
pcache1RemoveFromHash(pPage, 0);
pcache1PinPage(pPage);
pOther = pPage->pCache;
if( pOther->szAlloc != pCache->szAlloc ){
@@ -41319,13 +41371,11 @@
/* Step 5. If a usable page buffer has still not been found,
** attempt to allocate a new one.
*/
if( !pPage ){
- if( createFlag==1 ){ sqlite3BeginBenignMalloc(); }
- pPage = pcache1AllocPage(pCache);
- if( createFlag==1 ){ sqlite3EndBenignMalloc(); }
+ pPage = pcache1AllocPage(pCache, createFlag==1);
}
if( pPage ){
unsigned int h = iKey % pCache->nHash;
pCache->nPage++;
@@ -41413,11 +41463,14 @@
/* Step 1: Search the hash table for an existing entry. */
pPage = pCache->apHash[iKey % pCache->nHash];
while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
- /* Step 2: Abort if no existing page is found and createFlag is 0 */
+ /* Step 2: If the page was found in the hash table, then return it.
+ ** If the page was not in the hash table and createFlag is 0, abort.
+ ** Otherwise (page not in hash and createFlag!=0) continue with
+ ** subsequent steps to try to create the page. */
if( pPage ){
if( !pPage->isPinned ){
return pcache1PinPage(pPage);
}else{
return pPage;
@@ -41490,25 +41543,20 @@
/* It is an error to call this function if the page is already
** part of the PGroup LRU list.
*/
assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
- assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
assert( pPage->isPinned==1 );
if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
pcache1RemoveFromHash(pPage, 1);
}else{
/* Add the page to the PGroup LRU list. */
- if( pGroup->pLruHead ){
- pGroup->pLruHead->pLruPrev = pPage;
- pPage->pLruNext = pGroup->pLruHead;
- pGroup->pLruHead = pPage;
- }else{
- pGroup->pLruTail = pPage;
- pGroup->pLruHead = pPage;
- }
+ PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
+ pPage->pLruPrev = &pGroup->lru;
+ (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
+ *ppFirst = pPage;
pCache->nRecyclable++;
pPage->isPinned = 0;
}
pcache1LeaveMutex(pCache->pGroup);
@@ -41642,11 +41690,14 @@
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
assert( sqlite3_mutex_notheld(pcache1.mutex) );
if( sqlite3GlobalConfig.nPage==0 ){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
- while( (nReq<0 || nFreeisAnchor==0
+ ){
nFree += pcache1MemSize(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
nFree += sqlite3MemSize(p);
#endif
assert( p->isPinned==0 );
@@ -41670,11 +41721,11 @@
int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */
int *pnRecyclable /* OUT: Total number of pages available for recycling */
){
PgHdr1 *p;
int nRecyclable = 0;
- for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
+ for(p=pcache1.grp.lru.pLruNext; !p->isAnchor; p=p->pLruNext){
assert( p->isPinned==0 );
nRecyclable++;
}
*pnCurrent = pcache1.grp.nCurrentPage;
*pnMax = (int)pcache1.grp.nMaxPage;
@@ -42984,11 +43035,11 @@
u8 changeCountDone; /* Set after incrementing the change-counter */
u8 setMaster; /* True if a m-j name has been written to jrnl */
u8 doNotSpill; /* Do not spill the cache when non-zero */
u8 subjInMemory; /* True to use in-memory sub-journals */
u8 bUseFetch; /* True to use xFetch() */
- u8 hasBeenUsed; /* True if any content previously read */
+ u8 hasHeldSharedLock; /* True if a shared lock has ever been held */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
Pgno dbFileSize; /* Number of pages in the database file */
Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
int errCode; /* One of several kinds of errors */
@@ -47434,14 +47485,14 @@
assert( (pPager->eLock==SHARED_LOCK)
|| (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
);
}
- if( !pPager->tempFile && pPager->hasBeenUsed ){
+ if( !pPager->tempFile && pPager->hasHeldSharedLock ){
/* The shared-lock has just been acquired then check to
** see if the database has been modified. If the database has changed,
- ** flush the cache. The pPager->hasBeenUsed flag prevents this from
+ ** flush the cache. The hasHeldSharedLock flag prevents this from
** occurring on the very first access to a file, in order to save a
** single unnecessary sqlite3OsRead() call at the start-up.
**
** Database changes are detected by looking at 15 bytes beginning
** at offset 24 into the file. The first 4 of these 16 bytes are
@@ -47507,10 +47558,11 @@
assert( !MEMDB );
pager_unlock(pPager);
assert( pPager->eState==PAGER_OPEN );
}else{
pPager->eState = PAGER_READER;
+ pPager->hasHeldSharedLock = 1;
}
return rc;
}
/*
@@ -47590,25 +47642,29 @@
/* It is acceptable to use a read-only (mmap) page for any page except
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
** flag was specified by the caller. And so long as the db is not a
** temporary or in-memory database. */
- const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
+ const int bMmapOk = (pgno>1 && USEFETCH(pPager)
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
#ifdef SQLITE_HAS_CODEC
&& pPager->xCodec==0
#endif
);
+ /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
+ ** allows the compiler optimizer to reuse the results of the "pgno>1"
+ ** test in the previous statement, and avoid testing pgno==0 in the
+ ** common case where pgno is large. */
+ if( pgno<=1 && pgno==0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
assert( pPager->eState>=PAGER_READER );
assert( assert_pager_state(pPager) );
assert( noContent==0 || bMmapOk==0 );
- if( pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
- pPager->hasBeenUsed = 1;
+ assert( pPager->hasHeldSharedLock==1 );
/* If the pager is in the error state, return an error immediately.
** Otherwise, request the page from the PCache layer. */
if( pPager->errCode!=SQLITE_OK ){
rc = pPager->errCode;
@@ -47759,11 +47815,11 @@
sqlite3_pcache_page *pPage;
assert( pPager!=0 );
assert( pgno!=0 );
assert( pPager->pPCache!=0 );
pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
- assert( pPage==0 || pPager->hasBeenUsed );
+ assert( pPage==0 || pPager->hasHeldSharedLock );
if( pPage==0 ) return 0;
return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
}
/*
@@ -48726,11 +48782,11 @@
return pPager->readOnly;
}
#ifdef SQLITE_DEBUG
/*
-** Return the number of references to the pager.
+** Return the sum of the reference counts for all pages held by pPager.
*/
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
return sqlite3PcacheRefCount(pPager->pPCache);
}
#endif
@@ -50038,10 +50094,11 @@
u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
u8 truncateOnCommit; /* True to truncate WAL file on commit */
u8 syncHeader; /* Fsync the WAL header if true */
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
WalIndexHdr hdr; /* Wal-index header for current transaction */
+ u32 minFrame; /* Ignore wal frames before this one */
const char *zWalName; /* Name of WAL file */
u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
u8 lockError; /* True if a locking error has occurred */
#endif
@@ -51906,16 +51963,31 @@
** copied into the database by a checkpointer. If either of these things
** happened, then reading the database with the current value of
** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
** instead.
**
- ** This does not guarantee that the copy of the wal-index header is up to
- ** date before proceeding. That would not be possible without somehow
- ** blocking writers. It only guarantees that a dangerous checkpoint or
- ** log-wrap (either of which would require an exclusive lock on
- ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
+ ** Before checking that the live wal-index header has not changed
+ ** since it was read, set Wal.minFrame to the first frame in the wal
+ ** file that has not yet been checkpointed. This client will not need
+ ** to read any frames earlier than minFrame from the wal file - they
+ ** can be safely read directly from the database file.
+ **
+ ** Because a ShmBarrier() call is made between taking the copy of
+ ** nBackfill and checking that the wal-header in shared-memory still
+ ** matches the one cached in pWal->hdr, it is guaranteed that the
+ ** checkpointer that set nBackfill was not working with a wal-index
+ ** header newer than that cached in pWal->hdr. If it were, that could
+ ** cause a problem. The checkpointer could omit to checkpoint
+ ** a version of page X that lies before pWal->minFrame (call that version
+ ** A) on the basis that there is a newer version (version B) of the same
+ ** page later in the wal file. But if version B happens to like past
+ ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
+ ** that it can read version A from the database file. However, since
+ ** we can guarantee that the checkpointer that set nBackfill could not
+ ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
*/
+ pWal->minFrame = pInfo->nBackfill+1;
walShmBarrier(pWal);
if( pInfo->aReadMark[mxI]!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
@@ -51982,10 +52054,11 @@
u32 *piRead /* OUT: Frame number (or zero) */
){
u32 iRead = 0; /* If !=0, WAL frame to return data from */
u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */
int iHash; /* Used to loop through N hash tables */
+ int iMinHash;
/* This routine is only be called from within a read transaction. */
assert( pWal->readLock>=0 || pWal->lockError );
/* If the "last page" field of the wal-index header snapshot is 0, then
@@ -52022,11 +52095,12 @@
**
** (iFrame<=iLast):
** This condition filters out entries that were added to the hash
** table after the current read-transaction had started.
*/
- for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
+ iMinHash = walFramePage(pWal->minFrame);
+ for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
volatile ht_slot *aHash; /* Pointer to hash table */
volatile u32 *aPgno; /* Pointer to array of page numbers */
u32 iZero; /* Frame number corresponding to aPgno[0] */
int iKey; /* Hash slot index */
int nCollide; /* Number of hash collisions remaining */
@@ -52037,11 +52111,11 @@
return rc;
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
u32 iFrame = aHash[iKey] + iZero;
- if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
@@ -52054,11 +52128,12 @@
** of the wal-index file content. Make sure the results agree with the
** result obtained using the hash indexes above. */
{
u32 iRead2 = 0;
u32 iTest;
- for(iTest=iLast; iTest>0; iTest--){
+ assert( pWal->minFrame>0 );
+ for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
if( walFramePgno(pWal, iTest)==pgno ){
iRead2 = iTest;
break;
}
}
@@ -53494,13 +53569,15 @@
** two-byte aligned address. get2bytea() is only used for accessing the
** cell addresses in a btree header.
*/
#if SQLITE_BYTEORDER==4321
# define get2byteAligned(x) (*(u16*)(x))
-#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && GCC_VERSION>=4008000
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
-#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
#else
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
#endif
@@ -62492,21 +62569,19 @@
IntegrityCk *pCheck,
const char *zFormat,
...
){
va_list ap;
- char zBuf[200];
if( !pCheck->mxErr ) return;
pCheck->mxErr--;
pCheck->nErr++;
va_start(ap, zFormat);
if( pCheck->errMsg.nChar ){
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
}
if( pCheck->zPfx ){
- sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
- sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
+ sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
pCheck->mallocFailed = 1;
@@ -65327,11 +65402,11 @@
/*
** The expression object indicated by the second argument is guaranteed
** to be a scalar SQL function. If
**
** * all function arguments are SQL literals,
-** * the SQLITE_FUNC_CONSTANT function flag is set, and
+** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
**
** then this routine attempts to invoke the SQL function. Assuming no
** error occurs, output parameter (*ppVal) is set to point to a value
** object containing the result before returning SQLITE_OK.
@@ -65368,11 +65443,11 @@
pList = p->x.pList;
if( pList ) nVal = pList->nExpr;
nName = sqlite3Strlen30(p->u.zToken);
pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
assert( pFunc );
- if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0
+ if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
){
return SQLITE_OK;
}
@@ -65962,11 +66037,11 @@
/*
** Return the SQL associated with a prepared statement
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
- return (p && p->isPrepareV2) ? p->zSql : 0;
+ return p ? p->zSql : 0;
}
/*
** Swap all content between two VDBE structures.
*/
@@ -66109,10 +66184,48 @@
}
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
}
+/* Generate code for an unconditional jump to instruction iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){
+ return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
+}
+
+/* Generate code to cause the string zStr to be loaded into
+** register iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
+ return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
+}
+
+/*
+** Generate code that initializes multiple registers to string or integer
+** constants. The registers begin with iDest and increase consecutively.
+** One register is initialized for each characgter in zTypes[]. For each
+** "s" character in zTypes[], the register is a string if the argument is
+** not NULL, or OP_Null if the value is a null pointer. For each "i" character
+** in zTypes[], the register is initialized to an integer.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
+ va_list ap;
+ int i;
+ char c;
+ va_start(ap, zTypes);
+ for(i=0; (c = zTypes[i])!=0; i++){
+ if( c=='s' ){
+ const char *z = va_arg(ap, const char*);
+ int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++);
+ if( z ) sqlite3VdbeChangeP4(p, addr, z, 0);
+ }else{
+ assert( c=='i' );
+ sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++);
+ }
+ }
+ va_end(ap);
+}
/*
** Add an opcode that includes the p4 value as a pointer.
*/
SQLITE_PRIVATE int sqlite3VdbeAddOp4(
@@ -66128,11 +66241,12 @@
sqlite3VdbeChangeP4(p, addr, zP4, p4type);
return addr;
}
/*
-** Add an opcode that includes the p4 value with a P4_INT64 type.
+** Add an opcode that includes the p4 value with a P4_INT64 or
+** P4_REAL type.
*/
SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
Vdbe *p, /* Add the opcode to this VM */
int op, /* The new opcode */
int p1, /* The P1 operand */
@@ -66213,11 +66327,12 @@
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = -1-x;
assert( v->magic==VDBE_MAGIC_INIT );
assert( jnLabel );
- if( ALWAYS(j>=0) && p->aLabel ){
+ assert( j>=0 );
+ if( p->aLabel ){
p->aLabel[j] = v->nOp;
}
p->iFixedOp = v->nOp - 1;
}
@@ -66357,21 +66472,25 @@
|| (hasCreateTable && hasInitCoroutine) );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
/*
-** Loop through the program looking for P2 values that are negative
-** on jump instructions. Each such value is a label. Resolve the
-** label by setting the P2 value to its correct non-zero value.
-**
-** This routine is called once after all opcodes have been inserted.
-**
-** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
-** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
-** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
-**
-** The Op.opflags field is set on all opcodes.
+** This routine is called after all opcodes have been inserted. It loops
+** through all the opcodes and fixes up some details.
+**
+** (1) For each jump instruction with a negative P2 value (a label)
+** resolve the P2 value to an actual address.
+**
+** (2) Compute the maximum number of arguments used by any SQL function
+** and store that value in *pMaxFuncArgs.
+**
+** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
+** indicate what the prepared statement actually does.
+**
+** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
+**
+** (5) Reclaim the memory allocated for storing labels.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
@@ -66480,50 +66599,48 @@
/*
** Add a whole list of operations to the operation stack. Return the
** address of the first operation added.
*/
SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
- int addr;
+ int addr, i;
+ VdbeOp *pOut;
+ assert( nOp>0 );
assert( p->magic==VDBE_MAGIC_INIT );
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
return 0;
}
addr = p->nOp;
- if( ALWAYS(nOp>0) ){
- int i;
- VdbeOpList const *pIn = aOp;
- for(i=0; ip2;
- VdbeOp *pOut = &p->aOp[i+addr];
- pOut->opcode = pIn->opcode;
- pOut->p1 = pIn->p1;
- if( p2<0 ){
- assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
- pOut->p2 = addr + ADDR(p2);
- }else{
- pOut->p2 = p2;
- }
- pOut->p3 = pIn->p3;
- pOut->p4type = P4_NOTUSED;
- pOut->p4.p = 0;
- pOut->p5 = 0;
+ pOut = &p->aOp[addr];
+ for(i=0; ip2;
+ pOut->opcode = aOp->opcode;
+ pOut->p1 = aOp->p1;
+ if( p2<0 ){
+ assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
+ pOut->p2 = addr + ADDR(p2);
+ }else{
+ pOut->p2 = p2;
+ }
+ pOut->p3 = aOp->p3;
+ pOut->p4type = P4_NOTUSED;
+ pOut->p4.p = 0;
+ pOut->p5 = 0;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- pOut->zComment = 0;
+ pOut->zComment = 0;
#endif
#ifdef SQLITE_VDBE_COVERAGE
- pOut->iSrcLine = iLineno+i;
+ pOut->iSrcLine = iLineno+i;
#else
- (void)iLineno;
+ (void)iLineno;
#endif
#ifdef SQLITE_DEBUG
- if( p->db->flags & SQLITE_VdbeAddopTrace ){
- sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
- }
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
+ }
#endif
- }
- p->nOp += nOp;
}
+ p->nOp += nOp;
return addr;
}
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
/*
@@ -66552,62 +66669,36 @@
}
#endif
/*
-** Change the value of the P1 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqlite3VdbeAddOpList but we want to make a
-** few minor changes to the program.
+** Change the value of the opcode, or P1, P2, P3, or P5 operands
+** for a specific instruction.
*/
+SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
+ sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p1 = val;
- }
-}
-
-/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
-*/
+ sqlite3VdbeGetOp(p,addr)->p1 = val;
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p2 = val;
- }
-}
-
-/*
-** Change the value of the P3 operand for a specific instruction.
-*/
+ sqlite3VdbeGetOp(p,addr)->p2 = val;
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p3 = val;
- }
-}
-
-/*
-** Change the value of the P5 operand for the most recently
-** added operation.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
- assert( p!=0 );
- if( p->aOp ){
- assert( p->nOp>0 );
- p->aOp[p->nOp-1].p5 = val;
- }
+ sqlite3VdbeGetOp(p,addr)->p3 = val;
+}
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
+ sqlite3VdbeGetOp(p,-1)->p5 = p5;
}
/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- sqlite3VdbeChangeP2(p, addr, p->nOp);
p->pParse->iFixedOp = p->nOp - 1;
+ sqlite3VdbeChangeP2(p, addr, p->nOp);
}
/*
** If the input FuncDef structure is ephemeral, then free it. If
@@ -66988,12 +67079,13 @@
int n = sqlite3Strlen30(zColl);
if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
zColl = "B";
n = 1;
}
- if( i+n>nTemp-6 ){
+ if( i+n>nTemp-7 ){
memcpy(&zTemp[i],",...",4);
+ i += 4;
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
@@ -70754,11 +70846,11 @@
** be one of the values in the first assert() below. Variable p->rc
** contains the value that would be returned if sqlite3_finalize()
** were called on statement p.
*/
assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
- || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
+ || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
);
assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
/* If this statement was prepared using sqlite3_prepare_v2(), and an
** error has occurred, then return the error code in p->rc to the
@@ -70839,11 +70931,11 @@
** parameter) of the sqlite3_create_function() and
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
- assert( p && p->pFunc );
+ assert( p && p->pOut );
return p->pOut->db;
}
/*
** Return the current time for a statement. If the current time
@@ -72657,11 +72749,11 @@
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
goto no_mem;
}
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+ assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK;
p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
@@ -75094,16 +75186,16 @@
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
db->autoCommit = (u8)desiredAutoCommit;
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
- db->autoCommit = (u8)(1-desiredAutoCommit);
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
+ }
+ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ db->autoCommit = (u8)(1-desiredAutoCommit);
+ p->rc = rc = SQLITE_BUSY;
+ goto vdbe_return;
}
assert( db->nStatement==0 );
sqlite3CloseSavepoints(db);
if( p->rc==SQLITE_OK ){
rc = SQLITE_DONE;
@@ -75171,13 +75263,15 @@
}
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
- if( rc==SQLITE_BUSY ){
+ testcase( rc==SQLITE_BUSY_SNAPSHOT );
+ testcase( rc==SQLITE_BUSY_RECOVERY );
+ if( (rc&0xff)==SQLITE_BUSY ){
p->pc = (int)(pOp - aOp);
- p->rc = rc = SQLITE_BUSY;
+ p->rc = rc;
goto vdbe_return;
}
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
@@ -79009,11 +79103,12 @@
}
#endif
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
for(j=0; jnKeyCol; j++){
- if( pIdx->aiColumn[j]==iCol ){
+ /* FIXME: Be smarter about indexes that use expressions */
+ if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==(-2) ){
zFault = "indexed";
}
}
}
if( zFault ){
@@ -82590,10 +82685,15 @@
if( ALWAYS(pSrc) ){
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
return WRC_Abort;
}
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
+ }
}
}
return WRC_Continue;
}
@@ -82687,34 +82787,10 @@
/*
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.
**
-** If the result set column is a simple column reference, then this routine
-** makes an exact copy. But for any other kind of expression, this
-** routine make a copy of the result set column as the argument to the
-** TK_AS operator. The TK_AS operator causes the expression to be
-** evaluated just once and then reused for each alias.
-**
-** The reason for suppressing the TK_AS term when the expression is a simple
-** column reference is so that the column reference will be recognized as
-** usable by indices within the WHERE clause processing logic.
-**
-** The TK_AS operator is inhibited if zType[0]=='G'. This means
-** that in a GROUP BY clause, the expression is evaluated twice. Hence:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
-**
-** Is equivalent to:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
-**
-** The result of random()%5 in the GROUP BY clause is probably different
-** from the result in the result-set. On the other hand Standard SQL does
-** not allow the GROUP BY clause to contain references to result-set columns.
-** So this should never come up in well-formed queries.
-**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved. For example:
**
** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
@@ -82744,23 +82820,15 @@
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
- if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
- incrAggFunctionDepth(pDup, nSubquery);
- pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
- if( pDup==0 ) return;
- ExprSetProperty(pDup, EP_Skip);
- if( pEList->a[iCol].u.x.iAlias==0 ){
- pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias);
- }
- pDup->iTable = pEList->a[iCol].u.x.iAlias;
- }
+ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
+ ExprSetProperty(pDup, EP_Alias);
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
** allowing it to be repopulated by the memcpy() on the following line.
** The pExpr->u.zToken might point into memory that will be freed by the
@@ -82948,11 +83016,11 @@
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
*/
if( cnt==1 ){
- if( pItem->jointype & JT_NATURAL ) continue;
+ if( pItem->fg.jointype & JT_NATURAL ) continue;
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
}
cnt++;
pMatch = pItem;
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
@@ -82963,12 +83031,12 @@
}
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
pExpr->pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */
- assert( (pMatch->jointype & JT_RIGHT)==0 );
- if( (pMatch->jointype & JT_LEFT)!=0 ){
+ assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
+ if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
pSchema = pExpr->pTab->pSchema;
}
} /* if( pSrcList ) */
@@ -83049,13 +83117,13 @@
** forms the result set entry ("a+b" in the example) and return immediately.
** Note that the expression in the result set should have already been
** resolved by the time the WHERE clause is resolved.
**
** The ability to use an output result-set column in the WHERE, GROUP BY,
- ** or HAVING clauses, or as part of a larger expression in the ORDRE BY
+ ** or HAVING clauses, or as part of a larger expression in the ORDER BY
** clause is not standard SQL. This is a (goofy) SQLite extension, that
- ** is supported for backwards compatibility only. TO DO: Issue a warning
+ ** is supported for backwards compatibility only. Hence, we issue a warning
** on sqlite3_log() whenever the capability is used.
*/
if( (pEList = pNC->pEList)!=0
&& zTab==0
&& cnt==0
@@ -83148,11 +83216,11 @@
pExpr->pRight = 0;
pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
- if( pExpr->op!=TK_AS ){
+ if( !ExprHasProperty(pExpr, EP_Alias) ){
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
}
/* Increment the nRef value on all name contexts from TopNC up to
** the point where the name matched. */
for(;;){
@@ -83189,40 +83257,29 @@
}
return p;
}
/*
-** Report an error that an expression is not valid for a partial index WHERE
-** clause.
-*/
-static void notValidPartIdxWhere(
- Parse *pParse, /* Leave error message here */
- NameContext *pNC, /* The name context */
- const char *zMsg /* Type of error */
-){
- if( (pNC->ncFlags & NC_PartIdx)!=0 ){
- sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
- zMsg);
- }
-}
-
-#ifndef SQLITE_OMIT_CHECK
-/*
-** Report an error that an expression is not valid for a CHECK constraint.
-*/
-static void notValidCheckConstraint(
- Parse *pParse, /* Leave error message here */
- NameContext *pNC, /* The name context */
- const char *zMsg /* Type of error */
-){
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
- }
-}
-#else
-# define notValidCheckConstraint(P,N,M)
-#endif
+** Report an error that an expression is not valid for some set of
+** pNC->ncFlags values determined by validMask.
+*/
+static void notValid(
+ Parse *pParse, /* Leave error message here */
+ NameContext *pNC, /* The name context */
+ const char *zMsg, /* Type of error */
+ int validMask /* Set of contexts for which prohibited */
+){
+ assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
+ if( (pNC->ncFlags & validMask)!=0 ){
+ const char *zIn = "partial index WHERE clauses";
+ if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
+#ifndef SQLITE_OMIT_CHECK
+ else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
+#endif
+ sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
+ }
+}
/*
** Expression p should encode a floating point value between 1.0 and 0.0.
** Return 1024 times this value. Or return -1 if p is not a floating point
** value between 1.0 and 0.0.
@@ -83303,10 +83360,12 @@
const char *zTable;
const char *zDb;
Expr *pRight;
/* if( pSrcList==0 ) break; */
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
zTable = pExpr->pLeft->u.zToken;
zColumn = pRight->u.zToken;
@@ -83332,11 +83391,11 @@
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- notValidPartIdxWhere(pParse, pNC, "functions");
+ notValid(pParse, pNC, "functions", NC_PartIdx);
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
@@ -83380,13 +83439,22 @@
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
#endif
- if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
+ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
+ /* For the purposes of the EP_ConstFunc flag, date and time
+ ** functions and other functions that change slowly are considered
+ ** constant because they are constant for the duration of one query */
ExprSetProperty(pExpr,EP_ConstFunc);
}
+ if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
+ /* Date/time functions that use 'now', and other functions like
+ ** sqlite_version() that might change over time cannot be used
+ ** in an index. */
+ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);
+ }
}
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
is_agg = 0;
@@ -83428,23 +83496,21 @@
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
- notValidCheckConstraint(pParse, pNC, "subqueries");
- notValidPartIdxWhere(pParse, pNC, "subqueries");
+ notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
}
break;
}
case TK_VARIABLE: {
- notValidCheckConstraint(pParse, pNC, "parameters");
- notValidPartIdxWhere(pParse, pNC, "parameters");
+ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
@@ -83784,11 +83850,10 @@
NameContext *pOuterNC; /* Context that contains this SELECT */
NameContext sNC; /* Name context of this SELECT */
int isCompound; /* True if p is a compound select */
int nCompound; /* Number of compound terms processed so far */
Parse *pParse; /* Parsing context */
- ExprList *pEList; /* Result set expression list */
int i; /* Loop counter */
ExprList *pGroupBy; /* The GROUP BY clause */
Select *pLeftmost; /* Left-most of SELECT of a compound */
sqlite3 *db; /* Database connection */
@@ -83857,21 +83922,21 @@
/* Count the total number of references to pOuterNC and all of its
** parent contexts. After resolving references to expressions in
** pItem->pSelect, check if this value has changed. If so, then
** SELECT statement pItem->pSelect must be correlated. Set the
- ** pItem->isCorrelated flag if this is the case. */
+ ** pItem->fg.isCorrelated flag if this is the case. */
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
pParse->zAuthContext = zSavedContext;
if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
- assert( pItem->isCorrelated==0 && nRef<=0 );
- pItem->isCorrelated = (nRef!=0);
+ assert( pItem->fg.isCorrelated==0 && nRef<=0 );
+ pItem->fg.isCorrelated = (nRef!=0);
}
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
@@ -83879,18 +83944,11 @@
sNC.ncFlags = NC_AllowAgg;
sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
- pEList = p->pEList;
- assert( pEList!=0 );
- for(i=0; inExpr; i++){
- Expr *pX = pEList->a[i].pExpr;
- if( sqlite3ResolveExprNames(&sNC, pX) ){
- return WRC_Abort;
- }
- }
+ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
@@ -83918,10 +83976,20 @@
** re-evaluated for each reference to it.
*/
sNC.pEList = p->pEList;
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+
+ /* Resolve names in table-valued-function arguments */
+ for(i=0; ipSrc->nSrc; i++){
+ struct SrcList_item *pItem = &p->pSrc->a[i];
+ if( pItem->fg.isTabFunc
+ && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
+ }
+ }
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
@@ -84082,10 +84150,26 @@
}
pNC->ncFlags |= savedHasAgg;
return ExprHasProperty(pExpr, EP_Error);
}
+/*
+** Resolve all names for all expression in an expression list. This is
+** just like sqlite3ResolveExprNames() except that it works for an expression
+** list rather than a single expression.
+*/
+SQLITE_PRIVATE int sqlite3ResolveExprListNames(
+ NameContext *pNC, /* Namespace to resolve expressions in. */
+ ExprList *pList /* The expression list to be analyzed. */
+){
+ int i;
+ assert( pList!=0 );
+ for(i=0; inExpr; i++){
+ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
+ }
+ return WRC_Continue;
+}
/*
** Resolve all names in all expressions of a SELECT and in all
** decendents of the SELECT, including compounds off of p->pPrior,
** subqueries in expressions, and subqueries used as FROM clause
@@ -84125,19 +84209,18 @@
** Any errors cause an error message to be set in pParse.
*/
SQLITE_PRIVATE void sqlite3ResolveSelfReference(
Parse *pParse, /* Parsing context */
Table *pTab, /* The table being referenced */
- int type, /* NC_IsCheck or NC_PartIdx */
+ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
Expr *pExpr, /* Expression to resolve. May be NULL. */
ExprList *pList /* Expression list to resolve. May be NUL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
- int i; /* Loop counter */
- assert( type==NC_IsCheck || type==NC_PartIdx );
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = pTab->zName;
sSrc.a[0].pTab = pTab;
@@ -84144,17 +84227,11 @@
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = type;
if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
- if( pList ){
- for(i=0; inExpr; i++){
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
- return;
- }
- }
- }
+ if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
}
/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
@@ -84248,11 +84325,11 @@
s.n = sqlite3Strlen30(s.z);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}
/*
-** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
+** Skip over any TK_COLLATE operators and any unlikely()
** or likelihood() function at the root of an expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
@@ -84259,11 +84336,11 @@
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
- assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS );
+ assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
return pExpr;
}
@@ -84590,11 +84667,11 @@
** for this node and for the pToken argument is a single allocation
** obtained from sqlite3DbMalloc(). The calling function
** is responsible for making sure the node eventually gets freed.
**
** If dequote is true, then the token (if it exists) is dequoted.
-** If dequote is false, no dequoting is performance. The deQuote
+** If dequote is false, no dequoting is performed. The deQuote
** parameter is ignored if pToken is NULL or if the token does not
** appear to be quoted. If the quotes were of the form "..." (double-quotes)
** then the EP_DblQuoted flag is set on the expression node.
**
** Special case: If op==TK_INTEGER and pToken points to a string that
@@ -85191,20 +85268,22 @@
Table *pTab;
pNewItem->pSchema = pOldItem->pSchema;
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->jointype = pOldItem->jointype;
+ pNewItem->fg = pOldItem->fg;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
- pNewItem->isCorrelated = pOldItem->isCorrelated;
- pNewItem->viaCoroutine = pOldItem->viaCoroutine;
- pNewItem->isRecursive = pOldItem->isRecursive;
- pNewItem->zIndexedBy = sqlite3DbStrDup(db, pOldItem->zIndexedBy);
- pNewItem->notIndexed = pOldItem->notIndexed;
- pNewItem->pIndex = pOldItem->pIndex;
+ if( pNewItem->fg.isIndexedBy ){
+ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
+ }
+ pNewItem->pIBIndex = pOldItem->pIBIndex;
+ if( pNewItem->fg.isTabFunc ){
+ pNewItem->u1.pFuncArg =
+ sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
+ }
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
}
pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
@@ -85314,10 +85393,24 @@
/* Avoid leaking memory if malloc has failed. */
sqlite3ExprDelete(db, pExpr);
sqlite3ExprListDelete(db, pList);
return 0;
}
+
+/*
+** Set the sort order for the last element on the given ExprList.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
+ if( p==0 ) return;
+ assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
+ assert( p->nExpr>0 );
+ if( iSortOrder<0 ){
+ assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
+ return;
+ }
+ p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
+}
/*
** Set the ExprList.a[].zName element of the most recently added item
** on the expression list.
**
@@ -86286,11 +86379,11 @@
}
sqlite3ReleaseTempReg(pParse, regToFree);
}
if( regCkNull ){
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+ sqlite3VdbeGoto(v, destIfFalse);
}
sqlite3VdbeResolveLabel(v, labelOk);
sqlite3ReleaseTempReg(pParse, regCkNull);
}else{
@@ -86304,11 +86397,11 @@
sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
}else{
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
+ sqlite3VdbeGoto(v, destIfNull);
sqlite3VdbeJumpHere(v, addr1);
}
}
if( eType==IN_INDEX_ROWID ){
@@ -86354,11 +86447,11 @@
*/
j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+ sqlite3VdbeGoto(v, destIfFalse);
sqlite3VdbeJumpHere(v, j1);
}
}
}
sqlite3ReleaseTempReg(pParse, r1);
@@ -86572,10 +86665,32 @@
if( p->iReg==iReg ){
p->tempReg = 0;
}
}
}
+
+/* Generate code that will load into register regOut a value that is
+** appropriate for the iIdxCol-th column of index pIdx.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
+ Parse *pParse, /* The parsing context */
+ Index *pIdx, /* The index whose column is to be loaded */
+ int iTabCur, /* Cursor pointing to a table row */
+ int iIdxCol, /* The column of the index to be loaded */
+ int regOut /* Store the index column value in this register */
+){
+ i16 iTabCol = pIdx->aiColumn[iIdxCol];
+ if( iTabCol>=(-1) ){
+ sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
+ iTabCol, regOut);
+ return;
+ }
+ assert( pIdx->aColExpr );
+ assert( pIdx->aColExpr->nExpr>iIdxCol );
+ pParse->iSelfTab = iTabCur;
+ sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
+}
/*
** Generate code to extract the value of the iCol-th column of a table.
*/
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
@@ -86758,12 +86873,13 @@
if( pParse->ckBase>0 ){
/* Generating CHECK constraints or inserting into partial index */
inReg = pExpr->iColumn + pParse->ckBase;
break;
}else{
- /* Deleting from a partial index */
- iTab = pParse->iPartIdxTab;
+ /* Coding an expression that is part of an index where column names
+ ** in the index refer to the table to which the index belongs */
+ iTab = pParse->iSelfTab;
}
}
inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
@@ -86780,11 +86896,11 @@
break;
}
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
+ sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
break;
}
case TK_NULL: {
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
break;
@@ -86819,14 +86935,10 @@
}
case TK_REGISTER: {
inReg = pExpr->iTable;
break;
}
- case TK_AS: {
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- break;
- }
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
if( inReg!=target ){
@@ -87053,11 +87165,11 @@
pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG);
}
}
sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
- sqlite3ExprCodeExprList(pParse, pFarg, r1,
+ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */
}else{
r1 = 0;
}
@@ -87277,11 +87389,11 @@
nextCase = sqlite3VdbeMakeLabel(v);
testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
+ sqlite3VdbeGoto(v, endLabel);
sqlite3ExprCachePop(pParse);
sqlite3VdbeResolveLabel(v, nextCase);
}
if( (nExpr&1)!=0 ){
sqlite3ExprCachePush(pParse);
@@ -87469,29 +87581,32 @@
*/
SQLITE_PRIVATE int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* The expression list to be coded */
int target, /* Where to write results */
+ int srcReg, /* Source registers if SQLITE_ECEL_REF */
u8 flags /* SQLITE_ECEL_* flags */
){
struct ExprList_item *pItem;
- int i, n;
+ int i, j, n;
u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
+ Vdbe *v = pParse->pVdbe;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
n = pList->nExpr;
if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
for(pItem=pList->a, i=0; ipExpr;
- if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
+ if( (flags & SQLITE_ECEL_REF)!=0 && (j = pList->a[i].u.x.iOrderByCol)>0 ){
+ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+ }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
VdbeOp *pOp;
- Vdbe *v = pParse->pVdbe;
if( copyOp==OP_Copy
&& (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
&& pOp->p1+pOp->p3+1==inReg
&& pOp->p2+pOp->p3+1==target+i
){
@@ -87664,18 +87779,18 @@
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
int destIfFalse = sqlite3VdbeMakeLabel(v);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ sqlite3VdbeGoto(v, dest);
sqlite3VdbeResolveLabel(v, destIfFalse);
break;
}
#endif
default: {
if( exprAlwaysTrue(pExpr) ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
@@ -87827,11 +87942,11 @@
break;
}
#endif
default: {
if( exprAlwaysFalse(pExpr) ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
@@ -87903,11 +88018,13 @@
return 1;
}
return 2;
}
if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
- if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+ if( pA->op==TK_FUNCTION ){
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+ }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return pA->op==TK_COLLATE ? 1 : 2;
}
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
@@ -88811,11 +88928,11 @@
** SQLite tables) that are identified by the name of the virtual table.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pVTab ){
int i = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
+ sqlite3VdbeLoadString(v, i, zName);
sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
sqlite3MayAbort(pParse);
}
#endif
@@ -90169,11 +90286,11 @@
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
iTabCur = iTab++;
iIdxCur = iTab++;
pParse->nTab = MAX(pParse->nTab, iTab);
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
+ sqlite3VdbeLoadString(v, regTabname, pTab->zName);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol; /* Number of columns in pIdx. "N" */
int addrRewind; /* Address of "OP_Rewind iIdxCur" */
int addrNextRow; /* Address of "next_row:" */
@@ -90191,11 +90308,11 @@
zIdxName = pIdx->zName;
nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1;
}
/* Populate the register containing the index name. */
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
+ sqlite3VdbeLoadString(v, regIdxname, zIdxName);
VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
/*
** Pseudo-code for loop that calls stat_push():
**
@@ -90305,11 +90422,11 @@
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest);
+ sqlite3VdbeGoto(v, endDistinctTest);
/*
** chng_addr_0:
** regPrev(0) = idx(0)
@@ -90341,10 +90458,11 @@
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
int j, k, regKey;
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; jnKeyCol; j++){
k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ assert( k>=0 && knCol );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
@@ -90390,16 +90508,14 @@
/* We know that the regSampleRowid row exists because it was read by
** the previous loop. Thus the not-found jump of seekOp will never
** be taken */
VdbeCoverageNeverTaken(v);
#ifdef SQLITE_ENABLE_STAT3
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
- pIdx->aiColumn[0], regSample);
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
#else
for(i=0; iaiColumn[i];
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
#endif
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
@@ -92121,11 +92237,11 @@
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
/* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
+ sqlite3VdbeGoto(v, 1);
}
}
/* Get the VDBE program ready for execution
@@ -92256,10 +92372,21 @@
}
p = sqlite3FindTable(pParse->db, zName, zDbase);
if( p==0 ){
const char *zMsg = isView ? "no such view" : "no such table";
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
+ /* If zName is the not the name of a table in the schema created using
+ ** CREATE, then check to see if it is the name of an virtual table that
+ ** can be an eponymous virtual table. */
+ Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+ return pMod->pEpoTab;
+ }
+ }
+#endif
if( zDbase ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
}
@@ -92334,10 +92461,11 @@
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
sqlite3ExprDelete(db, p->pPartIdxWhere);
+ sqlite3ExprListDelete(db, p->aColExpr);
sqlite3DbFree(db, p->zColAff);
if( p->isResized ) sqlite3DbFree(db, p->azColl);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3_free(p->aiRowEst);
#endif
@@ -92460,11 +92588,11 @@
/*
** Delete memory allocated for the column names of a table or view (the
** Table.aCol[] array).
*/
-static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
int i;
Column *pCol;
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; inCol; i++, pCol++){
@@ -92527,17 +92655,15 @@
/* Delete any foreign keys attached to this table. */
sqlite3FkDelete(db, pTable);
/* Delete the Table structure itself.
*/
- sqliteDeleteColumnNames(db, pTable);
+ sqlite3DeleteColumnNames(db, pTable);
sqlite3DbFree(db, pTable->zName);
sqlite3DbFree(db, pTable->zColAff);
sqlite3SelectDelete(db, pTable->pSelect);
-#ifndef SQLITE_OMIT_CHECK
sqlite3ExprListDelete(db, pTable->pCheck);
-#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3VtabClear(db, pTable);
#endif
sqlite3DbFree(db, pTable);
@@ -92876,10 +93002,12 @@
*/
if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
int j1;
int fileFormat;
int reg1, reg2, reg3;
+ /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
+ static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( isVirtual ){
sqlite3VdbeAddOp0(v, OP_VBegin);
@@ -92920,11 +93048,11 @@
{
pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
- sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
+ sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeAddOp0(v, OP_Close);
}
@@ -93201,22 +93329,27 @@
zType = pTab->aCol[iCol].zType;
nTerm = 1;
}else{
nTerm = pList->nExpr;
for(i=0; inCol; iCol++){
- if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
- pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
- zType = pTab->aCol[iCol].zType;
- break;
+ Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
+ assert( pCExpr!=0 );
+ if( pCExpr->op==TK_ID ){
+ const char *zCName = pCExpr->u.zToken;
+ for(iCol=0; iColnCol; iCol++){
+ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
+ break;
+ }
}
}
}
}
if( nTerm==1
&& zType && sqlite3StrICmp(zType, "INTEGER")==0
- && sortOrder==SQLITE_SO_ASC
+ && sortOrder!=SQLITE_SO_DESC
){
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
@@ -93579,22 +93712,24 @@
** root-page for the table into an OP_CreateIndex opcode. The index
** created will become the PRIMARY KEY index.
*/
if( pParse->addrCrTab ){
assert( v );
- sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
+ sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
}
/* Locate the PRIMARY KEY index. Or, if this table was originally
** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
*/
if( pTab->iPKey>=0 ){
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse, 0, 0);
+ Token ipkToken;
+ ipkToken.z = pTab->aCol[pTab->iPKey].zName;
+ ipkToken.n = sqlite3Strlen30(ipkToken.z);
+ pList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
- pList->a[0].zName = sqlite3DbStrDup(pParse->db,
- pTab->aCol[pTab->iPKey].zName);
pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
if( pPk==0 ) return;
pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
@@ -93606,11 +93741,11 @@
** table entry. This is only required if currently generating VDBE
** code for a CREATE TABLE (not when parsing one as part of reading
** a database schema). */
if( v ){
assert( db->init.busy==0 );
- sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
+ sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
}
/*
** Remove all redundant columns from the PRIMARY KEY. For example, change
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
@@ -93716,13 +93851,14 @@
Table *p; /* The new table */
sqlite3 *db = pParse->db; /* The database connection */
int iDb; /* Database in which the table lives */
Index *pIdx; /* An implied index of the table */
- if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
+ if( pEnd==0 && pSelect==0 ){
return;
}
+ assert( !db->mallocFailed );
p = pParse->pNewTable;
if( p==0 ) return;
assert( !db->init.busy || !pSelect );
@@ -93849,11 +93985,11 @@
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
sqlite3TableAffinity(v, p, 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInsLoop);
+ sqlite3VdbeGoto(v, addrInsLoop);
sqlite3VdbeJumpHere(v, addrInsLoop);
sqlite3VdbeAddOp1(v, OP_Close, 1);
}
/* Compute the complete text of the CREATE statement */
@@ -93946,10 +94082,11 @@
SQLITE_PRIVATE void sqlite3CreateView(
Parse *pParse, /* The parsing context */
Token *pBegin, /* The CREATE token that begins the statement */
Token *pName1, /* The token that holds the name of the view */
Token *pName2, /* The token that holds the name of the view */
+ ExprList *pCNames, /* Optional list of view column names */
Select *pSelect, /* A SELECT statement that will become the new view */
int isTemp, /* TRUE for a TEMPORARY view */
int noErr /* Suppress error messages if VIEW already exists */
){
Table *p;
@@ -93966,52 +94103,47 @@
sqlite3SelectDelete(db, pSelect);
return;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
- if( p==0 || pParse->nErr ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
+ if( p==0 || pParse->nErr ) goto create_view_fail;
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
- if( sqlite3FixSelect(&sFix, pSelect) ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
+ if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;
/* Make a copy of the entire SELECT statement that defines the view.
** This will force all the Expr.token.z values to be dynamically
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- sqlite3SelectDelete(db, pSelect);
- if( db->mallocFailed ){
- return;
- }
- if( !db->init.busy ){
- sqlite3ViewGetColumnNames(pParse, p);
- }
+ p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
+ if( db->mallocFailed ) goto create_view_fail;
/* Locate the end of the CREATE VIEW statement. Make sEnd point to
** the end.
*/
sEnd = pParse->sLastToken;
- if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
+ assert( sEnd.z[0]!=0 );
+ if( sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
+ assert( n>0 );
z = pBegin->z;
- while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
+ while( sqlite3Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
+
+create_view_fail:
+ sqlite3SelectDelete(db, pSelect);
+ sqlite3ExprListDelete(db, pCNames);
return;
}
#endif /* SQLITE_OMIT_VIEW */
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -94025,10 +94157,11 @@
Select *pSel; /* Copy of the SELECT that implements the view */
int nErr = 0; /* Number of errors encountered */
int n; /* Temporarily holds the number of cursors assigned */
sqlite3 *db = pParse->db; /* Database connection for malloc errors */
sqlite3_xauth xAuth; /* Saved xAuth pointer */
+ u8 bEnabledLA; /* Saved db->lookaside.bEnabled state */
assert( pTable );
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( sqlite3VtabCallConnect(pParse, pTable) ){
@@ -94070,44 +94203,50 @@
** to the elements of the FROM clause. But we do not want these changes
** to be permanent. So the computation is done on a copy of the SELECT
** statement that defines the view.
*/
assert( pTable->pSelect );
- pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
- if( pSel ){
- u8 enableLookaside = db->lookaside.bEnabled;
- n = pParse->nTab;
- sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
- pTable->nCol = -1;
- db->lookaside.bEnabled = 0;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- xAuth = db->xAuth;
- db->xAuth = 0;
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
- db->xAuth = xAuth;
-#else
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
-#endif
- db->lookaside.bEnabled = enableLookaside;
- pParse->nTab = n;
- if( pSelTab ){
- assert( pTable->aCol==0 );
- pTable->nCol = pSelTab->nCol;
- pTable->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
- pSelTab->aCol = 0;
- sqlite3DeleteTable(db, pSelTab);
- assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
- pTable->pSchema->schemaFlags |= DB_UnresetViews;
- }else{
- pTable->nCol = 0;
- nErr++;
- }
- sqlite3SelectDelete(db, pSel);
- } else {
- nErr++;
- }
+ bEnabledLA = db->lookaside.bEnabled;
+ if( pTable->pCheck ){
+ db->lookaside.bEnabled = 0;
+ sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
+ &pTable->nCol, &pTable->aCol);
+ }else{
+ pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+ if( pSel ){
+ n = pParse->nTab;
+ sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+ pTable->nCol = -1;
+ db->lookaside.bEnabled = 0;
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ xAuth = db->xAuth;
+ db->xAuth = 0;
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+ db->xAuth = xAuth;
+#else
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+#endif
+ pParse->nTab = n;
+ if( pSelTab ){
+ assert( pTable->aCol==0 );
+ pTable->nCol = pSelTab->nCol;
+ pTable->aCol = pSelTab->aCol;
+ pSelTab->nCol = 0;
+ pSelTab->aCol = 0;
+ sqlite3DeleteTable(db, pSelTab);
+ assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
+ }else{
+ pTable->nCol = 0;
+ nErr++;
+ }
+ sqlite3SelectDelete(db, pSel);
+ } else {
+ nErr++;
+ }
+ }
+ db->lookaside.bEnabled = bEnabledLA;
+ pTable->pSchema->schemaFlags |= DB_UnresetViews;
#endif /* SQLITE_OMIT_VIEW */
return nErr;
}
#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
@@ -94120,11 +94259,11 @@
assert( sqlite3SchemaMutexHeld(db, idx, 0) );
if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
if( pTab->pSelect ){
- sqliteDeleteColumnNames(db, pTab);
+ sqlite3DeleteColumnNames(db, pTab);
pTab->aCol = 0;
pTab->nCol = 0;
}
}
DbClearProperty(db, idx, DB_UnresetViews);
@@ -94675,11 +94814,11 @@
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
if( IsUniqueIndex(pIndex) && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
- sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
+ sqlite3VdbeGoto(v, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
@@ -94730,10 +94869,34 @@
p->nKeyCol = nCol - 1;
*ppExtra = ((char*)p) + nByte;
}
return p;
}
+
+/*
+** Backwards Compatibility Hack:
+**
+** Historical versions of SQLite accepted strings as column names in
+** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
+**
+** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
+** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
+**
+** This is goofy. But to preserve backwards compatibility we continue to
+** accept it. This routine does the necessary conversion. It converts
+** the expression given in its argument from a TK_STRING into a TK_ID
+** if the expression is just a TK_STRING with an optional COLLATE clause.
+** If the epxression is anything other than TK_STRING, the expression is
+** unchanged.
+*/
+static void sqlite3StringToId(Expr *p){
+ if( p->op==TK_STRING ){
+ p->op = TK_ID;
+ }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
+ p->pLeft->op = TK_ID;
+ }
+}
/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
@@ -94772,11 +94935,10 @@
sqlite3 *db = pParse->db;
Db *pDb; /* The specific table containing the indexed database */
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
- const Column *pTabCol; /* A column in the table */
int nExtra = 0; /* Space allocated for zExtra[] */
int nExtraCol; /* Number of extra columns needed */
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
@@ -94927,24 +95089,29 @@
/* If pList==0, it means this routine was called to make a primary
** key out of the last column added to the table under construction.
** So create a fake list to simulate this.
*/
if( pList==0 ){
- pList = sqlite3ExprListAppend(pParse, 0, 0);
+ Token prevCol;
+ prevCol.z = pTab->aCol[pTab->nCol-1].zName;
+ prevCol.n = sqlite3Strlen30(prevCol.z);
+ pList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
- pList->a[0].zName = sqlite3DbStrDup(pParse->db,
- pTab->aCol[pTab->nCol-1].zName);
- pList->a[0].sortOrder = (u8)sortOrder;
+ assert( pList->nExpr==1 );
+ sqlite3ExprListSetSortOrder(pList, sortOrder);
+ }else{
+ sqlite3ExprListCheckLength(pParse, pList, "index");
}
/* Figure out how many bytes of space are required to store explicitly
** specified collation sequence names.
*/
for(i=0; inExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
- if( pExpr ){
- assert( pExpr->op==TK_COLLATE );
+ assert( pExpr!=0 );
+ if( pExpr->op==TK_COLLATE ){
nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
}
}
/*
@@ -94981,61 +95148,85 @@
sortOrderMask = -1; /* Honor DESC */
}else{
sortOrderMask = 0; /* Ignore DESC */
}
- /* Scan the names of the columns of the table to be indexed and
- ** load the column indices into the Index structure. Report an error
- ** if any column is not found.
+ /* Analyze the list of expressions that form the terms of the index and
+ ** report any errors. In the common case where the expression is exactly
+ ** a table column, store that column in aiColumn[]. For general expressions,
+ ** populate pIndex->aColExpr and store -2 in aiColumn[].
**
- ** TODO: Add a test to make sure that the same column is not named
- ** more than once within the same index. Only the first instance of
- ** the column will ever be used by the optimizer. Note that using the
- ** same column more than once cannot be an error because that would
- ** break backwards compatibility - it needs to be a warning.
+ ** TODO: Issue a warning if two or more columns of the index are identical.
+ ** TODO: Issue a warning if the table primary key is used as part of the
+ ** index key.
*/
for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){
- const char *zColName = pListItem->zName;
- int requestedSortOrder;
+ Expr *pCExpr; /* The i-th index expression */
+ int requestedSortOrder; /* ASC or DESC on the i-th expression */
char *zColl; /* Collation sequence name */
- for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){
- if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
- }
- if( j>=pTab->nCol ){
- sqlite3ErrorMsg(pParse, "table %s has no column named %s",
- pTab->zName, zColName);
- pParse->checkSchema = 1;
- goto exit_create_index;
- }
- assert( j<=0x7fff );
- pIndex->aiColumn[i] = (i16)j;
- if( pListItem->pExpr ){
- int nColl;
- assert( pListItem->pExpr->op==TK_COLLATE );
+ sqlite3StringToId(pListItem->pExpr);
+ sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
+ if( pParse->nErr ) goto exit_create_index;
+ pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr);
+ if( pCExpr->op!=TK_COLUMN ){
+ if( pTab==pParse->pNewTable ){
+ sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and "
+ "UNIQUE constraints");
+ goto exit_create_index;
+ }
+ if( pIndex->aColExpr==0 ){
+ ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
+ pIndex->aColExpr = pCopy;
+ if( !db->mallocFailed ){
+ assert( pCopy!=0 );
+ pListItem = &pCopy->a[i];
+ }
+ }
+ j = -2;
+ pIndex->aiColumn[i] = -2;
+ pIndex->uniqNotNull = 0;
+ }else{
+ j = pCExpr->iColumn;
+ assert( j<=0x7fff );
+ if( j<0 ){
+ j = pTab->iPKey;
+ }else if( pTab->aCol[j].notNull==0 ){
+ pIndex->uniqNotNull = 0;
+ }
+ pIndex->aiColumn[i] = (i16)j;
+ }
+ zColl = 0;
+ if( pListItem->pExpr->op==TK_COLLATE ){
+ int nColl;
zColl = pListItem->pExpr->u.zToken;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
- }else{
+ }else if( j>=0 ){
zColl = pTab->aCol[j].zColl;
- if( !zColl ) zColl = "BINARY";
}
+ if( !zColl ) zColl = "BINARY";
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
- if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
}
+
+ /* Append the table key to the end of the index. For WITHOUT ROWID
+ ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For
+ ** normal tables (when pPk==0) this will be the rowid.
+ */
if( pPk ){
for(j=0; jnKeyCol; j++){
int x = pPk->aiColumn[j];
+ assert( x>=0 );
if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
pIndex->nColumn--;
}else{
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
@@ -95082,10 +95273,11 @@
if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue;
for(k=0; knKeyCol; k++){
const char *z1;
const char *z2;
+ assert( pIdx->aiColumn[k]>=0 );
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
}
@@ -95113,10 +95305,11 @@
}
/* Link the new Index structure to its table and to the other
** in-memory database structures.
*/
+ assert( pParse->nErr==0 );
if( db->init.busy ){
Index *p;
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
pIndex->zName, pIndex);
@@ -95142,11 +95335,11 @@
** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
** or UNIQUE index in a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
- else if( pParse->nErr==0 && (HasRowid(pTab) || pTblName!=0) ){
+ else if( HasRowid(pTab) || pTblName!=0 ){
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
@@ -95602,11 +95795,12 @@
if( pList==0 ) return;
for(pItem=pList->a, i=0; inSrc; i++, pItem++){
sqlite3DbFree(db, pItem->zDatabase);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zAlias);
- sqlite3DbFree(db, pItem->zIndexedBy);
+ if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
+ if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
sqlite3DeleteTable(db, pItem->pTab);
sqlite3SelectDelete(db, pItem->pSelect);
sqlite3ExprDelete(db, pItem->pOn);
sqlite3IdListDelete(db, pItem->pUsing);
}
@@ -95675,20 +95869,40 @@
*/
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
assert( pIndexedBy!=0 );
if( p && ALWAYS(p->nSrc>0) ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
- assert( pItem->notIndexed==0 && pItem->zIndexedBy==0 );
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
- pItem->notIndexed = 1;
+ pItem->fg.notIndexed = 1;
}else{
- pItem->zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
+ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
+ pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0);
}
}
}
+
+/*
+** Add the list of function arguments to the SrcList entry for a
+** table-valued-function.
+*/
+SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
+ if( p && pList ){
+ struct SrcList_item *pItem = &p->a[p->nSrc-1];
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
+ pItem->u1.pFuncArg = pList;
+ pItem->fg.isTabFunc = 1;
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
+ }
+}
/*
** When building up a FROM clause in the parser, the join operator
** is initially attached to the left operand. But the code generator
** expects the join operator to be on the right operand. This routine
@@ -95705,13 +95919,13 @@
*/
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
for(i=p->nSrc-1; i>0; i--){
- p->a[i].jointype = p->a[i-1].jointype;
+ p->a[i].fg.jointype = p->a[i-1].fg.jointype;
}
- p->a[0].jointype = 0;
+ p->a[0].fg.jointype = 0;
}
}
/*
** Begin a transaction
@@ -95951,16 +96165,20 @@
int j;
StrAccum errMsg;
Table *pTab = pIdx->pTable;
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
- for(j=0; jnKeyCol; j++){
- char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
- sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
- sqlite3StrAccumAppend(&errMsg, ".", 1);
- sqlite3StrAccumAppendAll(&errMsg, zCol);
+ if( pIdx->aColExpr ){
+ sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
+ }else{
+ for(j=0; jnKeyCol; j++){
+ char *zCol;
+ assert( pIdx->aiColumn[j]>=0 );
+ zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+ sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
+ }
}
zErr = sqlite3StrAccumFinish(&errMsg);
sqlite3HaltConstraint(pParse,
IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY
: SQLITE_CONSTRAINT_UNIQUE,
@@ -96201,11 +96419,11 @@
pNew = pWith;
}else{
pNew->a[pNew->nCte].pSelect = pQuery;
pNew->a[pNew->nCte].pCols = pArglist;
pNew->a[pNew->nCte].zName = zName;
- pNew->a[pNew->nCte].zErr = 0;
+ pNew->a[pNew->nCte].zCteErr = 0;
pNew->nCte++;
}
return pNew;
}
@@ -97120,10 +97338,11 @@
}
/* Extract the rowid or primary key for the current row */
if( pPk ){
for(i=0; iaiColumn[i]>=(-1) );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pPk->aiColumn[i], iPk+i);
}
iKey = iPk;
}else{
@@ -97152,11 +97371,11 @@
}else if( pPk ){
/* Construct a composite key for the row to be deleted and remember it */
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
- sqlite3IndexAffinityStr(v, pPk), nPk);
+ sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
}else{
/* Get the rowid of the row to be deleted and remember it in the RowSet */
nKey = 1; /* OP_Seek always uses a single rowid */
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
@@ -97165,11 +97384,11 @@
/* End of the WHERE loop */
sqlite3WhereEnd(pWInfo);
if( okOnePass ){
/* Bypass the delete logic below if the WHERE loop found zero rows */
addrBypass = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
+ sqlite3VdbeGoto(v, addrBypass);
sqlite3VdbeJumpHere(v, addrDelete);
}
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
@@ -97227,11 +97446,11 @@
sqlite3VdbeResolveLabel(v, addrBypass);
}else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrLoop);
}else{
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
+ sqlite3VdbeGoto(v, addrLoop);
sqlite3VdbeJumpHere(v, addrLoop);
}
/* Close the cursors open on the table and its indexes. */
if( !isView && !IsVirtual(pTab) ){
@@ -97498,18 +97717,17 @@
Index *pPrior, /* Previously generated index key */
int regPrior /* Register holding previous generated key */
){
Vdbe *v = pParse->pVdbe;
int j;
- Table *pTab = pIdx->pTable;
int regBase;
int nCol;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
*piPartIdxLabel = sqlite3VdbeMakeLabel(v);
- pParse->iPartIdxTab = iDataCur;
+ pParse->iSelfTab = iDataCur;
sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
}else{
*piPartIdxLabel = 0;
@@ -97517,13 +97735,18 @@
}
nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
regBase = sqlite3GetTempRange(pParse, nCol);
if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
for(j=0; jaiColumn[j]==pIdx->aiColumn[j] ) continue;
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j],
- regBase+j);
+ if( pPrior
+ && pPrior->aiColumn[j]==pIdx->aiColumn[j]
+ && pPrior->aiColumn[j]>=(-1)
+ ){
+ /* This column was already computed by the previous index */
+ continue;
+ }
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
/* If the column affinity is REAL but the number is an integer, then it
** might be stored in the table as an integer (using a compact
** representation) then converted to REAL by an OP_RealAffinity opcode.
** But we are getting ready to store this value back into an index, where
** it should be converted by to INTEGER again. So omit the OP_RealAffinity
@@ -99288,19 +99511,19 @@
FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
- FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
- FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
+ DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
+ DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
#if SQLITE_USER_AUTHENTICATION
FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
FUNCTION(quote, 1, 0, 0, quoteFunc ),
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
VFUNCTION(changes, 0, 0, 0, changes ),
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
@@ -99308,12 +99531,12 @@
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
#ifdef SQLITE_SOUNDEX
FUNCTION(soundex, 1, 0, 0, soundexFunc ),
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
- FUNCTION(load_extension, 1, 0, 0, loadExt ),
- FUNCTION(load_extension, 2, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 2, 0, 0, loadExt ),
#endif
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
AGGREGATE2(count, 0, 0, 0, countStep, countFinalize,
@@ -99724,11 +99947,11 @@
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
}
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
+ sqlite3VdbeGoto(v, iOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
sqlite3VdbeJumpHere(v, iMustBeInt);
sqlite3ReleaseTempReg(pParse, regTemp);
}else{
int nCol = pFKey->nCol;
@@ -99762,15 +99985,15 @@
iParent = regData;
}
sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
+ sqlite3VdbeGoto(v, iOk);
}
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
- sqlite3IndexAffinityStr(v,pIdx), nCol);
+ sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
}
@@ -100823,11 +101046,11 @@
**
** Memory for the buffer containing the column index affinity string
** is managed along with the rest of the Index structure. It will be
** released when sqlite3DeleteIndex() is called.
*/
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
if( !pIdx->zColAff ){
/* The first time a column affinity string for a particular index is
** required, it is allocated and populated here. It is then stored as
** a member of the Index structure for subsequent use.
**
@@ -100835,19 +101058,29 @@
** sqliteDeleteIndex() when the Index structure itself is cleaned
** up.
*/
int n;
Table *pTab = pIdx->pTable;
- sqlite3 *db = sqlite3VdbeDb(v);
pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
if( !pIdx->zColAff ){
db->mallocFailed = 1;
return 0;
}
for(n=0; nnColumn; n++){
i16 x = pIdx->aiColumn[n];
- pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity;
+ if( x>=0 ){
+ pIdx->zColAff[n] = pTab->aCol[x].affinity;
+ }else if( x==(-1) ){
+ pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
+ }else{
+ char aff;
+ assert( x==(-2) );
+ assert( pIdx->aColExpr!=0 );
+ aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
+ if( aff==0 ) aff = SQLITE_AFF_BLOB;
+ pIdx->zColAff[n] = aff;
+ }
}
pIdx->zColAff[n] = 0;
}
return pIdx->zColAff;
@@ -101014,18 +101247,18 @@
memId = p->regCtr;
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
+ sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
+ sqlite3VdbeGoto(v, addr+9);
sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
sqlite3VdbeAddOp0(v, OP_Close);
}
}
@@ -101445,11 +101678,11 @@
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
+ sqlite3VdbeGoto(v, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
@@ -101459,15 +101692,17 @@
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
srcTab = -1;
assert( useTempTable==0 );
- nColumn = pList ? pList->nExpr : 0;
- for(i=0; ia[i].pExpr) ){
+ if( pList ){
+ nColumn = pList->nExpr;
+ if( sqlite3ResolveExprListNames(&sNC, pList) ){
goto insert_cleanup;
}
+ }else{
+ nColumn = 0;
}
}
/* If there is no IDLIST term but the table has an integer primary
** key, the set the ipkColumn variable to the integer primary key
@@ -101744,11 +101979,11 @@
if( useTempTable ){
sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
+ sqlite3VdbeGoto(v, addrCont);
sqlite3VdbeJumpHere(v, addrInsTop);
}
if( !IsVirtual(pTab) && !isView ){
/* Close all tables opened */
@@ -101991,11 +102226,11 @@
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; inExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v);
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
}else{
char *zName = pCheck->a[i].zName;
if( zName==0 ) zName = pTab->zName;
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
@@ -102099,11 +102334,11 @@
seenReplace = 1;
break;
}
case OE_Ignore: {
/*assert( seenReplace==0 );*/
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
}
sqlite3VdbeResolveLabel(v, addrRowidOk);
if( ipkTop ){
@@ -102147,19 +102382,26 @@
*/
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
for(i=0; inColumn; i++){
int iField = pIdx->aiColumn[i];
int x;
- if( iField<0 || iField==pTab->iPKey ){
- if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
- x = regNewData;
- regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
+ if( iField==(-2) ){
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
+ pParse->ckBase = 0;
+ VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
- x = iField + regNewData + 1;
+ if( iField==(-1) || iField==pTab->iPKey ){
+ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
+ x = regNewData;
+ regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
+ }else{
+ x = iField + regNewData + 1;
+ }
+ sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
- sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
- VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
@@ -102252,11 +102494,11 @@
case OE_Fail: {
sqlite3UniqueConstraint(pParse, onError, pIdx);
break;
}
case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
default: {
Trigger *pTrigger = 0;
assert( onError==OE_Replace );
@@ -102273,11 +102515,11 @@
sqlite3VdbeResolveLabel(v, addrUniqueOk);
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
if( ipkTop ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
+ sqlite3VdbeGoto(v, ipkTop+1);
sqlite3VdbeJumpHere(v, ipkBottom);
}
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
@@ -102475,10 +102717,17 @@
return 0; /* Different conflict resolution strategies */
}
for(i=0; inKeyCol; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
+ }
+ if( pSrc->aiColumn[i]==(-2) ){
+ assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
+ if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
+ pDest->aColExpr->a[i].pExpr, -1)!=0 ){
+ return 0; /* Different expressions in the index */
+ }
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
@@ -102719,11 +102968,11 @@
** is unable to test uniqueness.)
**
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
- emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
+ emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, addr1);
}
if( HasRowid(pSrc) ){
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
@@ -103396,10 +103645,11 @@
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
+#define sqlite3_vsnprintf sqlite3_api->vsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
@@ -104898,25 +105148,51 @@
}
db->temp_store = (u8)ts;
return SQLITE_OK;
}
#endif /* SQLITE_PAGER_PRAGMAS */
+
+/*
+** Set the names of the first N columns to the values in azCol[]
+*/
+static void setAllColumnNames(
+ Vdbe *v, /* The query under construction */
+ int N, /* Number of columns */
+ const char **azCol /* Names of columns */
+){
+ int i;
+ sqlite3VdbeSetNumCols(v, N);
+ for(i=0; inMem;
- i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
- if( pI64 ){
- memcpy(pI64, &value, sizeof(value));
- }
- sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
+static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
+ setOneColumnName(v, zLabel);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+}
+
+/*
+** Generate code to return a single text value.
+*/
+static void returnSingleText(
+ Vdbe *v, /* Prepared statement under construction */
+ const char *zLabel, /* Name of the result column */
+ const char *zValue /* Value to be returned */
+){
+ if( zValue ){
+ sqlite3VdbeLoadString(v, 1, (const char*)zValue);
+ setOneColumnName(v, zLabel);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ }
}
/*
** Set the safety_level and pager flags for pager iDb. Or if iDb<0
@@ -105076,18 +105352,12 @@
aFcntl[2] = zRight;
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
- if( aFcntl[0] ){
- int nMem = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
- sqlite3_free(aFcntl[0]);
- }
+ returnSingleText(v, "result", aFcntl[0]);
+ sqlite3_free(aFcntl[0]);
goto pragma_out;
}
if( rc!=SQLITE_NOTFOUND ){
if( aFcntl[0] ){
sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
@@ -105153,12 +105423,11 @@
{ OP_ResultRow, 1, 1, 0},
};
int addr;
sqlite3VdbeUsesBtree(v, iDb);
if( !zRight ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
+ setOneColumnName(v, "cache_size");
pParse->nMem += 2;
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
@@ -105188,11 +105457,11 @@
case PragTyp_PAGE_SIZE: {
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(pParse, "page_size", size);
+ returnSingleInt(v, "page_size", size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
@@ -105223,11 +105492,11 @@
for(ii=0; iinDb; ii++){
sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
}
}
b = sqlite3BtreeSecureDelete(pBt, b);
- returnSingleInt(pParse, "secure_delete", b);
+ returnSingleInt(v, "secure_delete", b);
break;
}
/*
** PRAGMA [database.]max_page_count
@@ -105302,14 +105571,11 @@
assert( eMode==PAGER_LOCKINGMODE_NORMAL
|| eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
zRet = "exclusive";
}
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ returnSingleText(v, "locking_mode", zRet);
break;
}
/*
** PRAGMA [database.]journal_mode
@@ -105318,13 +105584,11 @@
*/
case PragTyp_JOURNAL_MODE: {
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
int ii; /* Loop counter */
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
-
+ setOneColumnName(v, "journal_mode");
if( zRight==0 ){
/* If there is no "=MODE" part of the pragma, do a query for the
** current mode */
eMode = PAGER_JOURNALMODE_QUERY;
}else{
@@ -105366,11 +105630,11 @@
if( zRight ){
sqlite3DecOrHexToI64(zRight, &iLimit);
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(pParse, "journal_size_limit", iLimit);
+ returnSingleInt(v, "journal_size_limit", iLimit);
break;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
@@ -105384,11 +105648,11 @@
#ifndef SQLITE_OMIT_AUTOVACUUM
case PragTyp_AUTO_VACUUM: {
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
- returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
+ returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
}else{
int eAuto = getAutoVacuum(zRight);
assert( eAuto>=0 && eAuto<=2 );
db->nextAutovac = (u8)eAuto;
/* Call SetAutoVacuum() to set initialize the internal auto and
@@ -105462,11 +105726,11 @@
*/
case PragTyp_CACHE_SIZE: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
+ returnSingleInt(v, "cache_size", pDb->pSchema->cache_size);
}else{
int size = sqlite3Atoi(zRight);
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
@@ -105508,11 +105772,11 @@
#else
sz = 0;
rc = SQLITE_OK;
#endif
if( rc==SQLITE_OK ){
- returnSingleInt(pParse, "mmap_size", sz);
+ returnSingleInt(v, "mmap_size", sz);
}else if( rc!=SQLITE_NOTFOUND ){
pParse->nErr++;
pParse->rc = rc;
}
break;
@@ -105529,11 +105793,11 @@
** Note that it is possible for the library compile-time options to
** override this setting
*/
case PragTyp_TEMP_STORE: {
if( !zRight ){
- returnSingleInt(pParse, "temp_store", db->temp_store);
+ returnSingleInt(v, "temp_store", db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
break;
}
@@ -105548,17 +105812,11 @@
** If temporary directory is changed, then invalidateTempStorage.
**
*/
case PragTyp_TEMP_STORE_DIRECTORY: {
if( !zRight ){
- if( sqlite3_temp_directory ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "temp_store_directory", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
+ returnSingleText(v, "temp_store_directory", sqlite3_temp_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
int res;
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
@@ -105598,17 +105856,11 @@
** by this setting, regardless of its value.
**
*/
case PragTyp_DATA_STORE_DIRECTORY: {
if( !zRight ){
- if( sqlite3_data_directory ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "data_store_directory", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
+ returnSingleText(v, "data_store_directory", sqlite3_data_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
int res;
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
@@ -105643,18 +105895,11 @@
Pager *pPager = sqlite3BtreePager(pDb->pBt);
char *proxy_file_path = NULL;
sqlite3_file *pFile = sqlite3PagerFile(pPager);
sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
&proxy_file_path);
-
- if( proxy_file_path ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "lock_proxy_file", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
+ returnSingleText(v, "lock_proxy_file", proxy_file_path);
}else{
Pager *pPager = sqlite3BtreePager(pDb->pBt);
sqlite3_file *pFile = sqlite3PagerFile(pPager);
int res;
if( zRight[0] ){
@@ -105682,11 +105927,11 @@
** default value will be restored the next time the database is
** opened.
*/
case PragTyp_SYNCHRONOUS: {
if( !zRight ){
- returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
+ returnSingleInt(v, "synchronous", pDb->safety_level-1);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
@@ -105701,11 +105946,11 @@
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
case PragTyp_FLAG: {
if( zRight==0 ){
- returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
+ returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
}else{
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
@@ -105751,79 +105996,67 @@
*/
case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
+ static const char *azCol[] = {
+ "cid", "name", "type", "notnull", "dflt_value", "pk"
+ };
int i, k;
int nHidden = 0;
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- sqlite3VdbeSetNumCols(v, 6);
pParse->nMem = 6;
sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
+ setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
if( IsHiddenColumn(pCol) ){
nHidden++;
continue;
}
- sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- pCol->zType ? pCol->zType : "", 0);
- sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
- if( pCol->zDflt ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
- }
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
}else if( pPk==0 ){
k = 1;
}else{
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
- sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
+ sqlite3VdbeMultiLoad(v, 1, "issisi",
+ i-nHidden,
+ pCol->zName,
+ pCol->zType ? pCol->zType : "",
+ pCol->notNull ? 1 : 0,
+ pCol->zDflt,
+ k);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
}
break;
case PragTyp_STATS: {
+ static const char *azCol[] = { "table", "index", "width", "height" };
Index *pIdx;
HashElem *i;
v = sqlite3GetVdbe(pParse);
- sqlite3VdbeSetNumCols(v, 4);
pParse->nMem = 4;
sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC);
+ setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
- sqlite3VdbeAddOp2(v, OP_Integer,
- (int)sqlite3LogEstToInt(pTab->szTabRow), 3);
- sqlite3VdbeAddOp2(v, OP_Integer,
- (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4);
+ sqlite3VdbeMultiLoad(v, 1, "ssii",
+ pTab->zName,
+ 0,
+ (int)sqlite3LogEstToInt(pTab->szTabRow),
+ (int)sqlite3LogEstToInt(pTab->nRowLogEst));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Integer,
- (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3);
- sqlite3VdbeAddOp2(v, OP_Integer,
- (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4);
+ sqlite3VdbeMultiLoad(v, 2, "sii",
+ pIdx->zName,
+ (int)sqlite3LogEstToInt(pIdx->szIdxRow),
+ (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
}
}
}
break;
@@ -105831,10 +106064,13 @@
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
+ static const char *azCol[] = {
+ "seqno", "cid", "name", "desc", "coll", "key"
+ };
int i;
int mx;
if( pPragma->iArg ){
/* PRAGMA index_xinfo (newer version with more rows and columns) */
mx = pIdx->nColumn;
@@ -105843,33 +106079,22 @@
/* PRAGMA index_info (legacy version) */
mx = pIdx->nKeyCol;
pParse->nMem = 3;
}
pTab = pIdx->pTable;
- sqlite3VdbeSetNumCols(v, pParse->nMem);
sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- if( pPragma->iArg ){
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
- }
+ assert( pParse->nMem<=ArraySize(azCol) );
+ setAllColumnNames(v, pParse->nMem, azCol);
for(i=0; iaiColumn[i];
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
- if( cnum<0 ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
- }else{
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
- }
+ sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
+ cnum<0 ? 0 : pTab->aCol[cnum].zName);
if( pPragma->iArg ){
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
- sqlite3VdbeAddOp2(v, OP_Integer, inKeyCol, 6);
+ sqlite3VdbeMultiLoad(v, 4, "isi",
+ pIdx->aSortOrder[i],
+ pIdx->azColl[i],
+ inKeyCol);
}
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
}
}
}
@@ -105879,62 +106104,57 @@
Index *pIdx;
Table *pTab;
int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
+ static const char *azCol[] = {
+ "seq", "name", "unique", "origin", "partial"
+ };
v = sqlite3GetVdbe(pParse);
- sqlite3VdbeSetNumCols(v, 5);
pParse->nMem = 5;
sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
+ setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) );
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
const char *azOrigin[] = { "c", "u", "pk" };
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
+ sqlite3VdbeMultiLoad(v, 1, "isisi",
+ i,
+ pIdx->zName,
+ IsUniqueIndex(pIdx),
+ azOrigin[pIdx->idxType],
+ pIdx->pPartIdxWhere!=0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
}
}
}
break;
case PragTyp_DATABASE_LIST: {
+ static const char *azCol[] = { "seq", "name", "file" };
int i;
- sqlite3VdbeSetNumCols(v, 3);
pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
+ setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
for(i=0; inDb; i++){
if( db->aDb[i].pBt==0 ) continue;
assert( db->aDb[i].zName!=0 );
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
+ sqlite3VdbeMultiLoad(v, 1, "iss",
+ i,
+ db->aDb[i].zName,
+ sqlite3BtreeGetFilename(db->aDb[i].pBt));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
break;
case PragTyp_COLLATION_LIST: {
+ static const char *azCol[] = { "seq", "name" };
int i = 0;
HashElem *p;
- sqlite3VdbeSetNumCols(v, 2);
pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+ setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
- sqlite3VdbeAddOp2(v, OP_Integer, i++, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
+ sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
}
break;
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
@@ -105946,37 +106166,30 @@
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite3GetVdbe(pParse);
pFK = pTab->pFKey;
if( pFK ){
+ static const char *azCol[] = {
+ "id", "seq", "table", "from", "to", "on_update", "on_delete",
+ "match"
+ };
int i = 0;
- sqlite3VdbeSetNumCols(v, 8);
pParse->nMem = 8;
sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
+ setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) );
while(pFK){
int j;
for(j=0; jnCol; j++){
- char *zCol = pFK->aCol[j].zCol;
- char *zOnDelete = (char *)actionName(pFK->aAction[0]);
- char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
- pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
- sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
+ sqlite3VdbeMultiLoad(v, 1, "iissssss",
+ i,
+ j,
+ pFK->zTo,
+ pTab->aCol[pFK->aCol[j].iFrom].zName,
+ pFK->aCol[j].zCol,
+ actionName(pFK->aAction[1]), /* ON UPDATE */
+ actionName(pFK->aAction[0]), /* ON DELETE */
+ "NONE");
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
}
++i;
pFK = pFK->pNextFrom;
}
@@ -106001,21 +106214,18 @@
int regKey; /* Register to hold key for checking the FK */
int regRow; /* Registers to hold a row from pTab */
int addrTop; /* Top of a loop checking foreign keys */
int addrOk; /* Jump here if the key is OK */
int *aiCols; /* child to parent column mapping */
+ static const char *azCol[] = { "table", "rowid", "parent", "fkid" };
regResult = pParse->nMem+1;
pParse->nMem += 4;
regKey = ++pParse->nMem;
regRow = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
- sqlite3VdbeSetNumCols(v, 4);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
+ setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
sqlite3CodeVerifySchema(pParse, iDb);
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
while( k ){
if( zRight ){
pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
@@ -106026,12 +106236,11 @@
}
if( pTab==0 || pTab->pFKey==0 ) continue;
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
- P4_TRANSIENT);
+ sqlite3VdbeLoadString(v, regResult, pTab->zName);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
if( pParent==0 ) continue;
pIdx = 0;
sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
@@ -106072,29 +106281,27 @@
sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
}else{
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
}
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
+ sqlite3VdbeGoto(v, addrOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}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(v,pIdx), pFK->nCol);
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
VdbeCoverage(v);
}
}
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
- pFK->zTo, P4_TRANSIENT);
- sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
+ sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
sqlite3VdbeResolveLabel(v, addrOk);
sqlite3DbFree(db, aiCols);
}
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
@@ -106166,12 +106373,11 @@
assert( iDb==0 || pId2->z );
if( pId2->z==0 ) iDb = -1;
/* Initialize the VDBE program */
pParse->nMem = 6;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
+ setOneColumnName(v, "integrity_check");
/* Set the maximum error count */
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
if( zRight ){
sqlite3GetInt32(zRight, &mxErr);
@@ -106289,17 +106495,15 @@
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
/* Verify that an index entry exists for the current table row */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
pIdx->nColumn); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
+ sqlite3VdbeLoadString(v, 3, "row ");
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
- " missing from index ", P4_STATIC);
+ sqlite3VdbeLoadString(v, 4, " missing from index ");
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
- jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
- pIdx->zName, P4_TRANSIENT);
+ jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp2);
@@ -106316,38 +106520,36 @@
if( pTab->aCol[iCol].notNull ) continue;
sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
VdbeCoverage(v);
}
jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk);
+ sqlite3VdbeGoto(v, uniqOk);
sqlite3VdbeJumpHere(v, jmp6);
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
pIdx->nKeyCol); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- "non-unique entry in index ", P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5);
+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+ sqlite3VdbeGoto(v, jmp5);
sqlite3VdbeResolveLabel(v, uniqOk);
}
sqlite3VdbeJumpHere(v, jmp4);
sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
- "wrong # of entries in index ", P4_STATIC);
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
+ sqlite3VdbeLoadString(v, 3, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
@@ -106399,18 +106601,14 @@
{ 0, 0 }
};
const struct EncName *pEnc;
if( !zRight ){ /* "PRAGMA encoding" */
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
- sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName);
}else{ /* "PRAGMA encoding = XXX" */
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
** will be overwritten when the schema is next loaded. If it does not
** already exists, it will be created to use the new encoding value.
@@ -106507,15 +106705,14 @@
** one option per row.
*/
case PragTyp_COMPILE_OPTIONS: {
int i = 0;
const char *zOpt;
- sqlite3VdbeSetNumCols(v, 1);
pParse->nMem = 1;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
+ setOneColumnName(v, "compile_option");
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
+ sqlite3VdbeLoadString(v, 1, zOpt);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}
break;
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
@@ -106525,10 +106722,11 @@
** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
**
** Checkpoint the database.
*/
case PragTyp_WAL_CHECKPOINT: {
+ static const char *azCol[] = { "busy", "log", "checkpointed" };
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
int eMode = SQLITE_CHECKPOINT_PASSIVE;
if( zRight ){
if( sqlite3StrICmp(zRight, "full")==0 ){
eMode = SQLITE_CHECKPOINT_FULL;
@@ -106536,16 +106734,12 @@
eMode = SQLITE_CHECKPOINT_RESTART;
}else if( sqlite3StrICmp(zRight, "truncate")==0 ){
eMode = SQLITE_CHECKPOINT_TRUNCATE;
}
}
- sqlite3VdbeSetNumCols(v, 3);
+ setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
-
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
break;
@@ -106559,11 +106753,11 @@
*/
case PragTyp_WAL_AUTOCHECKPOINT: {
if( zRight ){
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
}
- returnSingleInt(pParse, "wal_autocheckpoint",
+ returnSingleInt(v, "wal_autocheckpoint",
db->xWalCallback==sqlite3WalDefaultHook ?
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
}
break;
#endif
@@ -106592,11 +106786,11 @@
/*case PragTyp_BUSY_TIMEOUT*/ default: {
assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
- returnSingleInt(pParse, "timeout", db->busyTimeout);
+ returnSingleInt(v, "timeout", db->busyTimeout);
break;
}
/*
** PRAGMA soft_heap_limit
@@ -106612,11 +106806,11 @@
case PragTyp_SOFT_HEAP_LIMIT: {
sqlite3_int64 N;
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N);
}
- returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
+ returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
break;
}
/*
** PRAGMA threads
@@ -106631,11 +106825,11 @@
&& sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
&& N>=0
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
- returnSingleInt(pParse, "threads",
+ returnSingleInt(v, "threads",
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
@@ -106644,29 +106838,27 @@
*/
case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
"unlocked", "shared", "reserved", "pending", "exclusive"
};
+ static const char *azCol[] = { "database", "status" };
int i;
- sqlite3VdbeSetNumCols(v, 2);
+ setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
for(i=0; inDb; i++){
Btree *pBt;
const char *zState = "unknown";
int j;
if( db->aDb[i].zName==0 ) continue;
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
pBt = db->aDb[i].pBt;
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
zState = "closed";
}else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0,
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
zState = azLockName[j];
}
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
+ sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zName, zState);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
break;
}
#endif
@@ -108027,16 +108219,16 @@
Table *pLeftTab = pLeft->pTab;
Table *pRightTab = pRight->pTab;
int isOuter;
if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
- isOuter = (pRight->jointype & JT_OUTER)!=0;
+ isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
/* When the NATURAL keyword is present, add WHERE clause terms for
** every column that the two tables have in common.
*/
- if( pRight->jointype & JT_NATURAL ){
+ if( pRight->fg.jointype & JT_NATURAL ){
if( pRight->pOn || pRight->pUsing ){
sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
return 1;
}
@@ -108117,10 +108309,11 @@
static void pushOntoSorter(
Parse *pParse, /* Parser context */
SortCtx *pSort, /* Information about the ORDER BY clause */
Select *pSelect, /* The whole SELECT statement */
int regData, /* First register holding data to be sorted */
+ int regOrigData, /* First register holding data before packing */
int nData, /* Number of elements in the data array */
int nPrefixReg /* No. of reg prior to regData available for use */
){
Vdbe *v = pParse->pVdbe; /* Stmt under construction */
int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
@@ -108130,18 +108323,20 @@
int regRecord = ++pParse->nMem; /* Assembled sorter record */
int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
assert( bSeq==0 || bSeq==1 );
+ assert( nData==1 || regData==regOrigData );
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
regBase = regData - nExpr - bSeq;
}else{
regBase = pParse->nMem + 1;
pParse->nMem += nBase;
}
- sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
+ sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
+ SQLITE_ECEL_DUP|SQLITE_ECEL_REF);
if( bSeq ){
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
}
if( nPrefixReg==0 ){
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
@@ -108215,11 +108410,11 @@
int iContinue /* Jump here to skip the current record */
){
if( iOffset>0 ){
int addr;
addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
+ sqlite3VdbeGoto(v, iContinue);
VdbeComment((v, "skip OFFSET records"));
sqlite3VdbeJumpHere(v, addr);
}
}
@@ -108347,11 +108542,11 @@
if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
ecelFlags = SQLITE_ECEL_DUP;
}else{
ecelFlags = 0;
}
- sqlite3ExprCodeExprList(pParse, pEList, regResult, ecelFlags);
+ sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags);
}
/* If the DISTINCT keyword was present on the SELECT statement
** and this row has been seen before, then do not make this row
** part of the result.
@@ -108463,11 +108658,11 @@
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
assert( pSort==0 );
}
#endif
if( pSort ){
- pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -108489,11 +108684,11 @@
if( pSort ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
- pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
@@ -108515,11 +108710,11 @@
** of the scan loop.
*/
case SRT_Mem: {
assert( nResultCol==1 );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
}else{
assert( regResult==iParm );
/* The LIMIT clause will jump out of the loop for us */
}
break;
@@ -108529,11 +108724,12 @@
case SRT_Coroutine: /* Send data to a co-routine */
case SRT_Output: { /* Return the results */
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol,
+ nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
@@ -108823,11 +109019,11 @@
struct ExprList_item *aOutEx = p->pEList->a;
#endif
if( pSort->labelBkOut ){
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
+ sqlite3VdbeGoto(v, addrBreak);
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
}
iTab = pSort->iECursor;
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
regRowid = 0;
@@ -109208,11 +109404,11 @@
** and other fields of Column are zeroed.
**
** Return SQLITE_OK on success. If a memory allocation error occurs,
** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
*/
-static int selectColumnsFromExprList(
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
i16 *pnCol, /* Write the number of columns here */
Column **paCol /* Write the new column list here */
){
@@ -109375,11 +109571,11 @@
** is disabled */
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
- selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
return 0;
@@ -109451,11 +109647,11 @@
assert( v!=0 );
if( sqlite3ExprIsInteger(p->pLimit, &n) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
+ sqlite3VdbeGoto(v, iBreak);
}else if( n>=0 && p->nSelectRow>(u64)n ){
p->nSelectRow = n;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -109554,11 +109750,11 @@
** \___________/ \_______________/
** p->pPrior p
**
**
** There is exactly one reference to the recursive-table in the FROM clause
-** of recursive-query, marked with the SrcList->a[].isRecursive flag.
+** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
**
** The setup-query runs once to generate an initial set of rows that go
** into a Queue table. Rows are extracted from the Queue table one by
** one. Each row extracted from Queue is output to pDest. Then the single
** extracted row (now in the iCurrent table) becomes the content of the
@@ -109619,11 +109815,11 @@
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
/* Locate the cursor number of the Current table */
for(i=0; ALWAYS(inSrc); i++){
- if( pSrc->a[i].isRecursive ){
+ if( pSrc->a[i].fg.isRecursive ){
iCurrent = pSrc->a[i].iCursor;
break;
}
}
@@ -109699,11 +109895,11 @@
assert( p->pPrior==0 );
p->pPrior = pSetup;
}
/* Keep running the loop until the Queue is empty */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
+ sqlite3VdbeGoto(v, addrTop);
sqlite3VdbeResolveLabel(v, addrBreak);
end_of_recursive_query:
sqlite3ExprListDelete(pParse->db, p->pOrderBy);
p->pOrderBy = pOrderBy;
@@ -110608,11 +110804,11 @@
}else{
VdbeNoopComment((v, "eof-A subroutine"));
addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
+ sqlite3VdbeGoto(v, addrEofA);
p->nSelectRow += pPrior->nSelectRow;
}
/* Generate a subroutine to run when the results from select B
** are exhausted and only data in select A remains.
@@ -110622,19 +110818,19 @@
if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
}else{
VdbeNoopComment((v, "eof-B subroutine"));
addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
+ sqlite3VdbeGoto(v, addrEofB);
}
/* Generate code to handle the case of AB
*/
VdbeNoopComment((v, "A-gt-B subroutine"));
@@ -110654,11 +110850,11 @@
addrAgtB = sqlite3VdbeCurrentAddr(v);
if( op==TK_ALL || op==TK_UNION ){
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
}
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
+ sqlite3VdbeGoto(v, labelCmpr);
/* This code runs once to initialize everything.
*/
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
@@ -111034,11 +111230,11 @@
** 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( (pSubitem->jointype & JT_OUTER)!=0 ){
+ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
return 0;
}
/* 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
@@ -111205,11 +111401,11 @@
nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
pSrc = pParent->pSrc; /* FROM clause of the outer query */
if( pSrc ){
assert( pParent==p ); /* First time through the loop */
- jointype = pSubitem->jointype;
+ jointype = pSubitem->fg.jointype;
}else{
assert( pParent!=p ); /* 2nd and subsequent times through the loop */
pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc==0 ){
assert( db->mallocFailed );
@@ -111245,11 +111441,11 @@
for(i=0; ia[i+iFrom].pUsing);
pSrc->a[i+iFrom] = pSubSrc->a[i];
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
- pSrc->a[iFrom].jointype = jointype;
+ pSrc->a[iFrom].fg.jointype = jointype;
/* Now begin substituting subquery result set expressions for
** references to the iParent in the outer query.
**
** Example:
@@ -111377,10 +111573,13 @@
** close would change the meaning of the LIMIT).
**
** (4) The inner query is the right operand of a LEFT JOIN. (The caller
** enforces this restriction since this routine does not have enough
** information to know.)
+**
+** (5) The WHERE clause expression originates in the ON or USING clause
+** of a LEFT JOIN.
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
@@ -111400,10 +111599,11 @@
}
while( pWhere->op==TK_AND ){
nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
pWhere = pWhere->pLeft;
}
+ if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
pNew = sqlite3ExprDup(db, pWhere, 0);
pNew = substExpr(db, pNew, iCursor, pSubq->pEList);
@@ -111496,13 +111696,13 @@
** was such a clause and the named index cannot be found, return
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
** pFrom->pIndex and return SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
- if( pFrom->pTab && pFrom->zIndexedBy ){
+ if( pFrom->pTab && pFrom->fg.isIndexedBy ){
Table *pTab = pFrom->pTab;
- char *zIndexedBy = pFrom->zIndexedBy;
+ char *zIndexedBy = pFrom->u1.zIndexedBy;
Index *pIdx;
for(pIdx=pTab->pIndex;
pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy);
pIdx=pIdx->pNext
);
@@ -111509,11 +111709,11 @@
if( !pIdx ){
sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
pParse->checkSchema = 1;
return SQLITE_ERROR;
}
- pFrom->pIndex = pIdx;
+ pFrom->pIBIndex = pIdx;
}
return SQLITE_OK;
}
/*
** Detect compound SELECT statements that use an ORDER BY clause with
@@ -111670,16 +111870,16 @@
Select *pSel;
Select *pLeft; /* Left-most SELECT statement */
int bMayRecursive; /* True if compound joined by UNION [ALL] */
With *pSavedWith; /* Initial value of pParse->pWith */
- /* If pCte->zErr is non-NULL at this point, then this is an illegal
+ /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
** recursive reference to CTE pCte. Leave an error in pParse and return
- ** early. If pCte->zErr is NULL, then this is not a recursive reference.
+ ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
** In this case, proceed. */
- if( pCte->zErr ){
- sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName);
+ if( pCte->zCteErr ){
+ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
return SQLITE_ERROR;
}
assert( pFrom->pTab==0 );
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
@@ -111704,11 +111904,11 @@
if( pItem->zDatabase==0
&& pItem->zName!=0
&& 0==sqlite3StrICmp(pItem->zName, pCte->zName)
){
pItem->pTab = pTab;
- pItem->isRecursive = 1;
+ pItem->fg.isRecursive = 1;
pTab->nRef++;
pSel->selFlags |= SF_Recursive;
}
}
}
@@ -111720,11 +111920,11 @@
);
return SQLITE_ERROR;
}
assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 ));
- pCte->zErr = "circular reference: %s";
+ pCte->zCteErr = "circular reference: %s";
pSavedWith = pParse->pWith;
pParse->pWith = pWith;
sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
@@ -111738,20 +111938,20 @@
return SQLITE_ERROR;
}
pEList = pCte->pCols;
}
- selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
if( bMayRecursive ){
if( pSel->selFlags & SF_Recursive ){
- pCte->zErr = "multiple recursive references: %s";
+ pCte->zCteErr = "multiple recursive references: %s";
}else{
- pCte->zErr = "recursive reference in a subquery: %s";
+ pCte->zCteErr = "recursive reference in a subquery: %s";
}
sqlite3WalkSelect(pWalker, pSel);
}
- pCte->zErr = 0;
+ pCte->zCteErr = 0;
pParse->pWith = pSavedWith;
}
return SQLITE_OK;
}
@@ -111834,12 +112034,12 @@
** an entry of the FROM clause is a subquery instead of a table or view,
** then create a transient table structure to describe the subquery.
*/
for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){
Table *pTab;
- assert( pFrom->isRecursive==0 || pFrom->pTab );
- if( pFrom->isRecursive ) continue;
+ assert( pFrom->fg.isRecursive==0 || pFrom->pTab );
+ if( pFrom->fg.isRecursive ) continue;
if( pFrom->pTab!=0 ){
/* This statement has already been prepared. There is no need
** to go further. */
assert( i==0 );
#ifndef SQLITE_OMIT_CTE
@@ -111861,11 +112061,11 @@
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nRef = 1;
pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
- selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
@@ -111998,11 +112198,11 @@
continue;
}
tableSeen = 1;
if( i>0 && zTName==0 ){
- if( (pFrom->jointype & JT_NATURAL)!=0
+ if( (pFrom->fg.jointype & JT_NATURAL)!=0
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
){
/* In a NATURAL join, omit the join columns from the
** table to the right of the join */
continue;
@@ -112284,11 +112484,11 @@
ExprList *pList = pF->pExpr->x.pList;
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
@@ -112525,11 +112725,11 @@
** for example. In that case, do not regenerate the code to manifest
** a view or the co-routine to implement a view. The first instance
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
- if( pItem->viaCoroutine==0 ){
+ if( pItem->fg.viaCoroutine==0 ){
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
}
@@ -112543,11 +112743,11 @@
pParse->nHeight += sqlite3SelectExprHeight(p);
/* Make copies of constant WHERE-clause terms in the outer query down
** inside the subquery. This can help the subquery to run more efficiently.
*/
- if( (pItem->jointype & JT_OUTER)==0
+ if( (pItem->fg.jointype & JT_OUTER)==0
&& pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
){
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){
SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
@@ -112572,11 +112772,11 @@
pItem->addrFillSub = addrTop;
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
- pItem->viaCoroutine = 1;
+ pItem->fg.viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
@@ -112590,11 +112790,11 @@
int retAddr;
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
- if( pItem->isCorrelated==0 ){
+ if( pItem->fg.isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
@@ -112688,11 +112888,11 @@
*/
iEnd = sqlite3VdbeMakeLabel(v);
p->nSelectRow = LARGEST_INT64;
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
- sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen;
+ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
sSort.sortFlags |= SORTFLAG_UseSorter;
}
/* Open an ephemeral index to use for the distinct set.
*/
@@ -112904,11 +113104,11 @@
j++;
}
}
regBase = sqlite3GetTempRange(pParse, nCol);
sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
+ sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
j = nGroupBy;
for(i=0; iiSorterColumn>=j ){
int r1 = j + regBase;
@@ -113016,11 +113216,11 @@
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output final row"));
/* Jump over the subroutines
*/
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
+ sqlite3VdbeGoto(v, addrEnd);
/* Generate a subroutine that outputs a single row of the result
** set. This subroutine first looks at the iUseFlag. If iUseFlag
** is less than or equal to zero, the subroutine is a no-op. If
** the processing calls for the query to abort, this subroutine
@@ -113170,11 +113370,11 @@
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
assert( pMinMax==0 || pMinMax->nExpr==1 );
if( sqlite3WhereIsOrdered(pWInfo)>0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
+ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
}
sqlite3WhereEnd(pWInfo);
finalizeAggFunctions(pParse, &sAggInfo);
@@ -114831,20 +115031,23 @@
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
- ** the key for accessing each index.
+ ** the key for accessing each index.
+ **
+ ** FIXME: Be smarter about omitting indexes that use expressions.
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
}else{
reg = 0;
for(i=0; inKeyCol; i++){
- if( aXRef[pIdx->aiColumn[i]]>=0 ){
+ i16 iIdxCol = pIdx->aiColumn[i];
+ if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
reg = ++pParse->nMem;
break;
}
}
}
@@ -114940,20 +115143,21 @@
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
WHERE_ONEPASS_DESIRED, iIdxCur);
if( pWInfo==0 ) goto update_cleanup;
okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
for(i=0; iaiColumn[i]>=(-1) );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
iPk+i);
}
if( okOnePass ){
sqlite3VdbeChangeToNoop(v, addrOpen);
nKey = nPk;
regKey = iPk;
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
- sqlite3IndexAffinityStr(v, pPk), nPk);
+ sqlite3IndexAffinityStr(db, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
}
sqlite3WhereEnd(pWInfo);
}
@@ -115186,11 +115390,11 @@
/* Nothing to do at end-of-loop for a single-pass */
}else if( pPk ){
sqlite3VdbeResolveLabel(v, labelContinue);
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
}else{
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
+ sqlite3VdbeGoto(v, labelContinue);
}
sqlite3VdbeResolveLabel(v, labelBreak);
/* Close all tables */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
@@ -115768,10 +115972,11 @@
memcpy(zCopy, zName, nName+1);
pMod->zName = zCopy;
pMod->pModule = pModule;
pMod->pAux = pAux;
pMod->xDestroy = xDestroy;
+ pMod->pEpoTab = 0;
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
assert( pDel==0 || pDel==pMod );
if( pDel ){
db->mallocFailed = 1;
sqlite3DbFree(db, pDel);
@@ -115995,27 +116200,21 @@
** The string is not copied - the pointer is stored. The
** string will be freed automatically when the table is
** deleted.
*/
static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
- int i = pTable->nModuleArg++;
- int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
+ int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
char **azModuleArg;
azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
if( azModuleArg==0 ){
- int j;
- for(j=0; jazModuleArg[j]);
- }
sqlite3DbFree(db, zArg);
- sqlite3DbFree(db, pTable->azModuleArg);
- pTable->nModuleArg = 0;
}else{
+ int i = pTable->nModuleArg++;
azModuleArg[i] = zArg;
azModuleArg[i+1] = 0;
+ pTable->azModuleArg = azModuleArg;
}
- pTable->azModuleArg = azModuleArg;
}
/*
** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
** statement. The module name has been parsed, but the optional list
@@ -116138,11 +116337,11 @@
sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
iReg = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
+ sqlite3VdbeLoadString(v, iReg, pTab->zName);
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
}
/* If we are rereading the sqlite_master table create the in-memory
** record of the table. The xConnect() method is not called until
@@ -116414,11 +116613,11 @@
/* If the module has been registered and includes a Create method,
** invoke it now. If the module has not been registered, return an
** error. Otherwise, do nothing.
*/
- if( !pMod ){
+ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
*pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
rc = SQLITE_ERROR;
}else{
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
}
@@ -116516,18 +116715,21 @@
Table *pTab;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
VTable *p;
+ int (*xDestroy)(sqlite3_vtab *);
for(p=pTab->pVTable; p; p=p->pNext){
assert( p->pVtab );
if( p->pVtab->nRef>0 ){
return SQLITE_LOCKED;
}
}
p = vtabDisconnectAll(db, pTab);
- rc = p->pMod->pModule->xDestroy(p->pVtab);
+ xDestroy = p->pMod->pModule->xDestroy;
+ assert( xDestroy!=0 ); /* Checked before the virtual table is created */
+ rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->pVTable==p && p->pNext==0 );
p->pVtab = 0;
pTab->pVTable = 0;
@@ -116801,10 +117003,71 @@
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
}else{
pToplevel->db->mallocFailed = 1;
}
}
+
+/*
+** Check to see if virtual tale module pMod can be have an eponymous
+** virtual table instance. If it can, create one if one does not already
+** exist. Return non-zero if the eponymous virtual table instance exists
+** when this routine returns, and return zero if it does not exist.
+**
+** An eponymous virtual table instance is one that is named after its
+** module, and more importantly, does not require a CREATE VIRTUAL TABLE
+** statement in order to come into existance. Eponymous virtual table
+** instances always exist. They cannot be DROP-ed.
+**
+** Any virtual table module for which xConnect and xCreate are the same
+** method can have an eponymous virtual table instance.
+*/
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
+ const sqlite3_module *pModule = pMod->pModule;
+ Table *pTab;
+ char *zErr = 0;
+ int nName;
+ int rc;
+ sqlite3 *db = pParse->db;
+ if( pMod->pEpoTab ) return 1;
+ if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
+ nName = sqlite3Strlen30(pMod->zName) + 1;
+ pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName);
+ if( pTab==0 ) return 0;
+ pMod->pEpoTab = pTab;
+ pTab->zName = (char*)&pTab[1];
+ memcpy(pTab->zName, pMod->zName, nName);
+ pTab->nRef = 1;
+ pTab->pSchema = db->aDb[0].pSchema;
+ pTab->tabFlags |= TF_Virtual;
+ pTab->nModuleArg = 0;
+ pTab->iPKey = -1;
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ addModuleArgument(db, pTab, 0);
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+ if( rc ){
+ sqlite3ErrorMsg(pParse, "%s", zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3VtabEponymousTableClear(db, pMod);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Erase the eponymous virtual table instance associated with
+** virtual table module pMod, if it exists.
+*/
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
+ Table *pTab = pMod->pEpoTab;
+ if( (pTab = pMod->pEpoTab)!=0 ){
+ sqlite3DeleteColumnNames(db, pTab);
+ sqlite3VtabClear(db, pTab);
+ sqlite3DbFree(db, pTab);
+ pMod->pEpoTab = 0;
+ }
+}
/*
** Return the ON CONFLICT resolution mode in effect for the virtual
** table update operation currently in progress.
**
@@ -117172,16 +117435,18 @@
*/
struct WhereScan {
WhereClause *pOrigWC; /* Original, innermost WhereClause */
WhereClause *pWC; /* WhereClause currently being scanned */
char *zCollName; /* Required collating sequence, if not NULL */
+ Expr *pIdxExpr; /* Search for this index expression */
char idxaff; /* Must match this affinity, if zCollName!=NULL */
unsigned char nEquiv; /* Number of entries in aEquiv[] */
unsigned char iEquiv; /* Next unused slot in aEquiv[] */
u32 opMask; /* Acceptable operators */
int k; /* Resume scanning at this->pWC->a[this->k] */
- int aEquiv[22]; /* Cursor,Column pairs for equivalence classes */
+ int aiCur[11]; /* Cursors in the equivalence class */
+ i16 aiColumn[11]; /* Corresponding column number in the eq-class */
};
/*
** An instance of the following structure holds all information about a
** WHERE clause. Mostly this is a container for one or more WhereTerms.
@@ -117361,10 +117626,11 @@
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
+SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
@@ -117437,10 +117703,20 @@
if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
sqlite3StrAccumAppendAll(pStr, zColumn);
sqlite3StrAccumAppend(pStr, zOp, 1);
sqlite3StrAccumAppend(pStr, "?", 1);
}
+
+/*
+** Return the name of the i-th column of the pIdx index.
+*/
+static const char *explainIndexColumnName(Index *pIdx, int i){
+ i = pIdx->aiColumn[i];
+ if( i==(-2) ) return "";
+ if( i==(-1) ) return "rowid";
+ return pIdx->pTable->aCol[i].zName;
+}
/*
** Argument pLevel describes a strategy for scanning table pTab. This
** function appends text to pStr that describes the subset of table
** rows scanned by the strategy in the form of an SQL expression.
@@ -117457,32 +117733,26 @@
static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
Index *pIndex = pLoop->u.btree.pIndex;
u16 nEq = pLoop->u.btree.nEq;
u16 nSkip = pLoop->nSkip;
int i, j;
- Column *aCol = pTab->aCol;
- i16 *aiColumn = pIndex->aiColumn;
if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
sqlite3StrAccumAppend(pStr, " (", 2);
for(i=0; i=nSkip ){
- explainAppendTerm(pStr, i, z, "=");
- }else{
- if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
- sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
- }
+ const char *z = explainIndexColumnName(pIndex, i);
+ if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+ sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
}
j = i;
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
- char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
+ const char *z = explainIndexColumnName(pIndex, i);
explainAppendTerm(pStr, i++, z, ">");
}
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
- char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
+ const char *z = explainIndexColumnName(pIndex, j);
explainAppendTerm(pStr, i, z, "<");
}
sqlite3StrAccumAppend(pStr, ")", 1);
}
@@ -117562,23 +117832,22 @@
sqlite3StrAccumAppend(&str, " USING ", 7);
sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
explainIndexRange(&str, pLoop, pItem->pTab);
}
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
- const char *zRange;
+ const char *zRangeOp;
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
- zRange = "(rowid=?)";
+ zRangeOp = "=";
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
- zRange = "(rowid>? AND rowid)";
+ zRangeOp = ">? AND rowid<";
}else if( flags&WHERE_BTM_LIMIT ){
- zRange = "(rowid>?)";
+ zRangeOp = ">";
}else{
assert( flags&WHERE_TOP_LIMIT);
- zRange = "(rowid)";
+ zRangeOp = "<";
}
- sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
- sqlite3StrAccumAppendAll(&str, zRange);
+ sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
@@ -117889,11 +118158,11 @@
*/
regBase = pParse->nMem + 1;
nReg = pLoop->u.btree.nEq + nExtraReg;
pParse->nMem += nReg;
- zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
+ zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx));
if( !zAff ){
pParse->db->mallocFailed = 1;
}
if( nSkip ){
@@ -118043,18 +118312,18 @@
/* If this is the right table of a LEFT OUTER JOIN, allocate and
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
- if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
+ if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
/* Special case of a FROM clause subquery implemented as a co-routine */
- if( pTabItem->viaCoroutine ){
+ if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
VdbeCoverage(v);
VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
@@ -118777,11 +119046,11 @@
if( pAndExpr ){
pAndExpr->pLeft = 0;
sqlite3ExprDelete(db, pAndExpr);
}
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
+ sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
@@ -118792,11 +119061,11 @@
** scan of the entire table.
*/
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
- if( pTabItem->isRecursive ){
+ if( pTabItem->fg.isRecursive ){
/* Tables marked isRecursive have only a single row that is stored in
** a pseudo-cursor. No need to Rewind or Next such cursors. */
pLevel->op = OP_Noop;
}else{
pLevel->op = aStep[bRev];
@@ -119699,10 +119968,55 @@
}
pS = pS->pPrior;
}
return mask;
}
+
+/*
+** 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
+** of the column that is indexed, or -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(
+ SrcList *pFrom, /* The FROM clause */
+ 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 */
+){
+ Index *pIdx;
+ int i;
+ int iCur;
+ if( pExpr->op==TK_COLUMN ){
+ *piCur = pExpr->iTable;
+ *piColumn = 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]!=(-2) ) continue;
+ if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ *piCur = iCur;
+ *piColumn = -2;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
/*
** 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
** subexpression and populate all the other fields of the WhereTerm
@@ -119770,20 +120084,23 @@
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
+ int iCur, iColumn;
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
- if( pLeft->op==TK_COLUMN ){
- pTerm->leftCursor = pLeft->iTable;
- pTerm->u.leftColumn = pLeft->iColumn;
+ if( exprMightBeIndexed(pSrc, prereqLeft, pLeft, &iCur, &iColumn) ){
+ pTerm->leftCursor = iCur;
+ pTerm->u.leftColumn = iColumn;
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
- if( pRight && pRight->op==TK_COLUMN ){
+ if( pRight
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, pRight, &iCur, &iColumn)
+ ){
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
if( pTerm->leftCursor>=0 ){
int idxNew;
@@ -119808,12 +120125,12 @@
pDup = pExpr;
pNew = pTerm;
}
exprCommute(pParse, pDup);
pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
- pNew->leftCursor = pLeft->iTable;
- pNew->u.leftColumn = pLeft->iColumn;
+ pNew->leftCursor = iCur;
+ pNew->u.leftColumn = iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
}
@@ -120152,10 +120469,50 @@
int i;
for(i=pWC->nTerm-1; i>=0; i--){
exprAnalyze(pTabList, pWC, i);
}
}
+
+/*
+** For table-valued-functions, transform the function arguments into
+** new WHERE clause terms.
+**
+** Each function argument translates into an equality constraint against
+** a HIDDEN column in the table.
+*/
+SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
+ Parse *pParse, /* Parsing context */
+ struct SrcList_item *pItem, /* The FROM clause term to process */
+ WhereClause *pWC /* Xfer function arguments to here */
+){
+ Table *pTab;
+ int j, k;
+ ExprList *pArgs;
+ Expr *pColRef;
+ Expr *pTerm;
+ if( pItem->fg.isTabFunc==0 ) return;
+ pTab = pItem->pTab;
+ assert( pTab!=0 );
+ pArgs = pItem->u1.pFuncArg;
+ assert( pArgs!=0 );
+ for(j=k=0; jnExpr; j++){
+ while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; }
+ if( k>=pTab->nCol ){
+ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
+ pTab->zName, j);
+ return;
+ }
+ pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ if( pColRef==0 ) return;
+ pColRef->iTable = pItem->iCursor;
+ pColRef->iColumn = k++;
+ pColRef->pTab = pTab;
+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+ whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+ }
+}
/************** End of whereexpr.c *******************************************/
/************** Begin file where.c *******************************************/
/*
** 2001 September 15
@@ -120328,41 +120685,44 @@
** established when the pScan object was initialized by whereScanInit().
** Return NULL if there are no more matching WhereTerms.
*/
static WhereTerm *whereScanNext(WhereScan *pScan){
int iCur; /* The cursor on the LHS of the term */
- int iColumn; /* The column on the LHS of the term. -1 for IPK */
+ i16 iColumn; /* The column on the LHS of the term. -1 for IPK */
Expr *pX; /* An expression being tested */
WhereClause *pWC; /* Shorthand for pScan->pWC */
WhereTerm *pTerm; /* The term being tested */
int k = pScan->k; /* Where to start scanning */
while( pScan->iEquiv<=pScan->nEquiv ){
- iCur = pScan->aEquiv[pScan->iEquiv-2];
- iColumn = pScan->aEquiv[pScan->iEquiv-1];
+ iCur = pScan->aiCur[pScan->iEquiv-1];
+ iColumn = pScan->aiColumn[pScan->iEquiv-1];
+ assert( iColumn!=(-2) || pScan->pIdxExpr!=0 );
while( (pWC = pScan->pWC)!=0 ){
for(pTerm=pWC->a+k; knTerm; k++, pTerm++){
if( pTerm->leftCursor==iCur
&& pTerm->u.leftColumn==iColumn
- && (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ && (iColumn!=(-2)
+ || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
+ && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
if( (pTerm->eOperator & WO_EQUIV)!=0
- && pScan->nEquivaEquiv)
+ && pScan->nEquivaiCur)
){
int j;
pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
assert( pX->op==TK_COLUMN );
- for(j=0; jnEquiv; j+=2){
- if( pScan->aEquiv[j]==pX->iTable
- && pScan->aEquiv[j+1]==pX->iColumn ){
+ for(j=0; jnEquiv; j++){
+ if( pScan->aiCur[j]==pX->iTable
+ && pScan->aiColumn[j]==pX->iColumn ){
break;
}
}
if( j==pScan->nEquiv ){
- pScan->aEquiv[j] = pX->iTable;
- pScan->aEquiv[j+1] = pX->iColumn;
- pScan->nEquiv += 2;
+ pScan->aiCur[j] = pX->iTable;
+ pScan->aiColumn[j] = pX->iColumn;
+ pScan->nEquiv++;
}
}
if( (pTerm->eOperator & pScan->opMask)!=0 ){
/* Verify the affinity and collating sequence match */
if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
@@ -120380,12 +120740,12 @@
continue;
}
}
if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
&& (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
- && pX->iTable==pScan->aEquiv[0]
- && pX->iColumn==pScan->aEquiv[1]
+ && pX->iTable==pScan->aiCur[0]
+ && pX->iColumn==pScan->aiColumn[0]
){
testcase( pTerm->eOperator & WO_IS );
continue;
}
pScan->k = k+1;
@@ -120396,11 +120756,11 @@
pScan->pWC = pScan->pWC->pOuter;
k = 0;
}
pScan->pWC = pScan->pOrigWC;
k = 0;
- pScan->iEquiv += 2;
+ pScan->iEquiv++;
}
return 0;
}
/*
@@ -120425,49 +120785,53 @@
int iCur, /* Cursor to scan for */
int iColumn, /* Column to scan for */
u32 opMask, /* Operator(s) to scan for */
Index *pIdx /* Must be compatible with this index */
){
- int j;
+ int j = 0;
/* memset(pScan, 0, sizeof(*pScan)); */
pScan->pOrigWC = pWC;
pScan->pWC = pWC;
+ pScan->pIdxExpr = 0;
+ if( pIdx ){
+ j = iColumn;
+ iColumn = pIdx->aiColumn[j];
+ if( iColumn==(-2) ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
+ }
if( pIdx && iColumn>=0 ){
pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
- for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
- if( NEVER(j>pIdx->nColumn) ) return 0;
- }
pScan->zCollName = pIdx->azColl[j];
}else{
pScan->idxaff = 0;
pScan->zCollName = 0;
}
pScan->opMask = opMask;
pScan->k = 0;
- pScan->aEquiv[0] = iCur;
- pScan->aEquiv[1] = iColumn;
- pScan->nEquiv = 2;
- pScan->iEquiv = 2;
+ pScan->aiCur[0] = iCur;
+ pScan->aiColumn[0] = iColumn;
+ pScan->nEquiv = 1;
+ pScan->iEquiv = 1;
return whereScanNext(pScan);
}
/*
** Search for a term in the WHERE clause that is of the form "X "
** where X is a reference to the iColumn of table iCur and is one of
** the WO_xx operator codes specified by the op parameter.
** Return a pointer to the term. Return 0 if not found.
+**
+** If pIdx!=0 then search for terms matching the iColumn-th column of pIdx
+** rather than the iColumn-th column of table iCur.
**
** The term returned might by Y= if there is another constraint in
** the WHERE clause that specifies that X=Y. Any such constraints will be
** identified by the WO_EQUIV bit in the pTerm->eOperator field. The
-** aEquiv[] array holds X and all its equivalents, with each SQL variable
-** taking up two slots in aEquiv[]. The first slot is for the cursor number
-** and the second is for the column number. There are 22 slots in aEquiv[]
-** so that means we can look for X plus up to 10 other equivalent values.
-** Hence a search for X will return if X=A1 and A1=A2 and A2=A3
-** and ... and A9=A10 and A10=.
+** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
+** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
+** other equivalent values. Hence a search for X will return if X=A1
+** and A1=A2 and A2=A3 and ... and A9=A10 and A10=.
**
** If there are multiple terms in the WHERE clause of the form "X "
** then try for the one with no dependencies on - in other words where
** is a constant expression of some kind. Only return entries of
** the form "X Y" where Y is a column in another table if no terms of
@@ -120531,10 +120895,29 @@
}
}
return -1;
}
+
+/*
+** Return TRUE if the iCol-th column of index pIdx is NOT NULL
+*/
+static int indexColumnNotNull(Index *pIdx, int iCol){
+ int j;
+ assert( pIdx!=0 );
+ assert( iCol>=0 && iColnColumn );
+ j = pIdx->aiColumn[iCol];
+ if( j>=0 ){
+ return pIdx->pTable->aCol[j].notNull;
+ }else if( j==(-1) ){
+ return 1;
+ }else{
+ assert( j==(-2) );
+ return 0; /* Assume an indexed expression can always yield a NULL */
+
+ }
+}
/*
** Return true if the DISTINCT expression-list passed as the third argument
** is redundant.
**
@@ -120582,16 +120965,13 @@
** contain a "col=X" term are subject to a NOT NULL constraint.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( !IsUniqueIndex(pIdx) ) continue;
for(i=0; inKeyCol; i++){
- i16 iCol = pIdx->aiColumn[i];
- if( 0==sqlite3WhereFindTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
- int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
- if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){
- break;
- }
+ if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){
+ if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break;
+ if( indexColumnNotNull(pIdx, i)==0 ) break;
}
}
if( i==pIdx->nKeyCol ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
@@ -120866,11 +121246,11 @@
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
sqlite3ExprCachePush(pParse);
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
- if( pTabItem->viaCoroutine ){
+ if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
@@ -120885,14 +121265,14 @@
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
- if( pTabItem->viaCoroutine ){
+ if( pTabItem->fg.viaCoroutine ){
translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- pTabItem->viaCoroutine = 0;
+ sqlite3VdbeGoto(v, addrTop);
+ pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
}
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
@@ -120939,10 +121319,11 @@
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ALL );
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
+ assert( pTerm->u.leftColumn>=(-1) );
nTerm++;
}
/* If the ORDER BY clause contains only columns in the current
** virtual table then allocate space for the aOrderBy part of
@@ -120994,10 +121375,11 @@
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_ALL );
if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
+ assert( pTerm->u.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
op = (u8)pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
pIdxCons[j].op = op;
@@ -121283,10 +121665,24 @@
nRet -= 20; assert( 20==sqlite3LogEst(4) );
}
}
return nRet;
}
+
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+/*
+** Return the affinity for a single column of an index.
+*/
+static char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
+ if( !pIdx->zColAff ){
+ if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
+ }
+ return pIdx->zColAff[iCol];
+}
+#endif
+
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** This function is called to estimate the number of rows visited by a
** range-scan on a skip-scan index. For example:
@@ -121334,11 +121730,11 @@
sqlite3 *db = pParse->db;
int nLower = -1;
int nUpper = p->nSample+1;
int rc = SQLITE_OK;
int iCol = p->aiColumn[nEq];
- u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
+ u8 aff = sqlite3IndexColumnAffinity(db, p, iCol);
CollSeq *pColl;
sqlite3_value *p1 = 0; /* Value extracted from pLower */
sqlite3_value *p2 = 0; /* Value extracted from pUpper */
sqlite3_value *pVal = 0; /* Value extracted from record */
@@ -121482,15 +121878,12 @@
if( pRec ){
testcase( pRec->nField!=pBuilder->nRecValid );
pRec->nField = pBuilder->nRecValid;
}
- if( nEq==p->nKeyCol ){
- aff = SQLITE_AFF_INTEGER;
- }else{
- aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
- }
+ aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq);
+ assert( nEq!=p->nKeyCol || aff==SQLITE_AFF_INTEGER );
/* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){
iLower = 0;
iUpper = p->nRowEst0;
}else{
@@ -121644,11 +122037,11 @@
if( nEq>=p->nColumn ){
*pnRow = 1;
return SQLITE_OK;
}
- aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
+ aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq-1);
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
pBuilder->pRec = pRec;
if( rc!=SQLITE_OK ) return rc;
if( bOk==0 ) return SQLITE_NOTFOUND;
pBuilder->nRecValid = nEq;
@@ -122071,22 +122464,24 @@
/* If pBuilder->pOrSet is defined, then only keep track of the costs
** and prereqs.
*/
if( pBuilder->pOrSet!=0 ){
+ if( pTemplate->nLTerm ){
#if WHERETRACE_ENABLED
- u16 n = pBuilder->pOrSet->n;
- int x =
+ u16 n = pBuilder->pOrSet->n;
+ int x =
#endif
- whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
pTemplate->nOut);
#if WHERETRACE_ENABLED /* 0x8 */
- if( sqlite3WhereTrace & 0x8 ){
- sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
- whereLoopPrint(pTemplate, pBuilder->pWC);
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
}
-#endif
return SQLITE_OK;
}
/* Look for an existing WhereLoop to replace with pTemplate
*/
@@ -122272,11 +122667,10 @@
u16 saved_nLTerm; /* Original value of pNew->nLTerm */
u16 saved_nEq; /* Original value of pNew->u.btree.nEq */
u16 saved_nSkip; /* Original value of pNew->nSkip */
u32 saved_wsFlags; /* Original value of pNew->wsFlags */
LogEst saved_nOut; /* Original value of pNew->nOut */
- int iCol; /* Index of the column in the table */
int rc = SQLITE_OK; /* Return code */
LogEst rSize; /* Number of rows in the table */
LogEst rLogSize; /* Logarithm of table size */
WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
@@ -122285,28 +122679,27 @@
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
- }else if( /*pProbe->tnum<=0 ||*/ (pSrc->jointype & JT_LEFT)!=0 ){
+ }else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
}else{
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
assert( pNew->u.btree.nEqnColumn );
- iCol = pProbe->aiColumn[pNew->u.btree.nEq];
- pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
- opMask, pProbe);
saved_nEq = pNew->u.btree.nEq;
saved_nSkip = pNew->nSkip;
saved_nLTerm = pNew->nLTerm;
saved_wsFlags = pNew->wsFlags;
saved_prereq = pNew->prereq;
saved_nOut = pNew->nOut;
+ pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq,
+ opMask, pProbe);
pNew->rSetup = 0;
rSize = pProbe->aiRowLogEst[0];
rLogSize = estLog(rSize);
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */
@@ -122315,11 +122708,11 @@
int nIn = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nRecValid = pBuilder->nRecValid;
#endif
if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
- && (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
+ && indexColumnNotNull(pProbe, saved_nEq)
){
continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
}
if( pTerm->prereqRight & pNew->maskSelf ) continue;
@@ -122352,12 +122745,14 @@
}
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
** changes "x IN (?)" into "x=?". */
}else if( eOp & (WO_EQ|WO_IS) ){
+ int iCol = pProbe->aiColumn[saved_nEq];
pNew->wsFlags |= WHERE_COLUMN_EQ;
- if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
+ assert( saved_nEq==pNew->u.btree.nEq );
+ if( iCol==(-1) || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){
if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{
pNew->wsFlags |= WHERE_ONEROW;
}
@@ -122404,11 +122799,11 @@
}else{
int nEq = ++pNew->u.btree.nEq;
assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
assert( pNew->nOut==saved_nOut );
- if( pTerm->truthProb<=0 && iCol>=0 ){
+ if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
assert( (eOp & WO_IN) || nIn==0 );
testcase( eOp & WO_IN );
pNew->nOut += pTerm->truthProb;
pNew->nOut -= nIn;
}else{
@@ -122580,10 +122975,14 @@
** in the current query. Return true if it can be and false if not.
*/
static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
int i;
WhereTerm *pTerm;
+ while( pWhere->op==TK_AND ){
+ if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0;
+ pWhere = pWhere->pRight;
+ }
for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){
Expr *pExpr = pTerm->pExpr;
if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
&& (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
){
@@ -122655,13 +123054,13 @@
pSrc = pTabList->a + pNew->iTab;
pTab = pSrc->pTab;
pWC = pBuilder->pWC;
assert( !IsVirtual(pSrc->pTab) );
- if( pSrc->pIndex ){
+ if( pSrc->pIBIndex ){
/* An INDEXED BY clause specifies a particular index to use */
- pProbe = pSrc->pIndex;
+ pProbe = pSrc->pIBIndex;
}else if( !HasRowid(pTab) ){
pProbe = pTab->pIndex;
}else{
/* There is no INDEXED BY clause. Create a fake Index object in local
** variable sPk to represent the rowid primary key index. Make this
@@ -122677,11 +123076,11 @@
sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
- if( pSrc->notIndexed==0 ){
+ if( pSrc->fg.notIndexed==0 ){
/* The real indices of the table are only considered if the
** NOT INDEXED qualifier is omitted from the FROM clause */
sPk.pNext = pFirst;
}
pProbe = &sPk;
@@ -122689,18 +123088,18 @@
rSize = pTab->nRowLogEst;
rLogSize = estLog(rSize);
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
- if( !pBuilder->pOrSet /* Not part of an OR optimization */
+ if( !pBuilder->pOrSet /* Not part of an OR optimization */
&& (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
- && pSrc->pIndex==0 /* Has no INDEXED BY clause */
- && !pSrc->notIndexed /* Has no NOT INDEXED clause */
- && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
- && !pSrc->isCorrelated /* Not a correlated subquery */
- && !pSrc->isRecursive /* Not a recursive common table expression. */
+ && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */
+ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
+ && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
+ && !pSrc->fg.isCorrelated /* Not a correlated subquery */
+ && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
){
/* Generate auto-index WhereLoops */
WhereTerm *pTerm;
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
for(pTerm=pWC->a; rc==SQLITE_OK && pTermpRec = 0;
#endif
/* If there was an INDEXED BY clause, then only that one index is
** considered. */
- if( pSrc->pIndex ) break;
+ if( pSrc->pIBIndex ) break;
}
return rc;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -123163,20 +123562,20 @@
whereLoopInit(pNew);
for(iTab=0, pItem=pTabList->a; pItemiTab = iTab;
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
- if( ((pItem->jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
+ if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
/* This condition is true when pItem is the FROM clause term on the
** right-hand-side of a LEFT or CROSS JOIN. */
mExtra = mPrior;
}
- priorJointype = pItem->jointype;
+ priorJointype = pItem->fg.jointype;
if( IsVirtual(pItem->pTab) ){
struct SrcList_item *p;
for(p=&pItem[1]; pjointype & (JT_LEFT|JT_CROSS)) ){
+ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
}
}
rc = whereLoopAddVirtual(pBuilder, mExtra, mUnusable);
}else{
@@ -123902,11 +124301,11 @@
if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
assert( pWInfo->pTabList->nSrc>=1 );
pItem = pWInfo->pTabList->a;
pTab = pItem->pTab;
if( IsVirtual(pTab) ) return 0;
- if( pItem->zIndexedBy ) return 0;
+ if( pItem->fg.isIndexedBy ) return 0;
iCur = pItem->iCursor;
pWC = &pWInfo->sWC;
pLoop = pBuilder->pNew;
pLoop->wsFlags = 0;
pLoop->nSkip = 0;
@@ -123927,11 +124326,11 @@
|| pIdx->pPartIdxWhere!=0
|| pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
) continue;
opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
for(j=0; jnKeyCol; j++){
- pTerm = sqlite3WhereFindTerm(pWC, iCur, pIdx->aiColumn[j], 0, opMask, pIdx);
+ pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx);
if( pTerm==0 ) break;
testcase( pTerm->eOperator & WO_IS );
pLoop->aLTerm[j] = pTerm;
}
if( j!=pIdx->nKeyCol ) continue;
@@ -124167,35 +124566,30 @@
}
}
/* Assign a bit from the bitmask to every term in the FROM clause.
**
- ** When assigning bitmask values to FROM clause cursors, it must be
- ** the case that if X is the bitmask for the N-th FROM clause term then
- ** the bitmask for all FROM clause terms to the left of the N-th term
- ** is (X-1). An expression from the ON clause of a LEFT JOIN can use
- ** its Expr.iRightJoinTable value to find the bitmask of the right table
- ** of the join. Subtracting one from the right table bitmask gives a
- ** bitmask for all tables to the left of the join. Knowing the bitmask
- ** for all tables to the left of a left join is important. Ticket #3015.
+ ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in
** pTabList, not just the first nTabList tables. nTabList is normally
** equal to pTabList->nSrc but might be shortened to 1 if the
** WHERE_ONETABLE_ONLY flag is set.
*/
for(ii=0; iinSrc; ii++){
createMask(pMaskSet, pTabList->a[ii].iCursor);
- }
-#ifndef NDEBUG
- {
- Bitmask toTheLeft = 0;
- for(ii=0; iinSrc; ii++){
- Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
- assert( (m-1)==toTheLeft );
- toTheLeft |= m;
- }
+ sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
+ }
+#ifdef SQLITE_DEBUG
+ for(ii=0; iinSrc; ii++){
+ Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
+ assert( m==MASKBIT(ii) );
}
#endif
/* Analyze all of the subexpressions. */
sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
@@ -124289,11 +124683,11 @@
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
while( pWInfo->nLevel>=2 ){
WhereTerm *pTerm, *pEnd;
pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
- if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
+ if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
&& (pLoop->wsFlags & WHERE_ONEROW)==0
){
break;
}
@@ -124527,11 +124921,11 @@
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
+ sqlite3VdbeGoto(v, pLevel->addrSkip);
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
if( pLevel->addrLikeRep ){
@@ -124555,11 +124949,11 @@
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
}
if( pLevel->op==OP_Return ){
sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
}else{
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
+ sqlite3VdbeGoto(v, pLevel->addrFirst);
}
sqlite3VdbeJumpHere(v, addr);
}
VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
@@ -124582,11 +124976,11 @@
/* For a co-routine, change all OP_Column references to the table of
** the co-routine into OP_Copy of result contained in a register.
** OP_Rowid becomes OP_Null.
*/
- if( pTabItem->viaCoroutine && !db->mallocFailed ){
+ if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
pTabItem->regResult);
continue;
}
@@ -124816,10 +125210,33 @@
){
pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zStart = pPreOp->z;
pOut->zEnd = pOperand->zEnd;
}
+
+ /* Add a single new term to an ExprList that is used to store a
+ ** list of identifiers. Report an error if the ID list contains
+ ** a COLLATE clause or an ASC or DESC keyword, except ignore the
+ ** error while parsing a legacy schema.
+ */
+ static ExprList *parserAddExprIdListTerm(
+ Parse *pParse,
+ ExprList *pPrior,
+ Token *pIdToken,
+ int hasCollate,
+ int sortOrder
+ ){
+ ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
+ if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
+ && pParse->db->init.busy==0
+ ){
+ sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
+ pIdToken->n, pIdToken->z);
+ }
+ sqlite3ExprListSetName(pParse, p, pIdToken, 1);
+ return p;
+ }
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
/*
** These constants (all generated automatically by the parser generator)
@@ -124860,14 +125277,21 @@
** zero the stack is dynamically sized using realloc()
** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument
** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
-** YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
+** YY_MAX_SHIFT Maximum value for shift actions
+** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** YY_MIN_REDUCE Maximum value for reduce actions
+** YY_ERROR_ACTION The yy_action[] code for syntax error
+** YY_ACCEPT_ACTION The yy_action[] code for accept
+** YY_NO_ACTION The yy_action[] code for no-op
*/
#define YYCODETYPE unsigned char
#define YYNOCODE 254
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 70
@@ -124896,16 +125320,21 @@
#endif
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 642
-#define YYNRULE 327
#define YYFALLBACK 1
-#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
-#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
-#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
+#define YYNSTATE 436
+#define YYNRULE 328
+#define YY_MAX_SHIFT 435
+#define YY_MIN_SHIFTREDUCE 649
+#define YY_MAX_SHIFTREDUCE 976
+#define YY_MIN_REDUCE 977
+#define YY_MAX_REDUCE 1304
+#define YY_ERROR_ACTION 1305
+#define YY_ACCEPT_ACTION 1306
+#define YY_NO_ACTION 1307
/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
static const YYMINORTYPE yyzerominor = { 0 };
@@ -124928,20 +125357,24 @@
** action integer.
**
** Suppose the action integer is N. Then the action is determined as
** follows
**
-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
-** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
-** N == YYNSTATE+YYNRULE A syntax error has occurred.
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
+
+** N == YY_ERROR_ACTION A syntax error has occurred.
**
-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+** N == YY_ACCEPT_ACTION The parser accepts its input.
**
-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
@@ -124967,467 +125400,450 @@
** shifting terminals.
** 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.
*/
-#define YY_ACTTAB_COUNT (1497)
+#define YY_ACTTAB_COUNT (1501)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 306, 212, 432, 955, 639, 191, 955, 295, 559, 88,
- /* 10 */ 88, 88, 88, 81, 86, 86, 86, 86, 85, 85,
- /* 20 */ 84, 84, 84, 83, 330, 185, 184, 183, 635, 635,
- /* 30 */ 292, 606, 606, 88, 88, 88, 88, 683, 86, 86,
- /* 40 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 16,
- /* 50 */ 436, 597, 89, 90, 80, 600, 599, 601, 601, 87,
- /* 60 */ 87, 88, 88, 88, 88, 684, 86, 86, 86, 86,
- /* 70 */ 85, 85, 84, 84, 84, 83, 330, 306, 559, 84,
- /* 80 */ 84, 84, 83, 330, 65, 86, 86, 86, 86, 85,
- /* 90 */ 85, 84, 84, 84, 83, 330, 635, 635, 634, 633,
- /* 100 */ 182, 682, 550, 379, 376, 375, 17, 322, 606, 606,
- /* 110 */ 371, 198, 479, 91, 374, 82, 79, 165, 85, 85,
- /* 120 */ 84, 84, 84, 83, 330, 598, 635, 635, 107, 89,
- /* 130 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88,
- /* 140 */ 88, 88, 186, 86, 86, 86, 86, 85, 85, 84,
- /* 150 */ 84, 84, 83, 330, 306, 594, 594, 142, 328, 327,
- /* 160 */ 484, 249, 344, 238, 635, 635, 634, 633, 585, 448,
- /* 170 */ 526, 525, 229, 388, 1, 394, 450, 584, 449, 635,
- /* 180 */ 635, 635, 635, 319, 395, 606, 606, 199, 157, 273,
- /* 190 */ 382, 268, 381, 187, 635, 635, 634, 633, 311, 555,
- /* 200 */ 266, 593, 593, 266, 347, 588, 89, 90, 80, 600,
- /* 210 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 478,
- /* 220 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83,
- /* 230 */ 330, 306, 272, 536, 634, 633, 146, 610, 197, 310,
- /* 240 */ 575, 182, 482, 271, 379, 376, 375, 506, 21, 634,
- /* 250 */ 633, 634, 633, 635, 635, 374, 611, 574, 548, 440,
- /* 260 */ 111, 563, 606, 606, 634, 633, 324, 479, 608, 608,
- /* 270 */ 608, 300, 435, 573, 119, 407, 210, 162, 562, 883,
- /* 280 */ 592, 592, 306, 89, 90, 80, 600, 599, 601, 601,
- /* 290 */ 87, 87, 88, 88, 88, 88, 506, 86, 86, 86,
- /* 300 */ 86, 85, 85, 84, 84, 84, 83, 330, 620, 111,
- /* 310 */ 635, 635, 361, 606, 606, 358, 249, 349, 248, 433,
- /* 320 */ 243, 479, 586, 634, 633, 195, 611, 93, 119, 221,
- /* 330 */ 575, 497, 534, 534, 89, 90, 80, 600, 599, 601,
- /* 340 */ 601, 87, 87, 88, 88, 88, 88, 574, 86, 86,
- /* 350 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 306,
- /* 360 */ 77, 429, 638, 573, 589, 530, 240, 230, 242, 105,
- /* 370 */ 249, 349, 248, 515, 588, 208, 460, 529, 564, 173,
- /* 380 */ 634, 633, 970, 144, 430, 2, 424, 228, 380, 557,
- /* 390 */ 606, 606, 190, 153, 159, 158, 514, 51, 632, 631,
- /* 400 */ 630, 71, 536, 432, 954, 196, 610, 954, 614, 45,
- /* 410 */ 18, 89, 90, 80, 600, 599, 601, 601, 87, 87,
- /* 420 */ 88, 88, 88, 88, 261, 86, 86, 86, 86, 85,
- /* 430 */ 85, 84, 84, 84, 83, 330, 306, 608, 608, 608,
- /* 440 */ 542, 424, 402, 385, 241, 506, 451, 320, 211, 543,
- /* 450 */ 164, 436, 386, 293, 451, 587, 108, 496, 111, 334,
- /* 460 */ 391, 591, 424, 614, 27, 452, 453, 606, 606, 72,
- /* 470 */ 257, 70, 259, 452, 339, 342, 564, 582, 68, 415,
- /* 480 */ 469, 328, 327, 62, 614, 45, 110, 393, 89, 90,
- /* 490 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88,
- /* 500 */ 88, 152, 86, 86, 86, 86, 85, 85, 84, 84,
- /* 510 */ 84, 83, 330, 306, 110, 499, 520, 538, 402, 389,
- /* 520 */ 424, 110, 566, 500, 593, 593, 454, 82, 79, 165,
- /* 530 */ 424, 591, 384, 564, 340, 615, 188, 162, 424, 350,
- /* 540 */ 616, 424, 614, 44, 606, 606, 445, 582, 300, 434,
- /* 550 */ 151, 19, 614, 9, 568, 580, 348, 615, 469, 567,
- /* 560 */ 614, 26, 616, 614, 45, 89, 90, 80, 600, 599,
- /* 570 */ 601, 601, 87, 87, 88, 88, 88, 88, 411, 86,
- /* 580 */ 86, 86, 86, 85, 85, 84, 84, 84, 83, 330,
- /* 590 */ 306, 579, 110, 578, 521, 282, 433, 398, 400, 255,
- /* 600 */ 486, 82, 79, 165, 487, 164, 82, 79, 165, 488,
- /* 610 */ 488, 364, 387, 424, 544, 544, 509, 350, 362, 155,
- /* 620 */ 191, 606, 606, 559, 642, 640, 333, 82, 79, 165,
- /* 630 */ 305, 564, 507, 312, 357, 614, 45, 329, 596, 595,
- /* 640 */ 194, 337, 89, 90, 80, 600, 599, 601, 601, 87,
- /* 650 */ 87, 88, 88, 88, 88, 424, 86, 86, 86, 86,
- /* 660 */ 85, 85, 84, 84, 84, 83, 330, 306, 20, 323,
- /* 670 */ 150, 263, 211, 543, 421, 596, 595, 614, 22, 424,
- /* 680 */ 193, 424, 284, 424, 391, 424, 509, 424, 577, 424,
- /* 690 */ 186, 335, 424, 559, 424, 313, 120, 546, 606, 606,
- /* 700 */ 67, 614, 47, 614, 50, 614, 48, 614, 100, 614,
- /* 710 */ 99, 614, 101, 576, 614, 102, 614, 109, 326, 89,
- /* 720 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88,
- /* 730 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84,
- /* 740 */ 84, 84, 83, 330, 306, 424, 311, 424, 585, 54,
- /* 750 */ 424, 516, 517, 590, 614, 112, 424, 584, 424, 572,
- /* 760 */ 424, 195, 424, 571, 424, 67, 424, 614, 94, 614,
- /* 770 */ 98, 424, 614, 97, 264, 606, 606, 195, 614, 46,
- /* 780 */ 614, 96, 614, 30, 614, 49, 614, 115, 614, 114,
- /* 790 */ 418, 229, 388, 614, 113, 306, 89, 90, 80, 600,
- /* 800 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 424,
- /* 810 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83,
- /* 820 */ 330, 119, 424, 590, 110, 372, 606, 606, 195, 53,
- /* 830 */ 250, 614, 29, 195, 472, 438, 729, 190, 302, 498,
- /* 840 */ 14, 523, 641, 2, 614, 43, 306, 89, 90, 80,
- /* 850 */ 600, 599, 601, 601, 87, 87, 88, 88, 88, 88,
- /* 860 */ 424, 86, 86, 86, 86, 85, 85, 84, 84, 84,
- /* 870 */ 83, 330, 424, 613, 964, 964, 354, 606, 606, 420,
- /* 880 */ 312, 64, 614, 42, 391, 355, 283, 437, 301, 255,
- /* 890 */ 414, 410, 495, 492, 614, 28, 471, 306, 89, 90,
- /* 900 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88,
- /* 910 */ 88, 424, 86, 86, 86, 86, 85, 85, 84, 84,
- /* 920 */ 84, 83, 330, 424, 110, 110, 110, 110, 606, 606,
- /* 930 */ 110, 254, 13, 614, 41, 532, 531, 283, 481, 531,
- /* 940 */ 457, 284, 119, 561, 356, 614, 40, 284, 306, 89,
- /* 950 */ 78, 80, 600, 599, 601, 601, 87, 87, 88, 88,
- /* 960 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84,
- /* 970 */ 84, 84, 83, 330, 110, 424, 341, 220, 555, 606,
- /* 980 */ 606, 351, 555, 318, 614, 95, 413, 255, 83, 330,
- /* 990 */ 284, 284, 255, 640, 333, 356, 255, 614, 39, 306,
- /* 1000 */ 356, 90, 80, 600, 599, 601, 601, 87, 87, 88,
- /* 1010 */ 88, 88, 88, 424, 86, 86, 86, 86, 85, 85,
- /* 1020 */ 84, 84, 84, 83, 330, 424, 317, 316, 141, 465,
- /* 1030 */ 606, 606, 219, 619, 463, 614, 10, 417, 462, 255,
- /* 1040 */ 189, 510, 553, 351, 207, 363, 161, 614, 38, 315,
- /* 1050 */ 218, 255, 255, 80, 600, 599, 601, 601, 87, 87,
- /* 1060 */ 88, 88, 88, 88, 424, 86, 86, 86, 86, 85,
- /* 1070 */ 85, 84, 84, 84, 83, 330, 76, 419, 255, 3,
- /* 1080 */ 878, 461, 424, 247, 331, 331, 614, 37, 217, 76,
- /* 1090 */ 419, 390, 3, 216, 215, 422, 4, 331, 331, 424,
- /* 1100 */ 547, 12, 424, 545, 614, 36, 424, 541, 422, 424,
- /* 1110 */ 540, 424, 214, 424, 408, 424, 539, 403, 605, 605,
- /* 1120 */ 237, 614, 25, 119, 614, 24, 588, 408, 614, 45,
- /* 1130 */ 118, 614, 35, 614, 34, 614, 33, 614, 23, 588,
- /* 1140 */ 60, 223, 603, 602, 513, 378, 73, 74, 140, 139,
- /* 1150 */ 424, 110, 265, 75, 426, 425, 59, 424, 610, 73,
- /* 1160 */ 74, 549, 402, 404, 424, 373, 75, 426, 425, 604,
- /* 1170 */ 138, 610, 614, 11, 392, 76, 419, 181, 3, 614,
- /* 1180 */ 32, 271, 369, 331, 331, 493, 614, 31, 149, 608,
- /* 1190 */ 608, 608, 607, 15, 422, 365, 614, 8, 137, 489,
- /* 1200 */ 136, 190, 608, 608, 608, 607, 15, 485, 176, 135,
- /* 1210 */ 7, 252, 477, 408, 174, 133, 175, 474, 57, 56,
- /* 1220 */ 132, 130, 119, 76, 419, 588, 3, 468, 245, 464,
- /* 1230 */ 171, 331, 331, 125, 123, 456, 447, 122, 446, 104,
- /* 1240 */ 336, 231, 422, 166, 154, 73, 74, 332, 116, 431,
- /* 1250 */ 121, 309, 75, 426, 425, 222, 106, 610, 308, 637,
- /* 1260 */ 204, 408, 629, 627, 628, 6, 200, 428, 427, 290,
- /* 1270 */ 203, 622, 201, 588, 62, 63, 289, 66, 419, 399,
- /* 1280 */ 3, 401, 288, 92, 143, 331, 331, 287, 608, 608,
- /* 1290 */ 608, 607, 15, 73, 74, 227, 422, 325, 69, 416,
- /* 1300 */ 75, 426, 425, 612, 412, 610, 192, 61, 569, 209,
- /* 1310 */ 396, 226, 278, 225, 383, 408, 527, 558, 276, 533,
- /* 1320 */ 552, 528, 321, 523, 370, 508, 180, 588, 494, 179,
- /* 1330 */ 366, 117, 253, 269, 522, 503, 608, 608, 608, 607,
- /* 1340 */ 15, 551, 502, 58, 274, 524, 178, 73, 74, 304,
- /* 1350 */ 501, 368, 303, 206, 75, 426, 425, 491, 360, 610,
- /* 1360 */ 213, 177, 483, 131, 345, 298, 297, 296, 202, 294,
- /* 1370 */ 480, 490, 466, 134, 172, 129, 444, 346, 470, 128,
- /* 1380 */ 314, 459, 103, 127, 126, 148, 124, 167, 443, 235,
- /* 1390 */ 608, 608, 608, 607, 15, 442, 439, 623, 234, 299,
- /* 1400 */ 145, 583, 291, 377, 581, 160, 119, 156, 270, 636,
- /* 1410 */ 971, 169, 279, 626, 520, 625, 473, 624, 170, 621,
- /* 1420 */ 618, 119, 168, 55, 409, 423, 537, 609, 286, 285,
- /* 1430 */ 405, 570, 560, 556, 5, 52, 458, 554, 147, 267,
- /* 1440 */ 519, 504, 518, 406, 262, 239, 260, 512, 343, 511,
- /* 1450 */ 258, 353, 565, 256, 224, 251, 359, 277, 275, 476,
- /* 1460 */ 475, 246, 352, 244, 467, 455, 236, 233, 232, 307,
- /* 1470 */ 441, 281, 205, 163, 397, 280, 535, 505, 330, 617,
- /* 1480 */ 971, 971, 971, 971, 367, 971, 971, 971, 971, 971,
- /* 1490 */ 971, 971, 971, 971, 971, 971, 338,
+ /* 0 */ 311, 1306, 145, 651, 2, 192, 652, 338, 780, 92,
+ /* 10 */ 92, 92, 92, 85, 90, 90, 90, 90, 89, 89,
+ /* 20 */ 88, 88, 88, 87, 335, 88, 88, 88, 87, 335,
+ /* 30 */ 327, 856, 856, 92, 92, 92, 92, 776, 90, 90,
+ /* 40 */ 90, 90, 89, 89, 88, 88, 88, 87, 335, 86,
+ /* 50 */ 83, 166, 93, 94, 84, 868, 871, 860, 860, 91,
+ /* 60 */ 91, 92, 92, 92, 92, 335, 90, 90, 90, 90,
+ /* 70 */ 89, 89, 88, 88, 88, 87, 335, 311, 780, 90,
+ /* 80 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 335,
+ /* 90 */ 123, 808, 689, 689, 689, 689, 112, 230, 430, 257,
+ /* 100 */ 809, 698, 430, 86, 83, 166, 324, 55, 856, 856,
+ /* 110 */ 201, 158, 276, 387, 271, 386, 188, 689, 689, 828,
+ /* 120 */ 833, 49, 944, 269, 833, 49, 123, 87, 335, 93,
+ /* 130 */ 94, 84, 868, 871, 860, 860, 91, 91, 92, 92,
+ /* 140 */ 92, 92, 342, 90, 90, 90, 90, 89, 89, 88,
+ /* 150 */ 88, 88, 87, 335, 311, 328, 333, 332, 701, 408,
+ /* 160 */ 394, 69, 690, 691, 690, 691, 715, 910, 251, 354,
+ /* 170 */ 250, 698, 704, 430, 908, 430, 909, 89, 89, 88,
+ /* 180 */ 88, 88, 87, 335, 391, 856, 856, 690, 691, 183,
+ /* 190 */ 95, 340, 384, 381, 380, 833, 31, 833, 49, 912,
+ /* 200 */ 912, 333, 332, 379, 123, 311, 93, 94, 84, 868,
+ /* 210 */ 871, 860, 860, 91, 91, 92, 92, 92, 92, 114,
+ /* 220 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
+ /* 230 */ 335, 430, 408, 399, 435, 657, 856, 856, 346, 57,
+ /* 240 */ 232, 828, 109, 20, 912, 912, 231, 393, 937, 760,
+ /* 250 */ 97, 751, 752, 833, 49, 708, 708, 93, 94, 84,
+ /* 260 */ 868, 871, 860, 860, 91, 91, 92, 92, 92, 92,
+ /* 270 */ 707, 90, 90, 90, 90, 89, 89, 88, 88, 88,
+ /* 280 */ 87, 335, 311, 114, 22, 706, 688, 58, 408, 390,
+ /* 290 */ 251, 349, 240, 749, 752, 689, 689, 847, 685, 115,
+ /* 300 */ 21, 231, 393, 689, 689, 697, 183, 355, 430, 384,
+ /* 310 */ 381, 380, 192, 856, 856, 780, 123, 160, 159, 223,
+ /* 320 */ 379, 738, 25, 315, 362, 841, 143, 689, 689, 835,
+ /* 330 */ 833, 48, 339, 937, 93, 94, 84, 868, 871, 860,
+ /* 340 */ 860, 91, 91, 92, 92, 92, 92, 914, 90, 90,
+ /* 350 */ 90, 90, 89, 89, 88, 88, 88, 87, 335, 311,
+ /* 360 */ 840, 840, 840, 266, 430, 690, 691, 778, 114, 1300,
+ /* 370 */ 1300, 430, 1, 690, 691, 697, 688, 689, 689, 689,
+ /* 380 */ 689, 689, 689, 287, 298, 780, 833, 10, 686, 115,
+ /* 390 */ 856, 856, 355, 833, 10, 828, 366, 690, 691, 363,
+ /* 400 */ 321, 76, 123, 74, 23, 737, 807, 323, 356, 353,
+ /* 410 */ 847, 93, 94, 84, 868, 871, 860, 860, 91, 91,
+ /* 420 */ 92, 92, 92, 92, 940, 90, 90, 90, 90, 89,
+ /* 430 */ 89, 88, 88, 88, 87, 335, 311, 806, 841, 429,
+ /* 440 */ 713, 941, 835, 430, 251, 354, 250, 690, 691, 690,
+ /* 450 */ 691, 690, 691, 86, 83, 166, 24, 942, 151, 753,
+ /* 460 */ 285, 907, 403, 907, 164, 833, 10, 856, 856, 965,
+ /* 470 */ 306, 754, 679, 840, 840, 840, 795, 216, 794, 222,
+ /* 480 */ 906, 344, 906, 904, 86, 83, 166, 286, 93, 94,
+ /* 490 */ 84, 868, 871, 860, 860, 91, 91, 92, 92, 92,
+ /* 500 */ 92, 430, 90, 90, 90, 90, 89, 89, 88, 88,
+ /* 510 */ 88, 87, 335, 311, 430, 724, 352, 705, 427, 699,
+ /* 520 */ 700, 376, 210, 833, 49, 793, 397, 857, 857, 940,
+ /* 530 */ 213, 762, 727, 334, 699, 700, 833, 10, 86, 83,
+ /* 540 */ 166, 345, 396, 902, 856, 856, 941, 385, 833, 9,
+ /* 550 */ 406, 869, 872, 187, 890, 728, 347, 398, 404, 977,
+ /* 560 */ 652, 338, 942, 954, 413, 93, 94, 84, 868, 871,
+ /* 570 */ 860, 860, 91, 91, 92, 92, 92, 92, 861, 90,
+ /* 580 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 335,
+ /* 590 */ 311, 1219, 114, 430, 834, 430, 5, 165, 192, 688,
+ /* 600 */ 832, 780, 430, 723, 430, 234, 325, 189, 163, 316,
+ /* 610 */ 356, 955, 115, 235, 269, 833, 35, 833, 36, 747,
+ /* 620 */ 720, 856, 856, 793, 833, 12, 833, 27, 745, 174,
+ /* 630 */ 968, 1290, 968, 1291, 1290, 310, 1291, 693, 317, 245,
+ /* 640 */ 264, 311, 93, 94, 84, 868, 871, 860, 860, 91,
+ /* 650 */ 91, 92, 92, 92, 92, 832, 90, 90, 90, 90,
+ /* 660 */ 89, 89, 88, 88, 88, 87, 335, 430, 320, 213,
+ /* 670 */ 762, 780, 856, 856, 920, 920, 369, 257, 966, 220,
+ /* 680 */ 966, 396, 663, 664, 665, 242, 259, 244, 262, 833,
+ /* 690 */ 37, 650, 2, 93, 94, 84, 868, 871, 860, 860,
+ /* 700 */ 91, 91, 92, 92, 92, 92, 430, 90, 90, 90,
+ /* 710 */ 90, 89, 89, 88, 88, 88, 87, 335, 311, 430,
+ /* 720 */ 239, 430, 917, 368, 430, 238, 916, 793, 833, 38,
+ /* 730 */ 430, 825, 430, 66, 430, 392, 430, 766, 766, 430,
+ /* 740 */ 367, 833, 39, 833, 28, 430, 833, 29, 68, 856,
+ /* 750 */ 856, 900, 833, 40, 833, 41, 833, 42, 833, 11,
+ /* 760 */ 72, 833, 43, 243, 305, 970, 114, 833, 99, 961,
+ /* 770 */ 93, 94, 84, 868, 871, 860, 860, 91, 91, 92,
+ /* 780 */ 92, 92, 92, 430, 90, 90, 90, 90, 89, 89,
+ /* 790 */ 88, 88, 88, 87, 335, 311, 430, 361, 430, 165,
+ /* 800 */ 147, 430, 186, 185, 184, 833, 44, 430, 289, 430,
+ /* 810 */ 246, 430, 971, 430, 212, 163, 430, 357, 833, 45,
+ /* 820 */ 833, 32, 932, 833, 46, 793, 856, 856, 718, 833,
+ /* 830 */ 47, 833, 33, 833, 117, 833, 118, 75, 833, 119,
+ /* 840 */ 288, 305, 967, 214, 935, 322, 311, 93, 94, 84,
+ /* 850 */ 868, 871, 860, 860, 91, 91, 92, 92, 92, 92,
+ /* 860 */ 430, 90, 90, 90, 90, 89, 89, 88, 88, 88,
+ /* 870 */ 87, 335, 430, 832, 426, 317, 288, 856, 856, 114,
+ /* 880 */ 763, 257, 833, 53, 930, 219, 364, 257, 257, 971,
+ /* 890 */ 361, 396, 257, 257, 833, 34, 257, 311, 93, 94,
+ /* 900 */ 84, 868, 871, 860, 860, 91, 91, 92, 92, 92,
+ /* 910 */ 92, 430, 90, 90, 90, 90, 89, 89, 88, 88,
+ /* 920 */ 88, 87, 335, 430, 217, 318, 124, 253, 856, 856,
+ /* 930 */ 218, 943, 257, 833, 100, 898, 759, 774, 361, 755,
+ /* 940 */ 423, 329, 758, 1017, 289, 833, 50, 682, 311, 93,
+ /* 950 */ 82, 84, 868, 871, 860, 860, 91, 91, 92, 92,
+ /* 960 */ 92, 92, 430, 90, 90, 90, 90, 89, 89, 88,
+ /* 970 */ 88, 88, 87, 335, 430, 256, 419, 114, 249, 856,
+ /* 980 */ 856, 331, 114, 400, 833, 101, 359, 187, 1064, 726,
+ /* 990 */ 725, 739, 401, 416, 420, 360, 833, 102, 424, 311,
+ /* 1000 */ 258, 94, 84, 868, 871, 860, 860, 91, 91, 92,
+ /* 1010 */ 92, 92, 92, 430, 90, 90, 90, 90, 89, 89,
+ /* 1020 */ 88, 88, 88, 87, 335, 430, 221, 261, 114, 114,
+ /* 1030 */ 856, 856, 808, 114, 156, 833, 98, 772, 733, 734,
+ /* 1040 */ 275, 809, 771, 316, 263, 265, 960, 833, 116, 307,
+ /* 1050 */ 741, 274, 722, 84, 868, 871, 860, 860, 91, 91,
+ /* 1060 */ 92, 92, 92, 92, 430, 90, 90, 90, 90, 89,
+ /* 1070 */ 89, 88, 88, 88, 87, 335, 80, 425, 830, 3,
+ /* 1080 */ 1214, 191, 430, 721, 336, 336, 833, 113, 252, 80,
+ /* 1090 */ 425, 68, 3, 913, 913, 428, 270, 336, 336, 430,
+ /* 1100 */ 377, 784, 430, 197, 833, 106, 430, 716, 428, 430,
+ /* 1110 */ 267, 430, 897, 68, 414, 430, 769, 409, 430, 71,
+ /* 1120 */ 430, 833, 105, 123, 833, 103, 847, 414, 833, 49,
+ /* 1130 */ 843, 833, 104, 833, 52, 800, 123, 833, 54, 847,
+ /* 1140 */ 833, 51, 833, 26, 831, 802, 77, 78, 191, 389,
+ /* 1150 */ 430, 372, 114, 79, 432, 431, 911, 911, 835, 77,
+ /* 1160 */ 78, 779, 893, 408, 410, 197, 79, 432, 431, 791,
+ /* 1170 */ 226, 835, 833, 30, 772, 80, 425, 716, 3, 771,
+ /* 1180 */ 411, 412, 897, 336, 336, 290, 291, 839, 703, 840,
+ /* 1190 */ 840, 840, 842, 19, 428, 695, 684, 672, 111, 671,
+ /* 1200 */ 843, 673, 840, 840, 840, 842, 19, 207, 661, 278,
+ /* 1210 */ 148, 304, 280, 414, 282, 6, 822, 348, 248, 241,
+ /* 1220 */ 358, 934, 720, 80, 425, 847, 3, 161, 382, 273,
+ /* 1230 */ 284, 336, 336, 415, 296, 958, 895, 894, 157, 674,
+ /* 1240 */ 107, 194, 428, 948, 135, 77, 78, 777, 953, 951,
+ /* 1250 */ 56, 319, 79, 432, 431, 121, 66, 835, 59, 128,
+ /* 1260 */ 146, 414, 350, 130, 351, 819, 131, 132, 133, 375,
+ /* 1270 */ 173, 149, 138, 847, 936, 365, 178, 70, 425, 827,
+ /* 1280 */ 3, 889, 62, 371, 915, 336, 336, 792, 840, 840,
+ /* 1290 */ 840, 842, 19, 77, 78, 208, 428, 144, 179, 373,
+ /* 1300 */ 79, 432, 431, 255, 180, 835, 260, 675, 181, 308,
+ /* 1310 */ 388, 744, 326, 743, 742, 414, 731, 718, 712, 402,
+ /* 1320 */ 309, 711, 788, 65, 277, 272, 789, 847, 730, 710,
+ /* 1330 */ 709, 279, 193, 787, 281, 876, 840, 840, 840, 842,
+ /* 1340 */ 19, 786, 283, 73, 418, 330, 422, 77, 78, 227,
+ /* 1350 */ 96, 407, 67, 405, 79, 432, 431, 292, 228, 835,
+ /* 1360 */ 215, 202, 229, 293, 767, 303, 302, 301, 204, 299,
+ /* 1370 */ 294, 295, 676, 7, 681, 433, 669, 206, 110, 224,
+ /* 1380 */ 203, 205, 434, 667, 666, 658, 120, 168, 656, 237,
+ /* 1390 */ 840, 840, 840, 842, 19, 337, 155, 233, 236, 341,
+ /* 1400 */ 167, 905, 108, 313, 903, 826, 314, 125, 126, 127,
+ /* 1410 */ 129, 170, 247, 756, 172, 928, 134, 136, 171, 60,
+ /* 1420 */ 61, 123, 169, 137, 175, 933, 176, 927, 8, 13,
+ /* 1430 */ 177, 254, 191, 918, 139, 370, 924, 140, 678, 150,
+ /* 1440 */ 374, 274, 182, 378, 141, 122, 63, 14, 383, 729,
+ /* 1450 */ 268, 15, 64, 225, 846, 845, 874, 16, 765, 770,
+ /* 1460 */ 4, 162, 209, 395, 211, 142, 878, 796, 801, 312,
+ /* 1470 */ 190, 71, 68, 875, 873, 939, 199, 938, 17, 195,
+ /* 1480 */ 18, 196, 417, 975, 152, 653, 976, 198, 153, 421,
+ /* 1490 */ 877, 154, 200, 844, 696, 81, 343, 297, 1019, 1018,
+ /* 1500 */ 300,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 22, 22, 23, 1, 24, 26, 15, 27, 80,
+ /* 0 */ 19, 144, 145, 146, 147, 24, 1, 2, 27, 80,
/* 10 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 20 */ 91, 92, 93, 94, 95, 108, 109, 110, 27, 28,
- /* 30 */ 23, 50, 51, 80, 81, 82, 83, 122, 85, 86,
- /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 22,
- /* 50 */ 70, 23, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 81, 82, 83, 122, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 93, 94, 95, 19, 97, 91,
- /* 80 */ 92, 93, 94, 95, 26, 85, 86, 87, 88, 89,
- /* 90 */ 90, 91, 92, 93, 94, 95, 27, 28, 97, 98,
- /* 100 */ 99, 122, 211, 102, 103, 104, 79, 19, 50, 51,
- /* 110 */ 19, 122, 59, 55, 113, 224, 225, 226, 89, 90,
- /* 120 */ 91, 92, 93, 94, 95, 23, 27, 28, 26, 71,
+ /* 20 */ 91, 92, 93, 94, 95, 91, 92, 93, 94, 95,
+ /* 30 */ 19, 50, 51, 80, 81, 82, 83, 212, 85, 86,
+ /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 224,
+ /* 50 */ 225, 226, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 60 */ 79, 80, 81, 82, 83, 95, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 94, 95, 19, 97, 85,
+ /* 80 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 90 */ 66, 33, 27, 28, 27, 28, 22, 201, 152, 152,
+ /* 100 */ 42, 27, 152, 224, 225, 226, 95, 211, 50, 51,
+ /* 110 */ 99, 100, 101, 102, 103, 104, 105, 27, 28, 59,
+ /* 120 */ 174, 175, 243, 112, 174, 175, 66, 94, 95, 71,
/* 130 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
- /* 140 */ 82, 83, 51, 85, 86, 87, 88, 89, 90, 91,
- /* 150 */ 92, 93, 94, 95, 19, 132, 133, 58, 89, 90,
- /* 160 */ 21, 108, 109, 110, 27, 28, 97, 98, 33, 100,
- /* 170 */ 7, 8, 119, 120, 22, 19, 107, 42, 109, 27,
- /* 180 */ 28, 27, 28, 95, 28, 50, 51, 99, 100, 101,
- /* 190 */ 102, 103, 104, 105, 27, 28, 97, 98, 107, 152,
- /* 200 */ 112, 132, 133, 112, 65, 69, 71, 72, 73, 74,
- /* 210 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 11,
+ /* 140 */ 82, 83, 195, 85, 86, 87, 88, 89, 90, 91,
+ /* 150 */ 92, 93, 94, 95, 19, 209, 89, 90, 173, 209,
+ /* 160 */ 210, 26, 97, 98, 97, 98, 181, 100, 108, 109,
+ /* 170 */ 110, 97, 174, 152, 107, 152, 109, 89, 90, 91,
+ /* 180 */ 92, 93, 94, 95, 163, 50, 51, 97, 98, 99,
+ /* 190 */ 55, 244, 102, 103, 104, 174, 175, 174, 175, 132,
+ /* 200 */ 133, 89, 90, 113, 66, 19, 71, 72, 73, 74,
+ /* 210 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 198,
/* 220 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 230 */ 95, 19, 101, 97, 97, 98, 24, 101, 122, 157,
- /* 240 */ 12, 99, 103, 112, 102, 103, 104, 152, 22, 97,
- /* 250 */ 98, 97, 98, 27, 28, 113, 27, 29, 91, 164,
- /* 260 */ 165, 124, 50, 51, 97, 98, 219, 59, 132, 133,
- /* 270 */ 134, 22, 23, 45, 66, 47, 212, 213, 124, 140,
- /* 280 */ 132, 133, 19, 71, 72, 73, 74, 75, 76, 77,
- /* 290 */ 78, 79, 80, 81, 82, 83, 152, 85, 86, 87,
- /* 300 */ 88, 89, 90, 91, 92, 93, 94, 95, 164, 165,
- /* 310 */ 27, 28, 230, 50, 51, 233, 108, 109, 110, 70,
- /* 320 */ 16, 59, 23, 97, 98, 26, 97, 22, 66, 185,
- /* 330 */ 12, 187, 27, 28, 71, 72, 73, 74, 75, 76,
- /* 340 */ 77, 78, 79, 80, 81, 82, 83, 29, 85, 86,
+ /* 230 */ 95, 152, 209, 210, 148, 149, 50, 51, 100, 53,
+ /* 240 */ 154, 59, 156, 22, 132, 133, 119, 120, 163, 163,
+ /* 250 */ 22, 192, 193, 174, 175, 27, 28, 71, 72, 73,
+ /* 260 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 270 */ 174, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 280 */ 94, 95, 19, 198, 198, 174, 152, 24, 209, 210,
+ /* 290 */ 108, 109, 110, 192, 193, 27, 28, 69, 164, 165,
+ /* 300 */ 79, 119, 120, 27, 28, 27, 99, 222, 152, 102,
+ /* 310 */ 103, 104, 24, 50, 51, 27, 66, 89, 90, 185,
+ /* 320 */ 113, 187, 22, 157, 239, 97, 58, 27, 28, 101,
+ /* 330 */ 174, 175, 246, 163, 71, 72, 73, 74, 75, 76,
+ /* 340 */ 77, 78, 79, 80, 81, 82, 83, 11, 85, 86,
/* 350 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 19,
- /* 360 */ 22, 148, 149, 45, 23, 47, 62, 154, 64, 156,
- /* 370 */ 108, 109, 110, 37, 69, 23, 163, 59, 26, 26,
- /* 380 */ 97, 98, 144, 145, 146, 147, 152, 200, 52, 23,
- /* 390 */ 50, 51, 26, 22, 89, 90, 60, 210, 7, 8,
- /* 400 */ 9, 138, 97, 22, 23, 26, 101, 26, 174, 175,
- /* 410 */ 197, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- /* 420 */ 80, 81, 82, 83, 16, 85, 86, 87, 88, 89,
- /* 430 */ 90, 91, 92, 93, 94, 95, 19, 132, 133, 134,
- /* 440 */ 23, 152, 208, 209, 140, 152, 152, 111, 195, 196,
- /* 450 */ 98, 70, 163, 160, 152, 23, 22, 164, 165, 246,
- /* 460 */ 207, 27, 152, 174, 175, 171, 172, 50, 51, 137,
- /* 470 */ 62, 139, 64, 171, 172, 222, 124, 27, 138, 24,
- /* 480 */ 163, 89, 90, 130, 174, 175, 197, 163, 71, 72,
+ /* 360 */ 132, 133, 134, 23, 152, 97, 98, 91, 198, 119,
+ /* 370 */ 120, 152, 22, 97, 98, 97, 152, 27, 28, 27,
+ /* 380 */ 28, 27, 28, 227, 160, 97, 174, 175, 164, 165,
+ /* 390 */ 50, 51, 222, 174, 175, 59, 230, 97, 98, 233,
+ /* 400 */ 188, 137, 66, 139, 234, 187, 177, 188, 152, 239,
+ /* 410 */ 69, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ /* 420 */ 80, 81, 82, 83, 12, 85, 86, 87, 88, 89,
+ /* 430 */ 90, 91, 92, 93, 94, 95, 19, 177, 97, 152,
+ /* 440 */ 23, 29, 101, 152, 108, 109, 110, 97, 98, 97,
+ /* 450 */ 98, 97, 98, 224, 225, 226, 22, 45, 24, 47,
+ /* 460 */ 152, 152, 152, 152, 152, 174, 175, 50, 51, 249,
+ /* 470 */ 250, 59, 21, 132, 133, 134, 124, 221, 124, 188,
+ /* 480 */ 171, 172, 171, 172, 224, 225, 226, 152, 71, 72,
/* 490 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 500 */ 83, 22, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 510 */ 93, 94, 95, 19, 197, 181, 182, 23, 208, 209,
- /* 520 */ 152, 197, 26, 189, 132, 133, 232, 224, 225, 226,
- /* 530 */ 152, 97, 91, 26, 232, 116, 212, 213, 152, 222,
- /* 540 */ 121, 152, 174, 175, 50, 51, 243, 97, 22, 23,
- /* 550 */ 22, 234, 174, 175, 177, 23, 239, 116, 163, 177,
- /* 560 */ 174, 175, 121, 174, 175, 71, 72, 73, 74, 75,
- /* 570 */ 76, 77, 78, 79, 80, 81, 82, 83, 24, 85,
+ /* 500 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 510 */ 93, 94, 95, 19, 152, 183, 65, 23, 170, 171,
+ /* 520 */ 172, 19, 23, 174, 175, 26, 152, 50, 51, 12,
+ /* 530 */ 196, 197, 37, 170, 171, 172, 174, 175, 224, 225,
+ /* 540 */ 226, 232, 208, 232, 50, 51, 29, 52, 174, 175,
+ /* 550 */ 188, 74, 75, 51, 103, 60, 222, 163, 209, 0,
+ /* 560 */ 1, 2, 45, 152, 47, 71, 72, 73, 74, 75,
+ /* 570 */ 76, 77, 78, 79, 80, 81, 82, 83, 101, 85,
/* 580 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- /* 590 */ 19, 23, 197, 11, 23, 227, 70, 208, 220, 152,
- /* 600 */ 31, 224, 225, 226, 35, 98, 224, 225, 226, 108,
- /* 610 */ 109, 110, 115, 152, 117, 118, 27, 222, 49, 123,
- /* 620 */ 24, 50, 51, 27, 0, 1, 2, 224, 225, 226,
- /* 630 */ 166, 124, 168, 169, 239, 174, 175, 170, 171, 172,
- /* 640 */ 22, 194, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 590 */ 19, 140, 198, 152, 23, 152, 22, 98, 24, 152,
+ /* 600 */ 152, 27, 152, 183, 152, 152, 111, 213, 214, 107,
+ /* 610 */ 152, 164, 165, 152, 112, 174, 175, 174, 175, 181,
+ /* 620 */ 182, 50, 51, 124, 174, 175, 174, 175, 190, 26,
+ /* 630 */ 22, 23, 22, 23, 26, 166, 26, 168, 169, 16,
+ /* 640 */ 16, 19, 71, 72, 73, 74, 75, 76, 77, 78,
/* 650 */ 79, 80, 81, 82, 83, 152, 85, 86, 87, 88,
- /* 660 */ 89, 90, 91, 92, 93, 94, 95, 19, 22, 208,
- /* 670 */ 24, 23, 195, 196, 170, 171, 172, 174, 175, 152,
- /* 680 */ 26, 152, 152, 152, 207, 152, 97, 152, 23, 152,
- /* 690 */ 51, 244, 152, 97, 152, 247, 248, 23, 50, 51,
- /* 700 */ 26, 174, 175, 174, 175, 174, 175, 174, 175, 174,
- /* 710 */ 175, 174, 175, 23, 174, 175, 174, 175, 188, 71,
- /* 720 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
- /* 730 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91,
- /* 740 */ 92, 93, 94, 95, 19, 152, 107, 152, 33, 24,
- /* 750 */ 152, 100, 101, 27, 174, 175, 152, 42, 152, 23,
- /* 760 */ 152, 26, 152, 23, 152, 26, 152, 174, 175, 174,
- /* 770 */ 175, 152, 174, 175, 23, 50, 51, 26, 174, 175,
- /* 780 */ 174, 175, 174, 175, 174, 175, 174, 175, 174, 175,
- /* 790 */ 163, 119, 120, 174, 175, 19, 71, 72, 73, 74,
- /* 800 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 152,
- /* 810 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 820 */ 95, 66, 152, 97, 197, 23, 50, 51, 26, 53,
- /* 830 */ 23, 174, 175, 26, 23, 23, 23, 26, 26, 26,
- /* 840 */ 36, 106, 146, 147, 174, 175, 19, 71, 72, 73,
+ /* 660 */ 89, 90, 91, 92, 93, 94, 95, 152, 220, 196,
+ /* 670 */ 197, 97, 50, 51, 108, 109, 110, 152, 70, 221,
+ /* 680 */ 70, 208, 7, 8, 9, 62, 62, 64, 64, 174,
+ /* 690 */ 175, 146, 147, 71, 72, 73, 74, 75, 76, 77,
+ /* 700 */ 78, 79, 80, 81, 82, 83, 152, 85, 86, 87,
+ /* 710 */ 88, 89, 90, 91, 92, 93, 94, 95, 19, 152,
+ /* 720 */ 195, 152, 31, 220, 152, 152, 35, 26, 174, 175,
+ /* 730 */ 152, 163, 152, 130, 152, 115, 152, 117, 118, 152,
+ /* 740 */ 49, 174, 175, 174, 175, 152, 174, 175, 26, 50,
+ /* 750 */ 51, 152, 174, 175, 174, 175, 174, 175, 174, 175,
+ /* 760 */ 138, 174, 175, 140, 22, 23, 198, 174, 175, 152,
+ /* 770 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 780 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90,
+ /* 790 */ 91, 92, 93, 94, 95, 19, 152, 152, 152, 98,
+ /* 800 */ 24, 152, 108, 109, 110, 174, 175, 152, 152, 152,
+ /* 810 */ 152, 152, 70, 152, 213, 214, 152, 152, 174, 175,
+ /* 820 */ 174, 175, 152, 174, 175, 124, 50, 51, 106, 174,
+ /* 830 */ 175, 174, 175, 174, 175, 174, 175, 138, 174, 175,
+ /* 840 */ 152, 22, 23, 22, 163, 189, 19, 71, 72, 73,
/* 850 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
/* 860 */ 152, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 870 */ 94, 95, 152, 196, 119, 120, 19, 50, 51, 168,
- /* 880 */ 169, 26, 174, 175, 207, 28, 152, 249, 250, 152,
- /* 890 */ 163, 163, 163, 163, 174, 175, 163, 19, 71, 72,
+ /* 870 */ 94, 95, 152, 152, 168, 169, 152, 50, 51, 198,
+ /* 880 */ 197, 152, 174, 175, 152, 240, 152, 152, 152, 70,
+ /* 890 */ 152, 208, 152, 152, 174, 175, 152, 19, 71, 72,
/* 900 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
/* 910 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 920 */ 93, 94, 95, 152, 197, 197, 197, 197, 50, 51,
- /* 930 */ 197, 194, 36, 174, 175, 191, 192, 152, 191, 192,
- /* 940 */ 163, 152, 66, 124, 152, 174, 175, 152, 19, 71,
+ /* 920 */ 93, 94, 95, 152, 195, 247, 248, 152, 50, 51,
+ /* 930 */ 195, 195, 152, 174, 175, 195, 195, 26, 152, 195,
+ /* 940 */ 252, 220, 163, 122, 152, 174, 175, 163, 19, 71,
/* 950 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
/* 960 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91,
- /* 970 */ 92, 93, 94, 95, 197, 152, 100, 188, 152, 50,
- /* 980 */ 51, 152, 152, 188, 174, 175, 252, 152, 94, 95,
- /* 990 */ 152, 152, 152, 1, 2, 152, 152, 174, 175, 19,
+ /* 970 */ 92, 93, 94, 95, 152, 195, 252, 198, 240, 50,
+ /* 980 */ 51, 189, 198, 19, 174, 175, 19, 51, 23, 100,
+ /* 990 */ 101, 26, 28, 163, 163, 28, 174, 175, 163, 19,
/* 1000 */ 152, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 1010 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90,
- /* 1020 */ 91, 92, 93, 94, 95, 152, 188, 188, 22, 194,
- /* 1030 */ 50, 51, 240, 173, 194, 174, 175, 252, 194, 152,
- /* 1040 */ 36, 181, 28, 152, 23, 219, 122, 174, 175, 219,
- /* 1050 */ 221, 152, 152, 73, 74, 75, 76, 77, 78, 79,
+ /* 1020 */ 91, 92, 93, 94, 95, 152, 240, 152, 198, 198,
+ /* 1030 */ 50, 51, 33, 198, 123, 174, 175, 116, 7, 8,
+ /* 1040 */ 101, 42, 121, 107, 152, 152, 23, 174, 175, 26,
+ /* 1050 */ 152, 112, 183, 73, 74, 75, 76, 77, 78, 79,
/* 1060 */ 80, 81, 82, 83, 152, 85, 86, 87, 88, 89,
- /* 1070 */ 90, 91, 92, 93, 94, 95, 19, 20, 152, 22,
- /* 1080 */ 23, 194, 152, 240, 27, 28, 174, 175, 240, 19,
- /* 1090 */ 20, 26, 22, 194, 194, 38, 22, 27, 28, 152,
- /* 1100 */ 23, 22, 152, 116, 174, 175, 152, 23, 38, 152,
- /* 1110 */ 23, 152, 221, 152, 57, 152, 23, 163, 50, 51,
- /* 1120 */ 194, 174, 175, 66, 174, 175, 69, 57, 174, 175,
- /* 1130 */ 40, 174, 175, 174, 175, 174, 175, 174, 175, 69,
- /* 1140 */ 22, 53, 74, 75, 30, 53, 89, 90, 22, 22,
- /* 1150 */ 152, 197, 23, 96, 97, 98, 22, 152, 101, 89,
- /* 1160 */ 90, 91, 208, 209, 152, 53, 96, 97, 98, 101,
- /* 1170 */ 22, 101, 174, 175, 152, 19, 20, 105, 22, 174,
- /* 1180 */ 175, 112, 19, 27, 28, 20, 174, 175, 24, 132,
- /* 1190 */ 133, 134, 135, 136, 38, 44, 174, 175, 107, 61,
- /* 1200 */ 54, 26, 132, 133, 134, 135, 136, 54, 107, 22,
- /* 1210 */ 5, 140, 1, 57, 36, 111, 122, 28, 79, 79,
- /* 1220 */ 131, 123, 66, 19, 20, 69, 22, 1, 16, 20,
- /* 1230 */ 125, 27, 28, 123, 111, 120, 23, 131, 23, 16,
- /* 1240 */ 68, 142, 38, 15, 22, 89, 90, 3, 167, 4,
- /* 1250 */ 248, 251, 96, 97, 98, 180, 180, 101, 251, 151,
- /* 1260 */ 6, 57, 151, 13, 151, 26, 25, 151, 161, 202,
- /* 1270 */ 153, 162, 153, 69, 130, 128, 203, 19, 20, 127,
- /* 1280 */ 22, 126, 204, 129, 22, 27, 28, 205, 132, 133,
- /* 1290 */ 134, 135, 136, 89, 90, 231, 38, 95, 137, 179,
- /* 1300 */ 96, 97, 98, 206, 179, 101, 122, 107, 159, 159,
- /* 1310 */ 125, 231, 216, 228, 107, 57, 184, 217, 216, 176,
- /* 1320 */ 217, 176, 48, 106, 18, 184, 158, 69, 159, 158,
- /* 1330 */ 46, 71, 237, 176, 176, 176, 132, 133, 134, 135,
- /* 1340 */ 136, 217, 176, 137, 216, 178, 158, 89, 90, 179,
- /* 1350 */ 176, 159, 179, 159, 96, 97, 98, 159, 159, 101,
- /* 1360 */ 5, 158, 202, 22, 18, 10, 11, 12, 13, 14,
- /* 1370 */ 190, 238, 17, 190, 158, 193, 41, 159, 202, 193,
- /* 1380 */ 159, 202, 245, 193, 193, 223, 190, 32, 159, 34,
- /* 1390 */ 132, 133, 134, 135, 136, 159, 39, 155, 43, 150,
- /* 1400 */ 223, 177, 201, 178, 177, 186, 66, 199, 177, 152,
- /* 1410 */ 253, 56, 215, 152, 182, 152, 202, 152, 63, 152,
- /* 1420 */ 152, 66, 67, 242, 229, 152, 174, 152, 152, 152,
- /* 1430 */ 152, 152, 152, 152, 199, 242, 202, 152, 198, 152,
- /* 1440 */ 152, 152, 183, 192, 152, 215, 152, 183, 215, 183,
- /* 1450 */ 152, 241, 214, 152, 211, 152, 152, 211, 211, 152,
- /* 1460 */ 152, 241, 152, 152, 152, 152, 152, 152, 152, 114,
- /* 1470 */ 152, 152, 235, 152, 152, 152, 174, 187, 95, 174,
- /* 1480 */ 253, 253, 253, 253, 236, 253, 253, 253, 253, 253,
- /* 1490 */ 253, 253, 253, 253, 253, 253, 141,
+ /* 1070 */ 90, 91, 92, 93, 94, 95, 19, 20, 23, 22,
+ /* 1080 */ 23, 26, 152, 152, 27, 28, 174, 175, 23, 19,
+ /* 1090 */ 20, 26, 22, 132, 133, 38, 152, 27, 28, 152,
+ /* 1100 */ 23, 215, 152, 26, 174, 175, 152, 27, 38, 152,
+ /* 1110 */ 23, 152, 27, 26, 57, 152, 23, 163, 152, 26,
+ /* 1120 */ 152, 174, 175, 66, 174, 175, 69, 57, 174, 175,
+ /* 1130 */ 27, 174, 175, 174, 175, 152, 66, 174, 175, 69,
+ /* 1140 */ 174, 175, 174, 175, 152, 23, 89, 90, 26, 91,
+ /* 1150 */ 152, 236, 198, 96, 97, 98, 132, 133, 101, 89,
+ /* 1160 */ 90, 152, 23, 209, 210, 26, 96, 97, 98, 152,
+ /* 1170 */ 212, 101, 174, 175, 116, 19, 20, 97, 22, 121,
+ /* 1180 */ 152, 193, 97, 27, 28, 152, 152, 152, 152, 132,
+ /* 1190 */ 133, 134, 135, 136, 38, 23, 152, 152, 26, 152,
+ /* 1200 */ 97, 152, 132, 133, 134, 135, 136, 235, 152, 212,
+ /* 1210 */ 199, 150, 212, 57, 212, 200, 203, 216, 241, 216,
+ /* 1220 */ 241, 203, 182, 19, 20, 69, 22, 186, 178, 177,
+ /* 1230 */ 216, 27, 28, 229, 202, 39, 177, 177, 200, 155,
+ /* 1240 */ 245, 122, 38, 41, 22, 89, 90, 91, 159, 159,
+ /* 1250 */ 242, 159, 96, 97, 98, 71, 130, 101, 242, 191,
+ /* 1260 */ 223, 57, 18, 194, 159, 203, 194, 194, 194, 18,
+ /* 1270 */ 158, 223, 191, 69, 203, 159, 158, 19, 20, 191,
+ /* 1280 */ 22, 203, 137, 46, 238, 27, 28, 159, 132, 133,
+ /* 1290 */ 134, 135, 136, 89, 90, 159, 38, 22, 158, 179,
+ /* 1300 */ 96, 97, 98, 237, 158, 101, 159, 159, 158, 179,
+ /* 1310 */ 107, 176, 48, 176, 176, 57, 184, 106, 176, 125,
+ /* 1320 */ 179, 178, 218, 107, 217, 176, 218, 69, 184, 176,
+ /* 1330 */ 176, 217, 159, 218, 217, 159, 132, 133, 134, 135,
+ /* 1340 */ 136, 218, 217, 137, 179, 95, 179, 89, 90, 228,
+ /* 1350 */ 129, 126, 128, 127, 96, 97, 98, 206, 231, 101,
+ /* 1360 */ 5, 25, 231, 205, 207, 10, 11, 12, 13, 14,
+ /* 1370 */ 204, 203, 17, 26, 162, 161, 13, 6, 180, 180,
+ /* 1380 */ 153, 153, 151, 151, 151, 151, 167, 32, 4, 34,
+ /* 1390 */ 132, 133, 134, 135, 136, 3, 22, 142, 43, 68,
+ /* 1400 */ 15, 23, 16, 251, 23, 120, 251, 248, 131, 111,
+ /* 1410 */ 123, 56, 16, 20, 125, 1, 123, 131, 63, 79,
+ /* 1420 */ 79, 66, 67, 111, 36, 28, 122, 1, 5, 22,
+ /* 1430 */ 107, 140, 26, 54, 54, 44, 61, 107, 20, 24,
+ /* 1440 */ 19, 112, 105, 53, 22, 40, 22, 22, 53, 30,
+ /* 1450 */ 23, 22, 22, 53, 23, 23, 23, 22, 116, 23,
+ /* 1460 */ 22, 122, 23, 26, 23, 22, 11, 124, 28, 114,
+ /* 1470 */ 36, 26, 26, 23, 23, 23, 122, 23, 36, 26,
+ /* 1480 */ 36, 22, 24, 23, 22, 1, 23, 26, 22, 24,
+ /* 1490 */ 23, 22, 122, 23, 23, 22, 141, 23, 122, 122,
+ /* 1500 */ 15,
};
-#define YY_SHIFT_USE_DFLT (-86)
-#define YY_SHIFT_COUNT (429)
-#define YY_SHIFT_MIN (-85)
-#define YY_SHIFT_MAX (1383)
+#define YY_SHIFT_USE_DFLT (-72)
+#define YY_SHIFT_COUNT (435)
+#define YY_SHIFT_MIN (-71)
+#define YY_SHIFT_MAX (1485)
static const short yy_shift_ofst[] = {
- /* 0 */ 992, 1057, 1355, 1156, 1204, 1204, 1, 262, -19, 135,
- /* 10 */ 135, 776, 1204, 1204, 1204, 1204, 69, 69, 53, 208,
- /* 20 */ 283, 755, 58, 725, 648, 571, 494, 417, 340, 263,
- /* 30 */ 212, 827, 827, 827, 827, 827, 827, 827, 827, 827,
- /* 40 */ 827, 827, 827, 827, 827, 827, 878, 827, 929, 980,
- /* 50 */ 980, 1070, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 0 */ 5, 1057, 1355, 1070, 1204, 1204, 1204, 90, 60, -19,
+ /* 10 */ 58, 58, 186, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 20 */ 67, 67, 182, 336, 65, 250, 135, 263, 340, 417,
+ /* 30 */ 494, 571, 622, 699, 776, 827, 827, 827, 827, 827,
+ /* 40 */ 827, 827, 827, 827, 827, 827, 827, 827, 827, 827,
+ /* 50 */ 878, 827, 929, 980, 980, 1156, 1204, 1204, 1204, 1204,
/* 60 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
/* 70 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- /* 80 */ 1258, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
- /* 90 */ 1204, 1204, 1204, 1204, -71, -47, -47, -47, -47, -47,
- /* 100 */ 0, 29, -12, 283, 283, 139, 91, 392, 392, 894,
- /* 110 */ 672, 726, 1383, -86, -86, -86, 88, 318, 318, 99,
- /* 120 */ 381, -20, 283, 283, 283, 283, 283, 283, 283, 283,
- /* 130 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
- /* 140 */ 283, 283, 283, 283, 624, 876, 726, 672, 1340, 1340,
- /* 150 */ 1340, 1340, 1340, 1340, -86, -86, -86, 305, 136, 136,
- /* 160 */ 142, 167, 226, 154, 137, 152, 283, 283, 283, 283,
- /* 170 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
- /* 180 */ 283, 283, 283, 336, 336, 336, 283, 283, 352, 283,
- /* 190 */ 283, 283, 283, 283, 228, 283, 283, 283, 283, 283,
- /* 200 */ 283, 283, 283, 283, 283, 501, 569, 596, 596, 596,
- /* 210 */ 507, 497, 441, 391, 353, 156, 156, 857, 353, 857,
- /* 220 */ 735, 813, 639, 715, 156, 332, 715, 715, 496, 419,
- /* 230 */ 646, 1357, 1184, 1184, 1335, 1335, 1184, 1341, 1260, 1144,
- /* 240 */ 1346, 1346, 1346, 1346, 1184, 1306, 1144, 1341, 1260, 1260,
- /* 250 */ 1144, 1184, 1306, 1206, 1284, 1184, 1184, 1306, 1184, 1306,
- /* 260 */ 1184, 1306, 1262, 1207, 1207, 1207, 1274, 1262, 1207, 1217,
- /* 270 */ 1207, 1274, 1207, 1207, 1185, 1200, 1185, 1200, 1185, 1200,
- /* 280 */ 1184, 1184, 1161, 1262, 1202, 1202, 1262, 1154, 1155, 1147,
- /* 290 */ 1152, 1144, 1241, 1239, 1250, 1250, 1254, 1254, 1254, 1254,
- /* 300 */ -86, -86, -86, -86, -86, -86, 1068, 304, 526, 249,
- /* 310 */ 408, -83, 434, 812, 27, 811, 807, 802, 751, 589,
- /* 320 */ 651, 163, 131, 674, 366, 450, 299, 148, 23, 102,
- /* 330 */ 229, -21, 1245, 1244, 1222, 1099, 1228, 1172, 1223, 1215,
- /* 340 */ 1213, 1115, 1106, 1123, 1110, 1209, 1105, 1212, 1226, 1098,
- /* 350 */ 1089, 1140, 1139, 1104, 1189, 1178, 1094, 1211, 1205, 1187,
- /* 360 */ 1101, 1071, 1153, 1175, 1146, 1138, 1151, 1091, 1164, 1165,
- /* 370 */ 1163, 1069, 1072, 1148, 1112, 1134, 1127, 1129, 1126, 1092,
- /* 380 */ 1114, 1118, 1088, 1090, 1093, 1087, 1084, 987, 1079, 1077,
- /* 390 */ 1074, 1065, 924, 1021, 1014, 1004, 1006, 819, 739, 896,
- /* 400 */ 855, 804, 739, 740, 736, 690, 654, 665, 618, 582,
- /* 410 */ 568, 528, 554, 379, 532, 479, 455, 379, 432, 371,
- /* 420 */ 341, 28, 338, 116, -11, -57, -85, 7, -8, 3,
+ /* 80 */ 1204, 1204, 1204, 1204, 1258, 1204, 1204, 1204, 1204, 1204,
+ /* 90 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, -71, -47,
+ /* 100 */ -47, -47, -47, -47, -6, 88, -66, 65, 65, 451,
+ /* 110 */ 502, 112, 112, 33, 127, 278, -30, -72, -72, -72,
+ /* 120 */ 11, 412, 412, 268, 608, 610, 65, 65, 65, 65,
+ /* 130 */ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ /* 140 */ 65, 65, 65, 65, 65, 559, 138, 278, 127, 24,
+ /* 150 */ 24, 24, 24, 24, 24, -72, -72, -72, 228, 341,
+ /* 160 */ 341, 207, 276, 300, 352, 354, 350, 65, 65, 65,
+ /* 170 */ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ /* 180 */ 65, 65, 65, 65, 495, 495, 495, 65, 65, 499,
+ /* 190 */ 65, 65, 65, 574, 65, 65, 517, 65, 65, 65,
+ /* 200 */ 65, 65, 65, 65, 65, 65, 65, 566, 691, 288,
+ /* 210 */ 288, 288, 701, 620, 1058, 675, 603, 964, 964, 967,
+ /* 220 */ 603, 967, 722, 965, 936, 999, 964, 264, 999, 999,
+ /* 230 */ 911, 921, 434, 1196, 1119, 1119, 1202, 1202, 1119, 1222,
+ /* 240 */ 1184, 1126, 1244, 1244, 1244, 1244, 1119, 1251, 1126, 1222,
+ /* 250 */ 1184, 1184, 1126, 1119, 1251, 1145, 1237, 1119, 1119, 1251,
+ /* 260 */ 1275, 1119, 1251, 1119, 1251, 1275, 1203, 1203, 1203, 1264,
+ /* 270 */ 1275, 1203, 1211, 1203, 1264, 1203, 1203, 1194, 1216, 1194,
+ /* 280 */ 1216, 1194, 1216, 1194, 1216, 1119, 1119, 1206, 1275, 1250,
+ /* 290 */ 1250, 1275, 1221, 1225, 1224, 1226, 1126, 1336, 1347, 1363,
+ /* 300 */ 1363, 1371, 1371, 1371, 1371, -72, -72, -72, -72, -72,
+ /* 310 */ -72, 477, 623, 742, 819, 624, 694, 74, 1023, 221,
+ /* 320 */ 1055, 1065, 1077, 1087, 1080, 889, 1031, 939, 1093, 1122,
+ /* 330 */ 1085, 1139, 961, 1024, 1172, 1103, 821, 1384, 1392, 1374,
+ /* 340 */ 1255, 1385, 1331, 1386, 1378, 1381, 1285, 1277, 1298, 1287,
+ /* 350 */ 1393, 1289, 1396, 1414, 1293, 1286, 1340, 1341, 1312, 1397,
+ /* 360 */ 1388, 1304, 1426, 1423, 1407, 1323, 1291, 1379, 1406, 1380,
+ /* 370 */ 1375, 1391, 1330, 1415, 1418, 1421, 1329, 1337, 1422, 1390,
+ /* 380 */ 1424, 1425, 1427, 1429, 1395, 1419, 1430, 1400, 1405, 1431,
+ /* 390 */ 1432, 1433, 1342, 1435, 1436, 1438, 1437, 1339, 1439, 1441,
+ /* 400 */ 1440, 1434, 1443, 1343, 1445, 1442, 1446, 1444, 1445, 1450,
+ /* 410 */ 1451, 1452, 1453, 1454, 1459, 1455, 1460, 1462, 1458, 1461,
+ /* 420 */ 1463, 1466, 1465, 1461, 1467, 1469, 1470, 1471, 1473, 1354,
+ /* 430 */ 1370, 1376, 1377, 1474, 1485, 1484,
};
-#define YY_REDUCE_USE_DFLT (-110)
-#define YY_REDUCE_COUNT (305)
-#define YY_REDUCE_MIN (-109)
-#define YY_REDUCE_MAX (1323)
+#define YY_REDUCE_USE_DFLT (-176)
+#define YY_REDUCE_COUNT (310)
+#define YY_REDUCE_MIN (-175)
+#define YY_REDUCE_MAX (1234)
static const short yy_reduce_ofst[] = {
- /* 0 */ 238, 954, 213, 289, 310, 234, 144, 317, -109, 382,
- /* 10 */ 377, 303, 461, 389, 378, 368, 302, 294, 253, 395,
- /* 20 */ 293, 324, 403, 403, 403, 403, 403, 403, 403, 403,
- /* 30 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- /* 40 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
- /* 50 */ 403, 1022, 1012, 1005, 998, 963, 961, 959, 957, 950,
- /* 60 */ 947, 930, 912, 873, 861, 823, 810, 771, 759, 720,
- /* 70 */ 708, 670, 657, 619, 614, 612, 610, 608, 606, 604,
- /* 80 */ 598, 595, 593, 580, 542, 540, 537, 535, 533, 531,
- /* 90 */ 529, 527, 503, 386, 403, 403, 403, 403, 403, 403,
- /* 100 */ 403, 403, 403, 95, 447, 82, 334, 504, 467, 403,
- /* 110 */ 477, 464, 403, 403, 403, 403, 860, 747, 744, 785,
- /* 120 */ 638, 638, 926, 891, 900, 899, 887, 844, 840, 835,
- /* 130 */ 848, 830, 843, 829, 792, 839, 826, 737, 838, 795,
- /* 140 */ 789, 47, 734, 530, 696, 777, 711, 677, 733, 730,
- /* 150 */ 729, 728, 727, 627, 448, 64, 187, 1305, 1302, 1252,
- /* 160 */ 1290, 1273, 1323, 1322, 1321, 1319, 1318, 1316, 1315, 1314,
- /* 170 */ 1313, 1312, 1311, 1310, 1308, 1307, 1304, 1303, 1301, 1298,
- /* 180 */ 1294, 1292, 1289, 1266, 1264, 1259, 1288, 1287, 1238, 1285,
- /* 190 */ 1281, 1280, 1279, 1278, 1251, 1277, 1276, 1275, 1273, 1268,
- /* 200 */ 1267, 1265, 1263, 1261, 1257, 1248, 1237, 1247, 1246, 1243,
- /* 210 */ 1238, 1240, 1235, 1249, 1234, 1233, 1230, 1220, 1214, 1210,
- /* 220 */ 1225, 1219, 1232, 1231, 1197, 1195, 1227, 1224, 1201, 1208,
- /* 230 */ 1242, 1137, 1236, 1229, 1193, 1181, 1221, 1177, 1196, 1179,
- /* 240 */ 1191, 1190, 1186, 1182, 1218, 1216, 1176, 1162, 1183, 1180,
- /* 250 */ 1160, 1199, 1203, 1133, 1095, 1198, 1194, 1188, 1192, 1171,
- /* 260 */ 1169, 1168, 1173, 1174, 1166, 1159, 1141, 1170, 1158, 1167,
- /* 270 */ 1157, 1132, 1145, 1143, 1124, 1128, 1103, 1102, 1100, 1096,
- /* 280 */ 1150, 1149, 1085, 1125, 1080, 1064, 1120, 1097, 1082, 1078,
- /* 290 */ 1073, 1067, 1109, 1107, 1119, 1117, 1116, 1113, 1111, 1108,
- /* 300 */ 1007, 1000, 1002, 1076, 1075, 1081,
+ /* 0 */ -143, 954, 86, 21, -50, 23, 79, 134, 170, -175,
+ /* 10 */ 229, 260, -121, 212, 219, 291, -54, 349, 362, 156,
+ /* 20 */ 309, 311, 334, 85, 224, 394, 314, 314, 314, 314,
+ /* 30 */ 314, 314, 314, 314, 314, 314, 314, 314, 314, 314,
+ /* 40 */ 314, 314, 314, 314, 314, 314, 314, 314, 314, 314,
+ /* 50 */ 314, 314, 314, 314, 314, 374, 441, 443, 450, 452,
+ /* 60 */ 515, 554, 567, 569, 572, 578, 580, 582, 584, 587,
+ /* 70 */ 593, 631, 644, 646, 649, 655, 657, 659, 661, 664,
+ /* 80 */ 708, 720, 759, 771, 810, 822, 861, 873, 912, 930,
+ /* 90 */ 947, 950, 957, 959, 963, 966, 968, 998, 314, 314,
+ /* 100 */ 314, 314, 314, 314, 314, 314, 314, 447, -53, 166,
+ /* 110 */ 438, 348, 363, 314, 473, 469, 314, 314, 314, 314,
+ /* 120 */ -15, 59, 101, 688, 220, 220, 525, 256, 729, 735,
+ /* 130 */ 736, 740, 741, 744, 645, 448, 738, 458, 786, 503,
+ /* 140 */ 780, 656, 721, 724, 792, 545, 568, 706, 683, 681,
+ /* 150 */ 779, 784, 830, 831, 835, 678, 601, -104, -2, 96,
+ /* 160 */ 111, 218, 287, 308, 310, 312, 335, 411, 453, 461,
+ /* 170 */ 573, 599, 617, 658, 665, 670, 732, 734, 775, 848,
+ /* 180 */ 875, 892, 893, 898, 332, 420, 869, 931, 944, 886,
+ /* 190 */ 983, 992, 1009, 958, 1017, 1028, 988, 1033, 1034, 1035,
+ /* 200 */ 287, 1036, 1044, 1045, 1047, 1049, 1056, 915, 972, 997,
+ /* 210 */ 1000, 1002, 886, 1011, 1015, 1061, 1013, 1001, 1003, 977,
+ /* 220 */ 1018, 979, 1050, 1041, 1040, 1052, 1014, 1004, 1059, 1060,
+ /* 230 */ 1032, 1038, 1084, 995, 1089, 1090, 1008, 1016, 1092, 1037,
+ /* 240 */ 1068, 1062, 1069, 1072, 1073, 1074, 1105, 1112, 1071, 1048,
+ /* 250 */ 1081, 1088, 1078, 1116, 1118, 1046, 1066, 1128, 1136, 1140,
+ /* 260 */ 1120, 1147, 1146, 1148, 1150, 1130, 1135, 1137, 1138, 1132,
+ /* 270 */ 1141, 1142, 1143, 1149, 1144, 1153, 1154, 1104, 1107, 1108,
+ /* 280 */ 1114, 1115, 1117, 1123, 1125, 1173, 1176, 1121, 1165, 1127,
+ /* 290 */ 1131, 1167, 1157, 1151, 1158, 1166, 1168, 1212, 1214, 1227,
+ /* 300 */ 1228, 1231, 1232, 1233, 1234, 1152, 1155, 1159, 1198, 1199,
+ /* 310 */ 1219,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 647, 964, 964, 964, 878, 878, 969, 964, 774, 802,
- /* 10 */ 802, 938, 969, 969, 969, 876, 969, 969, 969, 964,
- /* 20 */ 969, 778, 808, 969, 969, 969, 969, 969, 969, 969,
- /* 30 */ 969, 937, 939, 816, 815, 918, 789, 813, 806, 810,
- /* 40 */ 879, 872, 873, 871, 875, 880, 969, 809, 841, 856,
- /* 50 */ 840, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 60 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 70 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 80 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 90 */ 969, 969, 969, 969, 850, 855, 862, 854, 851, 843,
- /* 100 */ 842, 844, 845, 969, 969, 673, 739, 969, 969, 846,
- /* 110 */ 969, 685, 847, 859, 858, 857, 680, 969, 969, 969,
- /* 120 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 130 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 140 */ 969, 969, 969, 969, 647, 964, 969, 969, 964, 964,
- /* 150 */ 964, 964, 964, 964, 956, 778, 768, 969, 969, 969,
- /* 160 */ 969, 969, 969, 969, 969, 969, 969, 944, 942, 969,
- /* 170 */ 891, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 180 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 190 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 200 */ 969, 969, 969, 969, 653, 969, 911, 774, 774, 774,
- /* 210 */ 776, 754, 766, 655, 812, 791, 791, 923, 812, 923,
- /* 220 */ 710, 733, 707, 802, 791, 874, 802, 802, 775, 766,
- /* 230 */ 969, 949, 782, 782, 941, 941, 782, 821, 743, 812,
- /* 240 */ 750, 750, 750, 750, 782, 670, 812, 821, 743, 743,
- /* 250 */ 812, 782, 670, 917, 915, 782, 782, 670, 782, 670,
- /* 260 */ 782, 670, 884, 741, 741, 741, 725, 884, 741, 710,
- /* 270 */ 741, 725, 741, 741, 795, 790, 795, 790, 795, 790,
- /* 280 */ 782, 782, 969, 884, 888, 888, 884, 807, 796, 805,
- /* 290 */ 803, 812, 676, 728, 663, 663, 652, 652, 652, 652,
- /* 300 */ 961, 961, 956, 712, 712, 695, 969, 969, 969, 969,
- /* 310 */ 969, 969, 687, 969, 893, 969, 969, 969, 969, 969,
- /* 320 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 330 */ 969, 828, 969, 648, 951, 969, 969, 948, 969, 969,
- /* 340 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 350 */ 969, 969, 969, 969, 969, 969, 921, 969, 969, 969,
- /* 360 */ 969, 969, 969, 914, 913, 969, 969, 969, 969, 969,
- /* 370 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
- /* 380 */ 969, 969, 969, 969, 969, 969, 969, 757, 969, 969,
- /* 390 */ 969, 761, 969, 969, 969, 969, 969, 969, 804, 969,
- /* 400 */ 797, 969, 877, 969, 969, 969, 969, 969, 969, 969,
- /* 410 */ 969, 969, 969, 966, 969, 969, 969, 965, 969, 969,
- /* 420 */ 969, 969, 969, 830, 969, 829, 833, 969, 661, 969,
- /* 430 */ 644, 649, 960, 963, 962, 959, 958, 957, 952, 950,
- /* 440 */ 947, 946, 945, 943, 940, 936, 897, 895, 902, 901,
- /* 450 */ 900, 899, 898, 896, 894, 892, 818, 817, 814, 811,
- /* 460 */ 753, 935, 890, 752, 749, 748, 669, 953, 920, 929,
- /* 470 */ 928, 927, 822, 926, 925, 924, 922, 919, 906, 820,
- /* 480 */ 819, 744, 882, 881, 672, 910, 909, 908, 912, 916,
- /* 490 */ 907, 784, 751, 671, 668, 675, 679, 731, 732, 740,
- /* 500 */ 738, 737, 736, 735, 734, 730, 681, 686, 724, 709,
- /* 510 */ 708, 717, 716, 722, 721, 720, 719, 718, 715, 714,
- /* 520 */ 713, 706, 705, 711, 704, 727, 726, 723, 703, 747,
- /* 530 */ 746, 745, 742, 702, 701, 700, 833, 699, 698, 838,
- /* 540 */ 837, 866, 826, 755, 759, 758, 762, 763, 771, 770,
- /* 550 */ 769, 780, 781, 793, 792, 824, 823, 794, 779, 773,
- /* 560 */ 772, 788, 787, 786, 785, 777, 767, 799, 798, 868,
- /* 570 */ 783, 867, 865, 934, 933, 932, 931, 930, 870, 967,
- /* 580 */ 968, 887, 889, 886, 801, 800, 885, 869, 839, 836,
- /* 590 */ 690, 691, 905, 904, 903, 693, 692, 689, 688, 863,
- /* 600 */ 860, 852, 864, 861, 853, 849, 848, 834, 832, 831,
- /* 610 */ 827, 835, 760, 756, 825, 765, 764, 697, 696, 694,
- /* 620 */ 678, 677, 674, 667, 665, 664, 666, 662, 660, 659,
- /* 630 */ 658, 657, 656, 684, 683, 682, 654, 651, 650, 646,
- /* 640 */ 645, 643,
+ /* 0 */ 982, 1300, 1300, 1300, 1214, 1214, 1214, 1305, 1300, 1109,
+ /* 10 */ 1138, 1138, 1274, 1305, 1305, 1305, 1305, 1305, 1305, 1212,
+ /* 20 */ 1305, 1305, 1305, 1300, 1305, 1113, 1144, 1305, 1305, 1305,
+ /* 30 */ 1305, 1305, 1305, 1305, 1305, 1273, 1275, 1152, 1151, 1254,
+ /* 40 */ 1125, 1149, 1142, 1146, 1215, 1208, 1209, 1207, 1211, 1216,
+ /* 50 */ 1305, 1145, 1177, 1192, 1176, 1305, 1305, 1305, 1305, 1305,
+ /* 60 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 70 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 80 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 90 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1186, 1191,
+ /* 100 */ 1198, 1190, 1187, 1179, 1178, 1180, 1181, 1305, 1305, 1008,
+ /* 110 */ 1074, 1305, 1305, 1182, 1305, 1020, 1183, 1195, 1194, 1193,
+ /* 120 */ 1015, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 130 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 140 */ 1305, 1305, 1305, 1305, 1305, 982, 1300, 1305, 1305, 1300,
+ /* 150 */ 1300, 1300, 1300, 1300, 1300, 1292, 1113, 1103, 1305, 1305,
+ /* 160 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1280, 1278,
+ /* 170 */ 1305, 1227, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 180 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 190 */ 1305, 1305, 1305, 1109, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 200 */ 1305, 1305, 1305, 1305, 1305, 1305, 988, 1305, 1247, 1109,
+ /* 210 */ 1109, 1109, 1111, 1089, 1101, 990, 1148, 1127, 1127, 1259,
+ /* 220 */ 1148, 1259, 1045, 1068, 1042, 1138, 1127, 1210, 1138, 1138,
+ /* 230 */ 1110, 1101, 1305, 1285, 1118, 1118, 1277, 1277, 1118, 1157,
+ /* 240 */ 1078, 1148, 1085, 1085, 1085, 1085, 1118, 1005, 1148, 1157,
+ /* 250 */ 1078, 1078, 1148, 1118, 1005, 1253, 1251, 1118, 1118, 1005,
+ /* 260 */ 1220, 1118, 1005, 1118, 1005, 1220, 1076, 1076, 1076, 1060,
+ /* 270 */ 1220, 1076, 1045, 1076, 1060, 1076, 1076, 1131, 1126, 1131,
+ /* 280 */ 1126, 1131, 1126, 1131, 1126, 1118, 1118, 1305, 1220, 1224,
+ /* 290 */ 1224, 1220, 1143, 1132, 1141, 1139, 1148, 1011, 1063, 998,
+ /* 300 */ 998, 987, 987, 987, 987, 1297, 1297, 1292, 1047, 1047,
+ /* 310 */ 1030, 1305, 1305, 1305, 1305, 1305, 1305, 1022, 1305, 1229,
+ /* 320 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 330 */ 1305, 1305, 1305, 1305, 1305, 1305, 1164, 1305, 983, 1287,
+ /* 340 */ 1305, 1305, 1284, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 350 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 360 */ 1305, 1257, 1305, 1305, 1305, 1305, 1305, 1305, 1250, 1249,
+ /* 370 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 380 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 390 */ 1305, 1305, 1092, 1305, 1305, 1305, 1096, 1305, 1305, 1305,
+ /* 400 */ 1305, 1305, 1305, 1305, 1140, 1305, 1133, 1305, 1213, 1305,
+ /* 410 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1302,
+ /* 420 */ 1305, 1305, 1305, 1301, 1305, 1305, 1305, 1305, 1305, 1166,
+ /* 430 */ 1305, 1165, 1169, 1305, 996, 1305,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
@@ -125522,13 +125938,17 @@
** (In other words, the "major" token.)
**
** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
*/
struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number */
+ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */
YYMINORTYPE minor; /* The user-supplied minor token value. This
** is the value of the token */
};
@@ -125630,22 +126050,22 @@
"createkw", "temp", "ifnotexists", "dbnm",
"columnlist", "conslist_opt", "table_options", "select",
"column", "columnid", "type", "carglist",
"typetoken", "typename", "signed", "plus_num",
"minus_num", "ccons", "term", "expr",
- "onconf", "sortorder", "autoinc", "idxlist_opt",
+ "onconf", "sortorder", "autoinc", "eidlist_opt",
"refargs", "defer_subclause", "refarg", "refact",
"init_deferred_pred_opt", "conslist", "tconscomma", "tcons",
- "idxlist", "defer_subclause_opt", "orconf", "resolvetype",
- "raisetype", "ifexists", "fullname", "selectnowith",
- "oneselect", "with", "multiselect_op", "distinct",
- "selcollist", "from", "where_opt", "groupby_opt",
- "having_opt", "orderby_opt", "limit_opt", "values",
- "nexprlist", "exprlist", "sclp", "as",
- "seltablist", "stl_prefix", "joinop", "indexed_opt",
- "on_opt", "using_opt", "joinop2", "idlist",
- "sortlist", "setlist", "insert_cmd", "inscollist_opt",
+ "sortlist", "eidlist", "defer_subclause_opt", "orconf",
+ "resolvetype", "raisetype", "ifexists", "fullname",
+ "selectnowith", "oneselect", "with", "multiselect_op",
+ "distinct", "selcollist", "from", "where_opt",
+ "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
+ "values", "nexprlist", "exprlist", "sclp",
+ "as", "seltablist", "stl_prefix", "joinop",
+ "indexed_opt", "on_opt", "using_opt", "joinop2",
+ "idlist", "setlist", "insert_cmd", "idlist_opt",
"likeop", "between_op", "in_op", "case_operand",
"case_exprlist", "case_else", "uniqueflag", "collate",
"nmnum", "trigger_decl", "trigger_cmd_list", "trigger_time",
"trigger_event", "foreach_clause", "when_clause", "trigger_cmd",
"trnm", "tridxby", "database_kw_opt", "key_opt",
@@ -125722,11 +126142,11 @@
/* 60 */ "ccons ::= NULL onconf",
/* 61 */ "ccons ::= NOT NULL onconf",
/* 62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
/* 63 */ "ccons ::= UNIQUE onconf",
/* 64 */ "ccons ::= CHECK LP expr RP",
- /* 65 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 65 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
/* 66 */ "ccons ::= defer_subclause",
/* 67 */ "ccons ::= COLLATE ID|STRING",
/* 68 */ "autoinc ::=",
/* 69 */ "autoinc ::= AUTOINCR",
/* 70 */ "refargs ::=",
@@ -125750,14 +126170,14 @@
/* 88 */ "conslist ::= conslist tconscomma tcons",
/* 89 */ "conslist ::= tcons",
/* 90 */ "tconscomma ::= COMMA",
/* 91 */ "tconscomma ::=",
/* 92 */ "tcons ::= CONSTRAINT nm",
- /* 93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 94 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /* 93 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /* 94 */ "tcons ::= UNIQUE LP sortlist RP onconf",
/* 95 */ "tcons ::= CHECK LP expr RP onconf",
- /* 96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 96 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
/* 97 */ "defer_subclause_opt ::=",
/* 98 */ "defer_subclause_opt ::= defer_subclause",
/* 99 */ "onconf ::=",
/* 100 */ "onconf ::= ON CONFLICT resolvetype",
/* 101 */ "orconf ::=",
@@ -125766,11 +126186,11 @@
/* 104 */ "resolvetype ::= IGNORE",
/* 105 */ "resolvetype ::= REPLACE",
/* 106 */ "cmd ::= DROP TABLE ifexists fullname",
/* 107 */ "ifexists ::= IF EXISTS",
/* 108 */ "ifexists ::=",
- /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+ /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
/* 110 */ "cmd ::= DROP VIEW ifexists fullname",
/* 111 */ "cmd ::= select",
/* 112 */ "select ::= with selectnowith",
/* 113 */ "selectnowith ::= oneselect",
/* 114 */ "selectnowith ::= selectnowith multiselect_op oneselect",
@@ -125795,199 +126215,200 @@
/* 133 */ "from ::=",
/* 134 */ "from ::= FROM seltablist",
/* 135 */ "stl_prefix ::= seltablist joinop",
/* 136 */ "stl_prefix ::=",
/* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 138 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 139 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 140 */ "dbnm ::=",
- /* 141 */ "dbnm ::= DOT nm",
- /* 142 */ "fullname ::= nm dbnm",
- /* 143 */ "joinop ::= COMMA|JOIN",
- /* 144 */ "joinop ::= JOIN_KW JOIN",
- /* 145 */ "joinop ::= JOIN_KW nm JOIN",
- /* 146 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 147 */ "on_opt ::= ON expr",
- /* 148 */ "on_opt ::=",
- /* 149 */ "indexed_opt ::=",
- /* 150 */ "indexed_opt ::= INDEXED BY nm",
- /* 151 */ "indexed_opt ::= NOT INDEXED",
- /* 152 */ "using_opt ::= USING LP idlist RP",
- /* 153 */ "using_opt ::=",
- /* 154 */ "orderby_opt ::=",
- /* 155 */ "orderby_opt ::= ORDER BY sortlist",
- /* 156 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 157 */ "sortlist ::= expr sortorder",
- /* 158 */ "sortorder ::= ASC",
- /* 159 */ "sortorder ::= DESC",
- /* 160 */ "sortorder ::=",
- /* 161 */ "groupby_opt ::=",
- /* 162 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 163 */ "having_opt ::=",
- /* 164 */ "having_opt ::= HAVING expr",
- /* 165 */ "limit_opt ::=",
- /* 166 */ "limit_opt ::= LIMIT expr",
- /* 167 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 168 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 169 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
- /* 170 */ "where_opt ::=",
- /* 171 */ "where_opt ::= WHERE expr",
- /* 172 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 173 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 174 */ "setlist ::= nm EQ expr",
- /* 175 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt select",
- /* 176 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 177 */ "insert_cmd ::= INSERT orconf",
- /* 178 */ "insert_cmd ::= REPLACE",
- /* 179 */ "inscollist_opt ::=",
- /* 180 */ "inscollist_opt ::= LP idlist RP",
- /* 181 */ "idlist ::= idlist COMMA nm",
- /* 182 */ "idlist ::= nm",
- /* 183 */ "expr ::= term",
- /* 184 */ "expr ::= LP expr RP",
- /* 185 */ "term ::= NULL",
- /* 186 */ "expr ::= ID|INDEXED",
- /* 187 */ "expr ::= JOIN_KW",
- /* 188 */ "expr ::= nm DOT nm",
- /* 189 */ "expr ::= nm DOT nm DOT nm",
- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 191 */ "term ::= STRING",
- /* 192 */ "expr ::= VARIABLE",
- /* 193 */ "expr ::= expr COLLATE ID|STRING",
- /* 194 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 195 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 196 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 197 */ "term ::= CTIME_KW",
- /* 198 */ "expr ::= expr AND expr",
- /* 199 */ "expr ::= expr OR expr",
- /* 200 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 201 */ "expr ::= expr EQ|NE expr",
- /* 202 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 203 */ "expr ::= expr PLUS|MINUS expr",
- /* 204 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 205 */ "expr ::= expr CONCAT expr",
- /* 206 */ "likeop ::= LIKE_KW|MATCH",
- /* 207 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 208 */ "expr ::= expr likeop expr",
- /* 209 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 210 */ "expr ::= expr ISNULL|NOTNULL",
- /* 211 */ "expr ::= expr NOT NULL",
- /* 212 */ "expr ::= expr IS expr",
- /* 213 */ "expr ::= expr IS NOT expr",
- /* 214 */ "expr ::= NOT expr",
- /* 215 */ "expr ::= BITNOT expr",
- /* 216 */ "expr ::= MINUS expr",
- /* 217 */ "expr ::= PLUS expr",
- /* 218 */ "between_op ::= BETWEEN",
- /* 219 */ "between_op ::= NOT BETWEEN",
- /* 220 */ "expr ::= expr between_op expr AND expr",
- /* 221 */ "in_op ::= IN",
- /* 222 */ "in_op ::= NOT IN",
- /* 223 */ "expr ::= expr in_op LP exprlist RP",
- /* 224 */ "expr ::= LP select RP",
- /* 225 */ "expr ::= expr in_op LP select RP",
- /* 226 */ "expr ::= expr in_op nm dbnm",
- /* 227 */ "expr ::= EXISTS LP select RP",
- /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 230 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 231 */ "case_else ::= ELSE expr",
- /* 232 */ "case_else ::=",
- /* 233 */ "case_operand ::= expr",
- /* 234 */ "case_operand ::=",
- /* 235 */ "exprlist ::= nexprlist",
- /* 236 */ "exprlist ::=",
- /* 237 */ "nexprlist ::= nexprlist COMMA expr",
- /* 238 */ "nexprlist ::= expr",
- /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
- /* 240 */ "uniqueflag ::= UNIQUE",
- /* 241 */ "uniqueflag ::=",
- /* 242 */ "idxlist_opt ::=",
- /* 243 */ "idxlist_opt ::= LP idxlist RP",
- /* 244 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 245 */ "idxlist ::= nm collate sortorder",
- /* 246 */ "collate ::=",
- /* 247 */ "collate ::= COLLATE ID|STRING",
- /* 248 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 249 */ "cmd ::= VACUUM",
- /* 250 */ "cmd ::= VACUUM nm",
- /* 251 */ "cmd ::= PRAGMA nm dbnm",
- /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 256 */ "nmnum ::= plus_num",
- /* 257 */ "nmnum ::= nm",
- /* 258 */ "nmnum ::= ON",
- /* 259 */ "nmnum ::= DELETE",
- /* 260 */ "nmnum ::= DEFAULT",
- /* 261 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 262 */ "plus_num ::= INTEGER|FLOAT",
- /* 263 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 264 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 265 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 266 */ "trigger_time ::= BEFORE",
- /* 267 */ "trigger_time ::= AFTER",
- /* 268 */ "trigger_time ::= INSTEAD OF",
- /* 269 */ "trigger_time ::=",
- /* 270 */ "trigger_event ::= DELETE|INSERT",
- /* 271 */ "trigger_event ::= UPDATE",
- /* 272 */ "trigger_event ::= UPDATE OF idlist",
- /* 273 */ "foreach_clause ::=",
- /* 274 */ "foreach_clause ::= FOR EACH ROW",
- /* 275 */ "when_clause ::=",
- /* 276 */ "when_clause ::= WHEN expr",
- /* 277 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 279 */ "trnm ::= nm",
- /* 280 */ "trnm ::= nm DOT nm",
- /* 281 */ "tridxby ::=",
- /* 282 */ "tridxby ::= INDEXED BY nm",
- /* 283 */ "tridxby ::= NOT INDEXED",
- /* 284 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 285 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 286 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 287 */ "trigger_cmd ::= select",
- /* 288 */ "expr ::= RAISE LP IGNORE RP",
- /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 290 */ "raisetype ::= ROLLBACK",
- /* 291 */ "raisetype ::= ABORT",
- /* 292 */ "raisetype ::= FAIL",
- /* 293 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 294 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 295 */ "cmd ::= DETACH database_kw_opt expr",
- /* 296 */ "key_opt ::=",
- /* 297 */ "key_opt ::= KEY expr",
- /* 298 */ "database_kw_opt ::= DATABASE",
- /* 299 */ "database_kw_opt ::=",
- /* 300 */ "cmd ::= REINDEX",
- /* 301 */ "cmd ::= REINDEX nm dbnm",
- /* 302 */ "cmd ::= ANALYZE",
- /* 303 */ "cmd ::= ANALYZE nm dbnm",
- /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 306 */ "add_column_fullname ::= fullname",
- /* 307 */ "kwcolumn_opt ::=",
- /* 308 */ "kwcolumn_opt ::= COLUMNKW",
- /* 309 */ "cmd ::= create_vtab",
- /* 310 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 311 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 312 */ "vtabarglist ::= vtabarg",
- /* 313 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 314 */ "vtabarg ::=",
- /* 315 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 316 */ "vtabargtoken ::= ANY",
- /* 317 */ "vtabargtoken ::= lp anylist RP",
- /* 318 */ "lp ::= LP",
- /* 319 */ "anylist ::=",
- /* 320 */ "anylist ::= anylist LP anylist RP",
- /* 321 */ "anylist ::= anylist ANY",
- /* 322 */ "with ::=",
- /* 323 */ "with ::= WITH wqlist",
- /* 324 */ "with ::= WITH RECURSIVE wqlist",
- /* 325 */ "wqlist ::= nm idxlist_opt AS LP select RP",
- /* 326 */ "wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP",
+ /* 138 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 139 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 140 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 141 */ "dbnm ::=",
+ /* 142 */ "dbnm ::= DOT nm",
+ /* 143 */ "fullname ::= nm dbnm",
+ /* 144 */ "joinop ::= COMMA|JOIN",
+ /* 145 */ "joinop ::= JOIN_KW JOIN",
+ /* 146 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 147 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 148 */ "on_opt ::= ON expr",
+ /* 149 */ "on_opt ::=",
+ /* 150 */ "indexed_opt ::=",
+ /* 151 */ "indexed_opt ::= INDEXED BY nm",
+ /* 152 */ "indexed_opt ::= NOT INDEXED",
+ /* 153 */ "using_opt ::= USING LP idlist RP",
+ /* 154 */ "using_opt ::=",
+ /* 155 */ "orderby_opt ::=",
+ /* 156 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 157 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 158 */ "sortlist ::= expr sortorder",
+ /* 159 */ "sortorder ::= ASC",
+ /* 160 */ "sortorder ::= DESC",
+ /* 161 */ "sortorder ::=",
+ /* 162 */ "groupby_opt ::=",
+ /* 163 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 164 */ "having_opt ::=",
+ /* 165 */ "having_opt ::= HAVING expr",
+ /* 166 */ "limit_opt ::=",
+ /* 167 */ "limit_opt ::= LIMIT expr",
+ /* 168 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 169 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 170 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+ /* 171 */ "where_opt ::=",
+ /* 172 */ "where_opt ::= WHERE expr",
+ /* 173 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 174 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 175 */ "setlist ::= nm EQ expr",
+ /* 176 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+ /* 177 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+ /* 178 */ "insert_cmd ::= INSERT orconf",
+ /* 179 */ "insert_cmd ::= REPLACE",
+ /* 180 */ "idlist_opt ::=",
+ /* 181 */ "idlist_opt ::= LP idlist RP",
+ /* 182 */ "idlist ::= idlist COMMA nm",
+ /* 183 */ "idlist ::= nm",
+ /* 184 */ "expr ::= term",
+ /* 185 */ "expr ::= LP expr RP",
+ /* 186 */ "term ::= NULL",
+ /* 187 */ "expr ::= ID|INDEXED",
+ /* 188 */ "expr ::= JOIN_KW",
+ /* 189 */ "expr ::= nm DOT nm",
+ /* 190 */ "expr ::= nm DOT nm DOT nm",
+ /* 191 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 192 */ "term ::= STRING",
+ /* 193 */ "expr ::= VARIABLE",
+ /* 194 */ "expr ::= expr COLLATE ID|STRING",
+ /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 196 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 197 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 198 */ "term ::= CTIME_KW",
+ /* 199 */ "expr ::= expr AND expr",
+ /* 200 */ "expr ::= expr OR expr",
+ /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 202 */ "expr ::= expr EQ|NE expr",
+ /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 204 */ "expr ::= expr PLUS|MINUS expr",
+ /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 206 */ "expr ::= expr CONCAT expr",
+ /* 207 */ "likeop ::= LIKE_KW|MATCH",
+ /* 208 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 209 */ "expr ::= expr likeop expr",
+ /* 210 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 211 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 212 */ "expr ::= expr NOT NULL",
+ /* 213 */ "expr ::= expr IS expr",
+ /* 214 */ "expr ::= expr IS NOT expr",
+ /* 215 */ "expr ::= NOT expr",
+ /* 216 */ "expr ::= BITNOT expr",
+ /* 217 */ "expr ::= MINUS expr",
+ /* 218 */ "expr ::= PLUS expr",
+ /* 219 */ "between_op ::= BETWEEN",
+ /* 220 */ "between_op ::= NOT BETWEEN",
+ /* 221 */ "expr ::= expr between_op expr AND expr",
+ /* 222 */ "in_op ::= IN",
+ /* 223 */ "in_op ::= NOT IN",
+ /* 224 */ "expr ::= expr in_op LP exprlist RP",
+ /* 225 */ "expr ::= LP select RP",
+ /* 226 */ "expr ::= expr in_op LP select RP",
+ /* 227 */ "expr ::= expr in_op nm dbnm",
+ /* 228 */ "expr ::= EXISTS LP select RP",
+ /* 229 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 230 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 231 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 232 */ "case_else ::= ELSE expr",
+ /* 233 */ "case_else ::=",
+ /* 234 */ "case_operand ::= expr",
+ /* 235 */ "case_operand ::=",
+ /* 236 */ "exprlist ::= nexprlist",
+ /* 237 */ "exprlist ::=",
+ /* 238 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 239 */ "nexprlist ::= expr",
+ /* 240 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 241 */ "uniqueflag ::= UNIQUE",
+ /* 242 */ "uniqueflag ::=",
+ /* 243 */ "eidlist_opt ::=",
+ /* 244 */ "eidlist_opt ::= LP eidlist RP",
+ /* 245 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 246 */ "eidlist ::= nm collate sortorder",
+ /* 247 */ "collate ::=",
+ /* 248 */ "collate ::= COLLATE ID|STRING",
+ /* 249 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 250 */ "cmd ::= VACUUM",
+ /* 251 */ "cmd ::= VACUUM nm",
+ /* 252 */ "cmd ::= PRAGMA nm dbnm",
+ /* 253 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 254 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 255 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 257 */ "nmnum ::= plus_num",
+ /* 258 */ "nmnum ::= nm",
+ /* 259 */ "nmnum ::= ON",
+ /* 260 */ "nmnum ::= DELETE",
+ /* 261 */ "nmnum ::= DEFAULT",
+ /* 262 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 263 */ "plus_num ::= INTEGER|FLOAT",
+ /* 264 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 265 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 266 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 267 */ "trigger_time ::= BEFORE",
+ /* 268 */ "trigger_time ::= AFTER",
+ /* 269 */ "trigger_time ::= INSTEAD OF",
+ /* 270 */ "trigger_time ::=",
+ /* 271 */ "trigger_event ::= DELETE|INSERT",
+ /* 272 */ "trigger_event ::= UPDATE",
+ /* 273 */ "trigger_event ::= UPDATE OF idlist",
+ /* 274 */ "foreach_clause ::=",
+ /* 275 */ "foreach_clause ::= FOR EACH ROW",
+ /* 276 */ "when_clause ::=",
+ /* 277 */ "when_clause ::= WHEN expr",
+ /* 278 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 279 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 280 */ "trnm ::= nm",
+ /* 281 */ "trnm ::= nm DOT nm",
+ /* 282 */ "tridxby ::=",
+ /* 283 */ "tridxby ::= INDEXED BY nm",
+ /* 284 */ "tridxby ::= NOT INDEXED",
+ /* 285 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 286 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 287 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 288 */ "trigger_cmd ::= select",
+ /* 289 */ "expr ::= RAISE LP IGNORE RP",
+ /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 291 */ "raisetype ::= ROLLBACK",
+ /* 292 */ "raisetype ::= ABORT",
+ /* 293 */ "raisetype ::= FAIL",
+ /* 294 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 295 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 296 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 297 */ "key_opt ::=",
+ /* 298 */ "key_opt ::= KEY expr",
+ /* 299 */ "database_kw_opt ::= DATABASE",
+ /* 300 */ "database_kw_opt ::=",
+ /* 301 */ "cmd ::= REINDEX",
+ /* 302 */ "cmd ::= REINDEX nm dbnm",
+ /* 303 */ "cmd ::= ANALYZE",
+ /* 304 */ "cmd ::= ANALYZE nm dbnm",
+ /* 305 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 306 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 307 */ "add_column_fullname ::= fullname",
+ /* 308 */ "kwcolumn_opt ::=",
+ /* 309 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 310 */ "cmd ::= create_vtab",
+ /* 311 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 312 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 313 */ "vtabarglist ::= vtabarg",
+ /* 314 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 315 */ "vtabarg ::=",
+ /* 316 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 317 */ "vtabargtoken ::= ANY",
+ /* 318 */ "vtabargtoken ::= lp anylist RP",
+ /* 319 */ "lp ::= LP",
+ /* 320 */ "anylist ::=",
+ /* 321 */ "anylist ::= anylist LP anylist RP",
+ /* 322 */ "anylist ::= anylist ANY",
+ /* 323 */ "with ::=",
+ /* 324 */ "with ::= WITH wqlist",
+ /* 325 */ "with ::= WITH RECURSIVE wqlist",
+ /* 326 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 327 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
};
#endif /* NDEBUG */
#if YYSTACKDEPTH<=0
@@ -126063,13 +126484,13 @@
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
case 163: /* select */
- case 195: /* selectnowith */
- case 196: /* oneselect */
- case 207: /* values */
+ case 196: /* selectnowith */
+ case 197: /* oneselect */
+ case 208: /* values */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy3));
}
break;
case 174: /* term */
@@ -126076,53 +126497,53 @@
case 175: /* expr */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr);
}
break;
- case 179: /* idxlist_opt */
- case 188: /* idxlist */
- case 200: /* selcollist */
- case 203: /* groupby_opt */
- case 205: /* orderby_opt */
- case 208: /* nexprlist */
- case 209: /* exprlist */
- case 210: /* sclp */
- case 220: /* sortlist */
+ case 179: /* eidlist_opt */
+ case 188: /* sortlist */
+ case 189: /* eidlist */
+ case 201: /* selcollist */
+ case 204: /* groupby_opt */
+ case 206: /* orderby_opt */
+ case 209: /* nexprlist */
+ case 210: /* exprlist */
+ case 211: /* sclp */
case 221: /* setlist */
case 228: /* case_exprlist */
{
sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
}
break;
- case 194: /* fullname */
- case 201: /* from */
- case 212: /* seltablist */
- case 213: /* stl_prefix */
+ case 195: /* fullname */
+ case 202: /* from */
+ case 213: /* seltablist */
+ case 214: /* stl_prefix */
{
sqlite3SrcListDelete(pParse->db, (yypminor->yy65));
}
break;
- case 197: /* with */
+ case 198: /* with */
case 252: /* wqlist */
{
sqlite3WithDelete(pParse->db, (yypminor->yy59));
}
break;
- case 202: /* where_opt */
- case 204: /* having_opt */
- case 216: /* on_opt */
+ case 203: /* where_opt */
+ case 205: /* having_opt */
+ case 217: /* on_opt */
case 227: /* case_operand */
case 229: /* case_else */
case 238: /* when_clause */
case 243: /* key_opt */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy132));
}
break;
- case 217: /* using_opt */
- case 219: /* idlist */
- case 223: /* inscollist_opt */
+ case 218: /* using_opt */
+ case 220: /* idlist */
+ case 223: /* idlist_opt */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy408));
}
break;
case 234: /* trigger_cmd_list */
@@ -126218,14 +126639,14 @@
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
int stateno = pParser->yystack[pParser->yyidx].stateno;
- if( stateno>YY_SHIFT_COUNT
- || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
- return yy_default[stateno];
- }
+ if( stateno>=YY_MIN_REDUCE ) return stateno;
+ assert( stateno <= YY_SHIFT_COUNT );
+ i = yy_shift_ofst[stateno];
+ if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno];
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
if( iLookAhead>0 ){
#ifdef YYFALLBACK
@@ -126324,11 +126745,33 @@
sqlite3ErrorMsg(pParse, "parser stack overflow");
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
}
/*
-** Perform a shift action.
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void yyTraceShift(yyParser *yypParser, int yyNewState){
+ if( yyTraceFILE ){
+ int i;
+ if( yyNewStateyyidx; i++)
+ fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"\n");
+ }else{
+ fprintf(yyTraceFILE,"%sShift *\n",yyTracePrompt);
+ }
+ }
+}
+#else
+# define yyTraceShift(X,Y)
+#endif
+
+/*
+** Perform a shift action. Return the number of errors.
*/
static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */
@@ -126357,20 +126800,11 @@
#endif
yytos = &yypParser->yystack[yypParser->yyidx];
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
yytos->minor = *yypMinor;
-#ifndef NDEBUG
- if( yyTraceFILE && yypParser->yyidx>0 ){
- int i;
- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
- for(i=1; i<=yypParser->yyidx; i++)
- fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
- fprintf(yyTraceFILE,"\n");
- }
-#endif
+ yyTraceShift(yypParser, yyNewState);
}
/* The following table contains information about every rule that
** is used during the reduce.
*/
@@ -126473,96 +126907,97 @@
{ 187, 2 },
{ 187, 7 },
{ 187, 5 },
{ 187, 5 },
{ 187, 10 },
- { 189, 0 },
- { 189, 1 },
+ { 190, 0 },
+ { 190, 1 },
{ 176, 0 },
{ 176, 3 },
- { 190, 0 },
- { 190, 2 },
- { 191, 1 },
- { 191, 1 },
- { 191, 1 },
+ { 191, 0 },
+ { 191, 2 },
+ { 192, 1 },
+ { 192, 1 },
+ { 192, 1 },
{ 149, 4 },
- { 193, 2 },
- { 193, 0 },
- { 149, 8 },
+ { 194, 2 },
+ { 194, 0 },
+ { 149, 9 },
{ 149, 4 },
{ 149, 1 },
{ 163, 2 },
- { 195, 1 },
- { 195, 3 },
- { 198, 1 },
- { 198, 2 },
- { 198, 1 },
- { 196, 9 },
- { 196, 1 },
- { 207, 4 },
- { 207, 5 },
- { 199, 1 },
- { 199, 1 },
- { 199, 0 },
- { 210, 2 },
- { 210, 0 },
- { 200, 3 },
- { 200, 2 },
- { 200, 4 },
- { 211, 2 },
- { 211, 1 },
- { 211, 0 },
- { 201, 0 },
- { 201, 2 },
- { 213, 2 },
- { 213, 0 },
- { 212, 7 },
- { 212, 7 },
- { 212, 7 },
+ { 196, 1 },
+ { 196, 3 },
+ { 199, 1 },
+ { 199, 2 },
+ { 199, 1 },
+ { 197, 9 },
+ { 197, 1 },
+ { 208, 4 },
+ { 208, 5 },
+ { 200, 1 },
+ { 200, 1 },
+ { 200, 0 },
+ { 211, 2 },
+ { 211, 0 },
+ { 201, 3 },
+ { 201, 2 },
+ { 201, 4 },
+ { 212, 2 },
+ { 212, 1 },
+ { 212, 0 },
+ { 202, 0 },
+ { 202, 2 },
+ { 214, 2 },
+ { 214, 0 },
+ { 213, 7 },
+ { 213, 9 },
+ { 213, 7 },
+ { 213, 7 },
{ 159, 0 },
{ 159, 2 },
- { 194, 2 },
- { 214, 1 },
- { 214, 2 },
- { 214, 3 },
- { 214, 4 },
- { 216, 2 },
+ { 195, 2 },
+ { 215, 1 },
+ { 215, 2 },
+ { 215, 3 },
+ { 215, 4 },
+ { 217, 2 },
+ { 217, 0 },
{ 216, 0 },
- { 215, 0 },
- { 215, 3 },
- { 215, 2 },
- { 217, 4 },
- { 217, 0 },
- { 205, 0 },
- { 205, 3 },
- { 220, 4 },
- { 220, 2 },
+ { 216, 3 },
+ { 216, 2 },
+ { 218, 4 },
+ { 218, 0 },
+ { 206, 0 },
+ { 206, 3 },
+ { 188, 4 },
+ { 188, 2 },
{ 177, 1 },
{ 177, 1 },
{ 177, 0 },
- { 203, 0 },
- { 203, 3 },
{ 204, 0 },
- { 204, 2 },
- { 206, 0 },
- { 206, 2 },
- { 206, 4 },
- { 206, 4 },
+ { 204, 3 },
+ { 205, 0 },
+ { 205, 2 },
+ { 207, 0 },
+ { 207, 2 },
+ { 207, 4 },
+ { 207, 4 },
{ 149, 6 },
- { 202, 0 },
- { 202, 2 },
+ { 203, 0 },
+ { 203, 2 },
{ 149, 8 },
{ 221, 5 },
{ 221, 3 },
{ 149, 6 },
{ 149, 7 },
{ 222, 2 },
{ 222, 1 },
{ 223, 0 },
{ 223, 3 },
- { 219, 3 },
- { 219, 1 },
+ { 220, 3 },
+ { 220, 1 },
{ 175, 1 },
{ 175, 3 },
{ 174, 1 },
{ 175, 1 },
{ 175, 1 },
@@ -126611,21 +127046,21 @@
{ 228, 4 },
{ 229, 2 },
{ 229, 0 },
{ 227, 1 },
{ 227, 0 },
+ { 210, 1 },
+ { 210, 0 },
+ { 209, 3 },
{ 209, 1 },
- { 209, 0 },
- { 208, 3 },
- { 208, 1 },
{ 149, 12 },
{ 230, 1 },
{ 230, 0 },
{ 179, 0 },
{ 179, 3 },
- { 188, 5 },
- { 188, 3 },
+ { 189, 5 },
+ { 189, 3 },
{ 231, 0 },
{ 231, 2 },
{ 149, 4 },
{ 149, 1 },
{ 149, 2 },
@@ -126666,13 +127101,13 @@
{ 239, 5 },
{ 239, 5 },
{ 239, 1 },
{ 175, 4 },
{ 175, 6 },
- { 192, 1 },
- { 192, 1 },
- { 192, 1 },
+ { 193, 1 },
+ { 193, 1 },
+ { 193, 1 },
{ 149, 4 },
{ 149, 6 },
{ 149, 3 },
{ 243, 0 },
{ 243, 2 },
@@ -126698,13 +127133,13 @@
{ 249, 3 },
{ 250, 1 },
{ 251, 0 },
{ 251, 4 },
{ 251, 2 },
- { 197, 0 },
- { 197, 2 },
- { 197, 3 },
+ { 198, 0 },
+ { 198, 2 },
+ { 198, 3 },
{ 252, 6 },
{ 252, 8 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -126725,12 +127160,13 @@
sqlite3ParserARG_FETCH;
yymsp = &yypParser->yystack[yypParser->yyidx];
#ifndef NDEBUG
if( yyTraceFILE && yyruleno>=0
&& yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ fprintf(yyTraceFILE, "%sReduce [%s] -> state %d.\n", yyTracePrompt,
+ yyRuleName[yyruleno], yymsp[-yysize].stateno);
}
#endif /* NDEBUG */
/* Silence complaints from purify about yygotominor being uninitialized
** in some cases when it is copied into the stack after the following
@@ -126823,21 +127259,23 @@
case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81);
case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83);
case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85);
case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
- case 218: /* between_op ::= BETWEEN */ yytestcase(yyruleno==218);
- case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
+ case 219: /* between_op ::= BETWEEN */ yytestcase(yyruleno==219);
+ case 222: /* in_op ::= IN */ yytestcase(yyruleno==222);
+ case 247: /* collate ::= */ yytestcase(yyruleno==247);
{yygotominor.yy328 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69);
case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84);
case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
- case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
- case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
+ case 220: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==220);
+ case 223: /* in_op ::= NOT IN */ yytestcase(yyruleno==223);
+ case 248: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==248);
{yygotominor.yy328 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy186,0);
@@ -126880,22 +127318,21 @@
case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42);
case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45);
case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48);
case 130: /* as ::= AS nm */ yytestcase(yyruleno==130);
case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131);
- case 141: /* dbnm ::= DOT nm */ yytestcase(yyruleno==141);
- case 150: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==150);
- case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
- case 256: /* nmnum ::= plus_num */ yytestcase(yyruleno==256);
- case 257: /* nmnum ::= nm */ yytestcase(yyruleno==257);
- case 258: /* nmnum ::= ON */ yytestcase(yyruleno==258);
- case 259: /* nmnum ::= DELETE */ yytestcase(yyruleno==259);
- case 260: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==260);
- case 261: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==261);
- case 262: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==262);
- case 263: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==263);
- case 279: /* trnm ::= nm */ yytestcase(yyruleno==279);
+ case 142: /* dbnm ::= DOT nm */ yytestcase(yyruleno==142);
+ case 151: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==151);
+ case 257: /* nmnum ::= plus_num */ yytestcase(yyruleno==257);
+ case 258: /* nmnum ::= nm */ yytestcase(yyruleno==258);
+ case 259: /* nmnum ::= ON */ yytestcase(yyruleno==259);
+ case 260: /* nmnum ::= DELETE */ yytestcase(yyruleno==260);
+ case 261: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==261);
+ case 262: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==262);
+ case 263: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==263);
+ case 264: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==264);
+ case 280: /* trnm ::= nm */ yytestcase(yyruleno==280);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
case 44: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
@@ -126951,11 +127388,11 @@
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);}
break;
case 64: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);}
break;
- case 65: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+ case 65: /* ccons ::= REFERENCES nm eidlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);}
break;
case 66: /* ccons ::= defer_subclause */
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);}
break;
@@ -127006,20 +127443,20 @@
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
case 90: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+ case 93: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);}
break;
- case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
+ case 94: /* tcons ::= UNIQUE LP sortlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);}
break;
case 95: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);}
break;
- case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+ case 96: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328);
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328);
}
break;
@@ -127041,13 +127478,13 @@
case 106: /* cmd ::= DROP TABLE ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328);
}
break;
- case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+ case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy3, yymsp[-7].minor.yy328, yymsp[-5].minor.yy328);
}
break;
case 110: /* cmd ::= DROP VIEW ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
@@ -127160,18 +127597,18 @@
break;
case 124: /* distinct ::= */
{yygotominor.yy381 = 0;}
break;
case 125: /* sclp ::= selcollist COMMA */
- case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
+ case 244: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==244);
{yygotominor.yy14 = yymsp[-1].minor.yy14;}
break;
case 126: /* sclp ::= */
- case 154: /* orderby_opt ::= */ yytestcase(yyruleno==154);
- case 161: /* groupby_opt ::= */ yytestcase(yyruleno==161);
- case 236: /* exprlist ::= */ yytestcase(yyruleno==236);
- case 242: /* idxlist_opt ::= */ yytestcase(yyruleno==242);
+ case 155: /* orderby_opt ::= */ yytestcase(yyruleno==155);
+ case 162: /* groupby_opt ::= */ yytestcase(yyruleno==162);
+ case 237: /* exprlist ::= */ yytestcase(yyruleno==237);
+ case 243: /* eidlist_opt ::= */ yytestcase(yyruleno==243);
{yygotominor.yy14 = 0;}
break;
case 127: /* selcollist ::= sclp expr as */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr);
@@ -127206,11 +127643,11 @@
}
break;
case 135: /* stl_prefix ::= seltablist joinop */
{
yygotominor.yy65 = yymsp[-1].minor.yy65;
- if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328;
+ if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy328;
}
break;
case 136: /* stl_prefix ::= */
{yygotominor.yy65 = 0;}
break;
@@ -127218,16 +127655,22 @@
{
yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0);
}
break;
- case 138: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 138: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+{
+ yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy65,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
+ sqlite3SrcListFuncArgs(pParse, yygotominor.yy65, yymsp[-4].minor.yy14);
+}
+ break;
+ case 139: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
}
break;
- case 139: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 140: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){
yygotominor.yy65 = yymsp[-4].minor.yy65;
}else if( yymsp[-4].minor.yy65->nSrc==1 ){
yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
@@ -127247,175 +127690,177 @@
pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,SF_NestedFrom,0,0);
yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
}
}
break;
- case 140: /* dbnm ::= */
- case 149: /* indexed_opt ::= */ yytestcase(yyruleno==149);
+ case 141: /* dbnm ::= */
+ case 150: /* indexed_opt ::= */ yytestcase(yyruleno==150);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
- case 142: /* fullname ::= nm dbnm */
+ case 143: /* fullname ::= nm dbnm */
{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 143: /* joinop ::= COMMA|JOIN */
+ case 144: /* joinop ::= COMMA|JOIN */
{ yygotominor.yy328 = JT_INNER; }
break;
- case 144: /* joinop ::= JOIN_KW JOIN */
+ case 145: /* joinop ::= JOIN_KW JOIN */
{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
- case 145: /* joinop ::= JOIN_KW nm JOIN */
+ case 146: /* joinop ::= JOIN_KW nm JOIN */
{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
- case 146: /* joinop ::= JOIN_KW nm nm JOIN */
+ case 147: /* joinop ::= JOIN_KW nm nm JOIN */
{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
- case 147: /* on_opt ::= ON expr */
- case 164: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==164);
- case 171: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==171);
- case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
- case 233: /* case_operand ::= expr */ yytestcase(yyruleno==233);
+ case 148: /* on_opt ::= ON expr */
+ case 165: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==165);
+ case 172: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==172);
+ case 232: /* case_else ::= ELSE expr */ yytestcase(yyruleno==232);
+ case 234: /* case_operand ::= expr */ yytestcase(yyruleno==234);
{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;}
break;
- case 148: /* on_opt ::= */
- case 163: /* having_opt ::= */ yytestcase(yyruleno==163);
- case 170: /* where_opt ::= */ yytestcase(yyruleno==170);
- case 232: /* case_else ::= */ yytestcase(yyruleno==232);
- case 234: /* case_operand ::= */ yytestcase(yyruleno==234);
+ case 149: /* on_opt ::= */
+ case 164: /* having_opt ::= */ yytestcase(yyruleno==164);
+ case 171: /* where_opt ::= */ yytestcase(yyruleno==171);
+ case 233: /* case_else ::= */ yytestcase(yyruleno==233);
+ case 235: /* case_operand ::= */ yytestcase(yyruleno==235);
{yygotominor.yy132 = 0;}
break;
- case 151: /* indexed_opt ::= NOT INDEXED */
+ case 152: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
- case 152: /* using_opt ::= USING LP idlist RP */
- case 180: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==180);
+ case 153: /* using_opt ::= USING LP idlist RP */
+ case 181: /* idlist_opt ::= LP idlist RP */ yytestcase(yyruleno==181);
{yygotominor.yy408 = yymsp[-1].minor.yy408;}
break;
- case 153: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
+ case 154: /* using_opt ::= */
+ case 180: /* idlist_opt ::= */ yytestcase(yyruleno==180);
{yygotominor.yy408 = 0;}
break;
- case 155: /* orderby_opt ::= ORDER BY sortlist */
- case 162: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==162);
- case 235: /* exprlist ::= nexprlist */ yytestcase(yyruleno==235);
+ case 156: /* orderby_opt ::= ORDER BY sortlist */
+ case 163: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==163);
+ case 236: /* exprlist ::= nexprlist */ yytestcase(yyruleno==236);
{yygotominor.yy14 = yymsp[0].minor.yy14;}
break;
- case 156: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 157: /* sortlist ::= sortlist COMMA expr sortorder */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy346.pExpr);
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
+ sqlite3ExprListSetSortOrder(yygotominor.yy14,yymsp[0].minor.yy328);
}
break;
- case 157: /* sortlist ::= expr sortorder */
+ case 158: /* sortlist ::= expr sortorder */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy346.pExpr);
- if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328;
+ sqlite3ExprListSetSortOrder(yygotominor.yy14,yymsp[0].minor.yy328);
}
break;
- case 158: /* sortorder ::= ASC */
- case 160: /* sortorder ::= */ yytestcase(yyruleno==160);
+ case 159: /* sortorder ::= ASC */
{yygotominor.yy328 = SQLITE_SO_ASC;}
break;
- case 159: /* sortorder ::= DESC */
+ case 160: /* sortorder ::= DESC */
{yygotominor.yy328 = SQLITE_SO_DESC;}
break;
- case 165: /* limit_opt ::= */
+ case 161: /* sortorder ::= */
+{yygotominor.yy328 = SQLITE_SO_UNDEFINED;}
+ break;
+ case 166: /* limit_opt ::= */
{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;}
break;
- case 166: /* limit_opt ::= LIMIT expr */
+ case 167: /* limit_opt ::= LIMIT expr */
{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;}
break;
- case 167: /* limit_opt ::= LIMIT expr OFFSET expr */
+ case 168: /* limit_opt ::= LIMIT expr OFFSET expr */
{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;}
break;
- case 168: /* limit_opt ::= LIMIT expr COMMA expr */
+ case 169: /* limit_opt ::= LIMIT expr COMMA expr */
{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;}
break;
- case 169: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
+ case 170: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
{
sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0);
sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132);
}
break;
- case 172: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ case 173: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
sqlite3WithPush(pParse, yymsp[-7].minor.yy59, 1);
sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0);
sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list");
sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186);
}
break;
- case 173: /* setlist ::= setlist COMMA nm EQ expr */
+ case 174: /* setlist ::= setlist COMMA nm EQ expr */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
}
break;
- case 174: /* setlist ::= nm EQ expr */
+ case 175: /* setlist ::= nm EQ expr */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
}
break;
- case 175: /* cmd ::= with insert_cmd INTO fullname inscollist_opt select */
+ case 176: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
{
sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
sqlite3Insert(pParse, yymsp[-2].minor.yy65, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186);
}
break;
- case 176: /* cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
+ case 177: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
{
sqlite3WithPush(pParse, yymsp[-6].minor.yy59, 1);
sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);
}
break;
- case 177: /* insert_cmd ::= INSERT orconf */
+ case 178: /* insert_cmd ::= INSERT orconf */
{yygotominor.yy186 = yymsp[0].minor.yy186;}
break;
- case 178: /* insert_cmd ::= REPLACE */
+ case 179: /* insert_cmd ::= REPLACE */
{yygotominor.yy186 = OE_Replace;}
break;
- case 181: /* idlist ::= idlist COMMA nm */
+ case 182: /* idlist ::= idlist COMMA nm */
{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);}
break;
- case 182: /* idlist ::= nm */
+ case 183: /* idlist ::= nm */
{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
- case 183: /* expr ::= term */
+ case 184: /* expr ::= term */
{yygotominor.yy346 = yymsp[0].minor.yy346;}
break;
- case 184: /* expr ::= LP expr RP */
+ case 185: /* expr ::= LP expr RP */
{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
- case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
+ case 186: /* term ::= NULL */
+ case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191);
+ case 192: /* term ::= STRING */ yytestcase(yyruleno==192);
{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
- case 186: /* expr ::= ID|INDEXED */
- case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
+ case 187: /* expr ::= ID|INDEXED */
+ case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188);
{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
- case 188: /* expr ::= nm DOT nm */
+ case 189: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 189: /* expr ::= nm DOT nm DOT nm */
+ case 190: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 192: /* expr ::= VARIABLE */
+ case 193: /* expr ::= VARIABLE */
{
if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
@@ -127431,24 +127876,24 @@
sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr);
}
spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 193: /* expr ::= expr COLLATE ID|STRING */
+ case 194: /* expr ::= expr COLLATE ID|STRING */
{
yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0, 1);
yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 194: /* expr ::= CAST LP expr AS typetoken RP */
+ case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0);
spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 195: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 196: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
@@ -127456,39 +127901,39 @@
if( yymsp[-2].minor.yy381==SF_Distinct && yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->flags |= EP_Distinct;
}
}
break;
- case 196: /* expr ::= ID|INDEXED LP STAR RP */
+ case 197: /* expr ::= ID|INDEXED LP STAR RP */
{
yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 197: /* term ::= CTIME_KW */
+ case 198: /* term ::= CTIME_KW */
{
yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 198: /* expr ::= expr AND expr */
- case 199: /* expr ::= expr OR expr */ yytestcase(yyruleno==199);
- case 200: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==205);
+ case 199: /* expr ::= expr AND expr */
+ case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
+ case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
+ case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
+ case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);}
break;
- case 206: /* likeop ::= LIKE_KW|MATCH */
+ case 207: /* likeop ::= LIKE_KW|MATCH */
{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 0;}
break;
- case 207: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 208: /* likeop ::= NOT LIKE_KW|MATCH */
{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 1;}
break;
- case 208: /* expr ::= expr likeop expr */
+ case 209: /* expr ::= expr likeop expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy346.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy346.pExpr);
yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy96.eOperator);
@@ -127496,11 +127941,11 @@
yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
}
break;
- case 209: /* expr ::= expr likeop expr ESCAPE expr */
+ case 210: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy346.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
@@ -127509,39 +127954,39 @@
yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
}
break;
- case 210: /* expr ::= expr ISNULL|NOTNULL */
+ case 211: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);}
break;
- case 211: /* expr ::= expr NOT NULL */
+ case 212: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);}
break;
- case 212: /* expr ::= expr IS expr */
+ case 213: /* expr ::= expr IS expr */
{
spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_ISNULL);
}
break;
- case 213: /* expr ::= expr IS NOT expr */
+ case 214: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_NOTNULL);
}
break;
- case 214: /* expr ::= NOT expr */
- case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
+ case 215: /* expr ::= NOT expr */
+ case 216: /* expr ::= BITNOT expr */ yytestcase(yyruleno==216);
{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 216: /* expr ::= MINUS expr */
+ case 217: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 217: /* expr ::= PLUS expr */
+ case 218: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 220: /* expr ::= expr between_op expr AND expr */
+ case 221: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
@@ -127552,11 +127997,11 @@
if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
}
break;
- case 223: /* expr ::= expr in_op LP exprlist RP */
+ case 224: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy14==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -127606,11 +128051,11 @@
}
yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 224: /* expr ::= LP select RP */
+ case 225: /* expr ::= LP select RP */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
@@ -127620,11 +128065,11 @@
}
yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 225: /* expr ::= expr in_op LP select RP */
+ case 226: /* expr ::= expr in_op LP select RP */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
@@ -127635,11 +128080,11 @@
if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 226: /* expr ::= expr in_op nm dbnm */
+ case 227: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
@@ -127651,11 +128096,11 @@
if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart;
yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
- case 227: /* expr ::= EXISTS LP select RP */
+ case 228: /* expr ::= EXISTS LP select RP */
{
Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy3;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
@@ -127665,11 +128110,11 @@
}
yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 229: /* expr ::= CASE case_operand case_exprlist case_else END */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14;
sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
@@ -127679,274 +128124,263 @@
}
yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 230: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr);
yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
}
break;
- case 230: /* case_exprlist ::= WHEN expr THEN expr */
+ case 231: /* case_exprlist ::= WHEN expr THEN expr */
{
yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
}
break;
- case 237: /* nexprlist ::= nexprlist COMMA expr */
+ case 238: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);}
break;
- case 238: /* nexprlist ::= expr */
+ case 239: /* nexprlist ::= expr */
{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);}
break;
- case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
+ case 240: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy328,
&yymsp[-11].minor.yy0, yymsp[0].minor.yy132, SQLITE_SO_ASC, yymsp[-8].minor.yy328);
}
break;
- case 240: /* uniqueflag ::= UNIQUE */
- case 291: /* raisetype ::= ABORT */ yytestcase(yyruleno==291);
+ case 241: /* uniqueflag ::= UNIQUE */
+ case 292: /* raisetype ::= ABORT */ yytestcase(yyruleno==292);
{yygotominor.yy328 = OE_Abort;}
break;
- case 241: /* uniqueflag ::= */
+ case 242: /* uniqueflag ::= */
{yygotominor.yy328 = OE_None;}
break;
- case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 245: /* idxlist ::= nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
- yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
- if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
-}
- break;
- case 246: /* collate ::= */
-{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
- break;
- case 248: /* cmd ::= DROP INDEX ifexists fullname */
+ case 245: /* eidlist ::= eidlist COMMA nm collate sortorder */
+{
+ yygotominor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy328, yymsp[0].minor.yy328);
+}
+ break;
+ case 246: /* eidlist ::= nm collate sortorder */
+{
+ yygotominor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy328, yymsp[0].minor.yy328);
+}
+ break;
+ case 249: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);}
break;
- case 249: /* cmd ::= VACUUM */
- case 250: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==250);
+ case 250: /* cmd ::= VACUUM */
+ case 251: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==251);
{sqlite3Vacuum(pParse);}
break;
- case 251: /* cmd ::= PRAGMA nm dbnm */
+ case 252: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 253: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 254: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 255: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 256: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 264: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 265: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all);
}
break;
- case 265: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 266: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
- case 266: /* trigger_time ::= BEFORE */
- case 269: /* trigger_time ::= */ yytestcase(yyruleno==269);
+ case 267: /* trigger_time ::= BEFORE */
+ case 270: /* trigger_time ::= */ yytestcase(yyruleno==270);
{ yygotominor.yy328 = TK_BEFORE; }
break;
- case 267: /* trigger_time ::= AFTER */
+ case 268: /* trigger_time ::= AFTER */
{ yygotominor.yy328 = TK_AFTER; }
break;
- case 268: /* trigger_time ::= INSTEAD OF */
+ case 269: /* trigger_time ::= INSTEAD OF */
{ yygotominor.yy328 = TK_INSTEAD;}
break;
- case 270: /* trigger_event ::= DELETE|INSERT */
- case 271: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==271);
+ case 271: /* trigger_event ::= DELETE|INSERT */
+ case 272: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==272);
{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;}
break;
- case 272: /* trigger_event ::= UPDATE OF idlist */
+ case 273: /* trigger_event ::= UPDATE OF idlist */
{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;}
break;
- case 275: /* when_clause ::= */
- case 296: /* key_opt ::= */ yytestcase(yyruleno==296);
+ case 276: /* when_clause ::= */
+ case 297: /* key_opt ::= */ yytestcase(yyruleno==297);
{ yygotominor.yy132 = 0; }
break;
- case 276: /* when_clause ::= WHEN expr */
- case 297: /* key_opt ::= KEY expr */ yytestcase(yyruleno==297);
+ case 277: /* when_clause ::= WHEN expr */
+ case 298: /* key_opt ::= KEY expr */ yytestcase(yyruleno==298);
{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; }
break;
- case 277: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 278: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy473!=0 );
yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473;
yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473;
yygotominor.yy473 = yymsp[-2].minor.yy473;
}
break;
- case 278: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 279: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy473!=0 );
yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473;
yygotominor.yy473 = yymsp[-1].minor.yy473;
}
break;
- case 280: /* trnm ::= nm DOT nm */
+ case 281: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
}
break;
- case 282: /* tridxby ::= INDEXED BY nm */
+ case 283: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 283: /* tridxby ::= NOT INDEXED */
+ case 284: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 284: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+ case 285: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); }
break;
- case 285: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
+ case 286: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);}
break;
- case 286: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+ case 287: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);}
break;
- case 287: /* trigger_cmd ::= select */
+ case 288: /* trigger_cmd ::= select */
{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); }
break;
- case 288: /* expr ::= RAISE LP IGNORE RP */
+ case 289: /* expr ::= RAISE LP IGNORE RP */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
if( yygotominor.yy346.pExpr ){
yygotominor.yy346.pExpr->affinity = OE_Ignore;
}
yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 289: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 290: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
if( yygotominor.yy346.pExpr ) {
yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328;
}
yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z;
yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 290: /* raisetype ::= ROLLBACK */
+ case 291: /* raisetype ::= ROLLBACK */
{yygotominor.yy328 = OE_Rollback;}
break;
- case 292: /* raisetype ::= FAIL */
+ case 293: /* raisetype ::= FAIL */
{yygotominor.yy328 = OE_Fail;}
break;
- case 293: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 294: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328);
}
break;
- case 294: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 295: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132);
}
break;
- case 295: /* cmd ::= DETACH database_kw_opt expr */
+ case 296: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr);
}
break;
- case 300: /* cmd ::= REINDEX */
+ case 301: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 301: /* cmd ::= REINDEX nm dbnm */
+ case 302: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 302: /* cmd ::= ANALYZE */
+ case 303: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 303: /* cmd ::= ANALYZE nm dbnm */
+ case 304: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 304: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 305: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0);
}
break;
- case 305: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ case 306: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 306: /* add_column_fullname ::= fullname */
+ case 307: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65);
}
break;
- case 309: /* cmd ::= create_vtab */
+ case 310: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 310: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 311: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 311: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 312: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy328);
}
break;
- case 314: /* vtabarg ::= */
+ case 315: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 316: /* vtabargtoken ::= ANY */
- case 317: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==317);
- case 318: /* lp ::= LP */ yytestcase(yyruleno==318);
+ case 317: /* vtabargtoken ::= ANY */
+ case 318: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==318);
+ case 319: /* lp ::= LP */ yytestcase(yyruleno==319);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 322: /* with ::= */
+ case 323: /* with ::= */
{yygotominor.yy59 = 0;}
break;
- case 323: /* with ::= WITH wqlist */
- case 324: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==324);
+ case 324: /* with ::= WITH wqlist */
+ case 325: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==325);
{ yygotominor.yy59 = yymsp[0].minor.yy59; }
break;
- case 325: /* wqlist ::= nm idxlist_opt AS LP select RP */
+ case 326: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
yygotominor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3);
}
break;
- case 326: /* wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP */
+ case 327: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
yygotominor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3);
}
break;
default:
@@ -127970,49 +128404,48 @@
/* (53) carglist ::= */ yytestcase(yyruleno==53);
/* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60);
/* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88);
/* (89) conslist ::= tcons */ yytestcase(yyruleno==89);
/* (91) tconscomma ::= */ yytestcase(yyruleno==91);
- /* (273) foreach_clause ::= */ yytestcase(yyruleno==273);
- /* (274) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==274);
- /* (281) tridxby ::= */ yytestcase(yyruleno==281);
- /* (298) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==298);
- /* (299) database_kw_opt ::= */ yytestcase(yyruleno==299);
- /* (307) kwcolumn_opt ::= */ yytestcase(yyruleno==307);
- /* (308) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==308);
- /* (312) vtabarglist ::= vtabarg */ yytestcase(yyruleno==312);
- /* (313) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==313);
- /* (315) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==315);
- /* (319) anylist ::= */ yytestcase(yyruleno==319);
- /* (320) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==320);
- /* (321) anylist ::= anylist ANY */ yytestcase(yyruleno==321);
+ /* (274) foreach_clause ::= */ yytestcase(yyruleno==274);
+ /* (275) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==275);
+ /* (282) tridxby ::= */ yytestcase(yyruleno==282);
+ /* (299) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==299);
+ /* (300) database_kw_opt ::= */ yytestcase(yyruleno==300);
+ /* (308) kwcolumn_opt ::= */ yytestcase(yyruleno==308);
+ /* (309) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==309);
+ /* (313) vtabarglist ::= vtabarg */ yytestcase(yyruleno==313);
+ /* (314) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==314);
+ /* (316) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==316);
+ /* (320) anylist ::= */ yytestcase(yyruleno==320);
+ /* (321) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==321);
+ /* (322) anylist ::= anylist ANY */ yytestcase(yyruleno==322);
break;
};
assert( yyruleno>=0 && yyrulenoyyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
- if( yyact < YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+ /* If the reduce action popped at least
** one element off the stack, then we can push the new element back
** onto the stack here, and skip the stack overflow test in yy_shift().
** That gives a significant speed improvement. */
if( yysize ){
yypParser->yyidx++;
yymsp -= yysize-1;
yymsp->stateno = (YYACTIONTYPE)yyact;
yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
- }else
-#endif
- {
+ yyTraceShift(yypParser, yyact);
+ }else{
yy_shift(yypParser,yyact,yygoto,&yygotominor);
}
}else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
+ assert( yyact == YY_ACCEPT_ACTION );
yy_accept(yypParser);
}
}
/*
@@ -128133,16 +128566,17 @@
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yypParser->yyerrcnt--;
yymajor = YYNOCODE;
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
+ }else if( yyact <= YY_MAX_REDUCE ){
+ yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{
assert( yyact == YY_ERROR_ACTION );
#ifdef YYERRORSYMBOL
int yymx;
#endif
@@ -128188,11 +128622,11 @@
while(
yypParser->yyidx >= 0 &&
yymx != YYERRORSYMBOL &&
(yyact = yy_find_reduce_action(
yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
+ YYERRORSYMBOL)) >= YY_MIN_REDUCE
){
yy_pop_parser_stack(yypParser);
}
if( yypParser->yyidx < 0 || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -128238,10 +128672,15 @@
}
yymajor = YYNOCODE;
#endif
}
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sReturn\n",yyTracePrompt);
+ }
+#endif
return;
}
/************** End of parse.c ***********************************************/
/************** Begin file tokenize.c ****************************************/
@@ -128926,10 +129365,11 @@
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
i = 0;
assert( pzErrMsg!=0 );
+ /* sqlite3ParserTrace(stdout, "parser: "); */
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
db->mallocFailed = 1;
return SQLITE_NOMEM;
}
@@ -130370,20 +130810,26 @@
** db. This is called when db is being closed.
*/
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
+ HashElem *p;
sqlite3BtreeEnterAll(db);
for(i=0; inDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
if( db->aDb[i].pSchema ){
- HashElem *p;
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
Table *pTab = (Table *)sqliteHashData(p);
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
}
}
+ }
+ for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
+ Module *pMod = (Module *)sqliteHashData(p);
+ if( pMod->pEpoTab ){
+ sqlite3VtabDisconnect(db, pMod->pEpoTab);
+ }
}
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
@@ -130558,10 +131004,11 @@
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
Module *pMod = (Module *)sqliteHashData(i);
if( pMod->xDestroy ){
pMod->xDestroy(pMod->pAux);
}
+ sqlite3VtabEponymousTableClear(db, pMod);
sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
@@ -156962,14 +157409,10 @@
/* #include */
/* #include */
/* #include */
-#if !defined(_WIN32)
-/* # include */
-#endif
-
/* #include "sqlite3.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
/************** Begin file sqlite3rbu.h **************************************/
@@ -157070,10 +157513,22 @@
**
** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control);
**
** The order of the columns in the data_% table does not matter.
**
+** Instead of a regular table, the RBU database may also contain virtual
+** tables or view named using the data_ naming scheme.
+**
+** Instead of the plain data_ naming scheme, RBU database tables
+** may also be named data_, where is any sequence
+** of zero or more numeric characters (0-9). This can be significant because
+** tables within the RBU database are always processed in order sorted by
+** name. By judicious selection of the the portion of the names
+** of the RBU tables the user can therefore control the order in which they
+** are processed. This can be useful, for example, to ensure that "external
+** content" FTS4 tables are updated before their underlying content tables.
+**
** If the target database table is a virtual table or a table that has no
** PRIMARY KEY declaration, the data_% table must also contain a column
** named "rbu_rowid". This column is mapped to the tables implicit primary
** key column - "rowid". Virtual tables for which the "rowid" column does
** not function like a primary key value cannot be updated using RBU. For
@@ -157149,10 +157604,18 @@
** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d');
**
** is similar to an UPDATE statement such as:
**
** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4;
+**
+** Finally, if an 'f' character appears in place of a 'd' or 's' in an
+** ota_control string, the contents of the data_xxx table column is assumed
+** to be a "fossil delta" - a patch to be applied to a blob value in the
+** format used by the fossil source-code management system. In this case
+** the existing value within the target database table must be of type BLOB.
+** It is replaced by the result of applying the specified fossil delta to
+** itself.
**
** If the target database table is a virtual table or a table with no PRIMARY
** KEY, the rbu_control value should not include a character corresponding
** to the rbu_rowid value. For example, this:
**
@@ -157307,10 +157770,22 @@
** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops
** that immediately return the same value.
*/
SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *pRbu);
+/*
+** Force RBU to save its state to disk.
+**
+** If a power failure or application crash occurs during an update, following
+** system recovery RBU may resume the update from the point at which the state
+** was last saved. In other words, from the most recent successful call to
+** sqlite3rbu_close() or this function.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *pRbu);
+
/*
** Close an RBU handle.
**
** If the RBU update has been completely applied, mark the RBU database
** as fully applied. Otherwise, assuming no error has occurred, save the
@@ -157539,10 +158014,11 @@
int eType; /* Table type - an RBU_PK_XXX value */
/* Output variables. zTbl==0 implies EOF. */
int bCleanup; /* True in "cleanup" state */
const char *zTbl; /* Name of target db table */
+ const char *zDataTbl; /* Name of rbu db table (or null) */
const char *zIdx; /* Name of target db index (or null) */
int iTnum; /* Root page of current object */
int iPkTnum; /* If eType==EXTERNAL, root of PK index */
int bUnique; /* Current index is unique */
@@ -157549,11 +158025,11 @@
/* Statements created by rbuObjIterPrepareAll() */
int nCol; /* Number of columns in current object */
sqlite3_stmt *pSelect; /* Source data */
sqlite3_stmt *pInsert; /* Statement for INSERT operations */
sqlite3_stmt *pDelete; /* Statement for DELETE ops */
- sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zTbl */
+ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
/* Last UPDATE used (for PK b-tree updates only), or NULL. */
RbuUpdateStmt *pRbuUpdate;
};
@@ -157659,10 +158135,256 @@
const char *zWal; /* Wal filename for this main db file */
rbu_file *pWalFd; /* Wal file descriptor for this main db */
rbu_file *pMainNext; /* Next MAIN_DB file */
};
+
+/*************************************************************************
+** The following three functions, found below:
+**
+** rbuDeltaGetInt()
+** rbuDeltaChecksum()
+** rbuDeltaApply()
+**
+** are lifted from the fossil source code (http://fossil-scm.org). They
+** are used to implement the scalar SQL function rbu_fossil_delta().
+*/
+
+/*
+** Read bytes from *pz and convert them into a positive integer. When
+** finished, leave *pz pointing to the first character past the end of
+** the integer. The *pLen parameter holds the length of the string
+** in *pz and is decremented once for each character in the integer.
+*/
+static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
+ static const signed char zValue[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36,
+ -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1,
+ };
+ unsigned int v = 0;
+ int c;
+ unsigned char *z = (unsigned char*)*pz;
+ unsigned char *zStart = z;
+ while( (c = zValue[0x7f&*(z++)])>=0 ){
+ v = (v<<6) + c;
+ }
+ z--;
+ *pLen -= z - zStart;
+ *pz = (char*)z;
+ return v;
+}
+
+/*
+** Compute a 32-bit checksum on the N-byte buffer. Return the result.
+*/
+static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
+ const unsigned char *z = (const unsigned char *)zIn;
+ unsigned sum0 = 0;
+ unsigned sum1 = 0;
+ unsigned sum2 = 0;
+ unsigned sum3 = 0;
+ while(N >= 16){
+ sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
+ sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
+ sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
+ sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
+ z += 16;
+ N -= 16;
+ }
+ while(N >= 4){
+ sum0 += z[0];
+ sum1 += z[1];
+ sum2 += z[2];
+ sum3 += z[3];
+ z += 4;
+ N -= 4;
+ }
+ sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
+ switch(N){
+ case 3: sum3 += (z[2] << 8);
+ case 2: sum3 += (z[1] << 16);
+ case 1: sum3 += (z[0] << 24);
+ default: ;
+ }
+ return sum3;
+}
+
+/*
+** Apply a delta.
+**
+** The output buffer should be big enough to hold the whole output
+** file and a NUL terminator at the end. The delta_output_size()
+** routine will determine this size for you.
+**
+** The delta string should be null-terminated. But the delta string
+** may contain embedded NUL characters (if the input and output are
+** binary files) so we also have to pass in the length of the delta in
+** the lenDelta parameter.
+**
+** This function returns the size of the output file in bytes (excluding
+** the final NUL terminator character). Except, if the delta string is
+** malformed or intended for use with a source file other than zSrc,
+** then this routine returns -1.
+**
+** Refer to the delta_create() documentation above for a description
+** of the delta file format.
+*/
+static int rbuDeltaApply(
+ const char *zSrc, /* The source or pattern file */
+ int lenSrc, /* Length of the source file */
+ const char *zDelta, /* Delta to apply to the pattern */
+ int lenDelta, /* Length of the delta */
+ char *zOut /* Write the output into this preallocated buffer */
+){
+ unsigned int limit;
+ unsigned int total = 0;
+#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+ char *zOrigOut = zOut;
+#endif
+
+ limit = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ while( *zDelta && lenDelta>0 ){
+ unsigned int cnt, ofst;
+ cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
+ switch( zDelta[0] ){
+ case '@': {
+ zDelta++; lenDelta--;
+ ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( lenDelta>0 && zDelta[0]!=',' ){
+ /* ERROR: copy command not terminated by ',' */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: copy exceeds output file size */
+ return -1;
+ }
+ if( (int)(ofst+cnt) > lenSrc ){
+ /* ERROR: copy extends past end of input */
+ return -1;
+ }
+ memcpy(zOut, &zSrc[ofst], cnt);
+ zOut += cnt;
+ break;
+ }
+ case ':': {
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: insert command gives an output larger than predicted */
+ return -1;
+ }
+ if( (int)cnt>lenDelta ){
+ /* ERROR: insert count exceeds size of delta */
+ return -1;
+ }
+ memcpy(zOut, zDelta, cnt);
+ zOut += cnt;
+ zDelta += cnt;
+ lenDelta -= cnt;
+ break;
+ }
+ case ';': {
+ zDelta++; lenDelta--;
+ zOut[0] = 0;
+#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+ if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
+ /* ERROR: bad checksum */
+ return -1;
+ }
+#endif
+ if( total!=limit ){
+ /* ERROR: generated size does not match predicted size */
+ return -1;
+ }
+ return total;
+ }
+ default: {
+ /* ERROR: unknown delta operator */
+ return -1;
+ }
+ }
+ }
+ /* ERROR: unterminated delta */
+ return -1;
+}
+
+static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
+ int size;
+ size = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ return size;
+}
+
+/*
+** End of code taken from fossil.
+*************************************************************************/
+
+/*
+** Implementation of SQL scalar function rbu_fossil_delta().
+**
+** This function applies a fossil delta patch to a blob. Exactly two
+** arguments must be passed to this function. The first is the blob to
+** patch and the second the patch to apply. If no error occurs, this
+** function returns the patched blob.
+*/
+static void rbuFossilDeltaFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *aDelta;
+ int nDelta;
+ const char *aOrig;
+ int nOrig;
+
+ int nOut;
+ int nOut2;
+ char *aOut;
+
+ assert( argc==2 );
+
+ nOrig = sqlite3_value_bytes(argv[0]);
+ aOrig = (const char*)sqlite3_value_blob(argv[0]);
+ nDelta = sqlite3_value_bytes(argv[1]);
+ aDelta = (const char*)sqlite3_value_blob(argv[1]);
+
+ /* Figure out the size of the output */
+ nOut = rbuDeltaOutputSize(aDelta, nDelta);
+ if( nOut<0 ){
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ return;
+ }
+
+ aOut = sqlite3_malloc(nOut+1);
+ if( aOut==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
+ if( nOut2!=nOut ){
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ }else{
+ sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
+ }
+ }
+}
+
/*
** Prepare the SQL statement in buffer zSql against database handle db.
** If successful, set *ppStmt to point to the new statement and return
** SQLITE_OK.
@@ -157826,11 +158548,12 @@
if( rc!=SQLITE_ROW ){
rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
pIter->zTbl = 0;
}else{
pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
- rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM;
+ pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
+ rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
}
}else{
if( pIter->zIdx==0 ){
sqlite3_stmt *pIdx = pIter->pIdxIter;
rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
@@ -157857,10 +158580,44 @@
p->rc = rc;
}
return rc;
}
+
+/*
+** The implementation of the rbu_target_name() SQL function. This function
+** accepts one argument - the name of a table in the RBU database. If the
+** table name matches the pattern:
+**
+** data[0-9]_
+**
+** where is any sequence of 1 or more characters, is returned.
+** Otherwise, if the only argument does not match the above pattern, an SQL
+** NULL is returned.
+**
+** "data_t1" -> "t1"
+** "data0123_t2" -> "t2"
+** "dataAB_t3" -> NULL
+*/
+static void rbuTargetNameFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zIn;
+ assert( argc==1 );
+
+ zIn = (const char*)sqlite3_value_text(argv[0]);
+ if( zIn && strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
+ int i;
+ for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
+ if( zIn[i]=='_' && zIn[i+1] ){
+ sqlite3_result_text(context, &zIn[i+1], -1, SQLITE_STATIC);
+ }
+ }
+}
+
/*
** Initialize the iterator structure passed as the second argument.
**
** If no error occurs, SQLITE_OK is returned and the iterator is left
** pointing to the first entry. Otherwise, an error code and message is
@@ -157870,12 +158627,13 @@
static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
int rc;
memset(pIter, 0, sizeof(RbuObjIter));
rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg,
- "SELECT substr(name, 6) FROM sqlite_master "
- "WHERE type IN ('table', 'view') AND name LIKE 'data_%'"
+ "SELECT rbu_target_name(name) AS target, name FROM sqlite_master "
+ "WHERE type IN ('table', 'view') AND target IS NOT NULL "
+ "ORDER BY name"
);
if( rc==SQLITE_OK ){
rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
"SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
@@ -158138,11 +158896,11 @@
}
*peType = RBU_PK_NONE;
}
rbuTableType_end: {
- int i;
+ unsigned int i;
for(i=0; irc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
- sqlite3_mprintf("SELECT * FROM 'data_%q'", pIter->zTbl)
+ sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl)
);
if( p->rc==SQLITE_OK ){
nCol = sqlite3_column_count(pStmt);
rbuAllocateIterArrays(p, pIter, nCol);
}
@@ -158242,11 +159000,11 @@
if( p->rc==SQLITE_OK
&& bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
){
p->rc = SQLITE_ERROR;
p->zErrmsg = sqlite3_mprintf(
- "table data_%q %s rbu_rowid column", pIter->zTbl,
+ "table %q %s rbu_rowid column", pIter->zDataTbl,
(bRbuRowid ? "may not have" : "requires")
);
}
/* Check that all non-HIDDEN columns in the destination table are also
@@ -158263,12 +159021,12 @@
for(i=iOrder; inTblCol; i++){
if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
}
if( i==pIter->nTblCol ){
p->rc = SQLITE_ERROR;
- p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s",
- pIter->zTbl, zName
+ p->zErrmsg = sqlite3_mprintf("column missing from %q: %s",
+ pIter->zDataTbl, zName
);
}else{
int iPk = sqlite3_column_int(pStmt, 5);
int bNotNull = sqlite3_column_int(pStmt, 3);
const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
@@ -158551,11 +159309,11 @@
){
char *zList = 0;
if( p->rc==SQLITE_OK ){
int i;
- if( strlen(zMask)!=pIter->nTblCol ){
+ if( (int)strlen(zMask)!=pIter->nTblCol ){
rbuBadControlError(p);
}else{
const char *zSep = "";
for(i=0; inTblCol; i++){
char c = zMask[pIter->aiSrcOrder[i]];
@@ -158563,15 +159321,21 @@
zList = rbuMPrintf(p, "%z%s\"%w\"=?%d",
zList, zSep, pIter->azTblCol[i], i+1
);
zSep = ", ";
}
- if( c=='d' ){
+ else if( c=='d' ){
zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)",
zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
);
zSep = ", ";
+ }
+ else if( c=='f' ){
+ zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)",
+ zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
+ );
+ zSep = ", ";
}
}
}
}
return zList;
@@ -158819,11 +159583,11 @@
if( zBind ){
assert( pIter->pTmpInsert==0 );
p->rc = prepareFreeAndCollectError(
p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
"INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)",
- p->zStateDb, pIter->zTbl, zCollist, zRbuRowid, zBind
+ p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind
));
}
}
static void rbuTmpInsertFunc(
@@ -158915,22 +159679,22 @@
if( p->rc==SQLITE_OK ){
char *zSql;
if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
zSql = sqlite3_mprintf(
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
- zCollist, p->zStateDb, pIter->zTbl,
+ zCollist, p->zStateDb, pIter->zDataTbl,
zCollist, zLimit
);
}else{
zSql = sqlite3_mprintf(
- "SELECT %s, rbu_control FROM 'data_%q' "
+ "SELECT %s, rbu_control FROM '%q' "
"WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
"UNION ALL "
"SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
"ORDER BY %s%s",
- zCollist, pIter->zTbl,
- zCollist, p->zStateDb, pIter->zTbl,
+ zCollist, pIter->zDataTbl,
+ zCollist, p->zStateDb, pIter->zDataTbl,
zCollist, zLimit
);
}
p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
}
@@ -158950,20 +159714,10 @@
char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new");
zCollist = rbuObjIterGetCollist(p, pIter);
pIter->nCol = pIter->nTblCol;
- /* Create the SELECT statement to read keys from data_xxx */
- if( p->rc==SQLITE_OK ){
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
- sqlite3_mprintf(
- "SELECT %s, rbu_control%s FROM 'data_%q'%s",
- zCollist, (bRbuRowid ? ", rbu_rowid" : ""), zTbl, zLimit
- )
- );
- }
-
/* Create the imposter table or tables (if required). */
rbuCreateImposterTable(p, pIter);
rbuCreateImposterTable2(p, pIter);
zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_");
@@ -158993,14 +159747,14 @@
}
/* Create the rbu_tmp_xxx table and the triggers to populate it. */
rbuMPrintfExec(p, p->dbRbu,
"CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS "
- "SELECT *%s FROM 'data_%q' WHERE 0;"
- , p->zStateDb
- , zTbl, (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
- , zTbl
+ "SELECT *%s FROM '%q' WHERE 0;"
+ , p->zStateDb, pIter->zDataTbl
+ , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
+ , pIter->zDataTbl
);
rbuMPrintfExec(p, p->dbMain,
"CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
"BEGIN "
@@ -159031,10 +159785,21 @@
);
}
rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
}
+
+ /* Create the SELECT statement to read keys from data_xxx */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
+ sqlite3_mprintf(
+ "SELECT %s, rbu_control%s FROM '%q'%s",
+ zCollist, (bRbuRowid ? ", rbu_rowid" : ""),
+ pIter->zDataTbl, zLimit
+ )
+ );
+ }
sqlite3_free(zWhere);
sqlite3_free(zOldlist);
sqlite3_free(zNewlist);
sqlite3_free(zBindings);
@@ -159161,10 +159926,22 @@
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_create_function(p->dbMain,
"rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
);
}
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_create_function(p->dbMain,
+ "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_create_function(p->dbRbu,
+ "rbu_target_name", 1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
+ );
+ }
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
}
rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
@@ -159591,11 +160368,11 @@
rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
if( pUpdate ){
for(i=0; p->rc==SQLITE_OK && inCol; i++){
char c = zMask[pIter->aiSrcOrder[i]];
pVal = sqlite3_column_value(pIter->pSelect, i);
- if( pIter->abTblPk[i] || c=='x' || c=='d' ){
+ if( pIter->abTblPk[i] || c!='.' ){
p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
}
}
if( p->rc==SQLITE_OK
&& (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
@@ -159703,11 +160480,11 @@
/* Clean up the rbu_tmp_xxx table for the previous table. It
** cannot be dropped as there are currently active SQL statements.
** But the contents can be deleted. */
if( pIter->abIndexed ){
rbuMPrintfExec(p, p->dbRbu,
- "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zTbl
+ "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
);
}
}else{
rbuObjIterPrepareAll(p, pIter, 0);
@@ -159926,14 +160703,17 @@
** If there is a "*-oal" file in the file-system corresponding to the
** target database in the file-system, delete it. If an error occurs,
** leave an error code and error message in the rbu handle.
*/
static void rbuDeleteOalFile(sqlite3rbu *p){
- char *zOal = sqlite3_mprintf("%s-oal", p->zTarget);
- assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
- unlink(zOal);
- sqlite3_free(zOal);
+ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
+ if( zOal ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
+ assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
+ pVfs->xDelete(pVfs, zOal, 0);
+ sqlite3_free(zOal);
+ }
}
/*
** Allocate a private rbu VFS for the rbu handle passed as the only
** argument. This VFS will be used unless the call to sqlite3rbu_open()
@@ -160042,18 +160822,29 @@
p->zErrmsg = sqlite3_mprintf("database modified during rbu update");
}
if( p->rc==SQLITE_OK ){
if( p->eStage==RBU_STAGE_OAL ){
+ sqlite3 *db = p->dbMain;
/* Open transactions both databases. The *-oal file is opened or
** created at this point. */
- p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+ p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
}
-
+
+ /* Check if the main database is a zipvfs db. If it is, set the upper
+ ** level pager to use "journal_mode=off". This prevents it from
+ ** generating a large journal using a temp file. */
+ if( p->rc==SQLITE_OK ){
+ int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
+ if( frc==SQLITE_OK ){
+ p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
+ }
+ }
+
/* Point the object iterator at the first object */
if( p->rc==SQLITE_OK ){
p->rc = rbuObjIterFirst(p, &p->objiter);
}
@@ -160162,10 +160953,36 @@
** current RBU update was started.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){
return pRbu->nProgress;
}
+
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){
+ int rc = p->rc;
+
+ if( rc==SQLITE_DONE ) return SQLITE_OK;
+
+ assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
+ }
+
+ p->rc = rc;
+ rbuSaveState(p, p->eStage);
+ rc = p->rc;
+
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0);
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
+ }
+
+ p->rc = rc;
+ return rc;
+}
/**************************************************************************
** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour
** of a standard VFS in the following ways:
**
@@ -160642,11 +161459,12 @@
rbuVfsSectorSize, /* xSectorSize */
rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */
rbuVfsShmMap, /* xShmMap */
rbuVfsShmLock, /* xShmLock */
rbuVfsShmBarrier, /* xShmBarrier */
- rbuVfsShmUnmap /* xShmUnmap */
+ rbuVfsShmUnmap, /* xShmUnmap */
+ 0, 0 /* xFetch, xUnfetch */
};
rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
rbu_file *pFd = (rbu_file *)pFile;
int rc = SQLITE_OK;
@@ -160984,10 +161802,13 @@
**
** The dbstat virtual table is used to extract low-level formatting
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
** for an example implementation.
+**
+** Additional information is available on the "dbstat.html" page of the
+** official SQLite documentation.
*/
/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -161032,11 +161853,12 @@
" ncell INTEGER, /* Cells on page (0 for overflow) */" \
" payload INTEGER, /* Bytes of payload on this page */" \
" unused INTEGER, /* Bytes of unused space on this page */" \
" mx_payload INTEGER, /* Largest payload size of all cells */" \
" pgoffset INTEGER, /* Offset of page in file */" \
- " pgsize INTEGER /* Size of the page */" \
+ " pgsize INTEGER, /* Size of the page */" \
+ " schema TEXT HIDDEN /* Database schema being analyzed */" \
");"
typedef struct StatTable StatTable;
typedef struct StatCursor StatCursor;
@@ -161070,10 +161892,11 @@
struct StatCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Iterates through set of root pages */
int isEof; /* After pStmt has returned SQLITE_DONE */
+ int iDb; /* Schema used for this query */
StatPage aPage[32];
int iPage; /* Current entry in aPage[] */
/* Values to return. */
@@ -161147,13 +161970,36 @@
return SQLITE_OK;
}
/*
** There is no "best-index". This virtual table always does a linear
-** scan of the binary VFS log file.
+** scan. However, a schema=? constraint should cause this table to
+** operate on a different database schema, so check for it.
+**
+** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ int i;
+
+ pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
+
+ /* Look for a valid schema=? constraint. If found, change the idxNum to
+ ** 1 and request the value of that constraint be sent to xFilter. And
+ ** lower the cost estimate to encourage the constrained version to be
+ ** used.
+ */
+ for(i=0; inConstraint; i++){
+ if( pIdxInfo->aConstraint[i].usable==0 ) continue;
+ if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
/* Records are always returned in ascending order of (name, path).
** If this will satisfy the client, set the orderByConsumed flag so that
** SQLite does not do an external sort.
*/
@@ -161169,50 +162015,31 @@
)
){
pIdxInfo->orderByConsumed = 1;
}
- pIdxInfo->estimatedCost = 10.0;
return SQLITE_OK;
}
/*
** Open a new statvfs cursor.
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
StatTable *pTab = (StatTable *)pVTab;
StatCursor *pCsr;
- int rc;
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
if( pCsr==0 ){
- rc = SQLITE_NOMEM;
+ return SQLITE_NOMEM;
}else{
- char *zSql;
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
-
- zSql = sqlite3_mprintf(
- "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
- " UNION ALL "
- "SELECT name, rootpage, type"
- " FROM \"%w\".sqlite_master WHERE rootpage!=0"
- " ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_free(pCsr);
- pCsr = 0;
- }
+ pCsr->iDb = pTab->iDb;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
- return rc;
+ return SQLITE_OK;
}
static void statClearPage(StatPage *p){
int i;
if( p->aCell ){
@@ -161233,10 +162060,11 @@
statClearPage(&pCsr->aPage[i]);
}
pCsr->iPage = 0;
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
+ pCsr->isEof = 0;
}
/*
** Close a statvfs cursor.
*/
@@ -161395,11 +162223,11 @@
int rc;
int nPayload;
char *z;
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable *)pCursor->pVtab;
- Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
+ Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
@@ -161533,13 +162361,47 @@
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
StatCursor *pCsr = (StatCursor *)pCursor;
+ StatTable *pTab = (StatTable*)(pCursor->pVtab);
+ char *zSql;
+ int rc = SQLITE_OK;
+ char *zMaster;
+ if( idxNum==1 ){
+ const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
+ pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
+ if( pCsr->iDb<0 ){
+ sqlite3_free(pCursor->pVtab->zErrMsg);
+ pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
+ return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ }
+ }else{
+ pCsr->iDb = pTab->iDb;
+ }
statResetCsr(pCsr);
- return statNext(pCursor);
+ sqlite3_finalize(pCsr->pStmt);
+ pCsr->pStmt = 0;
+ zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
+ zSql = sqlite3_mprintf(
+ "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
+ " UNION ALL "
+ "SELECT name, rootpage, type"
+ " FROM \"%w\".%s WHERE rootpage!=0"
+ " ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
+ if( zSql==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = statNext(pCursor);
+ }
+ return rc;
}
static int statColumn(
sqlite3_vtab_cursor *pCursor,
sqlite3_context *ctx,
@@ -161572,14 +162434,19 @@
sqlite3_result_int(ctx, pCsr->nMxPayload);
break;
case 8: /* pgoffset */
sqlite3_result_int64(ctx, pCsr->iOffset);
break;
- default: /* pgsize */
- assert( i==9 );
+ case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
+ default: { /* schema */
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
+ int iDb = pCsr->iDb;
+ sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC);
+ break;
+ }
}
return SQLITE_OK;
}
static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
Index: SQLite.Interop/src/core/sqlite3.h
==================================================================
--- SQLite.Interop/src/core/sqlite3.h
+++ SQLite.Interop/src/core/sqlite3.h
@@ -109,13 +109,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.11.1"
-#define SQLITE_VERSION_NUMBER 3008011
-#define SQLITE_SOURCE_ID "2015-07-29 20:00:57 cf538e2783e468bbc25e7cb2a9ee64d3e0e80b2f"
+#define SQLITE_VERSION "3.8.12"
+#define SQLITE_VERSION_NUMBER 3008012
+#define SQLITE_SOURCE_ID "2015-09-09 19:44:33 8d2ed150a7a15626965cf994ef48c3ab61eca6ec"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
@@ -475,10 +475,11 @@
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
+#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -3371,11 +3372,12 @@
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
-** [sqlite3_step(S)] but has not run to completion and/or has not
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
** interface returns false if S is a NULL pointer. If S is not a
** NULL pointer and is not a pointer to a valid [prepared statement]
** object, then the behavior is undefined and probably undesirable.
**
Index: SQLite.Interop/src/core/sqlite3ext.h
==================================================================
--- SQLite.Interop/src/core/sqlite3ext.h
+++ SQLite.Interop/src/core/sqlite3ext.h
@@ -410,10 +410,11 @@
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
+#define sqlite3_vsnprintf sqlite3_api->vsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
Index: SQLite.Interop/src/ext/fts5.c
==================================================================
--- SQLite.Interop/src/ext/fts5.c
+++ SQLite.Interop/src/ext/fts5.c
@@ -227,11 +227,11 @@
int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
int (*xTokenize)(Fts5Context*,
const char *pText, int nText, /* Text to tokenize */
void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, const char*, int, int, int) /* Callback */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
);
int (*xPhraseCount)(Fts5Context*);
int (*xPhraseSize)(Fts5Context*, int iPhrase);
@@ -288,21 +288,49 @@
** allocated using xCreate(). Fts5 guarantees that this function will
** be invoked exactly once for each successful call to xCreate().
**
** xTokenize:
** This function is expected to tokenize the nText byte string indicated
-** by argument pText. pText may not be nul-terminated. The first argument
-** passed to this function is a pointer to an Fts5Tokenizer object returned
-** by an earlier call to xCreate().
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+**
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
+** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
+** In many cases, method (1) above is the best approach. It does not add
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
+** token "first" is subsituted for "1st" by the tokenizer, then the query:
+**
+**
+** ... MATCH '1s*'
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
+** For full prefix support, method (3) may be preferred. In this case,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
+** a query such as '1s*' will match documents that contain the literal
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
+** extra disk space, as no extra entries are added to the FTS index.
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
typedef struct fts5_tokenizer fts5_tokenizer;
struct fts5_tokenizer {
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
void (*xDelete)(Fts5Tokenizer*);
int (*xTokenize)(Fts5Tokenizer*,
void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
const char *pText, int nText,
int (*xToken)(
void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
const char *pToken, /* Pointer to buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Byte offset of token within input text */
int iEnd /* Byte offset of end of token within input text */
)
);
};
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
/*
** END OF CUSTOM TOKENIZERS
*************************************************************************/
/*************************************************************************
** FTS5 EXTENSION REGISTRATION API
*/
typedef struct fts5_api fts5_api;
struct fts5_api {
- int iVersion; /* Currently always set to 1 */
+ int iVersion; /* Currently always set to 2 */
/* Create a new tokenizer */
int (*xCreateTokenizer)(
fts5_api *pApi,
const char *zName,
@@ -543,13 +689,14 @@
static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
static int sqlite3Fts5Tokenize(
Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
const char *pText, int nText, /* Text to tokenize */
void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, const char*, int, int, int) /* Callback */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
);
static void sqlite3Fts5Dequote(char *z);
/* Load the contents of the %_config table */
@@ -611,12 +758,14 @@
int iCol; /* If (iCol>=0), this column only */
const u8 *a; /* Position list to iterate through */
int n; /* Size of buffer at a[] in bytes */
int i; /* Current offset in a[] */
+ u8 bFlag; /* For client use (any custom purpose) */
+
/* Output variables */
- int bEof; /* Set to true at EOF */
+ u8 bEof; /* Set to true at EOF */
i64 iPos; /* (iCol<<32) + iPos */
};
static int sqlite3Fts5PoslistReaderInit(
int iCol, /* If (iCol>=0), this column only */
const u8 *a, int n, /* Poslist buffer to iterate through */
@@ -758,13 +907,13 @@
*/
static int sqlite3Fts5IndexErrcode(Fts5Index*);
static void sqlite3Fts5IndexReset(Fts5Index*);
/*
-** Get or set the "averages" record.
+** Get or set the "averages" values.
*/
-static int sqlite3Fts5IndexGetAverages(Fts5Index *p, Fts5Buffer *pBuf);
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
/*
** Functions called by the storage module as part of integrity-check.
*/
@@ -973,11 +1122,11 @@
static int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
-static int sqlite3Fts5ExprPhraseExpr(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
+static int sqlite3Fts5ExprClonePhrase(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
/*******************************************
** The fts5_expr.c API above this point is used by the other hand-written
** C code in this module. The interfaces below this point are called by
** the parser code in fts5parse.y. */
@@ -1241,18 +1390,22 @@
/*
** Tokenizer callback used by implementation of highlight() function.
*/
static int fts5HighlightCb(
void *pContext, /* Pointer to HighlightContext object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStartOff, /* Start offset of token */
int iEndOff /* End offset of token */
){
HighlightContext *p = (HighlightContext*)pContext;
int rc = SQLITE_OK;
- int iPos = p->iPos++;
+ int iPos;
+
+ if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
+ iPos = p->iPos++;
if( p->iRangeEnd>0 ){
if( iPosiRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
}
@@ -2602,16 +2755,19 @@
** because the callback returned another non-zero value, it is assumed
** to be an SQLite error code and returned to the caller.
*/
static int sqlite3Fts5Tokenize(
Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
const char *pText, int nText, /* Text to tokenize */
void *pCtx, /* Context passed to xToken() */
- int (*xToken)(void*, const char*, int, int, int) /* Callback */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
){
if( pText==0 ) return SQLITE_OK;
- return pConfig->pTokApi->xTokenize(pConfig->pTok, pCtx, pText, nText, xToken);
+ return pConfig->pTokApi->xTokenize(
+ pConfig->pTok, pCtx, flags, pText, nText, xToken
+ );
}
/*
** Argument pIn points to the first character in what is expected to be
** a comma-separated list of SQL literals followed by a ')' character.
@@ -2841,10 +2997,12 @@
/*
** All token types in the generated fts5parse.h file are greater than 0.
*/
#define FTS5_EOF 0
+#define FTS5_LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
+
typedef struct Fts5ExprTerm Fts5ExprTerm;
/*
** Functions generated by lemon from fts5parse.y.
*/
@@ -2892,10 +3050,11 @@
*/
struct Fts5ExprTerm {
int bPrefix; /* True for a prefix term */
char *zTerm; /* nul-terminated term */
Fts5IndexIter *pIter; /* Iterator for this term */
+ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
};
/*
** A phrase. One or more terms that must appear in a contiguous sequence
** within a document for it to match.
@@ -3000,10 +3159,14 @@
break;
}
default: {
const char *z2;
+ if( sqlite3Fts5IsBareword(z[0])==0 ){
+ sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
+ return FTS5_EOF;
+ }
tok = FTS5_STRING;
for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
pToken->n = (z2 - z);
if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR;
if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
@@ -3063,83 +3226,10 @@
sqlite3_free(sParse.apPhrase);
*pzErr = sParse.zErr;
return sParse.rc;
}
-/*
-** Create a new FTS5 expression by cloning phrase iPhrase of the
-** expression passed as the second argument.
-*/
-static int sqlite3Fts5ExprPhraseExpr(
- Fts5Config *pConfig,
- Fts5Expr *pExpr,
- int iPhrase,
- Fts5Expr **ppNew
-){
- int rc = SQLITE_OK; /* Return code */
- Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
- Fts5ExprPhrase *pCopy; /* Copy of pOrig */
- Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
-
- pOrig = pExpr->apExprPhrase[iPhrase];
- pCopy = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * pOrig->nTerm
- );
- if( pCopy ){
- int i; /* Used to iterate through phrase terms */
- Fts5ExprPhrase **apPhrase;
- Fts5ExprNode *pNode;
- Fts5ExprNearset *pNear;
-
- pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
- apPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprPhrase*)
- );
- pNode = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNode));
- pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
- sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)
- );
-
- for(i=0; inTerm; i++){
- pCopy->aTerm[i].zTerm = sqlite3Fts5Strndup(&rc, pOrig->aTerm[i].zTerm,-1);
- pCopy->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
- }
-
- if( rc==SQLITE_OK ){
- /* All the allocations succeeded. Put the expression object together. */
- pNew->pIndex = pExpr->pIndex;
- pNew->pRoot = pNode;
- pNew->nPhrase = 1;
- pNew->apExprPhrase = apPhrase;
- pNew->apExprPhrase[0] = pCopy;
-
- pNode->eType = (pOrig->nTerm==1 ? FTS5_TERM : FTS5_STRING);
- pNode->pNear = pNear;
-
- pNear->nPhrase = 1;
- pNear->apPhrase[0] = pCopy;
-
- pCopy->nTerm = pOrig->nTerm;
- pCopy->pNode = pNode;
- }else{
- /* At least one allocation failed. Free them all. */
- for(i=0; inTerm; i++){
- sqlite3_free(pCopy->aTerm[i].zTerm);
- }
- sqlite3_free(pCopy);
- sqlite3_free(pNear);
- sqlite3_free(pNode);
- sqlite3_free(apPhrase);
- sqlite3_free(pNew);
- pNew = 0;
- }
- }
-
- *ppNew = pNew;
- return rc;
-}
-
/*
** Free the expression node object passed as the only argument.
*/
static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
if( p ){
@@ -3168,10 +3258,119 @@
for(i=0; inCol; i++){
if( pColset->aiCol[i]==iCol ) return 1;
}
return 0;
}
+
+/*
+** Argument pTerm must be a synonym iterator. Return the current rowid
+** that it points to.
+*/
+static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
+ i64 iRet = 0;
+ int bRetValid = 0;
+ Fts5ExprTerm *p;
+
+ assert( pTerm->pSynonym );
+ assert( bDesc==0 || bDesc==1 );
+ for(p=pTerm; p; p=p->pSynonym){
+ if( 0==sqlite3Fts5IterEof(p->pIter) ){
+ i64 iRowid = sqlite3Fts5IterRowid(p->pIter);
+ if( bRetValid==0 || (bDesc!=(iRowidpSynonym );
+ for(p=pTerm; p; p=p->pSynonym){
+ Fts5IndexIter *pIter = p->pIter;
+ if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
+ const u8 *a;
+ int n;
+ i64 dummy;
+ rc = sqlite3Fts5IterPoslist(pIter, &a, &n, &dummy);
+ if( rc!=SQLITE_OK ) goto synonym_poslist_out;
+ if( nIter==nAlloc ){
+ int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
+ Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM;
+ goto synonym_poslist_out;
+ }
+ memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
+ nAlloc = nAlloc*2;
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ aIter = aNew;
+ }
+ sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[nIter]);
+ assert( aIter[nIter].bEof==0 );
+ nIter++;
+ }
+ }
+
+ assert( *pbDel==0 );
+ if( nIter==1 ){
+ *pa = (u8*)aIter[0].a;
+ *pn = aIter[0].n;
+ }else{
+ Fts5PoslistWriter writer = {0};
+ Fts5Buffer buf = {0,0,0};
+ i64 iPrev = -1;
+ while( 1 ){
+ int i;
+ i64 iMin = FTS5_LARGEST_INT64;
+ for(i=0; inTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
if( !aIter ) return SQLITE_NOMEM;
}
+ memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
/* Initialize a term iterator for each term in the phrase */
for(i=0; inTerm; i++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
i64 dummy;
- int n;
- const u8 *a;
- rc = sqlite3Fts5IterPoslist(pPhrase->aTerm[i].pIter, &a, &n, &dummy);
- if( rc || sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]) ){
- goto ismatch_out;
+ int n = 0;
+ int bFlag = 0;
+ const u8 *a = 0;
+ if( pTerm->pSynonym ){
+ rc = fts5ExprSynonymPoslist(pTerm, pNode->iRowid, &bFlag, (u8**)&a, &n);
+ }else{
+ rc = sqlite3Fts5IterPoslist(pTerm->pIter, &a, &n, &dummy);
}
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+ sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]);
+ aIter[i].bFlag = bFlag;
+ if( aIter[i].bEof ) goto ismatch_out;
}
while( 1 ){
int bMatch;
i64 iPos = aIter[0].iPos;
@@ -3250,10 +3457,13 @@
}
}
ismatch_out:
*pbMatch = (pPhrase->poslist.n>0);
+ for(i=0; inTerm; i++){
+ if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
+ }
if( aIter!=aStatic ) sqlite3_free(aIter);
return rc;
}
typedef struct Fts5LookaheadReader Fts5LookaheadReader;
@@ -3417,21 +3627,59 @@
Fts5Expr *pExpr, /* Expression pPhrase belongs to */
Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */
int bFromValid,
i64 iFrom
){
- Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
- int rc;
-
- assert( Fts5NodeIsString(pNode) );
- if( bFromValid ){
- rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
- }else{
- rc = sqlite3Fts5IterNext(pIter);
+ Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
+ int rc = SQLITE_OK;
+
+ if( pTerm->pSynonym ){
+ int bEof = 1;
+ Fts5ExprTerm *p;
+
+ /* Find the firstest rowid any synonym points to. */
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
+
+ /* Advance each iterator that currently points to iRowid. Or, if iFrom
+ ** is valid - each iterator that points to a rowid before iFrom. */
+ for(p=pTerm; p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 ii = sqlite3Fts5IterRowid(p->pIter);
+ if( ii==iRowid
+ || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc)
+ ){
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(p->pIter);
+ }
+ if( rc!=SQLITE_OK ) break;
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ bEof = 0;
+ }
+ }else{
+ bEof = 0;
+ }
+ }
+ }
+
+ /* Set the EOF flag if either all synonym iterators are at EOF or an
+ ** error has occurred. */
+ pNode->bEof = (rc || bEof);
+ }else{
+ Fts5IndexIter *pIter = pTerm->pIter;
+
+ assert( Fts5NodeIsString(pNode) );
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+
+ pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
}
- pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
return rc;
}
/*
** Advance iterator pIter until it points to a value equal to or laster
@@ -3465,10 +3713,39 @@
}
*piLast = iRowid;
return 0;
}
+
+static int fts5ExprSynonymAdvanceto(
+ Fts5ExprTerm *pTerm, /* Term iterator to advance */
+ int bDesc, /* True if iterator is "rowid DESC" */
+ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
+ int *pRc /* OUT: Error code */
+){
+ int rc = SQLITE_OK;
+ i64 iLast = *piLast;
+ Fts5ExprTerm *p;
+ int bEof = 0;
+
+ for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 iRowid = sqlite3Fts5IterRowid(p->pIter);
+ if( (bDesc==0 && iLast>iRowid) || (bDesc && iLastpIter, iLast);
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ bEof = 1;
+ }else{
+ *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
+ }
+ return bEof;
+}
/*
** IN/OUT parameter (*pa) points to a position list n bytes in size. If
** the position list contains entries for column iCol, then (*pa) is set
** to point to the sub-position-list for that column and the number of
@@ -3536,13 +3813,13 @@
/* Check that each phrase in the nearset matches the current row.
** Populate the pPhrase->poslist buffers at the same time. If any
** phrase is not a match, break out of the loop early. */
for(i=0; rc==SQLITE_OK && inPhrase; i++){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- if( pPhrase->nTerm>1 || pNear->pColset ){
+ if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
int bMatch = 0;
- rc = fts5ExprPhraseIsMatch(pExpr, pNear->pColset, pPhrase, &bMatch);
+ rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
if( bMatch==0 ) break;
}else{
rc = sqlite3Fts5IterPoslistBuffer(
pPhrase->aTerm[0].pIter, &pPhrase->poslist
);
@@ -3574,10 +3851,11 @@
int nPos;
int rc;
assert( pNode->eType==FTS5_TERM );
assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
+ assert( pPhrase->aTerm[0].pSynonym==0 );
rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
/* If the term may match any column, then this must be a match.
** Return immediately in this case. Otherwise, try to find the
@@ -3620,73 +3898,102 @@
Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
int rc = SQLITE_OK;
i64 iLast; /* Lastest rowid any iterator points to */
int i, j; /* Phrase and token index, respectively */
int bMatch; /* True if all terms are at the same rowid */
+ const int bDesc = pExpr->bDesc;
- assert( pNear->nPhrase>1 || pNear->apPhrase[0]->nTerm>1 );
+ /* Check that this node should not be FTS5_TERM */
+ assert( pNear->nPhrase>1
+ || pNear->apPhrase[0]->nTerm>1
+ || pNear->apPhrase[0]->aTerm[0].pSynonym
+ );
/* Initialize iLast, the "lastest" rowid any iterator points to. If the
** iterator skips through rowids in the default ascending order, this means
** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
** means the minimum rowid. */
- iLast = sqlite3Fts5IterRowid(pLeft->aTerm[0].pIter);
+ if( pLeft->aTerm[0].pSynonym ){
+ iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
+ }else{
+ iLast = sqlite3Fts5IterRowid(pLeft->aTerm[0].pIter);
+ }
do {
bMatch = 1;
for(i=0; inPhrase; i++){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
for(j=0; jnTerm; j++){
- Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
- i64 iRowid = sqlite3Fts5IterRowid(pIter);
- if( iRowid!=iLast ) bMatch = 0;
- if( fts5ExprAdvanceto(pIter, pExpr->bDesc, &iLast,&rc,&pNode->bEof) ){
- return rc;
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ if( pTerm->pSynonym ){
+ int bEof = 1;
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
+ if( iRowid==iLast ) continue;
+ bMatch = 0;
+ if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
+ pNode->bEof = 1;
+ return rc;
+ }
+ }else{
+ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
+ i64 iRowid = sqlite3Fts5IterRowid(pIter);
+ if( iRowid==iLast ) continue;
+ bMatch = 0;
+ if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
+ return rc;
+ }
}
}
}
}while( bMatch==0 );
- pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode));
pNode->iRowid = iLast;
+ pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode));
return rc;
}
/*
** Initialize all term iterators in the pNear object. If any term is found
-** to match no documents at all, set *pbEof to true and return immediately,
-** without initializing any further iterators.
+** to match no documents at all, return immediately without initializing any
+** further iterators.
*/
static int fts5ExprNearInitAll(
Fts5Expr *pExpr,
Fts5ExprNode *pNode
){
Fts5ExprNearset *pNear = pNode->pNear;
- Fts5ExprTerm *pTerm;
- Fts5ExprPhrase *pPhrase;
int i, j;
int rc = SQLITE_OK;
for(i=0; rc==SQLITE_OK && inPhrase; i++){
- pPhrase = pNear->apPhrase[i];
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
for(j=0; jnTerm; j++){
- pTerm = &pPhrase->aTerm[j];
- if( pTerm->pIter ){
- sqlite3Fts5IterClose(pTerm->pIter);
- pTerm->pIter = 0;
- }
- rc = sqlite3Fts5IndexQuery(
- pExpr->pIndex, pTerm->zTerm, strlen(pTerm->zTerm),
- (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
- (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
- &pTerm->pIter
- );
- assert( rc==SQLITE_OK || pTerm->pIter==0 );
- if( pTerm->pIter==0 || sqlite3Fts5IterEof(pTerm->pIter) ){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ Fts5ExprTerm *p;
+ int bEof = 1;
+
+ for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){
+ if( p->pIter ){
+ sqlite3Fts5IterClose(p->pIter);
+ p->pIter = 0;
+ }
+ rc = sqlite3Fts5IndexQuery(
+ pExpr->pIndex, p->zTerm, strlen(p->zTerm),
+ (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
+ (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
+ &p->pIter
+ );
+ assert( rc==SQLITE_OK || p->pIter==0 );
+ if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
+ bEof = 0;
+ }
+ }
+
+ if( bEof ){
pNode->bEof = 1;
- break;
+ return rc;
}
}
}
return rc;
@@ -3848,14 +4155,21 @@
rc = fts5ExprNearAdvanceFirst(pExpr, pNode, bFromValid, iFrom);
break;
};
case FTS5_TERM: {
- rc = fts5ExprNearAdvanceFirst(pExpr, pNode, bFromValid, iFrom);
- if( pNode->bEof==0 ){
+ Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+ if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
assert( rc==SQLITE_OK );
rc = fts5ExprTokenTest(pExpr, pNode);
+ }else{
+ pNode->bEof = 1;
}
return rc;
};
case FTS5_AND: {
@@ -4085,14 +4399,20 @@
*/
static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
if( pPhrase ){
int i;
for(i=0; inTerm; i++){
+ Fts5ExprTerm *pSyn;
+ Fts5ExprTerm *pNext;
Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
sqlite3_free(pTerm->zTerm);
- if( pTerm->pIter ){
- sqlite3Fts5IterClose(pTerm->pIter);
+ sqlite3Fts5IterClose(pTerm->pIter);
+
+ for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
+ pNext = pSyn->pSynonym;
+ sqlite3Fts5IterClose(pSyn->pIter);
+ sqlite3_free(pSyn);
}
}
if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
sqlite3_free(pPhrase);
}
@@ -4150,45 +4470,72 @@
}
typedef struct TokenCtx TokenCtx;
struct TokenCtx {
Fts5ExprPhrase *pPhrase;
+ int rc;
};
/*
** Callback for tokenizing terms used by ParseTerm().
*/
static int fts5ParseTokenize(
void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
- int iStart, /* Start offset of token */
- int iEnd /* End offset of token */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
){
int rc = SQLITE_OK;
const int SZALLOC = 8;
TokenCtx *pCtx = (TokenCtx*)pContext;
Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
- Fts5ExprTerm *pTerm;
-
- if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
- Fts5ExprPhrase *pNew;
- int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
-
- pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
- sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
- );
- if( pNew==0 ) return SQLITE_NOMEM;
- if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
- pCtx->pPhrase = pPhrase = pNew;
- pNew->nTerm = nNew - SZALLOC;
- }
-
- pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
- memset(pTerm, 0, sizeof(Fts5ExprTerm));
- pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
-
+
+ /* If an error has already occurred, this is a no-op */
+ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
+
+ assert( pPhrase==0 || pPhrase->nTerm>0 );
+ if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
+ Fts5ExprTerm *pSyn;
+ int nByte = sizeof(Fts5ExprTerm) + nToken+1;
+ pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
+ if( pSyn==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pSyn, 0, nByte);
+ pSyn->zTerm = (char*)&pSyn[1];
+ memcpy(pSyn->zTerm, pToken, nToken);
+ pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
+ pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
+ }
+ }else{
+ Fts5ExprTerm *pTerm;
+ if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
+ Fts5ExprPhrase *pNew;
+ int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
+
+ pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
+ sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
+ );
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
+ pCtx->pPhrase = pPhrase = pNew;
+ pNew->nTerm = nNew - SZALLOC;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
+ memset(pTerm, 0, sizeof(Fts5ExprTerm));
+ pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
+ }
+ }
+
+ pCtx->rc = rc;
return rc;
}
/*
@@ -4236,15 +4583,18 @@
memset(&sCtx, 0, sizeof(TokenCtx));
sCtx.pPhrase = pAppend;
rc = fts5ParseStringFromToken(pToken, &z);
if( rc==SQLITE_OK ){
+ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
+ int n;
sqlite3Fts5Dequote(z);
- rc = sqlite3Fts5Tokenize(pConfig, z, strlen(z), &sCtx, fts5ParseTokenize);
+ n = strlen(z);
+ rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
}
sqlite3_free(z);
- if( rc ){
+ if( rc || (rc = sCtx.rc) ){
pParse->rc = rc;
fts5ExprPhraseFree(sCtx.pPhrase);
sCtx.pPhrase = 0;
}else if( sCtx.pPhrase ){
@@ -4268,10 +4618,83 @@
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
}
return sCtx.pPhrase;
}
+
+/*
+** Create a new FTS5 expression by cloning phrase iPhrase of the
+** expression passed as the second argument.
+*/
+static int sqlite3Fts5ExprClonePhrase(
+ Fts5Config *pConfig,
+ Fts5Expr *pExpr,
+ int iPhrase,
+ Fts5Expr **ppNew
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
+ int i; /* Used to iterate through phrase terms */
+
+ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
+
+ TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
+
+
+ pOrig = pExpr->apExprPhrase[iPhrase];
+
+ pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
+ if( rc==SQLITE_OK ){
+ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprPhrase*));
+ }
+ if( rc==SQLITE_OK ){
+ pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprNode));
+ }
+ if( rc==SQLITE_OK ){
+ pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
+ }
+
+ for(i=0; rc==SQLITE_OK && inTerm; i++){
+ int tflags = 0;
+ Fts5ExprTerm *p;
+ for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
+ const char *zTerm = p->zTerm;
+ rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, strlen(zTerm), 0, 0);
+ tflags = FTS5_TOKEN_COLOCATED;
+ }
+ if( rc==SQLITE_OK ){
+ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ /* All the allocations succeeded. Put the expression object together. */
+ pNew->pIndex = pExpr->pIndex;
+ pNew->nPhrase = 1;
+ pNew->apExprPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->nPhrase = 1;
+ sCtx.pPhrase->pNode = pNew->pRoot;
+
+ if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
+ pNew->pRoot->eType = FTS5_TERM;
+ }else{
+ pNew->pRoot->eType = FTS5_STRING;
+ }
+ }else{
+ sqlite3Fts5ExprFree(pNew);
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ pNew = 0;
+ }
+
+ *ppNew = pNew;
+ return rc;
+}
+
/*
** Token pTok has appeared in a MATCH expression where the NEAR operator
** is expected. If token pTok does not contain "NEAR", store an error
** in the pParse object.
@@ -4449,11 +4872,14 @@
if( eType==FTS5_STRING ){
int iPhrase;
for(iPhrase=0; iPhrasenPhrase; iPhrase++){
pNear->apPhrase[iPhrase]->pNode = pRet;
}
- if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 ){
+ if( pNear->nPhrase==1
+ && pNear->apPhrase[0]->nTerm==1
+ && pNear->apPhrase[0]->aTerm[0].pSynonym==0
+ ){
pRet->eType = FTS5_TERM;
}
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
@@ -4469,20 +4895,32 @@
}
return pRet;
}
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
- char *zQuoted = sqlite3_malloc(strlen(pTerm->zTerm) * 2 + 3 + 2);
+ int nByte = 0;
+ Fts5ExprTerm *p;
+ char *zQuoted;
+
+ /* Determine the maximum amount of space required. */
+ for(p=pTerm; p; p=p->pSynonym){
+ nByte += strlen(pTerm->zTerm) * 2 + 3 + 2;
+ }
+ zQuoted = sqlite3_malloc(nByte);
+
if( zQuoted ){
int i = 0;
- char *zIn = pTerm->zTerm;
- zQuoted[i++] = '"';
- while( *zIn ){
- if( *zIn=='"' ) zQuoted[i++] = '"';
- zQuoted[i++] = *zIn++;
+ for(p=pTerm; p; p=p->pSynonym){
+ char *zIn = p->zTerm;
+ zQuoted[i++] = '"';
+ while( *zIn ){
+ if( *zIn=='"' ) zQuoted[i++] = '"';
+ zQuoted[i++] = *zIn++;
+ }
+ zQuoted[i++] = '"';
+ if( p->pSynonym ) zQuoted[i++] = '|';
}
- zQuoted[i++] = '"';
if( pTerm->bPrefix ){
zQuoted[i++] = ' ';
zQuoted[i++] = '*';
}
zQuoted[i++] = '\0';
@@ -5629,11 +6067,10 @@
typedef struct Fts5Data Fts5Data;
typedef struct Fts5DlidxIter Fts5DlidxIter;
typedef struct Fts5DlidxLvl Fts5DlidxLvl;
typedef struct Fts5DlidxWriter Fts5DlidxWriter;
-typedef struct Fts5NodeIter Fts5NodeIter;
typedef struct Fts5PageWriter Fts5PageWriter;
typedef struct Fts5SegIter Fts5SegIter;
typedef struct Fts5DoclistIter Fts5DoclistIter;
typedef struct Fts5SegWriter Fts5SegWriter;
typedef struct Fts5Structure Fts5Structure;
@@ -5862,28 +6299,10 @@
Fts5CResult *aFirst; /* Current merge state (see above) */
Fts5SegIter aSeg[1]; /* Array of segment iterators */
};
-/*
-** Object for iterating through the conents of a single internal node in
-** memory.
-*/
-struct Fts5NodeIter {
- /* Internal. Set and managed by fts5NodeIterXXX() functions. Except,
- ** the EOF test for the iterator is (Fts5NodeIter.aData==0). */
- const u8 *aData;
- int nData;
- int iOff;
-
- /* Output variables */
- Fts5Buffer term;
- int nEmpty;
- int iChild;
- int bDlidx;
-};
-
/*
** An instance of the following type is used to iterate through the contents
** of a doclist-index record.
**
** pData:
@@ -5909,27 +6328,10 @@
int nLvl;
int iSegid;
Fts5DlidxLvl aLvl[1];
};
-
-
-/*
-** The first argument passed to this macro is a pointer to an Fts5Buffer
-** object.
-*/
-#define fts5BufferSize(pBuf,n) { \
- if( pBuf->nSpacep, n); \
- if( pNew==0 ){ \
- sqlite3_free(pBuf->p); \
- } \
- pBuf->nSpace = n; \
- pBuf->p = pNew; \
- } \
-}
-
static void fts5PutU16(u8 *aOut, u16 iVal){
aOut[0] = (iVal>>8);
aOut[1] = (iVal&0xFF);
}
@@ -5953,19 +6355,20 @@
** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
** +ve if pRight is smaller than pLeft. In other words:
**
** res = *pLeft - *pRight
*/
+#ifdef SQLITE_DEBUG
static int fts5BufferCompareBlob(
Fts5Buffer *pLeft, /* Left hand side of comparison */
const u8 *pRight, int nRight /* Right hand side of comparison */
){
int nCmp = MIN(pLeft->n, nRight);
int res = memcmp(pLeft->p, pRight, nCmp);
return (res==0 ? (pLeft->n - nRight) : res);
}
-
+#endif
/*
** Compare the contents of the two buffers using memcmp(). If one buffer
** is a prefix of the other, it is considered the lesser.
**
@@ -6001,15 +6404,18 @@
p->pReader = 0;
sqlite3_blob_close(pReader);
}
}
-static Fts5Data *fts5DataReadOrBuffer(
- Fts5Index *p,
- Fts5Buffer *pBuf,
- i64 iRowid
-){
+
+/*
+** Retrieve a record from the %_data table.
+**
+** If an error occurs, NULL is returned and an error left in the
+** Fts5Index object.
+*/
+static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = 0;
if( p->rc==SQLITE_OK ){
int rc = SQLITE_OK;
if( p->pReader ){
@@ -6025,12 +6431,12 @@
fts5CloseReader(p);
}
if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
}
- /* If the blob handle is not yet open, open and seek it. Otherwise, use
- ** the blob_reopen() API to reseek the existing blob handle. */
+ /* If the blob handle is not open at this point, open it and seek
+ ** to the requested entry. */
if( p->pReader==0 && rc==SQLITE_OK ){
Fts5Config *pConfig = p->pConfig;
rc = sqlite3_blob_open(pConfig->db,
pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
);
@@ -6044,26 +6450,17 @@
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
int nByte = sqlite3_blob_bytes(p->pReader);
- if( pBuf ){
- fts5BufferSize(pBuf, MAX(nByte, p->pConfig->pgsz) + 20);
- pBuf->n = nByte;
- aOut = pBuf->p;
- if( aOut==0 ){
- rc = SQLITE_NOMEM;
- }
- }else{
- int nSpace = nByte + FTS5_DATA_PADDING;
- pRet = (Fts5Data*)sqlite3_malloc(nSpace+sizeof(Fts5Data));
- if( pRet ){
- pRet->n = nByte;
- aOut = pRet->p = (u8*)&pRet[1];
- }else{
- rc = SQLITE_NOMEM;
- }
+ int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
+ pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
+ if( pRet ){
+ pRet->n = nByte;
+ aOut = pRet->p = (u8*)&pRet[1];
+ }else{
+ rc = SQLITE_NOMEM;
}
if( rc==SQLITE_OK ){
rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
}
@@ -6074,37 +6471,14 @@
}
p->rc = rc;
p->nRead++;
}
- return pRet;
-}
-
-/*
-** Retrieve a record from the %_data table.
-**
-** If an error occurs, NULL is returned and an error left in the
-** Fts5Index object.
-*/
-static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
- Fts5Data *pRet = fts5DataReadOrBuffer(p, 0, iRowid);
assert( (pRet==0)==(p->rc!=SQLITE_OK) );
return pRet;
}
-/*
-** Read a record from the %_data table into the buffer supplied as the
-** second argument.
-**
-** If an error occurs, an error is left in the Fts5Index object. If an
-** error has already occurred when this function is called, it is a
-** no-op.
-*/
-static void fts5DataBuffer(Fts5Index *p, Fts5Buffer *pBuf, i64 iRowid){
- (void)fts5DataReadOrBuffer(p, pBuf, iRowid);
-}
-
/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
*/
static void fts5DataRelease(Fts5Data *pData){
@@ -6369,23 +6743,22 @@
*/
static Fts5Structure *fts5StructureRead(Fts5Index *p){
Fts5Config *pConfig = p->pConfig;
Fts5Structure *pRet = 0; /* Object to return */
int iCookie; /* Configuration cookie */
+ Fts5Data *pData;
Fts5Buffer buf = {0, 0, 0};
- fts5DataBuffer(p, &buf, FTS5_STRUCTURE_ROWID);
- if( buf.p==0 ) return 0;
- assert( buf.nSpace>=(buf.n + FTS5_DATA_ZERO_PADDING) );
- memset(&buf.p[buf.n], 0, FTS5_DATA_ZERO_PADDING);
- p->rc = fts5StructureDecode(buf.p, buf.n, &iCookie, &pRet);
-
+ pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
+ if( p->rc ) return 0;
+ memset(&pData->p[pData->n], 0, FTS5_DATA_PADDING);
+ p->rc = fts5StructureDecode(pData->p, pData->n, &iCookie, &pRet);
if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
- fts5BufferFree(&buf);
+ fts5DataRelease(pData);
if( p->rc!=SQLITE_OK ){
fts5StructureRelease(pRet);
pRet = 0;
}
return pRet;
@@ -6564,66 +6937,10 @@
fts5StructurePromoteTo(p, iPromote, szPromote, pStruct);
}
}
-/*
-** If the pIter->iOff offset currently points to an entry indicating one
-** or more term-less nodes, advance past it and set pIter->nEmpty to
-** the number of empty child nodes.
-*/
-static void fts5NodeIterGobbleNEmpty(Fts5NodeIter *pIter){
- if( pIter->iOffnData && 0==(pIter->aData[pIter->iOff] & 0xfe) ){
- pIter->bDlidx = pIter->aData[pIter->iOff] & 0x01;
- pIter->iOff++;
- pIter->iOff += fts5GetVarint32(&pIter->aData[pIter->iOff], pIter->nEmpty);
- }else{
- pIter->nEmpty = 0;
- pIter->bDlidx = 0;
- }
-}
-
-/*
-** Advance to the next entry within the node.
-*/
-static void fts5NodeIterNext(int *pRc, Fts5NodeIter *pIter){
- if( pIter->iOff>=pIter->nData ){
- pIter->aData = 0;
- pIter->iChild += pIter->nEmpty;
- }else{
- int nPre, nNew;
- pIter->iOff += fts5GetVarint32(&pIter->aData[pIter->iOff], nPre);
- pIter->iOff += fts5GetVarint32(&pIter->aData[pIter->iOff], nNew);
- pIter->term.n = nPre-2;
- fts5BufferAppendBlob(pRc, &pIter->term, nNew, pIter->aData+pIter->iOff);
- pIter->iOff += nNew;
- pIter->iChild += (1 + pIter->nEmpty);
- fts5NodeIterGobbleNEmpty(pIter);
- if( *pRc ) pIter->aData = 0;
- }
-}
-
-
-/*
-** Initialize the iterator object pIter to iterate through the internal
-** segment node in pData.
-*/
-static void fts5NodeIterInit(const u8 *aData, int nData, Fts5NodeIter *pIter){
- memset(pIter, 0, sizeof(*pIter));
- pIter->aData = aData;
- pIter->nData = nData;
- pIter->iOff = fts5GetVarint32(aData, pIter->iChild);
- fts5NodeIterGobbleNEmpty(pIter);
-}
-
-/*
-** Free any memory allocated by the iterator object.
-*/
-static void fts5NodeIterFree(Fts5NodeIter *pIter){
- fts5BufferFree(&pIter->term);
-}
-
/*
** Advance the iterator passed as the only argument. If the end of the
** doclist-index page is reached, return non-zero.
*/
static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){
@@ -7377,123 +7694,10 @@
}
pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
}
-#ifdef SQLITE_DEBUG
-static void fts5AssertNodeSeekOk(
- Fts5Buffer *pNode,
- const u8 *pTerm, int nTerm, /* Term to search for */
- int iExpectPg,
- int bExpectDlidx
-){
- int bDlidx;
- int iPg;
- int rc = SQLITE_OK;
- Fts5NodeIter node;
-
- fts5NodeIterInit(pNode->p, pNode->n, &node);
- assert( node.term.n==0 );
- iPg = node.iChild;
- bDlidx = node.bDlidx;
- for(fts5NodeIterNext(&rc, &node);
- node.aData && fts5BufferCompareBlob(&node.term, pTerm, nTerm)<=0;
- fts5NodeIterNext(&rc, &node)
- ){
- iPg = node.iChild;
- bDlidx = node.bDlidx;
- }
- fts5NodeIterFree(&node);
-
- assert( rc!=SQLITE_OK || iPg==iExpectPg );
- assert( rc!=SQLITE_OK || bDlidx==bExpectDlidx );
-}
-#else
-#define fts5AssertNodeSeekOk(v,w,x,y,z)
-#endif
-
-/*
-** Argument pNode is an internal b-tree node. This function searches
-** within the node for the largest term that is smaller than or equal
-** to (pTerm/nTerm).
-**
-** It returns the associated page number. Or, if (pTerm/nTerm) is smaller
-** than all terms within the node, the leftmost child page number.
-**
-** Before returning, (*pbDlidx) is set to true if the last term on the
-** returned child page number has a doclist-index. Or left as is otherwise.
-*/
-static int fts5NodeSeek(
- Fts5Buffer *pNode, /* Node to search */
- const u8 *pTerm, int nTerm, /* Term to search for */
- int *pbDlidx /* OUT: True if dlidx flag is set */
-){
- int iPg;
- u8 *pPtr = pNode->p;
- u8 *pEnd = &pPtr[pNode->n];
- int nMatch = 0; /* Number of bytes of pTerm already matched */
-
- assert( *pbDlidx==0 );
-
- pPtr += fts5GetVarint32(pPtr, iPg);
- while( pPtr=pEnd ) break;
- }
-
- /* Read the next "term" pointer. Set nKeep to the number of bytes to
- ** keep from the previous term, and nNew to the number of bytes of
- ** new data that will be appended to it. */
- nKeep = (int)*pPtr++;
- nNew = (int)*pPtr++;
- if( (nKeep | nNew) & 0x0080 ){
- pPtr -= 2;
- pPtr += fts5GetVarint32(pPtr, nKeep);
- pPtr += fts5GetVarint32(pPtr, nNew);
- }
- nKeep -= 2;
-
- /* Compare (pTerm/nTerm) to the current term on the node (the one described
- ** by nKeep/nNew). If the node term is larger, break out of the while()
- ** loop.
- **
- ** Otherwise, if (pTerm/nTerm) is larger or the two terms are equal,
- ** leave variable nMatch set to the size of the largest prefix common to
- ** both terms in bytes. */
- if( nKeep==nMatch ){
- int nTst = MIN(nNew, nTerm-nMatch);
- int i;
- for(i=0; i pTerm[nMatch]) ) break;
- }else if( nKeeprc==SQLITE_OK ){
+ do{
if( bMove ) fts5SegIterNext(p, pIter, 0);
if( pIter->pLeaf==0 ) break;
if( bRev==0 && pIter->iRowid>=iMatch ) break;
if( bRev!=0 && pIter->iRowid<=iMatch ) break;
bMove = 1;
- }
+ }while( p->rc==SQLITE_OK );
}
/*
** Free the iterator object passed as the second argument.
@@ -9795,17 +9999,13 @@
** function populates it with the initial structure objects for each index,
** and the initial version of the "averages" record (a zero-byte blob).
*/
static int sqlite3Fts5IndexReinit(Fts5Index *p){
Fts5Structure s;
-
- assert( p->rc==SQLITE_OK );
- p->rc = sqlite3Fts5IndexSetAverages(p, (const u8*)"", 0);
-
memset(&s, 0, sizeof(Fts5Structure));
+ fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
fts5StructureWrite(p, &s);
-
return fts5IndexReturn(p);
}
/*
** Open a new Fts5Index handle. If the bCreate argument is true, create
@@ -10123,17 +10323,32 @@
fts5CloseReader(pIndex);
}
}
/*
-** Read the "averages" record into the buffer supplied as the second
-** argument. Return SQLITE_OK if successful, or an SQLite error code
-** if an error occurs.
+** Read and decode the "averages" record from the database.
+**
+** Parameter anSize must point to an array of size nCol, where nCol is
+** the number of user defined columns in the FTS table.
*/
-static int sqlite3Fts5IndexGetAverages(Fts5Index *p, Fts5Buffer *pBuf){
- assert( p->rc==SQLITE_OK );
- fts5DataReadOrBuffer(p, pBuf, FTS5_AVERAGES_ROWID);
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){
+ int nCol = p->pConfig->nCol;
+ Fts5Data *pData;
+
+ *pnRow = 0;
+ memset(anSize, 0, sizeof(i64) * nCol);
+ pData = fts5DataRead(p, FTS5_AVERAGES_ROWID);
+ if( p->rc==SQLITE_OK && pData->n ){
+ int i = 0;
+ int iCol;
+ i += fts5GetVarint(&pData->p[i], (u64*)pnRow);
+ for(iCol=0; in && iColp[i], (u64*)&anSize[iCol]);
+ }
+ }
+
+ fts5DataRelease(pData);
return fts5IndexReturn(p);
}
/*
** Replace the current "averages" record with the contents of the buffer
@@ -10663,17 +10878,17 @@
int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
if( iSegid==0 ){
if( iKey==FTS5_AVERAGES_ROWID ){
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "(averages) ");
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
}else{
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "(structure)");
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
}
}
else{
- sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "(%ssegid=%d h=%d pgno=%d)",
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
);
}
}
@@ -10823,77 +11038,57 @@
/* todo */
}else{
fts5DecodeStructure(&rc, &s, a, n);
}
}else{
-
Fts5Buffer term;
+ int iTermOff = 0;
+ int iRowidOff = 0;
+ int iOff;
+ int nKeep = 0;
+
memset(&term, 0, sizeof(Fts5Buffer));
- if( iHeight==0 ){
- int iTermOff = 0;
- int iRowidOff = 0;
- int iOff;
- int nKeep = 0;
-
- if( n>=4 ){
- iRowidOff = fts5GetU16(&a[0]);
- iTermOff = fts5GetU16(&a[2]);
- }else{
- sqlite3Fts5BufferSet(&rc, &s, 8, (const u8*)"corrupt");
- goto decode_out;
- }
-
- if( iRowidOff ){
- iOff = iRowidOff;
- }else if( iTermOff ){
- iOff = iTermOff;
- }else{
- iOff = n;
- }
- fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
-
- assert( iRowidOff==0 || iOff==iRowidOff );
- if( iRowidOff ){
- iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], n-iOff);
- }
-
- assert( iTermOff==0 || iOff==iTermOff );
- while( iOff=4 ){
+ iRowidOff = fts5GetU16(&a[0]);
+ iTermOff = fts5GetU16(&a[2]);
+ }else{
+ sqlite3Fts5BufferSet(&rc, &s, 8, (const u8*)"corrupt");
+ goto decode_out;
+ }
+
+ if( iRowidOff ){
+ iOff = iRowidOff;
+ }else if( iTermOff ){
+ iOff = iTermOff;
+ }else{
+ iOff = n;
+ }
+ fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
+
+ assert( iRowidOff==0 || iOff==iRowidOff );
+ if( iRowidOff ){
+ iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], n-iOff);
+ }
+
+ assert( iTermOff==0 || iOff==iTermOff );
+ while( iOffbase.pVtab);
- return sqlite3Fts5Tokenize(pTab->pConfig, pText, nText, pUserData, xToken);
+ return sqlite3Fts5Tokenize(
+ pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
+ );
}
static int fts5ApiPhraseCount(Fts5Context *pCtx){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
@@ -12617,17 +12814,20 @@
return rc;
}
static int fts5ColumnSizeCb(
void *pContext, /* Pointer to int */
+ int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
){
int *pCnt = (int*)pContext;
- *pCnt = *pCnt + 1;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
+ (*pCnt)++;
+ }
return SQLITE_OK;
}
static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
@@ -12653,11 +12853,13 @@
const char *z; int n;
void *p = (void*)(&pCsr->aColumnSize[i]);
pCsr->aColumnSize[i] = 0;
rc = fts5ApiColumnText(pCtx, i, &z, &n);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5Tokenize(pConfig, z, n, p, fts5ColumnSizeCb);
+ rc = sqlite3Fts5Tokenize(
+ pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
+ );
}
}
}
}
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
@@ -12815,11 +13017,11 @@
Fts5Config *pConf = pTab->pConfig;
pNew->ePlan = FTS5_PLAN_MATCH;
pNew->iFirstRowid = SMALLEST_INT64;
pNew->iLastRowid = LARGEST_INT64;
pNew->base.pVtab = (sqlite3_vtab*)pTab;
- rc = sqlite3Fts5ExprPhraseExpr(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
+ rc = sqlite3Fts5ExprClonePhrase(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
}
if( rc==SQLITE_OK ){
for(rc = fts5CursorFirst(pTab, pNew, 0);
rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
@@ -13257,11 +13459,11 @@
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apVal /* Function arguments */
){
assert( nArg==0 );
- sqlite3_result_text(pCtx, "fts5: 2015-08-18 19:09:28 8599402092537ab3df8926eb900661c12d738d4c", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2015-09-09 19:44:33 8d2ed150a7a15626965cf994ef48c3ab61eca6ec", -1, SQLITE_TRANSIENT);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
@@ -13306,11 +13508,11 @@
rc = SQLITE_NOMEM;
}else{
void *p = (void*)pGlobal;
memset(pGlobal, 0, sizeof(Fts5Global));
pGlobal->db = db;
- pGlobal->api.iVersion = 1;
+ pGlobal->api.iVersion = 2;
pGlobal->api.xCreateFunction = fts5CreateAux;
pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
pGlobal->api.xFindTokenizer = fts5FindTokenizer;
rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
@@ -13704,19 +13906,22 @@
/*
** Tokenization callback used when inserting tokens into the FTS index.
*/
static int fts5StorageInsertCallback(
void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
){
Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
Fts5Index *pIdx = pCtx->pStorage->pIndex;
- int iPos = pCtx->szCol++;
- return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, iPos, pToken, nToken);
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
+ return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
}
/*
** If a row with rowid iDel is present in the %_content table, add the
** delete-markers to the FTS index necessary to delete it. Do not actually
@@ -13739,10 +13944,11 @@
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1] ) continue;
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pSeek, iCol),
sqlite3_column_bytes(pSeek, iCol),
(void*)&ctx,
fts5StorageInsertCallback
);
@@ -13796,26 +14002,11 @@
** occurs.
*/
static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){
int rc = SQLITE_OK;
if( p->bTotalsValid==0 ){
- int nCol = p->pConfig->nCol;
- Fts5Buffer buf;
- memset(&buf, 0, sizeof(buf));
-
- memset(p->aTotalSize, 0, sizeof(i64) * nCol);
- p->nTotalRow = 0;
- rc = sqlite3Fts5IndexGetAverages(p->pIndex, &buf);
- if( rc==SQLITE_OK && buf.n ){
- int i = 0;
- int iCol;
- i += fts5GetVarint(&buf.p[i], (u64*)&p->nTotalRow);
- for(iCol=0; iaTotalSize[iCol]);
- }
- }
- sqlite3_free(buf.p);
+ rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize);
p->bTotalsValid = bCache;
}
return rc;
}
@@ -13910,10 +14101,11 @@
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
for(iCol=0; rc==SQLITE_OK && iColnCol; iCol++){
if( pConfig->abUnindexed[iCol] ) continue;
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_value_text(apVal[iCol]),
sqlite3_value_bytes(apVal[iCol]),
(void*)&ctx,
fts5StorageInsertCallback
);
@@ -13999,10 +14191,11 @@
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iRowid);
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pScan, ctx.iCol+1),
sqlite3_column_bytes(pScan, ctx.iCol+1),
(void*)&ctx,
fts5StorageInsertCallback
);
@@ -14116,10 +14309,11 @@
}
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
sqlite3_value_bytes(apVal[ctx.iCol+2]),
(void*)&ctx,
fts5StorageInsertCallback
);
@@ -14183,19 +14377,22 @@
/*
** Tokenization callback used by integrity check.
*/
static int fts5StorageIntegrityCallback(
void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
){
Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
- int iPos = pCtx->szCol++;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
pCtx->cksum ^= sqlite3Fts5IndexCksum(
- pCtx->pConfig, pCtx->iRowid, pCtx->iCol, iPos, pToken, nToken
+ pCtx->pConfig, pCtx->iRowid, pCtx->iCol, pCtx->szCol-1, pToken, nToken
);
return SQLITE_OK;
}
/*
@@ -14226,23 +14423,27 @@
int rc2;
while( SQLITE_ROW==sqlite3_step(pScan) ){
int i;
ctx.iRowid = sqlite3_column_int64(pScan, 0);
ctx.szCol = 0;
- rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
+ if( pConfig->bColumnsize ){
+ rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
+ }
for(i=0; rc==SQLITE_OK && inCol; i++){
if( pConfig->abUnindexed[i] ) continue;
ctx.iCol = i;
ctx.szCol = 0;
- rc = sqlite3Fts5Tokenize(
- pConfig,
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pScan, i+1),
sqlite3_column_bytes(pScan, i+1),
(void*)&ctx,
fts5StorageIntegrityCallback
);
- if( ctx.szCol!=aColSize[i] ) rc = FTS5_CORRUPT;
+ if( pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
+ rc = FTS5_CORRUPT;
+ }
aTotalSize[i] += ctx.szCol;
}
if( rc!=SQLITE_OK ) break;
}
rc2 = sqlite3_reset(pScan);
@@ -14263,11 +14464,11 @@
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
@@ -14347,13 +14548,16 @@
**
** An SQLite error code is returned if an error occurs, or SQLITE_OK
** otherwise.
*/
static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
- int nCol = p->pConfig->nCol;
- sqlite3_stmt *pLookup = 0;
- int rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
+ int nCol = p->pConfig->nCol; /* Number of user columns in table */
+ sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
+ int rc; /* Return Code */
+
+ assert( p->pConfig->bColumnsize );
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
if( rc==SQLITE_OK ){
int bCorrupt = 1;
sqlite3_bind_int64(pLookup, 1, iRowid);
if( SQLITE_ROW==sqlite3_step(pLookup) ){
const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
@@ -14560,12 +14764,13 @@
** Tokenize some text using the ascii tokenizer.
*/
static int fts5AsciiTokenize(
Fts5Tokenizer *pTokenizer,
void *pCtx,
+ int flags,
const char *pText, int nText,
- int (*xToken)(void*, const char*, int nToken, int iStart, int iEnd)
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
int rc = SQLITE_OK;
int ie;
int is = 0;
@@ -14602,11 +14807,11 @@
nFold = nByte*2;
}
asciiFold(pFold, &pText[is], nByte);
/* Invoke the token callback */
- rc = xToken(pCtx, pFold, nByte, is, ie);
+ rc = xToken(pCtx, 0, pFold, nByte, is, ie);
is = ie+1;
}
if( pFold!=aFold ) sqlite3_free(pFold);
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
@@ -14829,12 +15034,13 @@
}
static int fts5UnicodeTokenize(
Fts5Tokenizer *pTokenizer,
void *pCtx,
+ int flags,
const char *pText, int nText,
- int (*xToken)(void*, const char*, int nToken, int iStart, int iEnd)
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
int rc = SQLITE_OK;
unsigned char *a = p->aTokenChar;
@@ -14919,11 +15125,11 @@
}
ie = zCsr - (unsigned char*)pText;
}
/* Invoke the token callback */
- rc = xToken(pCtx, aFold, zOut-aFold, is, ie);
+ rc = xToken(pCtx, 0, aFold, zOut-aFold, is, ie);
}
tokenize_done:
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
return rc;
@@ -14997,11 +15203,11 @@
}
typedef struct PorterContext PorterContext;
struct PorterContext {
void *pCtx;
- int (*xToken)(void*, const char*, int, int, int);
+ int (*xToken)(void*, int, const char*, int, int, int);
char *aBuf;
};
typedef struct PorterRule PorterRule;
struct PorterRule {
@@ -15562,10 +15768,11 @@
}
}
static int fts5PorterCb(
void *pCtx,
+ int tflags,
const char *pToken,
int nToken,
int iStart,
int iEnd
){
@@ -15619,32 +15826,33 @@
&& aBuf[nBuf-2]=='l' && fts5Porter_MGt1(aBuf, nBuf-1)
){
nBuf--;
}
- return p->xToken(p->pCtx, aBuf, nBuf, iStart, iEnd);
+ return p->xToken(p->pCtx, tflags, aBuf, nBuf, iStart, iEnd);
pass_through:
- return p->xToken(p->pCtx, pToken, nToken, iStart, iEnd);
+ return p->xToken(p->pCtx, tflags, pToken, nToken, iStart, iEnd);
}
/*
** Tokenize using the porter tokenizer.
*/
static int fts5PorterTokenize(
Fts5Tokenizer *pTokenizer,
void *pCtx,
+ int flags,
const char *pText, int nText,
- int (*xToken)(void*, const char*, int nToken, int iStart, int iEnd)
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
PorterContext sCtx;
sCtx.xToken = xToken;
sCtx.pCtx = pCtx;
sCtx.aBuf = p->aBuf;
return p->tokenizer.xTokenize(
- p->pTokenizer, (void*)&sCtx, pText, nText, fts5PorterCb
+ p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
);
}
/*
** Register all built-in tokenizers with FTS5.
@@ -15669,11 +15877,11 @@
&aBuiltin[i].x,
0
);
}
- return SQLITE_OK;
+ return rc;
}
#line 2 "fts5_unicode2.c"
@@ -16940,14 +17148,21 @@
** zero the stack is dynamically sized using realloc()
** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument
** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument
** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
+** fts5YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
** fts5YYNSTATE the combined number of states.
** fts5YYNRULE the number of rules in the grammar
-** fts5YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
+** fts5YY_MAX_SHIFT Maximum value for shift actions
+** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** fts5YY_MIN_REDUCE Maximum value for reduce actions
+** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
+** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
+** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
*/
#define fts5YYCODETYPE unsigned char
#define fts5YYNOCODE 27
#define fts5YYACTIONTYPE unsigned char
#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
@@ -16965,15 +17180,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 40
-#define fts5YYNRULE 24
-#define fts5YY_NO_ACTION (fts5YYNSTATE+fts5YYNRULE+2)
-#define fts5YY_ACCEPT_ACTION (fts5YYNSTATE+fts5YYNRULE+1)
-#define fts5YY_ERROR_ACTION (fts5YYNSTATE+fts5YYNRULE)
+#define fts5YYNSTATE 26
+#define fts5YYNRULE 24
+#define fts5YY_MAX_SHIFT 25
+#define fts5YY_MIN_SHIFTREDUCE 40
+#define fts5YY_MAX_SHIFTREDUCE 63
+#define fts5YY_MIN_REDUCE 64
+#define fts5YY_MAX_REDUCE 87
+#define fts5YY_ERROR_ACTION 88
+#define fts5YY_ACCEPT_ACTION 89
+#define fts5YY_NO_ACTION 90
/* The fts5yyzerominor constant is used to initialize instances of
** fts5YYMINORTYPE objects to zero. */
static const fts5YYMINORTYPE fts5yyzerominor = { 0 };
@@ -16996,20 +17216,24 @@
** action integer.
**
** Suppose the action integer is N. Then the action is determined as
** follows
**
-** 0 <= N < fts5YYNSTATE Shift N. That is, push the lookahead
+** 0 <= N <= fts5YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
-** fts5YYNSTATE <= N < fts5YYNSTATE+fts5YYNRULE Reduce by rule N-fts5YYNSTATE.
+** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
+**
+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
+** and fts5YY_MAX_REDUCE
+
+** N == fts5YY_ERROR_ACTION A syntax error has occurred.
**
-** N == fts5YYNSTATE+fts5YYNRULE A syntax error has occurred.
+** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
**
-** N == fts5YYNSTATE+fts5YYNRULE+1 The parser accepts its input.
-**
-** N == fts5YYNSTATE+fts5YYNRULE+2 No such action. Denotes unused
+** N == fts5YY_NO_ACTION No such action. Denotes unused
** slots in the fts5yy_action[] table.
**
** The action table is constructed as a single large table named fts5yy_action[].
** Given state S and lookahead X, the action is computed as
**
@@ -17037,51 +17261,50 @@
** shifting non-terminals after a reduce.
** fts5yy_default[] Default action for each state.
*/
#define fts5YY_ACTTAB_COUNT (78)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 65, 15, 26, 5, 36, 24, 4, 2, 23, 25,
- /* 10 */ 26, 5, 36, 24, 29, 28, 23, 17, 26, 5,
- /* 20 */ 36, 24, 6, 18, 23, 39, 26, 5, 36, 24,
- /* 30 */ 51, 7, 23, 14, 26, 5, 36, 24, 33, 2,
- /* 40 */ 23, 40, 3, 4, 2, 3, 4, 2, 7, 22,
- /* 50 */ 37, 38, 36, 24, 35, 33, 23, 1, 23, 11,
- /* 60 */ 8, 9, 20, 21, 12, 19, 11, 13, 9, 32,
- /* 70 */ 31, 34, 33, 30, 16, 27, 10, 12,
+ /* 0 */ 89, 15, 46, 5, 48, 24, 12, 19, 23, 14,
+ /* 10 */ 46, 5, 48, 24, 20, 21, 23, 43, 46, 5,
+ /* 20 */ 48, 24, 6, 18, 23, 17, 46, 5, 48, 24,
+ /* 30 */ 75, 7, 23, 25, 46, 5, 48, 24, 62, 47,
+ /* 40 */ 23, 48, 24, 7, 11, 23, 9, 3, 4, 2,
+ /* 50 */ 62, 50, 52, 44, 64, 3, 4, 2, 49, 4,
+ /* 60 */ 2, 1, 23, 11, 16, 9, 12, 2, 10, 61,
+ /* 70 */ 53, 59, 62, 60, 22, 13, 55, 8,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
- /* 0 */ 15, 16, 17, 18, 19, 20, 2, 3, 23, 16,
- /* 10 */ 17, 18, 19, 20, 9, 10, 23, 16, 17, 18,
+ /* 0 */ 15, 16, 17, 18, 19, 20, 10, 11, 23, 16,
+ /* 10 */ 17, 18, 19, 20, 23, 24, 23, 16, 17, 18,
/* 20 */ 19, 20, 22, 23, 23, 16, 17, 18, 19, 20,
- /* 30 */ 5, 6, 23, 16, 17, 18, 19, 20, 13, 3,
- /* 40 */ 23, 0, 1, 2, 3, 1, 2, 3, 6, 12,
- /* 50 */ 17, 7, 19, 20, 19, 13, 23, 6, 23, 8,
- /* 60 */ 5, 10, 23, 24, 10, 11, 8, 10, 10, 7,
- /* 70 */ 10, 25, 13, 25, 21, 10, 10, 10,
+ /* 30 */ 5, 6, 23, 16, 17, 18, 19, 20, 13, 17,
+ /* 40 */ 23, 19, 20, 6, 8, 23, 10, 1, 2, 3,
+ /* 50 */ 13, 9, 10, 7, 0, 1, 2, 3, 19, 2,
+ /* 60 */ 3, 6, 23, 8, 21, 10, 10, 3, 10, 25,
+ /* 70 */ 10, 10, 13, 25, 12, 10, 7, 5,
};
-#define fts5YY_SHIFT_USE_DFLT (-1)
+#define fts5YY_SHIFT_USE_DFLT (-5)
#define fts5YY_SHIFT_COUNT (25)
-#define fts5YY_SHIFT_MIN (0)
-#define fts5YY_SHIFT_MAX (67)
+#define fts5YY_SHIFT_MIN (-4)
+#define fts5YY_SHIFT_MAX (72)
static const signed char fts5yy_shift_ofst[] = {
- /* 0 */ 51, 51, 51, 51, 51, 58, 54, 67, 66, 25,
- /* 10 */ 42, 65, 59, 59, 44, 41, 5, 4, 37, 60,
- /* 20 */ 37, 62, 57, 37, 55, 36,
+ /* 0 */ 55, 55, 55, 55, 55, 36, -4, 56, 58, 25,
+ /* 10 */ 37, 60, 59, 59, 46, 54, 42, 57, 62, 61,
+ /* 20 */ 62, 69, 65, 62, 72, 64,
};
#define fts5YY_REDUCE_USE_DFLT (-16)
#define fts5YY_REDUCE_COUNT (13)
#define fts5YY_REDUCE_MIN (-15)
-#define fts5YY_REDUCE_MAX (53)
+#define fts5YY_REDUCE_MAX (48)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -15, 17, 9, 1, -7, 33, 39, 0, 35, 48,
- /* 10 */ 48, 53, 48, 46,
+ /* 0 */ -15, -7, 1, 9, 17, 22, -9, 0, 39, 44,
+ /* 10 */ 44, 43, 44, 48,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 64, 64, 64, 64, 64, 45, 58, 64, 64, 63,
- /* 10 */ 63, 64, 63, 63, 64, 64, 64, 42, 56, 64,
- /* 20 */ 57, 64, 64, 54, 64, 41, 46, 53, 52, 50,
- /* 30 */ 61, 59, 55, 62, 60, 49, 48, 47, 44, 43,
+ /* 0 */ 88, 88, 88, 88, 88, 69, 82, 88, 88, 87,
+ /* 10 */ 87, 88, 87, 87, 88, 88, 88, 66, 80, 88,
+ /* 20 */ 81, 88, 88, 78, 88, 65,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
@@ -17106,13 +17329,17 @@
** (In other words, the "major" token.)
**
** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
*/
struct fts5yyStackEntry {
- fts5YYACTIONTYPE stateno; /* The state-number */
+ fts5YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
fts5YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */
fts5YYMINORTYPE minor; /* The user-supplied minor token value. This
** is the value of the token */
};
@@ -17292,34 +17519,34 @@
case 17: /* cnearset */
case 18: /* exprlist */
{
#line 75 "fts5parse.y"
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy18));
-#line 427 "fts5parse.c"
+#line 446 "fts5parse.c"
}
break;
case 19: /* nearset */
case 22: /* nearphrases */
{
#line 123 "fts5parse.y"
sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy26));
-#line 435 "fts5parse.c"
+#line 454 "fts5parse.c"
}
break;
case 20: /* colset */
case 21: /* colsetlist */
{
#line 105 "fts5parse.y"
sqlite3_free((fts5yypminor->fts5yy38));
-#line 443 "fts5parse.c"
+#line 462 "fts5parse.c"
}
break;
case 23: /* phrase */
{
#line 154 "fts5parse.y"
sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy11));
-#line 450 "fts5parse.c"
+#line 469 "fts5parse.c"
}
break;
default: break; /* If no destructor action specified: do nothing */
}
}
@@ -17402,14 +17629,14 @@
fts5YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
int stateno = pParser->fts5yystack[pParser->fts5yyidx].stateno;
- if( stateno>fts5YY_SHIFT_COUNT
- || (i = fts5yy_shift_ofst[stateno])==fts5YY_SHIFT_USE_DFLT ){
- return fts5yy_default[stateno];
- }
+ if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
+ assert( stateno <= fts5YY_SHIFT_COUNT );
+ i = fts5yy_shift_ofst[stateno];
+ if( i==fts5YY_SHIFT_USE_DFLT ) return fts5yy_default[stateno];
assert( iLookAhead!=fts5YYNOCODE );
i += iLookAhead;
if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
if( iLookAhead>0 ){
#ifdef fts5YYFALLBACK
@@ -17504,16 +17731,38 @@
/* Here code is inserted which will execute if the parser
** stack every overflows */
#line 35 "fts5parse.y"
assert( 0 );
-#line 639 "fts5parse.c"
+#line 658 "fts5parse.c"
sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
}
/*
-** Perform a shift action.
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
+ if( fts5yyTraceFILE ){
+ int i;
+ if( fts5yyNewStatefts5yyidx; i++)
+ fprintf(fts5yyTraceFILE," %s",fts5yyTokenName[fts5yypParser->fts5yystack[i].major]);
+ fprintf(fts5yyTraceFILE,"\n");
+ }else{
+ fprintf(fts5yyTraceFILE,"%sShift *\n",fts5yyTracePrompt);
+ }
+ }
+}
+#else
+# define fts5yyTraceShift(X,Y)
+#endif
+
+/*
+** Perform a shift action. Return the number of errors.
*/
static void fts5yy_shift(
fts5yyParser *fts5yypParser, /* The parser to be shifted */
int fts5yyNewState, /* The new state to shift in */
int fts5yyMajor, /* The major token to shift in */
@@ -17542,20 +17791,11 @@
#endif
fts5yytos = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
fts5yytos->minor = *fts5yypMinor;
-#ifndef NDEBUG
- if( fts5yyTraceFILE && fts5yypParser->fts5yyidx>0 ){
- int i;
- fprintf(fts5yyTraceFILE,"%sShift %d\n",fts5yyTracePrompt,fts5yyNewState);
- fprintf(fts5yyTraceFILE,"%sStack:",fts5yyTracePrompt);
- for(i=1; i<=fts5yypParser->fts5yyidx; i++)
- fprintf(fts5yyTraceFILE," %s",fts5yyTokenName[fts5yypParser->fts5yystack[i].major]);
- fprintf(fts5yyTraceFILE,"\n");
- }
-#endif
+ fts5yyTraceShift(fts5yypParser, fts5yyNewState);
}
/* The following table contains information about every rule that
** is used during the reduce.
*/
@@ -17607,12 +17847,13 @@
sqlite3Fts5ParserARG_FETCH;
fts5yymsp = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
#ifndef NDEBUG
if( fts5yyTraceFILE && fts5yyruleno>=0
&& fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
- fprintf(fts5yyTraceFILE, "%sReduce [%s].\n", fts5yyTracePrompt,
- fts5yyRuleName[fts5yyruleno]);
+ fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+ fprintf(fts5yyTraceFILE, "%sReduce [%s] -> state %d.\n", fts5yyTracePrompt,
+ fts5yyRuleName[fts5yyruleno], fts5yymsp[-fts5yysize].stateno);
}
#endif /* NDEBUG */
/* Silence complaints from purify about fts5yygotominor being uninitialized
** in some cases when it is copied into the stack after the following
@@ -17642,180 +17883,179 @@
** break;
*/
case 0: /* input ::= expr */
#line 69 "fts5parse.y"
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy18); }
-#line 777 "fts5parse.c"
+#line 810 "fts5parse.c"
break;
case 1: /* expr ::= expr AND expr */
#line 78 "fts5parse.y"
{
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
}
-#line 784 "fts5parse.c"
+#line 817 "fts5parse.c"
break;
case 2: /* expr ::= expr OR expr */
#line 81 "fts5parse.y"
{
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
}
-#line 791 "fts5parse.c"
+#line 824 "fts5parse.c"
break;
case 3: /* expr ::= expr NOT expr */
#line 84 "fts5parse.y"
{
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
}
-#line 798 "fts5parse.c"
+#line 831 "fts5parse.c"
break;
case 4: /* expr ::= LP expr RP */
#line 88 "fts5parse.y"
{fts5yygotominor.fts5yy18 = fts5yymsp[-1].minor.fts5yy18;}
-#line 803 "fts5parse.c"
+#line 836 "fts5parse.c"
break;
case 5: /* expr ::= exprlist */
case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
#line 89 "fts5parse.y"
{fts5yygotominor.fts5yy18 = fts5yymsp[0].minor.fts5yy18;}
-#line 809 "fts5parse.c"
+#line 842 "fts5parse.c"
break;
case 7: /* exprlist ::= exprlist cnearset */
#line 92 "fts5parse.y"
{
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-1].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
}
-#line 816 "fts5parse.c"
+#line 849 "fts5parse.c"
break;
case 8: /* cnearset ::= nearset */
#line 96 "fts5parse.y"
{
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
}
-#line 823 "fts5parse.c"
+#line 856 "fts5parse.c"
break;
case 9: /* cnearset ::= colset COLON nearset */
#line 99 "fts5parse.y"
{
sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy26, fts5yymsp[-2].minor.fts5yy38);
fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
}
-#line 831 "fts5parse.c"
+#line 864 "fts5parse.c"
break;
case 10: /* colset ::= LCP colsetlist RCP */
#line 109 "fts5parse.y"
{ fts5yygotominor.fts5yy38 = fts5yymsp[-1].minor.fts5yy38; }
-#line 836 "fts5parse.c"
+#line 869 "fts5parse.c"
break;
case 11: /* colset ::= STRING */
#line 110 "fts5parse.y"
{
fts5yygotominor.fts5yy38 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
-#line 843 "fts5parse.c"
+#line 876 "fts5parse.c"
break;
case 12: /* colsetlist ::= colsetlist STRING */
#line 114 "fts5parse.y"
{
fts5yygotominor.fts5yy38 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy38, &fts5yymsp[0].minor.fts5yy0); }
-#line 849 "fts5parse.c"
+#line 882 "fts5parse.c"
break;
case 13: /* colsetlist ::= STRING */
#line 116 "fts5parse.y"
{
fts5yygotominor.fts5yy38 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
-#line 856 "fts5parse.c"
+#line 889 "fts5parse.c"
break;
case 14: /* nearset ::= phrase */
#line 126 "fts5parse.y"
{ fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
-#line 861 "fts5parse.c"
+#line 894 "fts5parse.c"
break;
case 15: /* nearset ::= STRING LP nearphrases neardist_opt RP */
#line 127 "fts5parse.y"
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy26, &fts5yymsp[-1].minor.fts5yy0);
fts5yygotominor.fts5yy26 = fts5yymsp[-2].minor.fts5yy26;
}
-#line 870 "fts5parse.c"
+#line 903 "fts5parse.c"
break;
case 16: /* nearphrases ::= phrase */
#line 133 "fts5parse.y"
{
fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11);
}
-#line 877 "fts5parse.c"
+#line 910 "fts5parse.c"
break;
case 17: /* nearphrases ::= nearphrases phrase */
#line 136 "fts5parse.y"
{
fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy26, fts5yymsp[0].minor.fts5yy11);
}
-#line 884 "fts5parse.c"
+#line 917 "fts5parse.c"
break;
case 18: /* neardist_opt ::= */
#line 143 "fts5parse.y"
{ fts5yygotominor.fts5yy0.p = 0; fts5yygotominor.fts5yy0.n = 0; }
-#line 889 "fts5parse.c"
+#line 922 "fts5parse.c"
break;
case 19: /* neardist_opt ::= COMMA STRING */
#line 144 "fts5parse.y"
{ fts5yygotominor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
-#line 894 "fts5parse.c"
+#line 927 "fts5parse.c"
break;
case 20: /* phrase ::= phrase PLUS STRING star_opt */
#line 156 "fts5parse.y"
{
fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
}
-#line 901 "fts5parse.c"
+#line 934 "fts5parse.c"
break;
case 21: /* phrase ::= STRING star_opt */
#line 159 "fts5parse.y"
{
fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
}
-#line 908 "fts5parse.c"
+#line 941 "fts5parse.c"
break;
case 22: /* star_opt ::= STAR */
#line 168 "fts5parse.y"
{ fts5yygotominor.fts5yy20 = 1; }
-#line 913 "fts5parse.c"
+#line 946 "fts5parse.c"
break;
case 23: /* star_opt ::= */
#line 169 "fts5parse.y"
{ fts5yygotominor.fts5yy20 = 0; }
-#line 918 "fts5parse.c"
+#line 951 "fts5parse.c"
break;
default:
break;
};
assert( fts5yyruleno>=0 && fts5yyrulenofts5yyidx -= fts5yysize;
fts5yyact = fts5yy_find_reduce_action(fts5yymsp[-fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
- if( fts5yyact < fts5YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
+ if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ if( fts5yyact>fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+ /* If the reduce action popped at least
** one element off the stack, then we can push the new element back
** onto the stack here, and skip the stack overflow test in fts5yy_shift().
** That gives a significant speed improvement. */
if( fts5yysize ){
fts5yypParser->fts5yyidx++;
fts5yymsp -= fts5yysize-1;
fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
fts5yymsp->minor = fts5yygotominor;
- }else
-#endif
- {
+ fts5yyTraceShift(fts5yypParser, fts5yyact);
+ }else{
fts5yy_shift(fts5yypParser,fts5yyact,fts5yygoto,&fts5yygotominor);
}
}else{
- assert( fts5yyact == fts5YYNSTATE + fts5YYNRULE + 1 );
+ assert( fts5yyact == fts5YY_ACCEPT_ACTION );
fts5yy_accept(fts5yypParser);
}
}
/*
@@ -17851,11 +18091,11 @@
#line 30 "fts5parse.y"
sqlite3Fts5ParseError(
pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
);
-#line 986 "fts5parse.c"
+#line 1018 "fts5parse.c"
sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
/*
** The following is executed when the parser accepts
@@ -17938,16 +18178,17 @@
}
#endif
do{
fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
- if( fts5yyact fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,&fts5yyminorunion);
fts5yypParser->fts5yyerrcnt--;
fts5yymajor = fts5YYNOCODE;
- }else if( fts5yyact < fts5YYNSTATE + fts5YYNRULE ){
- fts5yy_reduce(fts5yypParser,fts5yyact-fts5YYNSTATE);
+ }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
+ fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
}else{
assert( fts5yyact == fts5YY_ERROR_ACTION );
#ifdef fts5YYERRORSYMBOL
int fts5yymx;
#endif
@@ -17993,11 +18234,11 @@
while(
fts5yypParser->fts5yyidx >= 0 &&
fts5yymx != fts5YYERRORSYMBOL &&
(fts5yyact = fts5yy_find_reduce_action(
fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].stateno,
- fts5YYERRORSYMBOL)) >= fts5YYNSTATE
+ fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
){
fts5yy_pop_parser_stack(fts5yypParser);
}
if( fts5yypParser->fts5yyidx < 0 || fts5yymajor==0 ){
fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -18043,11 +18284,16 @@
}
fts5yymajor = fts5YYNOCODE;
#endif
}
}while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yyidx>=0 );
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sReturn\n",fts5yyTracePrompt);
+ }
+#endif
return;
}
#endif /* !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_FTS5) */
Index: SQLite.Interop/src/win/interop.h
==================================================================
--- SQLite.Interop/src/win/interop.h
+++ SQLite.Interop/src/win/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.98.0"
+#define INTEROP_VERSION "1.0.99.0"
#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.98.0")]
-[assembly: AssemblyFileVersion("1.0.98.0")]
+[assembly: AssemblyVersion("1.0.99.0")]
+[assembly: AssemblyFileVersion("1.0.99.0")]
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.98.0")]
+[assembly: AssemblyVersion("1.0.99.0")]
#if !PLATFORM_COMPACTFRAMEWORK
-[assembly: AssemblyFileVersion("1.0.98.0")]
+[assembly: AssemblyFileVersion("1.0.99.0")]
#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.98.0";
+ internal const string DesignerVersion = "1.0.99.0";
#endif
///
/// The opaque pointer returned to us by the sqlite provider
///
Index: System.Data.SQLite/UnsafeNativeMethods.cs
==================================================================
--- System.Data.SQLite/UnsafeNativeMethods.cs
+++ System.Data.SQLite/UnsafeNativeMethods.cs
@@ -1317,11 +1317,11 @@
// be used because it provides several workarounds to .NET Compact
// Framework limitations important for proper operation of the core
// System.Data.SQLite functionality (e.g. being able to bind
// parameters and handle column values of types Int64 and Double).
//
- internal const string SQLITE_DLL = "SQLite.Interop.098.dll";
+ internal const string SQLITE_DLL = "SQLite.Interop.099.dll";
#elif SQLITE_STANDARD
//
// NOTE: Otherwise, if the standard SQLite library is enabled, use it.
//
internal const string SQLITE_DLL = "sqlite3";
Index: Tests/version.eagle
==================================================================
--- Tests/version.eagle
+++ Tests/version.eagle
@@ -29,11 +29,11 @@
# the source code files, the built binaries, and the release packages.
# The revision number is reserved for NuGet package versioning.
#
set version(major) 1
set version(minor) 0
-set version(build) 98; # NOTE: Incremented with each release.
+set version(build) 99; # NOTE: Incremented with each release.
set version(revision) 0
###############################################################################
#
Index: readme.htm
==================================================================
--- readme.htm
+++ readme.htm
@@ -3,12 +3,12 @@
ADO.NET SQLite Data Provider
-Version 1.0.98.0 - August 19, 2015
-Using SQLite 3.8.11.1
+Version 1.0.99.0 - October XX, 2015 (release scheduled)
+Using SQLite 3.8.12
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: http://sqlite.phxsoftware.com/
@@ -206,10 +206,16 @@ released versions of System.Data.SQLite.
-Version 1.0.98.0 - August 19, 2015
-Using SQLite 3.8.11.1
+Version 1.0.99.0 - October XX, 2015 (release scheduled)
+Using SQLite 3.8.12
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: http://sqlite.phxsoftware.com/
@@ -206,10 +206,16 @@ released versions of System.Data.SQLite.
Version History
++ 1.0.99.0 - October XX, 2015 (release scheduled) +
+-
+
1.0.98.0 - August 19, 2015
+ 1.0.99.0 - October XX, 2015 (release scheduled) +
+-
+
1.0.98.0 - August 19, 2015