Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update SQLite core library to the latest trunk code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e930be6c752793b784d3e673b666003a |
User & Date: | mistachkin 2012-05-06 18:43:10.321 |
Context
2012-05-08
| ||
23:59 | Update Eagle script library in externals to latest trunk. check-in: 8c9b9e41a6 user: mistachkin tags: trunk | |
2012-05-06
| ||
18:43 | Update SQLite core library to the latest trunk code. check-in: e930be6c75 user: mistachkin tags: trunk | |
2012-05-05
| ||
13:02 | In the test case for ticket [996d13cd87], after the first two interations, use a random number of worker threads accessing the connection pool. check-in: 4a360ab908 user: mistachkin tags: trunk | |
Changes
Changes to Doc/Extra/version.html.
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | </table> </div> <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.81.0 - June XX, 2012</b></p> <ul> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for <a href="http://system.data.sqlite.org/index.html/info/996d13cd87">[996d13cd87]</a>.</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> | > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | </table> </div> <div id="mainSection"> <div id="mainBody"> <h1 class="heading">Version History</h1> <p><b>1.0.81.0 - June XX, 2012</b></p> <ul> <li>Updated to SQLite 3.7.12.</li> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for <a href="http://system.data.sqlite.org/index.html/info/996d13cd87">[996d13cd87]</a>.</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> |
︙ | ︙ |
Changes to SQLite.Interop/props/sqlite3.props.
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="utf-8"?> <!-- * * sqlite3.props - * * Written by Joe Mistachkin. * Released to the public domain, use at your own risk! * --> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <PropertyGroup Label="UserMacros"> | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?xml version="1.0" encoding="utf-8"?> <!-- * * sqlite3.props - * * Written by Joe Mistachkin. * Released to the public domain, use at your own risk! * --> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <PropertyGroup Label="UserMacros"> <SQLITE_MANIFEST_VERSION>3.7.12.0</SQLITE_MANIFEST_VERSION> <SQLITE_RC_VERSION>3,7,12,0</SQLITE_RC_VERSION> <SQLITE_COMMON_DEFINES>SQLITE_THREADSAFE=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1</SQLITE_COMMON_DEFINES> <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES> <SQLITE_WINCE_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_DEFINES> <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1</SQLITE_DEBUG_DEFINES> <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES> <SQLITE_DISABLE_WARNINGS>4018;4055;4057;4090;4100;4127;4132;4146;4152;4210;4232;4244;4245;4389;4701;4706;4996</SQLITE_DISABLE_WARNINGS> <SQLITE_DISABLE_X64_WARNINGS>4232;4267;4306</SQLITE_DISABLE_X64_WARNINGS> |
︙ | ︙ |
Changes to SQLite.Interop/props/sqlite3.vsprops.
︙ | ︙ | |||
10 11 12 13 14 15 16 | <VisualStudioPropertySheet ProjectType="Visual C++" Version="8.00" Name="sqlite3" > <UserMacro Name="SQLITE_MANIFEST_VERSION" | | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <VisualStudioPropertySheet ProjectType="Visual C++" Version="8.00" Name="sqlite3" > <UserMacro Name="SQLITE_MANIFEST_VERSION" Value="3.7.12.0" PerformEnvironmentSet="true" /> <UserMacro Name="SQLITE_RC_VERSION" Value="3,7,12,0" PerformEnvironmentSet="true" /> <UserMacro Name="SQLITE_COMMON_DEFINES" Value="SQLITE_THREADSAFE=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1" PerformEnvironmentSet="true" /> |
︙ | ︙ |
Changes to SQLite.Interop/src/core/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.7.12. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
︙ | ︙ | |||
653 654 655 656 657 658 659 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.12" #define SQLITE_VERSION_NUMBER 3007012 #define SQLITE_SOURCE_ID "2012-05-01 14:21:57 bfa61e781cb442be641486e7e55a1518e888d830" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
2093 2094 2095 2096 2097 2098 2099 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] | | | 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE ** <dd> These options are obsolete and should not be used by new code. ** They are retained for backwards compatibility but are now no-ops. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
︙ | ︙ | |||
6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt> ** <dd>This parameter returns the number of pager cache misses that have ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 | > > > > > > > > > > > > | | 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt> ** <dd>This parameter returns the number of pager cache misses that have ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number |
︙ | ︙ | |||
7519 7520 7521 7522 7523 7524 7525 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, | > > > | > | 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, #ifdef SQLITE_RTREE_INT_ONLY int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), #else int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), #endif void *pContext ); /* ** A pointer to a structure of the following type is passed as the first ** argument to callbacks registered using rtree_geometry_callback(). |
︙ | ︙ | |||
9917 9918 9919 9920 9921 9922 9923 | struct FuncDestructor { int nRef; void (*xDestroy)(void *); void *pUserData; }; /* | | > > | | > > | 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 | struct FuncDestructor { int nRef; void (*xDestroy)(void *); void *pUserData; }; /* ** 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_LIKE 0x01 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */ #define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */ #define SQLITE_FUNC_COUNT 0x10 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x20 /* Built-in coalesce() or ifnull() function */ #define SQLITE_FUNC_LENGTH 0x40 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x80 /* Built-in typeof() function */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are ** used to create the initializers for the FuncDef structures. ** ** FUNCTION(zName, nArg, iArg, bNC, xFunc) ** Used to create a scalar function definition of a function zName |
︙ | ︙ | |||
9952 9953 9954 9955 9956 9957 9958 | ** that accepts nArg arguments and is implemented by a call to C ** function likeFunc. Argument pArg is cast to a (void *) and made ** available as the function user-data (sqlite3_user_data()). The ** FuncDef.flags variable is set to the value passed as the flags ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ | | > > > | 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 | ** that accepts nArg arguments and is implemented by a call to C ** function likeFunc. Argument pArg is cast to a (void *) and made ** available as the function user-data (sqlite3_user_data()). The ** FuncDef.flags variable is set to the value passed as the flags ** parameter. */ #define FUNCTION(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 FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg, 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_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ pArg, 0, xFunc, 0, 0, #zName, 0, 0} #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ |
︙ | ︙ | |||
10182 10183 10184 10185 10186 10187 10188 | Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ #ifndef SQLITE_OMIT_CHECK | | | 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 | Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ 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 #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE VTable *pVTable; /* List of VTable objects. */ int nModuleArg; /* Number of arguments to the module */ |
︙ | ︙ | |||
10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 | ** TK_TRIGGER: 1 -> new, 0 -> old */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 flags2; /* Second set of flags. EP2_... */ u8 op2; /* If a TK_REGISTER, the original value of Expr.op */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif }; | > | 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 | ** TK_TRIGGER: 1 -> new, 0 -> old */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 flags2; /* Second set of flags. EP2_... */ u8 op2; /* If a TK_REGISTER, the original value of Expr.op */ /* If TK_COLUMN, the value of p5 for OP_Column */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ #if SQLITE_MAX_EXPR_DEPTH>0 int nHeight; /* Height of the tree headed by this node */ #endif }; |
︙ | ︙ | |||
10597 10598 10599 10600 10601 10602 10603 | #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */ #define EP_FixedDest 0x0200 /* Result needed in a specific register */ #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */ | | | 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 | #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */ #define EP_FixedDest 0x0200 /* Result needed in a specific register */ #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Hint 0x1000 /* Not used */ #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ #define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ #define EP_Static 0x8000 /* Held in memory not obtained from malloc() */ /* ** The following are the meanings of bits in the Expr.flags2 field. */ |
︙ | ︙ | |||
10911 10912 10913 10914 10915 10916 10917 | SrcList *pSrcList; /* One or more tables used to resolve names */ ExprList *pEList; /* Optional list of named expressions */ int nRef; /* Number of names resolved by this context */ int nErr; /* Number of errors encountered while resolving names */ u8 allowAgg; /* Aggregate functions allowed here */ u8 hasAgg; /* True if aggregates are seen */ u8 isCheck; /* True if resolving names in a CHECK constraint */ | < | 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 | SrcList *pSrcList; /* One or more tables used to resolve names */ ExprList *pEList; /* Optional list of named expressions */ int nRef; /* Number of names resolved by this context */ int nErr; /* Number of errors encountered while resolving names */ u8 allowAgg; /* Aggregate functions allowed here */ u8 hasAgg; /* True if aggregates are seen */ u8 isCheck; /* True if resolving names in a CHECK constraint */ AggInfo *pAggInfo; /* Information about aggregates at this level */ NameContext *pNext; /* Next outer name context. NULL for outermost */ }; /* ** An instance of the following structure contains all information ** needed to generate code for a single SELECT statement. |
︙ | ︙ | |||
11116 11117 11118 11119 11120 11121 11122 11123 11124 11125 11126 11127 11128 11129 | yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ /* Information used while coding trigger programs. */ | > | 11139 11140 11141 11142 11143 11144 11145 11146 11147 11148 11149 11150 11151 11152 11153 | yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ Token constraintName;/* Name of the constraint currently being parsed */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ /* Information used while coding trigger programs. */ |
︙ | ︙ | |||
11184 11185 11186 11187 11188 11189 11190 | */ struct AuthContext { const char *zAuthContext; /* Put saved Parse.zAuthContext here */ Parse *pParse; /* The Parse structure */ }; /* | | > > | 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 | */ struct AuthContext { const char *zAuthContext; /* Put saved Parse.zAuthContext here */ Parse *pParse; /* The Parse structure */ }; /* ** Bitfield flags for P5 value in various opcodes. */ #define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */ #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ /* * Each trigger present in the database schema is stored as an instance of * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. * 1. In the "trigHash" hash table (part of the sqlite3* that represents the |
︙ | ︙ | |||
11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 | struct Walker { int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ Parse *pParse; /* Parser context. */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int i; /* Integer value */ } u; }; /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); | > | 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 | struct Walker { int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ Parse *pParse; /* Parser context. */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int i; /* Integer value */ SrcList *pSrcList; /* FROM clause */ } u; }; /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); |
︙ | ︙ | |||
11675 11676 11677 11678 11679 11680 11681 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *); #endif SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); | | | 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *); #endif SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**,ExprList*,u16); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); 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 sqlite3ExprCodeCopy(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); |
︙ | ︙ | |||
11742 11743 11744 11745 11746 11747 11748 | SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); | | | 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 | SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void); SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); |
︙ | ︙ | |||
13507 13508 13509 13510 13511 13512 13513 | /* ** Set *pCurrent to the total cache hits or misses encountered by all ** pagers the database handle is connected to. *pHighwater is always set ** to zero. */ case SQLITE_DBSTATUS_CACHE_HIT: | | > > | 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 | /* ** Set *pCurrent to the total cache hits or misses encountered by all ** pagers the database handle is connected to. *pHighwater is always set ** to zero. */ case SQLITE_DBSTATUS_CACHE_HIT: case SQLITE_DBSTATUS_CACHE_MISS: case SQLITE_DBSTATUS_CACHE_WRITE:{ int i; int nRet = 0; assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt ){ Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); } } |
︙ | ︙ | |||
24968 24969 24970 24971 24972 24973 24974 | ** Default permissions when creating a new file */ #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 #endif /* | | | | 24997 24998 24999 25000 25001 25002 25003 25004 25005 25006 25007 25008 25009 25010 25011 25012 | ** Default permissions when creating a new file */ #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 #endif /* ** Default permissions when creating auto proxy dir */ #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 #endif /* ** Maximum supported path-length. */ |
︙ | ︙ | |||
25523 25524 25525 25526 25527 25528 25529 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; } return 0; } /* ** Invoke open(). Do so multiple times, until it either succeeds or | | | > > > > > > | > > > | | 25552 25553 25554 25555 25556 25557 25558 25559 25560 25561 25562 25563 25564 25565 25566 25567 25568 25569 25570 25571 25572 25573 25574 25575 25576 25577 25578 25579 25580 25581 25582 25583 25584 25585 25586 25587 25588 25589 25590 25591 25592 25593 25594 25595 25596 25597 25598 25599 25600 25601 25602 25603 25604 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; } return 0; } /* ** Invoke open(). Do so multiple times, until it either succeeds or ** fails for some reason other than EINTR. ** ** If the file creation mode "m" is 0 then set it to the default for ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally ** 0644) as modified by the system umask. If m is not 0, then ** make the file creation mode be exactly m ignoring the umask. ** ** The m parameter will be non-zero only when creating -wal, -journal, ** and -shm files. We want those files to have *exactly* the same ** permissions as their original database, unadulterated by the umask. ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a ** transaction crashes and leaves behind hot journals, then any ** process that is able to write to the database will also be able to ** recover the hot journals. */ static int robust_open(const char *z, int f, mode_t m){ int fd; mode_t m2; mode_t origM = 0; if( m==0 ){ m2 = SQLITE_DEFAULT_FILE_PERMISSIONS; }else{ m2 = m; origM = osUmask(0); } do{ #if defined(O_CLOEXEC) fd = osOpen(z,f|O_CLOEXEC,m2); #else fd = osOpen(z,f,m2); #endif }while( fd<0 && errno==EINTR ); if( m ){ osUmask(origM); } #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); #endif return fd; } /* ** Helper functions to obtain and relinquish the global mutex. The ** global mutex is used to protect the unixInodeInfo and ** vxworksFileId objects used by this file, all of which may be ** shared by multiple threads. |
︙ | ︙ | |||
28347 28348 28349 28350 28351 28352 28353 | sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ | < < < | 28385 28386 28387 28388 28389 28390 28391 28392 28393 28394 28395 28396 28397 28398 | sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); } } *pFd = fd; return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); } |
︙ | ︙ | |||
28432 28433 28434 28435 28436 28437 28438 | SimulateIOError( return SQLITE_IOERR_TRUNCATE ); /* If the user has configured a chunk-size for this file, truncate the ** file so that it consists of an integer number of chunks (i.e. the ** actual file size after the operation may be larger than the requested ** size). */ | | | 28467 28468 28469 28470 28471 28472 28473 28474 28475 28476 28477 28478 28479 28480 28481 | SimulateIOError( return SQLITE_IOERR_TRUNCATE ); /* If the user has configured a chunk-size for this file, truncate the ** file so that it consists of an integer number of chunks (i.e. the ** actual file size after the operation may be larger than the requested ** size). */ if( pFile->szChunk>0 ){ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } rc = robust_ftruncate(pFile->h, (off_t)nByte); if( rc ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); |
︙ | ︙ | |||
30194 30195 30196 30197 30198 30199 30200 | } #if SQLITE_ENABLE_LOCKING_STYLE else{ p->openFlags = openFlags; } #endif | < < < < | 30229 30230 30231 30232 30233 30234 30235 30236 30237 30238 30239 30240 30241 30242 | } #if SQLITE_ENABLE_LOCKING_STYLE else{ p->openFlags = openFlags; } #endif noLock = eType!=SQLITE_OPEN_MAIN_DB; #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE if( fstatfs(fd, &fsInfo) == -1 ){ ((unixFile*)pFile)->lastErrno = errno; robust_close(p, fd, __LINE__); |
︙ | ︙ | |||
33725 33726 33727 33728 33729 33730 33731 33732 33733 33734 33735 33736 33737 33738 33739 33740 33741 33742 33743 33744 33745 33746 33747 33748 33749 33750 33751 33752 33753 33754 33755 33756 33757 33758 33759 33760 33761 33762 33763 33764 33765 33766 33767 | ){ osSleep(100); /* Wait a little before trying again */ } sqlite3_free(pFile->zDeleteOnClose); } #endif OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); OpenCounter(-1); return rc ? SQLITE_OK : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), "winClose", pFile->zPath); } /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ static int winRead( sqlite3_file *id, /* File to read from */ void *pBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ winFile *pFile = (winFile*)id; /* file handle */ DWORD nRead; /* Number of bytes actually read from file */ int nRetry = 0; /* Number of retrys */ assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ DWORD lastErrno; if( retryIoerr(&nRetry, &lastErrno) ) continue; pFile->lastErrno = lastErrno; return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, "winRead", pFile->zPath); } logIoerr(nRetry); | > > > > > > > > > > > > > > | 33756 33757 33758 33759 33760 33761 33762 33763 33764 33765 33766 33767 33768 33769 33770 33771 33772 33773 33774 33775 33776 33777 33778 33779 33780 33781 33782 33783 33784 33785 33786 33787 33788 33789 33790 33791 33792 33793 33794 33795 33796 33797 33798 33799 33800 33801 33802 33803 33804 33805 33806 33807 33808 33809 33810 33811 33812 | ){ osSleep(100); /* Wait a little before trying again */ } sqlite3_free(pFile->zDeleteOnClose); } #endif OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); if( rc ){ pFile->h = NULL; } OpenCounter(-1); return rc ? SQLITE_OK : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), "winClose", pFile->zPath); } /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ static int winRead( sqlite3_file *id, /* File to read from */ void *pBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ #if !SQLITE_OS_WINCE OVERLAPPED overlapped; /* The offset for ReadFile. */ #endif winFile *pFile = (winFile*)id; /* file handle */ DWORD nRead; /* Number of bytes actually read from file */ int nRetry = 0; /* Number of retrys */ assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); #if SQLITE_OS_WINCE if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ #else memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && osGetLastError()!=ERROR_HANDLE_EOF ){ #endif DWORD lastErrno; if( retryIoerr(&nRetry, &lastErrno) ) continue; pFile->lastErrno = lastErrno; return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, "winRead", pFile->zPath); } logIoerr(nRetry); |
︙ | ︙ | |||
33780 33781 33782 33783 33784 33785 33786 | */ static int winWrite( sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ | | > > > > > > > > > > > > > > > > > | > > > > > > > > | 33825 33826 33827 33828 33829 33830 33831 33832 33833 33834 33835 33836 33837 33838 33839 33840 33841 33842 33843 33844 33845 33846 33847 33848 33849 33850 33851 33852 33853 33854 33855 33856 33857 33858 33859 33860 33861 33862 33863 33864 33865 33866 33867 33868 33869 33870 33871 33872 33873 33874 33875 33876 33877 33878 33879 33880 33881 33882 33883 33884 33885 33886 33887 | */ static int winWrite( sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ int rc = 0; /* True if error has occured, else false */ winFile *pFile = (winFile*)id; /* File handle */ int nRetry = 0; /* Number of retries */ assert( amt>0 ); assert( pFile ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); #if SQLITE_OS_WINCE rc = seekWinFile(pFile, offset); if( rc==0 ){ #else { #endif #if !SQLITE_OS_WINCE OVERLAPPED overlapped; /* The offset for WriteFile. */ #endif u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ #if !SQLITE_OS_WINCE memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); #endif while( nRem>0 ){ #if SQLITE_OS_WINCE if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ #else if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ #endif if( retryIoerr(&nRetry, &lastErrno) ) continue; break; } if( nWrite<=0 ){ lastErrno = osGetLastError(); break; } #if !SQLITE_OS_WINCE offset += nWrite; overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); #endif aRem += nWrite; nRem -= nWrite; } if( nRem>0 ){ pFile->lastErrno = lastErrno; rc = 1; } |
︙ | ︙ | |||
37935 37936 37937 37938 37939 37940 37941 37942 37943 37944 37945 37946 37947 37948 | ** The number of rowset entries per allocation chunk. */ #define ROWSET_ENTRY_PER_CHUNK \ ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) /* ** Each entry in a RowSet is an instance of the following object. */ struct RowSetEntry { i64 v; /* ROWID value for this entry */ struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ }; | > > > > > | 38005 38006 38007 38008 38009 38010 38011 38012 38013 38014 38015 38016 38017 38018 38019 38020 38021 38022 38023 | ** The number of rowset entries per allocation chunk. */ #define ROWSET_ENTRY_PER_CHUNK \ ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) /* ** Each entry in a RowSet is an instance of the following object. ** ** This same object is reused to store a linked list of trees of RowSetEntry ** objects. In that alternative use, pRight points to the next entry ** in the list, pLeft points to the tree, and v is unused. The ** RowSet.pForest value points to the head of this forest list. */ struct RowSetEntry { i64 v; /* ROWID value for this entry */ struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ }; |
︙ | ︙ | |||
37964 37965 37966 37967 37968 37969 37970 | */ struct RowSet { struct RowSetChunk *pChunk; /* List of all chunk allocations */ sqlite3 *db; /* The database connection */ struct RowSetEntry *pEntry; /* List of entries using pRight */ struct RowSetEntry *pLast; /* Last entry on the pEntry list */ struct RowSetEntry *pFresh; /* Source of new entry objects */ | | | > > > > > > | | | > > | > > > > > > > > > > > > > > > > > > > > > > > < < < < < < | < < < > | | | | | | < | | 38039 38040 38041 38042 38043 38044 38045 38046 38047 38048 38049 38050 38051 38052 38053 38054 38055 38056 38057 38058 38059 38060 38061 38062 38063 38064 38065 38066 38067 38068 38069 38070 38071 38072 38073 38074 38075 38076 38077 38078 38079 38080 38081 38082 38083 38084 38085 38086 38087 38088 38089 38090 38091 38092 38093 38094 38095 38096 38097 38098 38099 38100 38101 38102 38103 38104 38105 38106 38107 38108 38109 38110 38111 38112 38113 38114 38115 38116 38117 38118 38119 38120 38121 38122 38123 38124 38125 38126 38127 38128 38129 38130 38131 38132 38133 38134 38135 38136 38137 38138 38139 38140 38141 38142 38143 38144 38145 38146 38147 38148 38149 38150 38151 38152 38153 38154 38155 38156 38157 38158 38159 38160 38161 38162 38163 38164 38165 38166 38167 38168 38169 38170 38171 38172 | */ struct RowSet { struct RowSetChunk *pChunk; /* List of all chunk allocations */ sqlite3 *db; /* The database connection */ struct RowSetEntry *pEntry; /* List of entries using pRight */ struct RowSetEntry *pLast; /* Last entry on the pEntry list */ struct RowSetEntry *pFresh; /* Source of new entry objects */ struct RowSetEntry *pForest; /* List of binary trees of entries */ u16 nFresh; /* Number of objects on pFresh */ u8 rsFlags; /* Various flags */ u8 iBatch; /* Current insert batch */ }; /* ** Allowed values for RowSet.rsFlags */ #define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ #define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ /* ** Turn bulk memory into a RowSet object. N bytes of memory ** are available at pSpace. The db pointer is used as a memory context ** for any subsequent allocations that need to occur. ** Return a pointer to the new RowSet object. ** ** It must be the case that N is sufficient to make a Rowset. If not ** an assertion fault occurs. ** ** If N is larger than the minimum, use the surplus as an initial ** allocation of entries available to be filled. */ SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ RowSet *p; assert( N >= ROUND8(sizeof(*p)) ); p = pSpace; p->pChunk = 0; p->db = db; p->pEntry = 0; p->pLast = 0; p->pForest = 0; p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); p->rsFlags = ROWSET_SORTED; p->iBatch = 0; return p; } /* ** Deallocate all chunks from a RowSet. This frees all memory that ** the RowSet has allocated over its lifetime. This routine is ** the destructor for the RowSet. */ SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ struct RowSetChunk *pChunk, *pNextChunk; for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ pNextChunk = pChunk->pNextChunk; sqlite3DbFree(p->db, pChunk); } p->pChunk = 0; p->nFresh = 0; p->pEntry = 0; p->pLast = 0; p->pForest = 0; p->rsFlags = ROWSET_SORTED; } /* ** Allocate a new RowSetEntry object that is associated with the ** given RowSet. Return a pointer to the new and completely uninitialized ** objected. ** ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this ** routine returns NULL. */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); if( p->nFresh==0 ){ struct RowSetChunk *pNew; pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); if( pNew==0 ){ return 0; } pNew->pNextChunk = p->pChunk; p->pChunk = pNew; p->pFresh = pNew->aEntry; p->nFresh = ROWSET_ENTRY_PER_CHUNK; } p->nFresh--; return p->pFresh++; } /* ** Insert a new value into a RowSet. ** ** The mallocFailed flag of the database connection is set if a ** memory allocation fails. */ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ struct RowSetEntry *pEntry; /* The new entry */ struct RowSetEntry *pLast; /* The last prior entry */ /* This routine is never called after sqlite3RowSetNext() */ assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); pEntry = rowSetEntryAlloc(p); if( pEntry==0 ) return; pEntry->v = rowid; pEntry->pRight = 0; pLast = p->pLast; if( pLast ){ if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){ p->rsFlags &= ~ROWSET_SORTED; } pLast->pRight = pEntry; }else{ p->pEntry = pEntry; } p->pLast = pEntry; } /* ** Merge two lists of RowSetEntry objects. Remove duplicates. ** ** The input lists are connected via pRight pointers and are ** assumed to each already be in sorted order. */ static struct RowSetEntry *rowSetEntryMerge( struct RowSetEntry *pA, /* First sorted list to be merged */ struct RowSetEntry *pB /* Second sorted list to be merged */ ){ struct RowSetEntry head; struct RowSetEntry *pTail; pTail = &head; |
︙ | ︙ | |||
38095 38096 38097 38098 38099 38100 38101 | assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); pTail->pRight = pB; } return head.pRight; } /* | | > | | < < | < | | | | > | | | < < | 38192 38193 38194 38195 38196 38197 38198 38199 38200 38201 38202 38203 38204 38205 38206 38207 38208 38209 38210 38211 38212 38213 38214 38215 38216 38217 38218 38219 38220 38221 38222 38223 38224 38225 38226 38227 38228 | assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); pTail->pRight = pB; } return head.pRight; } /* ** Sort all elements on the list of RowSetEntry objects into order of ** increasing v. */ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ unsigned int i; struct RowSetEntry *pNext, *aBucket[40]; memset(aBucket, 0, sizeof(aBucket)); while( pIn ){ pNext = pIn->pRight; pIn->pRight = 0; for(i=0; aBucket[i]; i++){ pIn = rowSetEntryMerge(aBucket[i], pIn); aBucket[i] = 0; } aBucket[i] = pIn; pIn = pNext; } pIn = 0; for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){ pIn = rowSetEntryMerge(pIn, aBucket[i]); } return pIn; } /* ** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects. ** Convert this tree into a linked list connected by the pRight pointers ** and return pointers to the first and last elements of the new list. |
︙ | ︙ | |||
38214 38215 38216 38217 38218 38219 38220 | p->pLeft = pLeft; p->pRight = rowSetNDeepTree(&pList, iDepth); } return p; } /* | | | | > | > > | > > > > > > > > > > > | | | < | | > > > > > > > | > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > | > > > | > > > > > > > | > | | | | | | | > | 38308 38309 38310 38311 38312 38313 38314 38315 38316 38317 38318 38319 38320 38321 38322 38323 38324 38325 38326 38327 38328 38329 38330 38331 38332 38333 38334 38335 38336 38337 38338 38339 38340 38341 38342 38343 38344 38345 38346 38347 38348 38349 38350 38351 38352 38353 38354 38355 38356 38357 38358 38359 38360 38361 38362 38363 38364 38365 38366 38367 38368 38369 38370 38371 38372 38373 38374 38375 38376 38377 38378 38379 38380 38381 38382 38383 38384 38385 38386 38387 38388 38389 38390 38391 38392 38393 38394 38395 38396 38397 38398 38399 38400 38401 38402 38403 38404 38405 38406 38407 38408 38409 38410 38411 38412 38413 38414 38415 38416 38417 38418 38419 38420 38421 38422 38423 38424 38425 38426 38427 38428 38429 38430 38431 38432 38433 38434 38435 38436 38437 38438 38439 38440 38441 38442 38443 38444 | p->pLeft = pLeft; p->pRight = rowSetNDeepTree(&pList, iDepth); } return p; } /* ** Take all the entries on p->pEntry and on the trees in p->pForest and ** sort them all together into one big ordered list on p->pEntry. ** ** This routine should only be called once in the life of a RowSet. */ static void rowSetToList(RowSet *p){ /* This routine is called only once */ assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); if( (p->rsFlags & ROWSET_SORTED)==0 ){ p->pEntry = rowSetEntrySort(p->pEntry); } /* While this module could theoretically support it, sqlite3RowSetNext() ** is never called after sqlite3RowSetText() for the same RowSet. So ** there is never a forest to deal with. Should this change, simply ** remove the assert() and the #if 0. */ assert( p->pForest==0 ); #if 0 while( p->pForest ){ struct RowSetEntry *pTree = p->pForest->pLeft; if( pTree ){ struct RowSetEntry *pHead, *pTail; rowSetTreeToList(pTree, &pHead, &pTail); p->pEntry = rowSetEntryMerge(p->pEntry, pHead); } p->pForest = p->pForest->pRight; } #endif p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */ } /* ** Extract the smallest element from the RowSet. ** Write the element into *pRowid. Return 1 on success. Return ** 0 if the RowSet is already empty. ** ** After this routine has been called, the sqlite3RowSetInsert() ** routine may not be called again. */ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ assert( p!=0 ); /* Merge the forest into a single sorted list on first call */ if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p); /* Return the next entry on the list */ if( p->pEntry ){ *pRowid = p->pEntry->v; p->pEntry = p->pEntry->pRight; if( p->pEntry==0 ){ sqlite3RowSetClear(p); } return 1; }else{ return 0; } } /* ** Check to see if element iRowid was inserted into the the rowset as ** part of any insert batch prior to iBatch. Return 1 or 0. ** ** If this is the first test of a new batch and if there exist entires ** on pRowSet->pEntry, then sort those entires into the forest at ** pRowSet->pForest so that they can be tested. */ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ struct RowSetEntry *p, *pTree; /* This routine is never called after sqlite3RowSetNext() */ assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); /* Sort entries into the forest on the first test of a new batch */ if( iBatch!=pRowSet->iBatch ){ p = pRowSet->pEntry; if( p ){ struct RowSetEntry **ppPrevTree = &pRowSet->pForest; if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ p = rowSetEntrySort(p); } for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ ppPrevTree = &pTree->pRight; if( pTree->pLeft==0 ){ pTree->pLeft = rowSetListToTree(p); break; }else{ struct RowSetEntry *pAux, *pTail; rowSetTreeToList(pTree->pLeft, &pAux, &pTail); pTree->pLeft = 0; p = rowSetEntryMerge(pAux, p); } } if( pTree==0 ){ *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); if( pTree ){ pTree->v = 0; pTree->pRight = 0; pTree->pLeft = rowSetListToTree(p); } } pRowSet->pEntry = 0; pRowSet->pLast = 0; pRowSet->rsFlags |= ROWSET_SORTED; } pRowSet->iBatch = iBatch; } /* Test to see if the iRowid value appears anywhere in the forest. ** Return 1 if it does and 0 if not. */ for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ p = pTree->pLeft; while( p ){ if( p->v<iRowid ){ p = p->pRight; }else if( p->v>iRowid ){ p = p->pLeft; }else{ return 1; } } } return 0; } /************** End of rowset.c **********************************************/ /************** Begin file pager.c *******************************************/ |
︙ | ︙ | |||
39092 39093 39094 39095 39096 39097 39098 | int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ | | | > > > > > > > > > | 39248 39249 39250 39251 39252 39253 39254 39255 39256 39257 39258 39259 39260 39261 39262 39263 39264 39265 39266 39267 39268 39269 39270 39271 39272 39273 39274 39275 39276 39277 39278 39279 39280 39281 39282 39283 39284 39285 39286 39287 39288 39289 | int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ int aStat[3]; /* Total cache hits, misses and writes */ #ifdef SQLITE_TEST int nRead; /* Database pages read */ #endif void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ #ifdef SQLITE_HAS_CODEC void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ void (*xCodecFree)(void*); /* Destructor for the codec */ void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif }; /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). */ #define PAGER_STAT_HIT 0 #define PAGER_STAT_MISS 1 #define PAGER_STAT_WRITE 2 /* ** The following global variables hold counters used for ** testing purposes only. These variables do not exist in ** a non-testing build. These variables are not thread-safe. */ #ifdef SQLITE_TEST SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ |
︙ | ︙ | |||
41393 41394 41395 41396 41397 41398 41399 41400 41401 41402 41403 41404 41405 41406 41407 41408 41409 41410 41411 41412 41413 41414 41415 41416 41417 41418 41419 | static int pagerWalFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ Pgno nTruncate, /* Database size after this commit */ int isCommit /* True if this is a commit */ ){ int rc; /* Return code */ #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) PgHdr *p; /* For looping over pages */ #endif assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG /* Verify that the page list is in accending order */ for(p=pList; p && p->pDirty; p=p->pDirty){ assert( p->pgno < p->pDirty->pgno ); } #endif if( isCommit ){ /* If a WAL transaction is being committed, there is no point in writing ** any pages with page numbers greater than nTruncate into the WAL file. ** They will never be read by any client. So remove them from the pDirty ** list here. */ PgHdr *p; PgHdr **ppNext = &pList; | > > > | | > > | > > > > | 41558 41559 41560 41561 41562 41563 41564 41565 41566 41567 41568 41569 41570 41571 41572 41573 41574 41575 41576 41577 41578 41579 41580 41581 41582 41583 41584 41585 41586 41587 41588 41589 41590 41591 41592 41593 41594 41595 41596 41597 41598 41599 41600 41601 41602 41603 41604 41605 | static int pagerWalFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ Pgno nTruncate, /* Database size after this commit */ int isCommit /* True if this is a commit */ ){ int rc; /* Return code */ int nList; /* Number of pages in pList */ #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES) PgHdr *p; /* For looping over pages */ #endif assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG /* Verify that the page list is in accending order */ for(p=pList; p && p->pDirty; p=p->pDirty){ assert( p->pgno < p->pDirty->pgno ); } #endif assert( pList->pDirty==0 || isCommit ); if( isCommit ){ /* If a WAL transaction is being committed, there is no point in writing ** any pages with page numbers greater than nTruncate into the WAL file. ** They will never be read by any client. So remove them from the pDirty ** list here. */ PgHdr *p; PgHdr **ppNext = &pList; nList = 0; for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ if( p->pgno<=nTruncate ){ ppNext = &p->pDirty; nList++; } } assert( pList ); }else{ nList = 1; } pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); rc = sqlite3WalFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ PgHdr *p; |
︙ | ︙ | |||
42485 42486 42487 42488 42489 42490 42491 42492 42493 42494 42495 42496 42497 42498 42499 | */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); } if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } /* Update any backup objects copying the contents of this pager. */ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); PAGERTRACE(("STORE %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pList))); IOTRACE(("PGOUT %p %d\n", pPager, pgno)); PAGER_INCR(sqlite3_pager_writedb_count); | > < | 42659 42660 42661 42662 42663 42664 42665 42666 42667 42668 42669 42670 42671 42672 42673 42674 42675 42676 42677 42678 42679 42680 42681 | */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); } if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } pPager->aStat[PAGER_STAT_WRITE]++; /* Update any backup objects copying the contents of this pager. */ sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); PAGERTRACE(("STORE %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pList))); IOTRACE(("PGOUT %p %d\n", pPager, pgno)); PAGER_INCR(sqlite3_pager_writedb_count); }else{ PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); } pager_set_pagehash(pList); pList = pList->pDirty; } |
︙ | ︙ | |||
43451 43452 43453 43454 43455 43456 43457 | assert( (*ppPage)->pgno==pgno ); assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); if( (*ppPage)->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); | | | 43625 43626 43627 43628 43629 43630 43631 43632 43633 43634 43635 43636 43637 43638 43639 | assert( (*ppPage)->pgno==pgno ); assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); if( (*ppPage)->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); pPager->aStat[PAGER_STAT_HIT]++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to ** be initialized. */ pPg = *ppPage; |
︙ | ︙ | |||
43493 43494 43495 43496 43497 43498 43499 | testcase( rc==SQLITE_NOMEM ); sqlite3EndBenignMalloc(); } memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ assert( pPg->pPager==pPager ); | | | 43667 43668 43669 43670 43671 43672 43673 43674 43675 43676 43677 43678 43679 43680 43681 | testcase( rc==SQLITE_NOMEM ); sqlite3EndBenignMalloc(); } memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ assert( pPg->pPager==pPager ); pPager->aStat[PAGER_STAT_MISS]++; rc = readDbPage(pPg); if( rc!=SQLITE_OK ){ goto pager_acquire_err; } } pager_set_pagehash(pPg); } |
︙ | ︙ | |||
44078 44079 44080 44081 44082 44083 44084 44085 44086 44087 44088 44089 44090 44091 | /* If running in direct mode, write the contents of page 1 to the file. */ if( DIRECT_MODE ){ const void *zBuf; assert( pPager->dbFileSize>0 ); CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); } if( rc==SQLITE_OK ){ pPager->changeCountDone = 1; } }else{ pPager->changeCountDone = 1; } | > | 44252 44253 44254 44255 44256 44257 44258 44259 44260 44261 44262 44263 44264 44265 44266 | /* If running in direct mode, write the contents of page 1 to the file. */ if( DIRECT_MODE ){ const void *zBuf; assert( pPager->dbFileSize>0 ); CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); pPager->aStat[PAGER_STAT_WRITE]++; } if( rc==SQLITE_OK ){ pPager->changeCountDone = 1; } }else{ pPager->changeCountDone = 1; } |
︙ | ︙ | |||
44521 44522 44523 44524 44525 44526 44527 | static int a[11]; a[0] = sqlite3PcacheRefCount(pPager->pPCache); a[1] = sqlite3PcachePagecount(pPager->pPCache); a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; | | | | < > < < < < | > > > | | | 44696 44697 44698 44699 44700 44701 44702 44703 44704 44705 44706 44707 44708 44709 44710 44711 44712 44713 44714 44715 44716 44717 44718 44719 44720 44721 44722 44723 44724 44725 44726 44727 44728 44729 44730 44731 44732 44733 44734 44735 44736 44737 44738 44739 | static int a[11]; a[0] = sqlite3PcacheRefCount(pPager->pPCache); a[1] = sqlite3PcachePagecount(pPager->pPCache); a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; a[6] = pPager->aStat[PAGER_STAT_HIT]; a[7] = pPager->aStat[PAGER_STAT_MISS]; a[8] = 0; /* Used to be pPager->nOvfl */ a[9] = pPager->nRead; a[10] = pPager->aStat[PAGER_STAT_WRITE]; return a; } #endif /* ** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or ** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the ** current cache hit or miss count, according to the value of eStat. If the ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS || eStat==SQLITE_DBSTATUS_CACHE_WRITE ); assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 ); *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT]; if( reset ){ pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0; } } /* ** Return true if this is an in-memory pager. */ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ |
︙ | ︙ | |||
49064 49065 49066 49067 49068 49069 49070 49071 49072 49073 49074 49075 | #define ISAUTOVACUUM 0 #endif /* ** This structure is passed around through all the sanity checking routines ** in order to keep track of some global state information. */ typedef struct IntegrityCk IntegrityCk; struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ | > > > > > > | | 49238 49239 49240 49241 49242 49243 49244 49245 49246 49247 49248 49249 49250 49251 49252 49253 49254 49255 49256 49257 49258 49259 49260 49261 49262 49263 | #define ISAUTOVACUUM 0 #endif /* ** This structure is passed around through all the sanity checking routines ** in order to keep track of some global state information. ** ** The aRef[] array is allocated so that there is 1 bit for each page in ** the database. As the integrity-check proceeds, for each page used in ** the database the corresponding bit is set. This allows integrity-check to ** detect pages that are used twice and orphaned pages (both of which ** indicate corruption). */ typedef struct IntegrityCk IntegrityCk; struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ Pgno nPage; /* Number of pages in the database */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int mallocFailed; /* A memory allocation error has occurred */ StrAccum errMsg; /* Accumulate the error message text here */ }; |
︙ | ︙ | |||
56149 56150 56151 56152 56153 56154 56155 | /* Assert that the caller has been consistent. If this cursor was opened ** expecting an index b-tree, then the caller should be inserting blob ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ assert( (pKey==0)==(pCur->pKeyInfo==0) ); | < < < < < < < > > > > > > > > | 56329 56330 56331 56332 56333 56334 56335 56336 56337 56338 56339 56340 56341 56342 56343 56344 56345 56346 56347 56348 56349 56350 56351 56352 56353 56354 56355 56356 56357 56358 56359 56360 56361 56362 56363 | /* Assert that the caller has been consistent. If this cursor was opened ** expecting an index b-tree, then the caller should be inserting blob ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ assert( (pKey==0)==(pCur->pKeyInfo==0) ); /* Save the positions of any other cursors open on this table. ** ** In some cases, the call to btreeMoveto() below is a no-op. For ** example, when inserting data into a table with auto-generated integer ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the ** integer key to use. It then calls this function to actually insert the ** data into the intkey B-Tree. In this case btreeMoveto() recognizes ** that the cursor is already where it needs to be and returns without ** doing any work. To avoid thwarting these optimizations, it is important ** not to clear the cursor here. */ rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced (assuming this is a replace ** operation - if it is not, the following is a no-op). */ if( pCur->pKeyInfo==0 ){ invalidateIncrblobCursors(p, nKey, 0); } if( !loc ){ rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc); if( rc ) return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; |
︙ | ︙ | |||
56279 56280 56281 56282 56283 56284 56285 | if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) || NEVER(pCur->eState!=CURSOR_VALID) ){ return SQLITE_ERROR; /* Something has gone awry. */ } | < < < < < < | 56460 56461 56462 56463 56464 56465 56466 56467 56468 56469 56470 56471 56472 56473 | if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) || NEVER(pCur->eState!=CURSOR_VALID) ){ return SQLITE_ERROR; /* Something has gone awry. */ } iCellDepth = pCur->iPage; iCellIdx = pCur->aiIdx[iCellDepth]; pPage = pCur->apPage[iCellDepth]; pCell = findCell(pPage, iCellIdx); /* If the page containing the entry to delete is not a leaf page, move ** the cursor to the largest entry in the tree that is smaller than |
︙ | ︙ | |||
56310 56311 56312 56313 56314 56315 56316 56317 56318 56319 56320 56321 56322 56323 | /* Save the positions of any other cursors open on this table before ** making any modifications. Make the page containing the entry to be ** deleted writable. Then free any overflow pages associated with the ** entry and finally remove the cell itself from within the page. */ rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; rc = clearCell(pPage, pCell); dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc); if( rc ) return rc; /* If the cell deleted was not located on a leaf page, then the cursor | > > > > > > > | 56485 56486 56487 56488 56489 56490 56491 56492 56493 56494 56495 56496 56497 56498 56499 56500 56501 56502 56503 56504 56505 | /* Save the positions of any other cursors open on this table before ** making any modifications. Make the page containing the entry to be ** deleted writable. Then free any overflow pages associated with the ** entry and finally remove the cell itself from within the page. */ rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; /* If this is a delete operation to remove a row from a table b-tree, ** invalidate any incrblob cursors open on the row being deleted. */ if( pCur->pKeyInfo==0 ){ invalidateIncrblobCursors(p, pCur->info.nKey, 0); } rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; rc = clearCell(pPage, pCell); dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc); if( rc ) return rc; /* If the cell deleted was not located on a leaf page, then the cursor |
︙ | ︙ | |||
56591 56592 56593 56594 56595 56596 56597 | */ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); | > > > | | | | < < < | 56773 56774 56775 56776 56777 56778 56779 56780 56781 56782 56783 56784 56785 56786 56787 56788 56789 56790 56791 56792 56793 | */ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); rc = saveAllCursors(pBt, (Pgno)iTable, 0); if( SQLITE_OK==rc ){ /* Invalidate all incrblob cursors open on table iTable (assuming iTable ** is the root of a table b-tree - if it is not, the following call is ** a no-op). */ invalidateIncrblobCursors(p, 0, 1); rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); return rc; } /* |
︙ | ︙ | |||
56912 56913 56914 56915 56916 56917 56918 56919 56920 56921 56922 56923 56924 56925 56926 56927 56928 56929 56930 56931 56932 | if( pCheck->errMsg.mallocFailed ){ pCheck->mallocFailed = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. ** Return 1 if there are 2 ore more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){ if( iPage==0 ) return 1; if( iPage>pCheck->nPage ){ checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage); return 1; } | > > > > > > > > > > > > > > > > > > > | > | | 57094 57095 57096 57097 57098 57099 57100 57101 57102 57103 57104 57105 57106 57107 57108 57109 57110 57111 57112 57113 57114 57115 57116 57117 57118 57119 57120 57121 57122 57123 57124 57125 57126 57127 57128 57129 57130 57131 57132 57133 57134 57135 57136 57137 57138 57139 57140 57141 57142 57143 57144 57145 57146 | if( pCheck->errMsg.mallocFailed ){ pCheck->mallocFailed = 1; } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that ** corresponds to page iPg is already set. */ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); } /* ** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. */ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); } /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. ** Return 1 if there are 2 ore more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){ if( iPage==0 ) return 1; if( iPage>pCheck->nPage ){ checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage); return 1; } if( getPageReferenced(pCheck, iPage) ){ checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage); return 1; } setPageReferenced(pCheck, iPage); return 0; } #ifndef SQLITE_OMIT_AUTOVACUUM /* ** Check that the entry in the pointer-map for page iChild maps to ** page iParent, pointer type ptrType. If not, append an error message ** to pCheck. |
︙ | ︙ | |||
57306 57307 57308 57309 57310 57311 57312 | sCheck.nErr = 0; sCheck.mallocFailed = 0; *pnErr = 0; if( sCheck.nPage==0 ){ sqlite3BtreeLeave(p); return 0; } | | > | < | < < | 57508 57509 57510 57511 57512 57513 57514 57515 57516 57517 57518 57519 57520 57521 57522 57523 57524 57525 57526 57527 57528 57529 57530 | sCheck.nErr = 0; sCheck.mallocFailed = 0; *pnErr = 0; if( sCheck.nPage==0 ){ sqlite3BtreeLeave(p); return 0; } sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ *pnErr = 1; sqlite3BtreeLeave(p); return 0; } i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); sCheck.errMsg.useMalloc = 2; /* Check the integrity of the freelist */ checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), get4byte(&pBt->pPage1->aData[36]), "Main freelist: "); |
︙ | ︙ | |||
57341 57342 57343 57344 57345 57346 57347 | checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL); } /* Make sure every page in the file is referenced */ for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM | | | | | | 57541 57542 57543 57544 57545 57546 57547 57548 57549 57550 57551 57552 57553 57554 57555 57556 57557 57558 57559 57560 57561 57562 57563 57564 57565 57566 57567 57568 57569 57570 57571 57572 57573 57574 57575 57576 57577 57578 57579 57580 57581 57582 57583 57584 57585 57586 57587 | checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL); } /* Make sure every page in the file is referenced */ for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); } #else /* If the database supports auto-vacuum, make sure no tables contain ** references to pointer-map pages. */ if( getPageReferenced(&sCheck, i)==0 && (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); } if( getPageReferenced(&sCheck, i)!=0 && (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); } #endif } /* Make sure this analysis did not leave any unref() pages. ** This is an internal consistency check; an integrity check ** of the integrity check. */ if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ checkAppendMsg(&sCheck, 0, "Outstanding page count goes from %d to %d during this analysis", nRef, sqlite3PagerRefcount(pBt->pPager) ); } /* Clean up and report errors. */ sqlite3BtreeLeave(p); sqlite3_free(sCheck.aPgRef); if( sCheck.mallocFailed ){ sqlite3StrAccumReset(&sCheck.errMsg); *pnErr = sCheck.nErr+1; return 0; } *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); |
︙ | ︙ | |||
58409 58410 58411 58412 58413 58414 58415 | #endif } /* ** Make sure pMem->z points to a writable allocation of at least ** n bytes. ** | < | > | | > > > > | 58609 58610 58611 58612 58613 58614 58615 58616 58617 58618 58619 58620 58621 58622 58623 58624 58625 58626 58627 58628 58629 58630 58631 58632 58633 58634 58635 58636 58637 58638 58639 58640 58641 58642 58643 | #endif } /* ** Make sure pMem->z points to a writable allocation of at least ** n bytes. ** ** If the third argument passed to this function is true, then memory ** cell pMem must contain a string or blob. In this case the content is ** preserved. Otherwise, if the third parameter to this function is false, ** any current string or blob value may be discarded. ** ** This function sets the MEM_Dyn flag and clears any xDel callback. ** It also clears MEM_Ephem and MEM_Static. If the preserve flag is ** not set, Mem.n is zeroed. */ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ assert( 1 >= ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) + (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + ((pMem->flags&MEM_Ephem) ? 1 : 0) + ((pMem->flags&MEM_Static) ? 1 : 0) ); assert( (pMem->flags&MEM_RowSet)==0 ); /* If the preserve flag is set to true, then the memory cell must already ** contain a valid string or blob value. */ assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); if( n<32 ) n = 32; if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){ if( preserve && pMem->z==pMem->zMalloc ){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); preserve = 0; }else{ |
︙ | ︙ | |||
60745 60746 60747 60748 60749 60750 60751 | */ if( pOp->p4type==P4_SUBPROGRAM ){ int nByte = (nSub+1)*sizeof(SubProgram*); int j; for(j=0; j<nSub; j++){ if( apSub[j]==pOp->p4.pProgram ) break; } | | | 60949 60950 60951 60952 60953 60954 60955 60956 60957 60958 60959 60960 60961 60962 60963 | */ if( pOp->p4type==P4_SUBPROGRAM ){ int nByte = (nSub+1)*sizeof(SubProgram*); int j; for(j=0; j<nSub; j++){ if( apSub[j]==pOp->p4.pProgram ) break; } if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){ apSub = (SubProgram **)pSub->z; apSub[nSub++] = pOp->p4.pProgram; pSub->flags |= MEM_Blob; pSub->n = nSub*sizeof(SubProgram*); } } } |
︙ | ︙ | |||
66994 66995 66996 66997 66998 66999 67000 67001 67002 67003 67004 67005 67006 67007 | ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. */ case OP_Column: { #if 0 /* local variables moved into u.an */ u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ | > > > > > | 67198 67199 67200 67201 67202 67203 67204 67205 67206 67207 67208 67209 67210 67211 67212 67213 67214 67215 67216 | ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. ** ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { #if 0 /* local variables moved into u.an */ u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ |
︙ | ︙ | |||
67136 67137 67138 67139 67140 67141 67142 | if( u.an.payloadSize <= (u32)u.an.avail ){ u.an.zRec = u.an.zData; u.an.pC->aRow = (u8*)u.an.zData; }else{ u.an.pC->aRow = 0; } } | | | 67345 67346 67347 67348 67349 67350 67351 67352 67353 67354 67355 67356 67357 67358 67359 | if( u.an.payloadSize <= (u32)u.an.avail ){ u.an.zRec = u.an.zData; u.an.pC->aRow = (u8*)u.an.zData; }else{ u.an.pC->aRow = 0; } } /* The following assert is true in all cases except when ** the database file has been corrupted externally. ** assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */ u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset); /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. ** |
︙ | ︙ | |||
67211 67212 67213 67214 67215 67216 67217 | u.an.szField = sqlite3VdbeSerialTypeLen(u.an.t); u.an.offset += u.an.szField; if( u.an.offset<u.an.szField ){ /* True if u.an.offset overflows */ u.an.zIdx = &u.an.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ break; } }else{ | | | | | 67420 67421 67422 67423 67424 67425 67426 67427 67428 67429 67430 67431 67432 67433 67434 67435 67436 67437 67438 | u.an.szField = sqlite3VdbeSerialTypeLen(u.an.t); u.an.offset += u.an.szField; if( u.an.offset<u.an.szField ){ /* True if u.an.offset overflows */ u.an.zIdx = &u.an.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ break; } }else{ /* If u.an.i is less that u.an.nField, then there are fewer fields in this ** record than SetNumColumns indicated there are columns in the ** table. Set the u.an.offset for any extra columns not present in ** the record to 0. This tells code below to store the default value ** for the column instead of deserializing a value from the record. */ u.an.aOffset[u.an.i] = 0; } } sqlite3VdbeMemRelease(&u.an.sMem); u.an.sMem.flags = MEM_Null; |
︙ | ︙ | |||
67245 67246 67247 67248 67249 67250 67251 67252 67253 67254 | ** then there are not enough fields in the record to satisfy the ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ if( u.an.aOffset[u.an.p2] ){ assert( rc==SQLITE_OK ); if( u.an.zRec ){ VdbeMemRelease(u.an.pDest); sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest); }else{ | > > > > > > > > > > > > > | | | > | | | | > | | 67454 67455 67456 67457 67458 67459 67460 67461 67462 67463 67464 67465 67466 67467 67468 67469 67470 67471 67472 67473 67474 67475 67476 67477 67478 67479 67480 67481 67482 67483 67484 67485 67486 67487 67488 67489 67490 67491 67492 67493 | ** then there are not enough fields in the record to satisfy the ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ if( u.an.aOffset[u.an.p2] ){ assert( rc==SQLITE_OK ); if( u.an.zRec ){ /* This is the common case where the whole row fits on a single page */ VdbeMemRelease(u.an.pDest); sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest); }else{ /* This branch happens only when the row overflows onto multiple pages */ u.an.t = u.an.aType[u.an.p2]; if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((u.an.t>=12 && (u.an.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) ){ /* Content is irrelevant for the typeof() function and for ** the length(X) function if X is a blob. So we might as well use ** bogus content rather than reading content from disk. NULL works ** for text and blob and whatever is in the u.an.payloadSize64 variable ** will work for everything else. */ u.an.zData = u.an.t<12 ? (char*)&u.an.payloadSize64 : 0; }else{ u.an.len = sqlite3VdbeSerialTypeLen(u.an.t); sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest); rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len, u.an.pC->isIndex, &u.an.sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } u.an.zData = u.an.sMem.z; } sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.t, u.an.pDest); } u.an.pDest->enc = encoding; }else{ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static); }else{ MemSetTypeFlag(u.an.pDest, MEM_Null); |
︙ | ︙ | |||
67591 67592 67593 67594 67595 67596 67597 | p->rc = rc = SQLITE_BUSY; goto vdbe_return; } db->isTransactionSavepoint = 0; rc = p->rc; }else{ u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1; | > | | > | 67815 67816 67817 67818 67819 67820 67821 67822 67823 67824 67825 67826 67827 67828 67829 67830 67831 67832 | p->rc = rc = SQLITE_BUSY; goto vdbe_return; } db->isTransactionSavepoint = 0; rc = p->rc; }else{ u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1; if( u.ar.p1==SAVEPOINT_ROLLBACK ){ for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){ sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT); } } for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){ rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } } |
︙ | ︙ | |||
73695 73696 73697 73698 73699 73700 73701 | testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); if( pDef==0 ){ | | | 73921 73922 73923 73924 73925 73926 73927 73928 73929 73930 73931 73932 73933 73934 73935 | testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); 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); if( pDef==0 ){ no_such_func = 1; }else{ wrong_num_args = 1; } }else{ is_agg = pDef->xFunc==0; |
︙ | ︙ | |||
74045 74046 74047 74048 74049 74050 74051 | */ static int resolveOrderGroupBy( NameContext *pNC, /* The name context of the SELECT statement */ Select *pSelect, /* The SELECT statement holding pOrderBy */ ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ const char *zType /* Either "ORDER" or "GROUP", as appropriate */ ){ | | | 74271 74272 74273 74274 74275 74276 74277 74278 74279 74280 74281 74282 74283 74284 74285 | */ static int resolveOrderGroupBy( NameContext *pNC, /* The name context of the SELECT statement */ Select *pSelect, /* The SELECT statement holding pOrderBy */ ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ const char *zType /* Either "ORDER" or "GROUP", as appropriate */ ){ int i, j; /* Loop counters */ int iCol; /* Column number */ struct ExprList_item *pItem; /* A term of the ORDER BY clause */ Parse *pParse; /* Parsing context */ int nResult; /* Number of terms in the result set */ if( pOrderBy==0 ) return 0; nResult = pSelect->pEList->nExpr; |
︙ | ︙ | |||
74081 74082 74083 74084 74085 74086 74087 74088 74089 74090 74091 74092 74093 74094 | continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ pItem->iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } } return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); } /* ** Resolve names in the SELECT statement p and all of its descendents. | > > > > > | 74307 74308 74309 74310 74311 74312 74313 74314 74315 74316 74317 74318 74319 74320 74321 74322 74323 74324 74325 | continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ pItem->iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } for(j=0; j<pSelect->pEList->nExpr; j++){ if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){ pItem->iOrderByCol = j+1; } } } return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); } /* ** Resolve names in the SELECT statement p and all of its descendents. |
︙ | ︙ | |||
74871 74872 74873 74874 74875 74876 74877 | SQLITE_PRIVATE Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 75102 75103 75104 75105 75106 75107 75108 75109 75110 75111 75112 75113 75114 75115 75116 75117 75118 75119 75120 75121 75122 75123 75124 75125 75126 75127 75128 75129 75130 75131 75132 75133 75134 75135 75136 75137 75138 75139 75140 75141 75142 75143 75144 75145 75146 75147 75148 75149 75150 75151 75152 75153 75154 75155 75156 75157 75158 75159 75160 75161 75162 75163 75164 | SQLITE_PRIVATE Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */ ){ Expr *p; if( op==TK_AND && pLeft && pRight ){ /* Take advantage of short-circuit false optimization for AND */ p = sqlite3ExprAnd(pParse->db, pLeft, pRight); }else{ p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); } if( p ) { sqlite3ExprCheckHeight(pParse, p->nHeight); } return p; } /* ** Return 1 if an expression must be FALSE in all cases and 0 if the ** expression might be true. This is an optimization. If is OK to ** return 0 here even if the expression really is always false (a ** false negative). But it is a bug to return 1 if the expression ** might be true in some rare circumstances (a false positive.) ** ** Note that if the expression is part of conditional for a ** LEFT JOIN, then we cannot determine at compile-time whether or not ** is it true or false, so always return 0. */ static int exprAlwaysFalse(Expr *p){ int v = 0; if( ExprHasProperty(p, EP_FromJoin) ) return 0; if( !sqlite3ExprIsInteger(p, &v) ) return 0; return v==0; } /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. ** ** If one side or the other of the AND is known to be false, then instead ** of returning an AND expression, just return a constant expression with ** a value of false. */ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ return pLeft; }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){ sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); }else{ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); return pNew; } } |
︙ | ︙ | |||
76419 76420 76421 76422 76423 76424 76425 | /* First replace any existing entry. ** ** Actually, the way the column cache is currently used, we are guaranteed ** that the object will never already be in cache. Verify this guarantee. */ #ifndef NDEBUG for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ | < < < < < < < < < | 76682 76683 76684 76685 76686 76687 76688 76689 76690 76691 76692 76693 76694 76695 | /* First replace any existing entry. ** ** Actually, the way the column cache is currently used, we are guaranteed ** that the object will never already be in cache. Verify this guarantee. */ #ifndef NDEBUG for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol ); } #endif /* Find an empty slot and replace it */ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ if( p->iReg==0 ){ |
︙ | ︙ | |||
76562 76563 76564 76565 76566 76567 76568 | ** is called. If iColumn<0 then code is generated that extracts the rowid. */ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ | | > > > > | > | 76816 76817 76818 76819 76820 76821 76822 76823 76824 76825 76826 76827 76828 76829 76830 76831 76832 76833 76834 76835 76836 76837 76838 76839 76840 76841 76842 76843 76844 76845 76846 76847 76848 76849 76850 | ** is called. If iColumn<0 then code is generated that extracts the rowid. */ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ int iTable, /* The cursor pointing to the table */ int iReg, /* Store results here */ u8 p5 /* P5 value for OP_Column */ ){ Vdbe *v = pParse->pVdbe; int i; struct yColCache *p; for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ p->lru = pParse->iCacheCnt++; sqlite3ExprCachePinRegister(pParse, p->iReg); return p->iReg; } } assert( v!=0 ); sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); if( p5 ){ sqlite3VdbeChangeP5(v, p5); }else{ sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); } return iReg; } /* ** Clear all column cache entries. */ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){ |
︙ | ︙ | |||
76705 76706 76707 76708 76709 76710 76711 | case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckBase>0 ); inReg = pExpr->iColumn + pParse->ckBase; }else{ inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, | | > | 76964 76965 76966 76967 76968 76969 76970 76971 76972 76973 76974 76975 76976 76977 76978 76979 | case TK_COLUMN: { if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckBase>0 ); inReg = pExpr->iColumn + pParse->ckBase; }else{ inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, pExpr->iColumn, pExpr->iTable, target, pExpr->op2); } break; } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); break; } |
︙ | ︙ | |||
76982 76983 76984 76985 76986 76987 76988 76989 76990 76991 76992 76993 76994 76995 | sqlite3VdbeResolveLabel(v, endCoalesce); break; } if( pFarg ){ r1 = sqlite3GetTempRange(pParse, nFarg); sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE | > > > > > > > > > > > > > > > > > > > | 77242 77243 77244 77245 77246 77247 77248 77249 77250 77251 77252 77253 77254 77255 77256 77257 77258 77259 77260 77261 77262 77263 77264 77265 77266 77267 77268 77269 77270 77271 77272 77273 77274 | sqlite3VdbeResolveLabel(v, endCoalesce); break; } if( pFarg ){ r1 = sqlite3GetTempRange(pParse, nFarg); /* For length() and typeof() functions with a column argument, ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data ** loading. */ if( (pDef->flags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ u8 exprOp; assert( nFarg==1 ); assert( pFarg->a[0].pExpr!=0 ); exprOp = pFarg->a[0].pExpr->op; if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); testcase( pDef->flags==SQLITE_FUNC_LENGTH ); pFarg->a[0].pExpr->op2 = pDef->flags; } } sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
78117 78118 78119 78120 78121 78122 78123 | if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; } | | | 78396 78397 78398 78399 78400 78401 78402 78403 78404 78405 78406 78407 78408 78409 78410 | if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; } }else if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 2; } } if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1; if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2; |
︙ | ︙ | |||
78153 78154 78155 78156 78157 78158 78159 78160 78161 78162 78163 78164 78165 78166 | Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; } return 0; } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 78432 78433 78434 78435 78436 78437 78438 78439 78440 78441 78442 78443 78444 78445 78446 78447 78448 78449 78450 78451 78452 78453 78454 78455 78456 78457 78458 78459 78460 78461 78462 78463 78464 78465 78466 78467 78468 78469 78470 78471 78472 78473 78474 78475 78476 78477 78478 78479 78480 | Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; } return 0; } /* ** This is the expression callback for sqlite3FunctionUsesOtherSrc(). ** ** Determine if an expression references any table other than one of the ** tables in pWalker->u.pSrcList and abort if it does. */ static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ int i; SrcList *pSrc = pWalker->u.pSrcList; for(i=0; i<pSrc->nSrc; i++){ if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue; } return WRC_Abort; }else{ return WRC_Continue; } } /* ** Determine if any of the arguments to the pExpr Function references ** any SrcList other than pSrcList. Return true if they do. Return ** false if pExpr has no argument or has only constant arguments or ** only references tables named in pSrcList. */ static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; assert( pExpr->op==TK_AGG_FUNCTION ); memset(&w, 0, sizeof(w)); w.xExprCallback = exprUsesOtherSrc; w.u.pSrcList = pSrcList; if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1; return 0; } /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; |
︙ | ︙ | |||
78269 78270 78271 78272 78273 78274 78275 | break; } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ } return WRC_Prune; } case TK_AGG_FUNCTION: { | | < < | 78583 78584 78585 78586 78587 78588 78589 78590 78591 78592 78593 78594 78595 78596 78597 | break; } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ } return WRC_Prune; } case TK_AGG_FUNCTION: { if( !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) ){ /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; i<pAggInfo->nFunc; i++, pItem++){ if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){ break; |
︙ | ︙ | |||
78315 78316 78317 78318 78319 78320 78321 | return WRC_Prune; } } } return WRC_Continue; } static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ | | < < | < < < | < > | 78627 78628 78629 78630 78631 78632 78633 78634 78635 78636 78637 78638 78639 78640 78641 78642 78643 78644 78645 78646 78647 78648 78649 78650 78651 78652 78653 78654 78655 78656 | return WRC_Prune; } } } return WRC_Continue; } static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ UNUSED_PARAMETER(pWalker); UNUSED_PARAMETER(pSelect); return WRC_Continue; } /* ** Analyze the given expression looking for aggregate functions and ** for variables that need to be added to the pParse->aAgg[] array. ** Make additional entries to the pParse->aAgg[] array as necessary. ** ** This routine should only be called after the expression has been ** analyzed by sqlite3ResolveExprNames(). */ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ Walker w; memset(&w, 0, sizeof(w)); w.xExprCallback = analyzeAggregate; w.xSelectCallback = analyzeAggregatesInSelect; w.u.pNC = pNC; assert( pNC->pSrcList!=0 ); sqlite3WalkExpr(&w, pExpr); } |
︙ | ︙ | |||
81729 81730 81731 81732 81733 81734 81735 | /* Delete the Table structure itself. */ sqliteDeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); sqlite3SelectDelete(db, pTable->pSelect); #ifndef SQLITE_OMIT_CHECK | | | 82036 82037 82038 82039 82040 82041 82042 82043 82044 82045 82046 82047 82048 82049 82050 | /* Delete the Table structure itself. */ sqliteDeleteColumnNames(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); } |
︙ | ︙ | |||
82392 82393 82394 82395 82396 82397 82398 | /* ** Add a new CHECK constraint to the table currently under construction. */ SQLITE_PRIVATE void sqlite3AddCheckConstraint( Parse *pParse, /* Parsing context */ Expr *pCheckExpr /* The check expression */ ){ | < | > > > | | 82699 82700 82701 82702 82703 82704 82705 82706 82707 82708 82709 82710 82711 82712 82713 82714 82715 82716 82717 82718 82719 82720 82721 82722 82723 | /* ** Add a new CHECK constraint to the table currently under construction. */ SQLITE_PRIVATE void sqlite3AddCheckConstraint( Parse *pParse, /* Parsing context */ Expr *pCheckExpr /* The check expression */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; if( pTab && !IN_DECLARE_VTAB ){ pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); if( pParse->constraintName.n ){ sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); } }else #endif { sqlite3ExprDelete(pParse->db, pCheckExpr); } } /* ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ |
︙ | ︙ | |||
82670 82671 82672 82673 82674 82675 82676 82677 82678 82679 82680 82681 82682 82683 82684 82685 82686 | #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. */ if( p->pCheck ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); sSrc.nSrc = 1; sSrc.a[0].zName = p->zName; sSrc.a[0].pTab = p; sSrc.a[0].iCursor = -1; sNC.pParse = pParse; sNC.pSrcList = &sSrc; sNC.isCheck = 1; | > > > > | | > | 82979 82980 82981 82982 82983 82984 82985 82986 82987 82988 82989 82990 82991 82992 82993 82994 82995 82996 82997 82998 82999 83000 83001 83002 83003 83004 83005 83006 83007 83008 83009 | #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. */ if( p->pCheck ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ ExprList *pList; /* List of all CHECK constraints */ int i; /* Loop counter */ memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); sSrc.nSrc = 1; sSrc.a[0].zName = p->zName; sSrc.a[0].pTab = p; sSrc.a[0].iCursor = -1; sNC.pParse = pParse; sNC.pSrcList = &sSrc; sNC.isCheck = 1; pList = p->pCheck; for(i=0; i<pList->nExpr; i++){ if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ return; } } } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number |
︙ | ︙ | |||
84232 84233 84234 84235 84236 84237 84238 | } exit_drop_index: sqlite3SrcListDelete(db, pName); } /* | | | | | | | > > > | < < > | | 84546 84547 84548 84549 84550 84551 84552 84553 84554 84555 84556 84557 84558 84559 84560 84561 84562 84563 84564 84565 84566 84567 84568 84569 84570 84571 84572 84573 84574 | } exit_drop_index: sqlite3SrcListDelete(db, pName); } /* ** pArray is a pointer to an array of objects. Each object in the ** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() ** to extend the array so that there is space for a new object at the end. ** ** When this function is called, *pnEntry contains the current size of ** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes ** in total). ** ** If the realloc() is successful (i.e. if no OOM condition occurs), the ** space allocated for the new object is zeroed, *pnEntry updated to ** reflect the new size of the array and a pointer to the new allocation ** returned. *pIdx is set to the index of the new array entry in this case. ** ** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains ** unchanged and a copy of pArray returned. */ SQLITE_PRIVATE void *sqlite3ArrayAllocate( sqlite3 *db, /* Connection to notify of malloc failures */ void *pArray, /* Array of objects. Might be reallocated */ int szEntry, /* Size of each object in the array */ int *pnEntry, /* Number of objects currently in use */ int *pIdx /* Write the index of a new slot here */ |
︙ | ︙ | |||
85230 85231 85232 85233 85234 85235 85236 85237 85238 85239 | } /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system ** that uses encoding enc. The value returned indicates how well the ** request is matched. A higher value indicates a better match. ** ** The returned value is always between 0 and 6, as follows: ** | > > > > > > > > | | < | < | | < | < | > > > > | > > > > | | > > | > > | > > > > > < < | > > | | < < | | | | | 85546 85547 85548 85549 85550 85551 85552 85553 85554 85555 85556 85557 85558 85559 85560 85561 85562 85563 85564 85565 85566 85567 85568 85569 85570 85571 85572 85573 85574 85575 85576 85577 85578 85579 85580 85581 85582 85583 85584 85585 85586 85587 85588 85589 85590 85591 85592 85593 85594 85595 85596 85597 85598 85599 85600 85601 85602 85603 85604 85605 85606 85607 85608 85609 85610 85611 | } /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system ** that uses encoding enc. The value returned indicates how well the ** request is matched. A higher value indicates a better match. ** ** If nArg is -1 that means to only return a match (non-zero) if p->nArg ** is also -1. In other words, we are searching for a function that ** takes a variable number of arguments. ** ** If nArg is -2 that means that we are searching for any function ** regardless of the number of arguments it uses, so return a positive ** match score for any ** ** The returned value is always between 0 and 6, as follows: ** ** 0: Not a match. ** 1: UTF8/16 conversion required and function takes any number of arguments. ** 2: UTF16 byte order change required and function takes any number of args. ** 3: encoding matches and function takes any number of arguments ** 4: UTF8/16 conversion required - argument count matches exactly ** 5: UTF16 byte order conversion required - argument count matches exactly ** 6: Perfect match: encoding and argument count match exactly. ** ** If nArg==(-2) then any function with a non-null xStep or xFunc is ** a perfect match and any function with both xStep and xFunc NULL is ** a non-match. */ #define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ static int matchQuality( FuncDef *p, /* The function we are evaluating for match quality */ int nArg, /* Desired number of arguments. (-1)==any */ u8 enc /* Desired text encoding */ ){ int match; /* nArg of -2 is a special case */ if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH; /* Wrong number of arguments means "no match" */ if( p->nArg!=nArg && p->nArg>=0 ) return 0; /* Give a better score to a function with a specific number of arguments ** than to function that accepts any number of arguments. */ if( p->nArg==nArg ){ match = 4; }else{ match = 1; } /* Bonus points if the text encoding matches */ if( enc==p->iPrefEnc ){ match += 2; /* Exact encoding match */ }else if( (enc & p->iPrefEnc & 2)!=0 ){ match += 1; /* Both are UTF16, but with different byte orders */ } return match; } /* ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ |
︙ | ︙ | |||
85318 85319 85320 85321 85322 85323 85324 | ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a | | < < | | > | | | > | 85653 85654 85655 85656 85657 85658 85659 85660 85661 85662 85663 85664 85665 85666 85667 85668 85669 85670 85671 85672 85673 85674 85675 85676 85677 85678 85679 85680 85681 85682 85683 85684 85685 85686 85687 85688 85689 85690 85691 85692 | ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a ** no matching function previously existed. ** ** If nArg is -2, then the first valid function found is returned. A ** function is valid if either xFunc or xStep is non-zero. The nArg==(-2) ** case is used to see if zName is a valid function name for some number ** of arguments. If nArg is -2, then createFlag must be 0. ** ** If createFlag is false, then a function with the required name and ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( sqlite3 *db, /* An open database */ const char *zName, /* Name of the function. Not null-terminated */ int nName, /* Number of characters in the name */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ u8 createFlag /* Create new entry if true and does not otherwise exist */ ){ FuncDef *p; /* Iterator variable */ FuncDef *pBest = 0; /* Best match found so far */ int bestScore = 0; /* Score of best match */ int h; /* Hash value */ assert( nArg>=(-2) ); assert( nArg>=(-1) || createFlag==0 ); assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(&db->aFunc, h, zName, nName); while( p ){ |
︙ | ︙ | |||
85389 85390 85391 85392 85393 85394 85395 | } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ | | | 85724 85725 85726 85727 85728 85729 85730 85731 85732 85733 85734 85735 85736 85737 85738 | } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if( createFlag && bestScore<FUNC_PERFECT_MATCH && (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ pBest->zName = (char *)&pBest[1]; pBest->nArg = (u16)nArg; pBest->iPrefEnc = enc; memcpy(pBest->zName, zName, nName); pBest->zName[nName] = 0; sqlite3FuncDefInsert(&db->aFunc, pBest); |
︙ | ︙ | |||
85841 85842 85843 85844 85845 85846 85847 | /* Collect rowids of every row to be deleted. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); pWInfo = sqlite3WhereBegin( pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK ); if( pWInfo==0 ) goto delete_from_cleanup; | | | 86176 86177 86178 86179 86180 86181 86182 86183 86184 86185 86186 86187 86188 86189 86190 | /* Collect rowids of every row to be deleted. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); pWInfo = sqlite3WhereBegin( pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK ); if( pWInfo==0 ) goto delete_from_cleanup; regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0); sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } sqlite3WhereEnd(pWInfo); /* Delete every item whose key was written to the list during the |
︙ | ︙ | |||
87661 87662 87663 87664 87665 87666 87667 | FUNCTION(trim, 2, 3, 0, trimFunc ), FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), | | | | < | < | 87996 87997 87998 87999 88000 88001 88002 88003 88004 88005 88006 88007 88008 88009 88010 88011 88012 88013 88014 88015 88016 88017 88018 88019 88020 88021 88022 88023 88024 88025 | FUNCTION(trim, 2, 3, 0, trimFunc ), FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), #ifndef SQLITE_OMIT_FLOATING_POINT FUNCTION(round, 1, 0, 0, roundFunc ), FUNCTION(round, 2, 0, 0, roundFunc ), #endif FUNCTION(upper, 1, 0, 0, upperFunc ), FUNCTION(lower, 1, 0, 0, lowerFunc ), FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), FUNCTION2(coalesce, -1, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE), FUNCTION(hex, 1, 0, 0, hexFunc ), FUNCTION2(ifnull, 2, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE), FUNCTION(random, 0, 0, 0, randomFunc ), FUNCTION(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 ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS |
︙ | ︙ | |||
90115 90116 90117 90118 90119 90120 90121 90122 90123 90124 90125 90126 90127 90128 90129 90130 90131 | int nCol; /* Number of columns */ int onError; /* Conflict resolution strategy */ int j1; /* Addresss of jump instruction */ int j2 = 0, j3; /* Addresses of jump instructions */ int regData; /* Register containing first data column */ int iCur; /* Table cursor number */ Index *pIdx; /* Pointer to one of the indices */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid; v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; regData = regRowid + 1; /* Test all NOT NULL constraints. | > > | 90448 90449 90450 90451 90452 90453 90454 90455 90456 90457 90458 90459 90460 90461 90462 90463 90464 90465 90466 | int nCol; /* Number of columns */ int onError; /* Conflict resolution strategy */ int j1; /* Addresss of jump instruction */ int j2 = 0, j3; /* Addresses of jump instructions */ int regData; /* Register containing first data column */ int iCur; /* Table cursor number */ Index *pIdx; /* Pointer to one of the indices */ sqlite3 *db; /* Database connection */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid; db = pParse->db; v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; regData = regRowid + 1; /* Test all NOT NULL constraints. |
︙ | ︙ | |||
90150 90151 90152 90153 90154 90155 90156 | case OE_Abort: sqlite3MayAbort(pParse); case OE_Rollback: case OE_Fail: { char *zMsg; sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT, onError, regData+i); | | | 90485 90486 90487 90488 90489 90490 90491 90492 90493 90494 90495 90496 90497 90498 90499 | case OE_Abort: sqlite3MayAbort(pParse); case OE_Rollback: case OE_Fail: { char *zMsg; sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT, onError, regData+i); zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC); break; } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest); break; |
︙ | ︙ | |||
90172 90173 90174 90175 90176 90177 90178 | } } } /* Test all CHECK constraints */ #ifndef SQLITE_OMIT_CHECK | | | < > > > | | | > | > > > > > | | | > | 90507 90508 90509 90510 90511 90512 90513 90514 90515 90516 90517 90518 90519 90520 90521 90522 90523 90524 90525 90526 90527 90528 90529 90530 90531 90532 90533 90534 90535 90536 90537 90538 90539 90540 90541 | } } } /* Test all CHECK constraints */ #ifndef SQLITE_OMIT_CHECK if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ ExprList *pCheck = pTab->pCheck; pParse->ckBase = regData; onError = overrideError!=OE_Default ? overrideError : OE_Abort; for(i=0; i<pCheck->nExpr; i++){ int allOk = sqlite3VdbeMakeLabel(v); sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); }else{ char *zConsName = pCheck->a[i].zName; if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ if( zConsName ){ zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName); }else{ zConsName = 0; } sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC); } sqlite3VdbeResolveLabel(v, allOk); } } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* If we have an INTEGER PRIMARY KEY, make sure the primary key ** of the new record does not previously exist. Except, if this ** is an UPDATE and the primary key is not changing, that is OK. */ |
︙ | ︙ | |||
90239 90240 90241 90242 90243 90244 90245 | ** ** REPLACE INTO t(rowid) VALUES($newrowid) ** ** to run without a statement journal if there are no indexes on the ** table. */ Trigger *pTrigger = 0; | | | 90583 90584 90585 90586 90587 90588 90589 90590 90591 90592 90593 90594 90595 90596 90597 | ** ** REPLACE INTO t(rowid) VALUES($newrowid) ** ** to run without a statement journal if there are no indexes on the ** table. */ Trigger *pTrigger = 0; if( db->flags&SQLITE_RecTriggers ){ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); } if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ sqlite3MultiWrite(pParse); sqlite3GenerateRowDelete( pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace ); |
︙ | ︙ | |||
90328 90329 90330 90331 90332 90333 90334 | case OE_Fail: { int j; StrAccum errMsg; const char *zSep; char *zErr; sqlite3StrAccumInit(&errMsg, 0, 0, 200); | | | 90672 90673 90674 90675 90676 90677 90678 90679 90680 90681 90682 90683 90684 90685 90686 | case OE_Fail: { int j; StrAccum errMsg; const char *zSep; char *zErr; sqlite3StrAccumInit(&errMsg, 0, 0, 200); errMsg.db = db; zSep = pIdx->nColumn>1 ? "columns " : "column "; for(j=0; j<pIdx->nColumn; j++){ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; sqlite3StrAccumAppend(&errMsg, zSep, -1); zSep = ", "; sqlite3StrAccumAppend(&errMsg, zCol, -1); } |
︙ | ︙ | |||
90352 90353 90354 90355 90356 90357 90358 | sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); break; } default: { Trigger *pTrigger = 0; assert( onError==OE_Replace ); sqlite3MultiWrite(pParse); | | | 90696 90697 90698 90699 90700 90701 90702 90703 90704 90705 90706 90707 90708 90709 90710 | sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); break; } default: { Trigger *pTrigger = 0; assert( onError==OE_Replace ); sqlite3MultiWrite(pParse); if( db->flags&SQLITE_RecTriggers ){ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); } sqlite3GenerateRowDelete( pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace ); seenReplace = 1; break; |
︙ | ︙ | |||
90682 90683 90684 90685 90686 90687 90688 | if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; } if( pSrcIdx==0 ){ return 0; /* pDestIdx has no corresponding index in pSrc */ } } #ifndef SQLITE_OMIT_CHECK | | | 91026 91027 91028 91029 91030 91031 91032 91033 91034 91035 91036 91037 91038 91039 91040 | if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; } if( pSrcIdx==0 ){ return 0; /* pDestIdx has no corresponding index in pSrc */ } } #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY /* Disallow the transfer optimization if the destination table constains ** any foreign key constraints. This is more restrictive than necessary. ** But the main beneficiary of the transfer optimization is the VACUUM |
︙ | ︙ | |||
95755 95756 95757 95758 95759 95760 95761 | int cnt; /* Index added to make the name unique */ Column *aCol, *pCol; /* For looping over result columns */ int nCol; /* Number of columns in the result set */ Expr *p; /* Expression for a single result column */ char *zName; /* Column name */ int nName; /* Size of name in zName[] */ | > | | | > > > > > > > | 96099 96100 96101 96102 96103 96104 96105 96106 96107 96108 96109 96110 96111 96112 96113 96114 96115 96116 96117 96118 96119 96120 96121 96122 96123 | int cnt; /* Index added to make the name unique */ Column *aCol, *pCol; /* For looping over result columns */ int nCol; /* Number of columns in the result set */ Expr *p; /* Expression for a single result column */ char *zName; /* Column name */ int nName; /* Size of name in zName[] */ if( pEList ){ nCol = pEList->nExpr; aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); testcase( aCol==0 ); }else{ nCol = 0; aCol = 0; } *pnCol = nCol; *paCol = aCol; for(i=0, pCol=aCol; i<nCol; i++, pCol++){ /* Get an appropriate name for the column */ p = pEList->a[i].pExpr; assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue) || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ |
︙ | ︙ | |||
97340 97341 97342 97343 97344 97345 97346 | } } /***** If we reach this point, flattening is permitted. *****/ /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; | | > | 97692 97693 97694 97695 97696 97697 97698 97699 97700 97701 97702 97703 97704 97705 97706 97707 | } } /***** If we reach this point, flattening is permitted. *****/ /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: ** ** SELECT <expr-list> FROM (<sub-query>) <where-clause> |
︙ | ︙ | |||
98725 98726 98727 98728 98729 98730 98731 | for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; int r2; r2 = sqlite3ExprCodeGetColumn(pParse, | | | 99078 99079 99080 99081 99082 99083 99084 99085 99086 99087 99088 99089 99090 99091 99092 | for(i=0; i<sAggInfo.nColumn; i++){ struct AggInfo_col *pCol = &sAggInfo.aCol[i]; if( pCol->iSorterColumn>=j ){ int r1 = j + regBase; int r2; r2 = sqlite3ExprCodeGetColumn(pParse, pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0); if( r1!=r2 ){ sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); } j++; } } regRecord = sqlite3GetTempReg(pParse); |
︙ | ︙ | |||
101906 101907 101908 101909 101910 101911 101912 | static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ | | | 102259 102260 102261 102262 102263 102264 102265 102266 102267 102268 102269 102270 102271 102272 102273 | static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ VtabCtx sCtx, *pPriorCtx; VTable *pVTable; int rc; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); |
︙ | ︙ | |||
101931 101932 101933 101934 101935 101936 101937 101938 101939 | pVTable->pMod = pMod; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); sCtx.pTab = pTab; sCtx.pVTable = pVTable; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); | > | | 102284 102285 102286 102287 102288 102289 102290 102291 102292 102293 102294 102295 102296 102297 102298 102299 102300 102301 | pVTable->pMod = pMod; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); sCtx.pTab = pTab; sCtx.pVTable = pVTable; pPriorCtx = db->pVtabCtx; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = pPriorCtx; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; if( SQLITE_OK!=rc ){ if( zErr==0 ){ *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf(db, "%s", zErr); |
︙ | ︙ | |||
103214 103215 103216 103217 103218 103219 103220 | return 0; } #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; | > | > > | 103568 103569 103570 103571 103572 103573 103574 103575 103576 103577 103578 103579 103580 103581 103582 103583 103584 103585 | return 0; } #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || IsVirtual(pLeft->pTab) ){ /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must ** be the name of an indexed column with TEXT affinity. */ return 0; } assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ pRight = pList->a[0].pExpr; |
︙ | ︙ | |||
104087 104088 104089 104090 104091 104092 104093 104094 104095 104096 104097 104098 | ** ** 1. The index is itself UNIQUE, and ** ** 2. All of the columns in the index are either part of the pDistinct ** list, or else the WHERE clause contains a term of the form "col=X", ** where X is a constant value. The collation sequences of the ** comparison and select-list expressions must match those of the index. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->onError==OE_None ) continue; for(i=0; i<pIdx->nColumn; i++){ int iCol = pIdx->aiColumn[i]; | > > > | | | | > | 104444 104445 104446 104447 104448 104449 104450 104451 104452 104453 104454 104455 104456 104457 104458 104459 104460 104461 104462 104463 104464 104465 104466 104467 104468 104469 104470 | ** ** 1. The index is itself UNIQUE, and ** ** 2. All of the columns in the index are either part of the pDistinct ** list, or else the WHERE clause contains a term of the form "col=X", ** where X is a constant value. The collation sequences of the ** comparison and select-list expressions must match those of the index. ** ** 3. All of those index columns for which the WHERE clause does not ** contain a "col=X" term are subject to a NOT NULL constraint. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->onError==OE_None ) continue; for(i=0; i<pIdx->nColumn; i++){ int iCol = pIdx->aiColumn[i]; if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){ int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i); if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){ break; } } } if( i==pIdx->nColumn ){ /* This index implies that the DISTINCT qualifier is redundant. */ return 1; } } |
︙ | ︙ | |||
104243 104244 104245 104246 104247 104248 104249 | if( j>=nTerm ){ /* All terms of the ORDER BY clause are covered by this index so ** this index can be used for sorting. */ return 1; } if( pIdx->onError!=OE_None && i==pIdx->nColumn && (wsFlags & WHERE_COLUMN_NULL)==0 | | > > > > | | | > | > | > > > | > > > | | 104604 104605 104606 104607 104608 104609 104610 104611 104612 104613 104614 104615 104616 104617 104618 104619 104620 104621 104622 104623 104624 104625 104626 104627 104628 104629 104630 104631 104632 104633 104634 104635 104636 104637 | if( j>=nTerm ){ /* All terms of the ORDER BY clause are covered by this index so ** this index can be used for sorting. */ return 1; } if( pIdx->onError!=OE_None && i==pIdx->nColumn && (wsFlags & WHERE_COLUMN_NULL)==0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ Column *aCol = pIdx->pTable->aCol; int i; /* All terms of this index match some prefix of the ORDER BY clause, ** the index is UNIQUE, and no terms on the tail of the ORDER BY ** refer to other tables in a join. So, assuming that the index entries ** visited contain no NULL values, then this index delivers rows in ** the required order. ** ** It is not possible for any of the first nEqCol index fields to be ** NULL (since the corresponding "=" operator in the WHERE clause would ** not be true). So if all remaining index columns have NOT NULL ** constaints attached to them, we can be confident that the visited ** index entries are free of NULLs. */ for(i=nEqCol; i<pIdx->nColumn; i++){ if( aCol[pIdx->aiColumn[i]].notNull==0 ) break; } return (i==pIdx->nColumn); } return 0; } /* ** Prepare a crude estimate of the logarithm of the input value. ** The results need not be exact. This is only used for estimating |
︙ | ︙ | |||
106911 106912 106913 106914 106915 106916 106917 | explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); int r; r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, | | | 107284 107285 107286 107287 107288 107289 107290 107291 107292 107293 107294 107295 107296 107297 107298 | explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); int r; r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, regRowid, 0); sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, sqlite3VdbeCurrentAddr(v)+2, r, iSet); } sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); /* The pSubWInfo->untestedTerms flag means that this OR term ** contained one or more AND term from a notReady table. The |
︙ | ︙ | |||
107824 107825 107826 107827 107828 107829 107830 | /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { Token eOperator; /* "like" or "glob" or "regexp" */ | | | 108197 108198 108199 108200 108201 108202 108203 108204 108205 108206 108207 108208 108209 108210 108211 | /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { Token eOperator; /* "like" or "glob" or "regexp" */ int bNot; /* True if the NOT keyword is present */ }; /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, ** TK_DELETE, or TK_INSTEAD. If the event is of the form ** |
︙ | ︙ | |||
108003 108004 108005 108006 108007 108008 108009 | #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse | | | | 108376 108377 108378 108379 108380 108381 108382 108383 108384 108385 108386 108387 108388 108389 108390 108391 | #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #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 627 #define YYNRULE 325 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) /* The yyzerominor constant is used to initialize instances of ** YYMINORTYPE objects to zero. */ |
︙ | ︙ | |||
108074 108075 108076 108077 108078 108079 108080 | ** yy_action. Used to detect hash collisions. ** yy_shift_ofst[] For each state, the offset into yy_action for ** 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. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | > > | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 108447 108448 108449 108450 108451 108452 108453 108454 108455 108456 108457 108458 108459 108460 108461 108462 108463 108464 108465 108466 108467 108468 108469 108470 108471 108472 108473 108474 108475 108476 108477 108478 108479 108480 108481 108482 108483 108484 108485 108486 108487 108488 108489 108490 108491 108492 108493 108494 108495 108496 108497 108498 108499 108500 108501 108502 108503 108504 108505 108506 108507 108508 108509 108510 108511 108512 108513 108514 108515 108516 108517 108518 108519 108520 108521 108522 108523 108524 108525 108526 108527 108528 108529 108530 108531 108532 108533 108534 108535 108536 108537 108538 108539 108540 108541 108542 108543 108544 108545 108546 108547 108548 108549 108550 108551 108552 108553 108554 108555 108556 108557 108558 108559 108560 108561 108562 108563 108564 108565 108566 108567 108568 108569 108570 108571 108572 108573 108574 108575 108576 108577 108578 108579 108580 108581 108582 108583 108584 108585 108586 108587 108588 108589 108590 108591 108592 108593 108594 108595 108596 108597 108598 108599 108600 108601 108602 108603 108604 108605 108606 108607 108608 108609 108610 108611 108612 108613 108614 108615 108616 108617 108618 108619 108620 108621 108622 108623 108624 108625 108626 108627 108628 108629 108630 108631 108632 108633 108634 108635 108636 108637 108638 108639 108640 108641 108642 108643 108644 108645 108646 108647 108648 108649 108650 108651 108652 108653 108654 108655 108656 108657 108658 108659 108660 108661 108662 108663 108664 108665 108666 108667 108668 108669 108670 108671 108672 108673 108674 108675 108676 108677 108678 108679 108680 108681 108682 108683 108684 108685 108686 108687 108688 108689 108690 108691 108692 108693 108694 108695 108696 108697 108698 108699 108700 108701 108702 108703 108704 108705 108706 108707 108708 108709 108710 108711 108712 108713 108714 108715 108716 108717 108718 108719 108720 108721 108722 108723 108724 108725 108726 108727 108728 108729 108730 108731 108732 108733 108734 108735 108736 108737 108738 108739 108740 108741 108742 108743 108744 108745 108746 108747 108748 108749 108750 108751 108752 108753 108754 108755 108756 108757 108758 108759 108760 108761 108762 108763 108764 108765 108766 108767 108768 108769 108770 108771 108772 108773 108774 108775 108776 108777 108778 108779 108780 108781 108782 108783 108784 108785 108786 108787 108788 108789 108790 108791 108792 108793 108794 108795 108796 108797 108798 108799 108800 108801 108802 108803 108804 108805 108806 108807 108808 108809 108810 108811 108812 108813 108814 108815 108816 108817 108818 108819 108820 108821 108822 108823 108824 108825 108826 108827 108828 108829 108830 108831 108832 108833 108834 108835 108836 108837 108838 108839 108840 108841 108842 108843 108844 108845 108846 108847 108848 108849 108850 108851 108852 108853 108854 108855 108856 108857 108858 108859 108860 108861 108862 108863 108864 108865 108866 108867 108868 108869 108870 108871 108872 108873 108874 108875 108876 108877 108878 108879 108880 108881 108882 108883 108884 108885 108886 108887 108888 108889 108890 108891 108892 108893 108894 108895 108896 108897 108898 108899 108900 108901 108902 108903 108904 108905 108906 108907 108908 108909 108910 108911 108912 108913 108914 108915 108916 108917 108918 108919 108920 108921 108922 108923 108924 108925 108926 108927 108928 | ** yy_action. Used to detect hash collisions. ** yy_shift_ofst[] For each state, the offset into yy_action for ** 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 (1561) static const YYACTIONTYPE yy_action[] = { /* 0 */ 310, 328, 573, 572, 15, 171, 185, 595, 56, 56, /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52, /* 20 */ 52, 52, 51, 233, 52, 52, 52, 51, 233, 624, /* 30 */ 588, 582, 56, 56, 56, 56, 314, 54, 54, 54, /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 299, 57, /* 50 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56, /* 60 */ 56, 56, 569, 54, 54, 54, 54, 53, 53, 52, /* 70 */ 52, 52, 51, 233, 310, 595, 326, 575, 663, 65, /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52, /* 90 */ 51, 233, 53, 53, 52, 52, 52, 51, 233, 489, /* 100 */ 663, 440, 663, 235, 588, 582, 553, 297, 363, 59, /* 110 */ 481, 67, 360, 1, 618, 351, 618, 620, 619, 207, /* 120 */ 6, 441, 442, 57, 58, 48, 580, 579, 581, 581, /* 130 */ 55, 55, 56, 56, 56, 56, 605, 54, 54, 54, /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 223, /* 150 */ 50, 47, 146, 598, 138, 281, 385, 276, 384, 168, /* 160 */ 489, 552, 620, 619, 620, 619, 272, 214, 440, 411, /* 170 */ 551, 604, 67, 165, 7, 618, 352, 353, 588, 582, /* 180 */ 443, 569, 192, 618, 414, 617, 616, 668, 441, 336, /* 190 */ 669, 62, 618, 599, 92, 382, 346, 57, 58, 48, /* 200 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56, /* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52, /* 220 */ 51, 233, 310, 465, 232, 231, 373, 132, 514, 513, /* 230 */ 617, 616, 617, 616, 398, 437, 411, 66, 280, 388, /* 240 */ 411, 595, 439, 220, 438, 620, 619, 337, 569, 279, /* 250 */ 201, 414, 588, 582, 166, 414, 546, 167, 68, 234, /* 260 */ 599, 92, 620, 619, 599, 92, 19, 570, 570, 466, /* 270 */ 564, 57, 58, 48, 580, 579, 581, 581, 55, 55, /* 280 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53, /* 290 */ 53, 52, 52, 52, 51, 233, 310, 411, 524, 232, /* 300 */ 231, 398, 593, 547, 559, 398, 348, 202, 175, 595, /* 310 */ 399, 315, 414, 617, 616, 387, 272, 255, 347, 254, /* 320 */ 558, 599, 74, 620, 619, 45, 588, 582, 235, 466, /* 330 */ 617, 616, 511, 591, 591, 591, 557, 578, 402, 545, /* 340 */ 600, 598, 570, 570, 601, 57, 58, 48, 580, 579, /* 350 */ 581, 581, 55, 55, 56, 56, 56, 56, 550, 54, /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233, /* 370 */ 310, 309, 411, 145, 566, 490, 213, 255, 347, 254, /* 380 */ 196, 195, 194, 587, 586, 531, 600, 414, 235, 174, /* 390 */ 601, 617, 616, 411, 620, 619, 599, 91, 547, 574, /* 400 */ 588, 582, 50, 47, 146, 584, 583, 471, 414, 249, /* 410 */ 565, 542, 186, 39, 304, 424, 562, 599, 16, 57, /* 420 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56, /* 430 */ 56, 56, 585, 54, 54, 54, 54, 53, 53, 52, /* 440 */ 52, 52, 51, 233, 310, 559, 290, 530, 529, 345, /* 450 */ 533, 576, 540, 246, 170, 248, 411, 396, 411, 422, /* 460 */ 199, 558, 617, 616, 165, 563, 50, 47, 146, 181, /* 470 */ 498, 414, 166, 414, 588, 582, 269, 557, 166, 518, /* 480 */ 599, 92, 599, 92, 561, 595, 469, 36, 173, 409, /* 490 */ 517, 577, 577, 57, 58, 48, 580, 579, 581, 581, /* 500 */ 55, 55, 56, 56, 56, 56, 338, 54, 54, 54, /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 304, /* 520 */ 423, 394, 526, 318, 869, 235, 167, 180, 473, 547, /* 530 */ 503, 247, 474, 381, 378, 377, 409, 351, 577, 577, /* 540 */ 409, 560, 577, 577, 376, 383, 364, 603, 588, 582, /* 550 */ 620, 619, 502, 595, 409, 494, 577, 577, 409, 266, /* 560 */ 577, 577, 421, 943, 422, 943, 198, 57, 58, 48, /* 570 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56, /* 580 */ 315, 54, 54, 54, 54, 53, 53, 52, 52, 52, /* 590 */ 51, 233, 310, 390, 421, 942, 509, 942, 556, 145, /* 600 */ 598, 391, 324, 262, 549, 264, 411, 425, 407, 573, /* 610 */ 572, 12, 197, 143, 489, 50, 47, 146, 617, 616, /* 620 */ 206, 414, 588, 582, 547, 429, 67, 212, 143, 618, /* 630 */ 599, 73, 504, 505, 207, 434, 475, 475, 366, 425, /* 640 */ 35, 57, 58, 48, 580, 579, 581, 581, 55, 55, /* 650 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53, /* 660 */ 53, 52, 52, 52, 51, 233, 310, 260, 598, 569, /* 670 */ 268, 615, 614, 613, 171, 411, 595, 11, 411, 350, /* 680 */ 411, 32, 618, 953, 183, 419, 2, 627, 625, 330, /* 690 */ 414, 352, 552, 414, 538, 414, 588, 582, 188, 599, /* 700 */ 69, 551, 599, 94, 599, 97, 374, 544, 166, 618, /* 710 */ 334, 359, 50, 47, 146, 57, 58, 48, 580, 579, /* 720 */ 581, 581, 55, 55, 56, 56, 56, 56, 411, 54, /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233, /* 740 */ 310, 411, 129, 414, 595, 22, 273, 156, 411, 566, /* 750 */ 406, 213, 599, 95, 570, 570, 414, 327, 169, 332, /* 760 */ 411, 618, 536, 414, 358, 599, 104, 483, 508, 356, /* 770 */ 588, 582, 599, 103, 484, 414, 470, 357, 166, 618, /* 780 */ 626, 2, 204, 323, 599, 105, 40, 528, 38, 57, /* 790 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56, /* 800 */ 56, 56, 411, 54, 54, 54, 54, 53, 53, 52, /* 810 */ 52, 52, 51, 233, 310, 411, 598, 414, 411, 260, /* 820 */ 273, 273, 273, 273, 426, 305, 599, 106, 520, 519, /* 830 */ 414, 411, 142, 414, 618, 618, 618, 618, 618, 599, /* 840 */ 133, 339, 599, 134, 588, 582, 414, 21, 30, 316, /* 850 */ 147, 459, 221, 170, 527, 599, 98, 222, 322, 321, /* 860 */ 320, 141, 259, 57, 58, 48, 580, 579, 581, 581, /* 870 */ 55, 55, 56, 56, 56, 56, 411, 54, 54, 54, /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 411, /* 890 */ 260, 414, 411, 458, 200, 35, 411, 358, 211, 228, /* 900 */ 599, 102, 468, 519, 414, 618, 28, 414, 538, 501, /* 910 */ 411, 414, 618, 599, 101, 358, 599, 93, 588, 582, /* 920 */ 599, 100, 522, 618, 427, 414, 306, 271, 598, 380, /* 930 */ 618, 602, 598, 452, 599, 77, 210, 57, 58, 48, /* 940 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56, /* 950 */ 411, 54, 54, 54, 54, 53, 53, 52, 52, 52, /* 960 */ 51, 233, 310, 411, 621, 414, 411, 127, 609, 270, /* 970 */ 598, 365, 51, 233, 599, 96, 625, 330, 414, 618, /* 980 */ 126, 414, 411, 618, 411, 253, 608, 599, 137, 27, /* 990 */ 599, 136, 588, 582, 375, 260, 125, 414, 164, 414, /* 1000 */ 371, 618, 279, 219, 542, 542, 599, 135, 599, 76, /* 1010 */ 618, 57, 46, 48, 580, 579, 581, 581, 55, 55, /* 1020 */ 56, 56, 56, 56, 411, 54, 54, 54, 54, 53, /* 1030 */ 53, 52, 52, 52, 51, 233, 310, 411, 450, 414, /* 1040 */ 411, 260, 542, 229, 285, 607, 479, 184, 599, 90, /* 1050 */ 367, 122, 414, 476, 121, 414, 618, 170, 411, 353, /* 1060 */ 618, 599, 89, 410, 599, 75, 588, 582, 472, 257, /* 1070 */ 538, 120, 159, 414, 618, 14, 464, 158, 618, 157, /* 1080 */ 461, 283, 599, 88, 449, 618, 58, 48, 580, 579, /* 1090 */ 581, 581, 55, 55, 56, 56, 56, 56, 411, 54, /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233, /* 1110 */ 310, 411, 260, 414, 411, 592, 260, 118, 25, 400, /* 1120 */ 10, 24, 599, 87, 117, 216, 414, 618, 349, 414, /* 1130 */ 618, 618, 411, 319, 618, 599, 99, 555, 599, 86, /* 1140 */ 588, 582, 4, 260, 457, 455, 115, 414, 251, 154, /* 1150 */ 451, 108, 618, 110, 436, 448, 599, 17, 618, 218, /* 1160 */ 107, 48, 580, 579, 581, 581, 55, 55, 56, 56, /* 1170 */ 56, 56, 435, 54, 54, 54, 54, 53, 53, 52, /* 1180 */ 52, 52, 51, 233, 44, 405, 217, 3, 411, 260, /* 1190 */ 543, 415, 619, 445, 64, 149, 539, 237, 333, 329, /* 1200 */ 203, 187, 408, 414, 618, 618, 420, 44, 405, 411, /* 1210 */ 3, 618, 599, 85, 415, 619, 148, 227, 622, 179, /* 1220 */ 313, 403, 312, 612, 414, 408, 611, 124, 417, 178, /* 1230 */ 610, 564, 243, 599, 84, 537, 8, 176, 235, 416, /* 1240 */ 294, 418, 623, 30, 403, 597, 411, 236, 293, 123, /* 1250 */ 618, 41, 42, 532, 564, 205, 292, 275, 43, 413, /* 1260 */ 412, 414, 395, 593, 507, 274, 31, 397, 291, 37, /* 1270 */ 599, 83, 618, 491, 41, 42, 267, 411, 265, 618, /* 1280 */ 618, 43, 413, 412, 596, 263, 593, 60, 618, 598, /* 1290 */ 261, 618, 414, 618, 591, 591, 591, 590, 589, 13, /* 1300 */ 618, 599, 72, 554, 235, 618, 44, 405, 256, 3, /* 1310 */ 361, 172, 340, 415, 619, 230, 411, 591, 591, 591, /* 1320 */ 590, 589, 13, 618, 408, 618, 182, 411, 286, 34, /* 1330 */ 405, 414, 3, 411, 463, 411, 415, 619, 29, 331, /* 1340 */ 599, 71, 414, 403, 392, 386, 284, 408, 414, 618, /* 1350 */ 414, 599, 82, 564, 411, 462, 354, 599, 81, 599, /* 1360 */ 80, 541, 250, 535, 282, 521, 403, 534, 516, 414, /* 1370 */ 618, 618, 454, 41, 42, 411, 564, 618, 599, 70, /* 1380 */ 43, 413, 412, 444, 515, 593, 242, 618, 325, 61, /* 1390 */ 414, 277, 239, 620, 619, 238, 41, 42, 618, 599, /* 1400 */ 18, 618, 512, 43, 413, 412, 511, 618, 593, 430, /* 1410 */ 618, 411, 128, 510, 308, 226, 591, 591, 591, 590, /* 1420 */ 589, 13, 215, 289, 618, 225, 414, 302, 301, 300, /* 1430 */ 177, 298, 411, 564, 453, 599, 79, 224, 618, 591, /* 1440 */ 591, 591, 590, 589, 13, 389, 492, 414, 150, 144, /* 1450 */ 241, 393, 288, 191, 190, 193, 599, 78, 165, 240, /* 1460 */ 414, 524, 487, 307, 618, 593, 618, 618, 486, 599, /* 1470 */ 9, 163, 152, 485, 466, 372, 480, 162, 153, 370, /* 1480 */ 161, 151, 209, 478, 258, 368, 477, 26, 160, 467, /* 1490 */ 140, 362, 131, 119, 116, 456, 591, 591, 591, 155, /* 1500 */ 114, 344, 343, 113, 112, 111, 447, 109, 130, 23, /* 1510 */ 317, 433, 20, 432, 431, 428, 606, 594, 63, 189, /* 1520 */ 404, 571, 255, 342, 244, 295, 287, 278, 311, 508, /* 1530 */ 496, 497, 495, 235, 493, 568, 379, 355, 460, 245, /* 1540 */ 341, 446, 303, 567, 5, 252, 548, 208, 139, 506, /* 1550 */ 369, 401, 500, 499, 296, 525, 335, 488, 482, 523, /* 1560 */ 233, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 19, 169, 170, 171, 22, 24, 24, 26, 77, 78, /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, /* 20 */ 89, 90, 91, 92, 88, 89, 90, 91, 92, 1, /* 30 */ 49, 50, 77, 78, 79, 80, 155, 82, 83, 84, /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 15, 68, /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 60 */ 79, 80, 230, 82, 83, 84, 85, 86, 87, 88, /* 70 */ 89, 90, 91, 92, 19, 94, 19, 23, 1, 25, /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90, /* 90 */ 91, 92, 86, 87, 88, 89, 90, 91, 92, 150, /* 100 */ 23, 150, 25, 116, 49, 50, 177, 158, 227, 54, /* 110 */ 161, 162, 231, 22, 165, 128, 165, 26, 27, 160, /* 120 */ 22, 170, 171, 68, 69, 70, 71, 72, 73, 74, /* 130 */ 75, 76, 77, 78, 79, 80, 23, 82, 83, 84, /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92, /* 150 */ 221, 222, 223, 194, 97, 98, 99, 100, 101, 102, /* 160 */ 150, 32, 26, 27, 26, 27, 109, 22, 150, 150, /* 170 */ 41, 161, 162, 96, 76, 165, 217, 150, 49, 50, /* 180 */ 229, 230, 172, 165, 165, 94, 95, 118, 170, 171, /* 190 */ 118, 232, 165, 174, 175, 185, 237, 68, 69, 70, /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90, /* 220 */ 91, 92, 19, 11, 86, 87, 19, 24, 7, 8, /* 230 */ 94, 95, 94, 95, 215, 97, 150, 22, 98, 220, /* 240 */ 150, 26, 104, 216, 106, 26, 27, 229, 230, 109, /* 250 */ 160, 165, 49, 50, 25, 165, 120, 50, 22, 197, /* 260 */ 174, 175, 26, 27, 174, 175, 204, 129, 130, 57, /* 270 */ 66, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86, /* 290 */ 87, 88, 89, 90, 91, 92, 19, 150, 94, 86, /* 300 */ 87, 215, 98, 25, 12, 215, 220, 160, 118, 94, /* 310 */ 220, 104, 165, 94, 95, 88, 109, 105, 106, 107, /* 320 */ 28, 174, 175, 26, 27, 22, 49, 50, 116, 57, /* 330 */ 94, 95, 103, 129, 130, 131, 44, 113, 46, 120, /* 340 */ 113, 194, 129, 130, 117, 68, 69, 70, 71, 72, /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 177, 82, /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, /* 370 */ 19, 163, 150, 95, 166, 167, 168, 105, 106, 107, /* 380 */ 105, 106, 107, 49, 50, 88, 113, 165, 116, 118, /* 390 */ 117, 94, 95, 150, 26, 27, 174, 175, 120, 23, /* 400 */ 49, 50, 221, 222, 223, 71, 72, 21, 165, 16, /* 410 */ 23, 166, 22, 136, 22, 23, 11, 174, 175, 68, /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 430 */ 79, 80, 98, 82, 83, 84, 85, 86, 87, 88, /* 440 */ 89, 90, 91, 92, 19, 12, 224, 23, 23, 63, /* 450 */ 205, 23, 23, 60, 25, 62, 150, 214, 150, 67, /* 460 */ 22, 28, 94, 95, 96, 23, 221, 222, 223, 23, /* 470 */ 23, 165, 25, 165, 49, 50, 23, 44, 25, 46, /* 480 */ 174, 175, 174, 175, 23, 26, 100, 136, 25, 112, /* 490 */ 57, 114, 115, 68, 69, 70, 71, 72, 73, 74, /* 500 */ 75, 76, 77, 78, 79, 80, 97, 82, 83, 84, /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 22, /* 520 */ 23, 215, 23, 215, 138, 116, 50, 23, 30, 25, /* 530 */ 36, 138, 34, 99, 100, 101, 112, 128, 114, 115, /* 540 */ 112, 23, 114, 115, 110, 51, 48, 173, 49, 50, /* 550 */ 26, 27, 58, 94, 112, 181, 114, 115, 112, 16, /* 560 */ 114, 115, 22, 23, 67, 25, 160, 68, 69, 70, /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 580 */ 104, 82, 83, 84, 85, 86, 87, 88, 89, 90, /* 590 */ 91, 92, 19, 19, 22, 23, 23, 25, 23, 95, /* 600 */ 194, 27, 108, 60, 25, 62, 150, 67, 169, 170, /* 610 */ 171, 35, 206, 207, 150, 221, 222, 223, 94, 95, /* 620 */ 160, 165, 49, 50, 120, 161, 162, 206, 207, 165, /* 630 */ 174, 175, 97, 98, 160, 241, 105, 106, 107, 67, /* 640 */ 25, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* 650 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86, /* 660 */ 87, 88, 89, 90, 91, 92, 19, 150, 194, 230, /* 670 */ 23, 7, 8, 9, 24, 150, 26, 35, 150, 219, /* 680 */ 150, 25, 165, 142, 143, 144, 145, 0, 1, 2, /* 690 */ 165, 217, 32, 165, 150, 165, 49, 50, 119, 174, /* 700 */ 175, 41, 174, 175, 174, 175, 23, 120, 25, 165, /* 710 */ 193, 237, 221, 222, 223, 68, 69, 70, 71, 72, /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, /* 740 */ 19, 150, 22, 165, 94, 24, 150, 25, 150, 166, /* 750 */ 167, 168, 174, 175, 129, 130, 165, 213, 35, 242, /* 760 */ 150, 165, 27, 165, 150, 174, 175, 181, 182, 19, /* 770 */ 49, 50, 174, 175, 188, 165, 23, 27, 25, 165, /* 780 */ 144, 145, 160, 187, 174, 175, 135, 23, 137, 68, /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88, /* 810 */ 89, 90, 91, 92, 19, 150, 194, 165, 150, 150, /* 820 */ 150, 150, 150, 150, 247, 248, 174, 175, 190, 191, /* 830 */ 165, 150, 118, 165, 165, 165, 165, 165, 165, 174, /* 840 */ 175, 219, 174, 175, 49, 50, 165, 52, 126, 245, /* 850 */ 246, 23, 238, 25, 23, 174, 175, 187, 187, 187, /* 860 */ 187, 39, 193, 68, 69, 70, 71, 72, 73, 74, /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, /* 890 */ 150, 165, 150, 23, 160, 25, 150, 150, 160, 52, /* 900 */ 174, 175, 190, 191, 165, 165, 22, 165, 150, 29, /* 910 */ 150, 165, 165, 174, 175, 150, 174, 175, 49, 50, /* 920 */ 174, 175, 165, 165, 23, 165, 25, 25, 194, 52, /* 930 */ 165, 174, 194, 193, 174, 175, 160, 68, 69, 70, /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, /* 960 */ 91, 92, 19, 150, 150, 165, 150, 22, 150, 23, /* 970 */ 194, 213, 91, 92, 174, 175, 1, 2, 165, 165, /* 980 */ 22, 165, 150, 165, 150, 238, 150, 174, 175, 22, /* 990 */ 174, 175, 49, 50, 52, 150, 22, 165, 102, 165, /* 1000 */ 19, 165, 109, 238, 166, 166, 174, 175, 174, 175, /* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165, /* 1040 */ 150, 150, 166, 205, 205, 150, 20, 24, 174, 175, /* 1050 */ 43, 104, 165, 59, 53, 165, 165, 25, 150, 150, /* 1060 */ 165, 174, 175, 150, 174, 175, 49, 50, 53, 138, /* 1070 */ 150, 22, 104, 165, 165, 5, 1, 118, 165, 35, /* 1080 */ 27, 205, 174, 175, 193, 165, 69, 70, 71, 72, /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, /* 1110 */ 19, 150, 150, 165, 150, 150, 150, 108, 76, 150, /* 1120 */ 22, 76, 174, 175, 127, 216, 165, 165, 25, 165, /* 1130 */ 165, 165, 150, 213, 165, 174, 175, 150, 174, 175, /* 1140 */ 49, 50, 22, 150, 23, 1, 119, 165, 16, 121, /* 1150 */ 20, 108, 165, 119, 23, 193, 174, 175, 165, 193, /* 1160 */ 127, 70, 71, 72, 73, 74, 75, 76, 77, 78, /* 1170 */ 79, 80, 23, 82, 83, 84, 85, 86, 87, 88, /* 1180 */ 89, 90, 91, 92, 19, 20, 193, 22, 150, 150, /* 1190 */ 150, 26, 27, 128, 16, 15, 150, 140, 65, 3, /* 1200 */ 164, 22, 37, 165, 165, 165, 4, 19, 20, 150, /* 1210 */ 22, 165, 174, 175, 26, 27, 246, 180, 149, 6, /* 1220 */ 249, 56, 249, 149, 165, 37, 149, 180, 149, 151, /* 1230 */ 13, 66, 193, 174, 175, 150, 25, 151, 116, 159, /* 1240 */ 199, 146, 147, 126, 56, 194, 150, 152, 200, 154, /* 1250 */ 165, 86, 87, 88, 66, 160, 201, 150, 93, 94, /* 1260 */ 95, 165, 123, 98, 150, 150, 124, 122, 202, 135, /* 1270 */ 174, 175, 165, 150, 86, 87, 150, 150, 150, 165, /* 1280 */ 165, 93, 94, 95, 203, 150, 98, 125, 165, 194, /* 1290 */ 150, 165, 165, 165, 129, 130, 131, 132, 133, 134, /* 1300 */ 165, 174, 175, 157, 116, 165, 19, 20, 150, 22, /* 1310 */ 150, 118, 217, 26, 27, 225, 150, 129, 130, 131, /* 1320 */ 132, 133, 134, 165, 37, 165, 157, 150, 210, 19, /* 1330 */ 20, 165, 22, 150, 150, 150, 26, 27, 104, 244, /* 1340 */ 174, 175, 165, 56, 121, 104, 210, 37, 165, 165, /* 1350 */ 165, 174, 175, 66, 150, 150, 150, 174, 175, 174, /* 1360 */ 175, 211, 150, 211, 210, 176, 56, 211, 176, 165, /* 1370 */ 165, 165, 150, 86, 87, 150, 66, 165, 174, 175, /* 1380 */ 93, 94, 95, 150, 184, 98, 150, 165, 47, 22, /* 1390 */ 165, 176, 150, 26, 27, 150, 86, 87, 165, 174, /* 1400 */ 175, 165, 178, 93, 94, 95, 103, 165, 98, 150, /* 1410 */ 165, 150, 22, 176, 179, 228, 129, 130, 131, 132, /* 1420 */ 133, 134, 5, 150, 165, 92, 165, 10, 11, 12, /* 1430 */ 13, 14, 150, 66, 17, 174, 175, 228, 165, 129, /* 1440 */ 130, 131, 132, 133, 134, 150, 184, 165, 31, 150, /* 1450 */ 33, 150, 150, 86, 87, 172, 174, 175, 96, 42, /* 1460 */ 165, 94, 176, 179, 165, 98, 165, 165, 176, 174, /* 1470 */ 175, 156, 55, 176, 57, 18, 157, 156, 61, 157, /* 1480 */ 156, 64, 157, 157, 235, 45, 236, 135, 156, 189, /* 1490 */ 68, 157, 218, 189, 22, 199, 129, 130, 131, 156, /* 1500 */ 192, 157, 18, 192, 192, 192, 199, 189, 218, 240, /* 1510 */ 157, 40, 240, 157, 157, 38, 153, 166, 243, 196, /* 1520 */ 226, 230, 105, 106, 107, 198, 209, 177, 111, 182, /* 1530 */ 166, 177, 177, 116, 166, 230, 178, 239, 199, 209, /* 1540 */ 209, 199, 148, 166, 196, 239, 208, 233, 172, 183, /* 1550 */ 234, 191, 183, 183, 195, 174, 139, 186, 186, 174, /* 1560 */ 92, }; #define YY_SHIFT_USE_DFLT (-70) #define YY_SHIFT_COUNT (418) #define YY_SHIFT_MIN (-69) #define YY_SHIFT_MAX (1484) static const short yy_shift_ofst[] = { /* 0 */ 975, 1188, 1417, 1188, 1287, 1287, 138, 138, 368, -19, /* 10 */ 1287, 1287, 1287, 1287, 272, 524, 129, 129, 795, 1165, /* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, /* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, /* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287, /* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, /* 60 */ 1287, 1287, 212, 524, 524, 213, 213, 459, 1122, 55, /* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869, /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45, /* 100 */ -45, -45, -45, -45, -1, 6, -64, 524, 524, 524, /* 110 */ 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, /* 120 */ 524, 524, 524, 386, 207, 524, 524, 524, 524, 524, /* 130 */ 409, -13, 459, 881, 1468, -70, -70, -70, 1367, 57, /* 140 */ 433, 433, 297, 236, 219, 136, 91, 572, 540, 524, /* 150 */ 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, /* 160 */ 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, /* 170 */ 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, /* 180 */ 650, 650, 650, 687, 1122, 1122, 1122, -70, -70, -70, /* 190 */ 204, 204, 434, 434, 494, 494, 494, 504, 446, 292, /* 200 */ 442, 428, 424, 77, 377, 377, 377, 377, 531, 498, /* 210 */ 377, 377, 278, 215, 227, 664, 722, 574, 574, 750, /* 220 */ 722, 750, 229, 459, 660, 459, 660, 476, 660, 574, /* 230 */ 651, 625, 625, 459, 579, 273, -18, 1477, 1193, 1193, /* 240 */ 1471, 1471, 1193, 1472, 1422, 1117, 1484, 1484, 1484, 1484, /* 250 */ 1193, 1457, 1117, 1472, 1422, 1422, 1193, 1457, 1352, 1440, /* 260 */ 1193, 1193, 1457, 1193, 1457, 1193, 1457, 1390, 1241, 1241, /* 270 */ 1241, 1362, 1341, 1333, 1333, 1390, 1241, 1303, 1241, 1341, /* 280 */ 1241, 1241, 1223, 1234, 1223, 1234, 1223, 1234, 1193, 1193, /* 290 */ 1134, 1162, 1145, 1142, 1139, 1117, 1122, 1211, 1217, 1217, /* 300 */ 1213, 1213, 1213, 1213, -70, -70, -70, -70, -70, -70, /* 310 */ 334, 393, 497, 392, 543, 275, 901, 98, 870, 828, /* 320 */ 753, 683, 453, 447, 535, 221, 140, 429, 54, 1202, /* 330 */ 1196, 1179, 1057, 1180, 1133, 1178, 1149, 1131, 1065, 1103, /* 340 */ 1033, 1043, 1034, 1130, 1028, 1132, 1144, 1027, 1121, 1120, /* 350 */ 1103, 1098, 997, 1045, 1042, 1009, 1053, 1044, 959, 1075, /* 360 */ 1070, 1049, 968, 931, 1015, 1032, 1001, 994, 1007, 947, /* 370 */ 1023, 1026, 981, 893, 896, 974, 942, 967, 958, 946, /* 380 */ 945, 877, 902, 880, 884, 847, 822, 831, 764, 714, /* 390 */ 735, 723, 720, 587, 615, 642, 656, 576, 615, 575, /* 400 */ 518, 463, 461, 438, 405, 390, 387, 376, 303, 224, /* 410 */ 271, 190, 92, 72, 69, 145, 113, 33, 28, }; #define YY_REDUCE_USE_DFLT (-169) #define YY_REDUCE_COUNT (309) #define YY_REDUCE_MIN (-168) #define YY_REDUCE_MAX (1394) static const short yy_reduce_ofst[] = { /* 0 */ 541, 90, 1095, 147, 86, 19, 18, -49, 10, 245, /* 10 */ 308, 306, 243, 222, -41, -51, 181, -71, 394, 1295, /* 20 */ 1282, 1261, 1225, 1204, 1185, 1183, 1177, 1166, 1127, 1096, /* 30 */ 1059, 1038, 982, 964, 961, 948, 908, 890, 887, 874, /* 40 */ 834, 832, 816, 813, 800, 760, 746, 742, 739, 726, /* 50 */ 681, 668, 665, 652, 610, 598, 591, 578, 530, 528, /* 60 */ 525, 456, 474, 464, 517, 439, -168, 208, 406, 491, /* 70 */ 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, /* 80 */ 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, /* 90 */ 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, /* 100 */ 491, 491, 491, 491, 491, 491, 491, 1039, 909, 993, /* 110 */ 966, 962, 891, 845, 740, 765, 920, 747, 27, 614, /* 120 */ 673, 758, 669, -119, 586, 672, 671, 670, 596, 544, /* 130 */ 622, 460, 583, 491, 491, 491, 491, 491, 757, 374, /* 140 */ 712, 638, 913, 1302, 1301, 1299, 1273, 577, 577, 1259, /* 150 */ 1245, 1242, 1236, 1233, 1222, 1212, 1206, 1205, 1184, 1160, /* 160 */ 1158, 1140, 1135, 1128, 1126, 1123, 1115, 1114, 1107, 1085, /* 170 */ 1046, 1040, 987, 969, 965, 913, 895, 836, 818, 814, /* 180 */ 876, 839, 838, 636, 776, 738, 734, 604, 421, 62, /* 190 */ 1385, 1381, 1372, 1371, 1370, 1369, 1366, 1338, 1359, 1360, /* 200 */ 1359, 1359, 1359, 1376, 1359, 1359, 1359, 1359, 1316, 1314, /* 210 */ 1359, 1359, 1338, 1377, 1348, 1394, 1342, 1331, 1330, 1306, /* 220 */ 1339, 1298, 1358, 1368, 1355, 1364, 1354, 1347, 1350, 1317, /* 230 */ 1294, 1305, 1291, 1351, 1327, 1323, 1363, 1275, 1357, 1356, /* 240 */ 1272, 1269, 1353, 1290, 1318, 1307, 1313, 1312, 1311, 1308, /* 250 */ 1344, 1343, 1296, 1274, 1304, 1300, 1334, 1332, 1250, 1249, /* 260 */ 1326, 1325, 1324, 1322, 1321, 1319, 1315, 1284, 1297, 1292, /* 270 */ 1286, 1283, 1262, 1209, 1187, 1235, 1237, 1224, 1215, 1200, /* 280 */ 1192, 1189, 1156, 1154, 1152, 1136, 1150, 1118, 1169, 1146, /* 290 */ 1090, 1081, 1066, 1055, 1048, 1041, 1051, 1080, 1086, 1078, /* 300 */ 1079, 1077, 1074, 1069, 973, 971, 970, 1047, 1037, 1036, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 632, 864, 952, 952, 864, 864, 952, 952, 683, 754, /* 10 */ 952, 952, 952, 862, 952, 952, 782, 782, 926, 952, /* 20 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 30 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 40 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 50 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 60 */ 952, 952, 952, 952, 952, 952, 952, 671, 758, 788, /* 70 */ 952, 952, 952, 952, 952, 952, 952, 952, 925, 927, /* 80 */ 796, 795, 905, 769, 793, 786, 790, 865, 858, 859, /* 90 */ 857, 861, 866, 952, 789, 825, 842, 824, 836, 841, /* 100 */ 848, 840, 837, 827, 826, 828, 829, 952, 952, 952, /* 110 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 120 */ 952, 952, 952, 658, 723, 952, 952, 952, 952, 952, /* 130 */ 952, 952, 952, 830, 831, 845, 844, 843, 952, 952, /* 140 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 150 */ 932, 930, 952, 877, 952, 952, 952, 952, 952, 952, /* 160 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 170 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 638, /* 180 */ 754, 754, 754, 632, 952, 952, 952, 944, 758, 748, /* 190 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 200 */ 952, 952, 952, 683, 798, 737, 915, 917, 952, 898, /* 210 */ 735, 660, 756, 673, 746, 640, 792, 771, 771, 910, /* 220 */ 792, 910, 697, 952, 782, 952, 782, 694, 782, 771, /* 230 */ 860, 952, 952, 952, 755, 746, 952, 937, 762, 762, /* 240 */ 929, 929, 762, 804, 727, 792, 734, 734, 734, 734, /* 250 */ 762, 655, 792, 804, 727, 727, 762, 655, 904, 902, /* 260 */ 762, 762, 655, 762, 655, 762, 655, 870, 725, 725, /* 270 */ 725, 683, 712, 874, 874, 870, 725, 697, 725, 712, /* 280 */ 725, 725, 775, 770, 775, 770, 775, 770, 762, 762, /* 290 */ 952, 787, 776, 785, 783, 792, 952, 715, 648, 648, /* 300 */ 637, 637, 637, 637, 949, 949, 944, 699, 699, 681, /* 310 */ 952, 952, 952, 952, 952, 952, 952, 879, 952, 952, /* 320 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 330 */ 633, 939, 952, 952, 936, 952, 952, 952, 952, 797, /* 340 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 350 */ 914, 952, 952, 952, 952, 952, 952, 952, 908, 952, /* 360 */ 952, 952, 952, 952, 952, 901, 900, 952, 952, 952, /* 370 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, /* 380 */ 952, 952, 716, 952, 952, 952, 952, 952, 952, 952, /* 390 */ 952, 952, 952, 952, 784, 952, 777, 952, 863, 952, /* 400 */ 952, 952, 952, 952, 952, 952, 952, 952, 952, 740, /* 410 */ 813, 952, 812, 816, 811, 665, 952, 646, 952, 629, /* 420 */ 634, 948, 951, 950, 947, 946, 945, 940, 938, 935, /* 430 */ 934, 933, 931, 928, 924, 883, 881, 888, 887, 886, /* 440 */ 885, 884, 882, 880, 878, 799, 794, 791, 923, 876, /* 450 */ 736, 733, 732, 654, 941, 907, 916, 803, 802, 805, /* 460 */ 913, 912, 911, 909, 906, 893, 801, 800, 728, 868, /* 470 */ 867, 657, 897, 896, 895, 899, 903, 894, 764, 656, /* 480 */ 653, 662, 718, 724, 722, 721, 720, 719, 717, 664, /* 490 */ 672, 682, 711, 696, 695, 873, 875, 872, 871, 704, /* 500 */ 703, 709, 708, 707, 706, 705, 702, 701, 700, 693, /* 510 */ 692, 698, 691, 714, 713, 710, 690, 731, 730, 729, /* 520 */ 726, 689, 688, 687, 816, 686, 685, 822, 821, 809, /* 530 */ 852, 751, 750, 749, 761, 760, 773, 772, 807, 806, /* 540 */ 774, 759, 753, 752, 768, 767, 766, 765, 757, 747, /* 550 */ 779, 781, 780, 778, 854, 763, 851, 922, 921, 920, /* 560 */ 919, 918, 856, 855, 823, 820, 676, 677, 891, 890, /* 570 */ 892, 889, 679, 678, 675, 674, 853, 742, 741, 849, /* 580 */ 846, 838, 834, 850, 847, 839, 835, 833, 832, 818, /* 590 */ 817, 815, 814, 810, 819, 667, 743, 739, 738, 808, /* 600 */ 745, 744, 684, 680, 661, 659, 652, 650, 649, 651, /* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666, /* 620 */ 665, 639, 636, 635, 631, 630, 628, }; /* The next table maps tokens into fallback tokens. If a construct ** like the following: ** ** %fallback ID X Y Z. ** |
︙ | ︙ | |||
108746 108747 108748 108749 108750 108751 108752 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", | | | 109117 109118 109119 109120 109121 109122 109123 109124 109125 109126 109127 109128 109129 109130 109131 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", "cname", "ccons", "term", "expr", "onconf", "sortorder", "autoinc", "idxlist_opt", "refargs", "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", "conslist", "tcons", "idxlist", "defer_subclause_opt", "orconf", "resolvetype", "raisetype", "ifexists", "fullname", "oneselect", "multiselect_op", "distinct", "selcollist", "from", "where_opt", "groupby_opt", "having_opt", "orderby_opt", "limit_opt", |
︙ | ︙ | |||
108826 108827 108828 108829 108830 108831 108832 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", | | | | | 109197 109198 109199 109200 109201 109202 109203 109204 109205 109206 109207 109208 109209 109210 109211 109212 109213 109214 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", /* 53 */ "carglist ::= carglist cname ccons", /* 54 */ "carglist ::=", /* 55 */ "cname ::= CONSTRAINT nm", /* 56 */ "cname ::=", /* 57 */ "ccons ::= DEFAULT term", /* 58 */ "ccons ::= DEFAULT LP expr RP", /* 59 */ "ccons ::= DEFAULT PLUS term", /* 60 */ "ccons ::= DEFAULT MINUS term", /* 61 */ "ccons ::= DEFAULT id", /* 62 */ "ccons ::= NULL onconf", /* 63 */ "ccons ::= NOT NULL onconf", |
︙ | ︙ | |||
108863 108864 108865 108866 108867 108868 108869 | /* 83 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", /* 84 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", /* 85 */ "init_deferred_pred_opt ::=", /* 86 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", /* 87 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", /* 88 */ "conslist_opt ::=", /* 89 */ "conslist_opt ::= COMMA conslist", | | | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 109234 109235 109236 109237 109238 109239 109240 109241 109242 109243 109244 109245 109246 109247 109248 109249 109250 109251 109252 109253 109254 109255 109256 109257 109258 109259 109260 109261 109262 109263 109264 109265 109266 109267 109268 109269 109270 109271 109272 109273 109274 109275 109276 109277 109278 109279 109280 109281 109282 109283 109284 109285 109286 109287 109288 109289 109290 109291 109292 109293 109294 109295 109296 109297 109298 109299 109300 109301 109302 109303 109304 109305 109306 109307 109308 109309 109310 109311 109312 109313 109314 109315 109316 109317 109318 109319 109320 109321 109322 109323 109324 109325 109326 109327 109328 109329 109330 109331 109332 109333 109334 109335 109336 109337 109338 109339 109340 109341 109342 109343 109344 109345 109346 109347 109348 109349 109350 109351 109352 109353 109354 109355 109356 109357 109358 109359 109360 109361 109362 109363 109364 109365 109366 109367 109368 109369 109370 109371 109372 109373 109374 109375 109376 109377 109378 109379 109380 109381 109382 109383 109384 109385 109386 109387 109388 109389 109390 109391 109392 109393 109394 109395 109396 109397 109398 109399 109400 109401 109402 109403 109404 109405 109406 109407 109408 109409 109410 109411 109412 109413 109414 109415 109416 109417 109418 109419 109420 109421 109422 109423 109424 109425 109426 109427 109428 109429 109430 109431 109432 109433 109434 109435 109436 109437 109438 109439 109440 109441 109442 109443 109444 109445 109446 109447 109448 109449 109450 109451 109452 109453 109454 109455 109456 109457 109458 109459 109460 109461 109462 109463 109464 109465 109466 109467 109468 109469 109470 109471 109472 109473 109474 109475 109476 109477 109478 109479 109480 109481 109482 | /* 83 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", /* 84 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", /* 85 */ "init_deferred_pred_opt ::=", /* 86 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", /* 87 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", /* 88 */ "conslist_opt ::=", /* 89 */ "conslist_opt ::= COMMA conslist", /* 90 */ "conslist ::= conslist COMMA cname tcons", /* 91 */ "conslist ::= cname tcons", /* 92 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", /* 93 */ "tcons ::= UNIQUE LP idxlist RP onconf", /* 94 */ "tcons ::= CHECK LP expr RP onconf", /* 95 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", /* 96 */ "defer_subclause_opt ::=", /* 97 */ "defer_subclause_opt ::= defer_subclause", /* 98 */ "onconf ::=", /* 99 */ "onconf ::= ON CONFLICT resolvetype", /* 100 */ "orconf ::=", /* 101 */ "orconf ::= OR resolvetype", /* 102 */ "resolvetype ::= raisetype", /* 103 */ "resolvetype ::= IGNORE", /* 104 */ "resolvetype ::= REPLACE", /* 105 */ "cmd ::= DROP TABLE ifexists fullname", /* 106 */ "ifexists ::= IF EXISTS", /* 107 */ "ifexists ::=", /* 108 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select", /* 109 */ "cmd ::= DROP VIEW ifexists fullname", /* 110 */ "cmd ::= select", /* 111 */ "select ::= oneselect", /* 112 */ "select ::= select multiselect_op oneselect", /* 113 */ "multiselect_op ::= UNION", /* 114 */ "multiselect_op ::= UNION ALL", /* 115 */ "multiselect_op ::= EXCEPT|INTERSECT", /* 116 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", /* 117 */ "distinct ::= DISTINCT", /* 118 */ "distinct ::= ALL", /* 119 */ "distinct ::=", /* 120 */ "sclp ::= selcollist COMMA", /* 121 */ "sclp ::=", /* 122 */ "selcollist ::= sclp expr as", /* 123 */ "selcollist ::= sclp STAR", /* 124 */ "selcollist ::= sclp nm DOT STAR", /* 125 */ "as ::= AS nm", /* 126 */ "as ::= ids", /* 127 */ "as ::=", /* 128 */ "from ::=", /* 129 */ "from ::= FROM seltablist", /* 130 */ "stl_prefix ::= seltablist joinop", /* 131 */ "stl_prefix ::=", /* 132 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", /* 133 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", /* 134 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", /* 135 */ "dbnm ::=", /* 136 */ "dbnm ::= DOT nm", /* 137 */ "fullname ::= nm dbnm", /* 138 */ "joinop ::= COMMA|JOIN", /* 139 */ "joinop ::= JOIN_KW JOIN", /* 140 */ "joinop ::= JOIN_KW nm JOIN", /* 141 */ "joinop ::= JOIN_KW nm nm JOIN", /* 142 */ "on_opt ::= ON expr", /* 143 */ "on_opt ::=", /* 144 */ "indexed_opt ::=", /* 145 */ "indexed_opt ::= INDEXED BY nm", /* 146 */ "indexed_opt ::= NOT INDEXED", /* 147 */ "using_opt ::= USING LP inscollist RP", /* 148 */ "using_opt ::=", /* 149 */ "orderby_opt ::=", /* 150 */ "orderby_opt ::= ORDER BY sortlist", /* 151 */ "sortlist ::= sortlist COMMA expr sortorder", /* 152 */ "sortlist ::= expr sortorder", /* 153 */ "sortorder ::= ASC", /* 154 */ "sortorder ::= DESC", /* 155 */ "sortorder ::=", /* 156 */ "groupby_opt ::=", /* 157 */ "groupby_opt ::= GROUP BY nexprlist", /* 158 */ "having_opt ::=", /* 159 */ "having_opt ::= HAVING expr", /* 160 */ "limit_opt ::=", /* 161 */ "limit_opt ::= LIMIT expr", /* 162 */ "limit_opt ::= LIMIT expr OFFSET expr", /* 163 */ "limit_opt ::= LIMIT expr COMMA expr", /* 164 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", /* 165 */ "where_opt ::=", /* 166 */ "where_opt ::= WHERE expr", /* 167 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", /* 168 */ "setlist ::= setlist COMMA nm EQ expr", /* 169 */ "setlist ::= nm EQ expr", /* 170 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist", /* 171 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", /* 173 */ "insert_cmd ::= INSERT orconf", /* 174 */ "insert_cmd ::= REPLACE", /* 175 */ "valuelist ::= VALUES LP nexprlist RP", /* 176 */ "valuelist ::= valuelist COMMA LP exprlist RP", /* 177 */ "inscollist_opt ::=", /* 178 */ "inscollist_opt ::= LP inscollist RP", /* 179 */ "inscollist ::= inscollist COMMA nm", /* 180 */ "inscollist ::= nm", /* 181 */ "expr ::= term", /* 182 */ "expr ::= LP expr RP", /* 183 */ "term ::= NULL", /* 184 */ "expr ::= id", /* 185 */ "expr ::= JOIN_KW", /* 186 */ "expr ::= nm DOT nm", /* 187 */ "expr ::= nm DOT nm DOT nm", /* 188 */ "term ::= INTEGER|FLOAT|BLOB", /* 189 */ "term ::= STRING", /* 190 */ "expr ::= REGISTER", /* 191 */ "expr ::= VARIABLE", /* 192 */ "expr ::= expr COLLATE ids", /* 193 */ "expr ::= CAST LP expr AS typetoken RP", /* 194 */ "expr ::= ID LP distinct exprlist RP", /* 195 */ "expr ::= ID LP STAR RP", /* 196 */ "term ::= CTIME_KW", /* 197 */ "expr ::= expr AND expr", /* 198 */ "expr ::= expr OR expr", /* 199 */ "expr ::= expr LT|GT|GE|LE expr", /* 200 */ "expr ::= expr EQ|NE expr", /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", /* 202 */ "expr ::= expr PLUS|MINUS expr", /* 203 */ "expr ::= expr STAR|SLASH|REM expr", /* 204 */ "expr ::= expr CONCAT expr", /* 205 */ "likeop ::= LIKE_KW", /* 206 */ "likeop ::= NOT LIKE_KW", /* 207 */ "likeop ::= MATCH", /* 208 */ "likeop ::= NOT 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 idxlist RP", /* 241 */ "uniqueflag ::= UNIQUE", /* 242 */ "uniqueflag ::=", /* 243 */ "idxlist_opt ::=", /* 244 */ "idxlist_opt ::= LP idxlist RP", /* 245 */ "idxlist ::= idxlist COMMA nm collate sortorder", /* 246 */ "idxlist ::= nm collate sortorder", /* 247 */ "collate ::=", /* 248 */ "collate ::= COLLATE ids", /* 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 number", /* 263 */ "plus_num ::= number", /* 264 */ "minus_num ::= MINUS number", /* 265 */ "number ::= INTEGER|FLOAT", /* 266 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", /* 267 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", /* 268 */ "trigger_time ::= BEFORE", /* 269 */ "trigger_time ::= AFTER", /* 270 */ "trigger_time ::= INSTEAD OF", /* 271 */ "trigger_time ::=", /* 272 */ "trigger_event ::= DELETE|INSERT", /* 273 */ "trigger_event ::= UPDATE", /* 274 */ "trigger_event ::= UPDATE OF inscollist", /* 275 */ "foreach_clause ::=", /* 276 */ "foreach_clause ::= FOR EACH ROW", /* 277 */ "when_clause ::=", /* 278 */ "when_clause ::= WHEN expr", /* 279 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", /* 280 */ "trigger_cmd_list ::= trigger_cmd SEMI", /* 281 */ "trnm ::= nm", /* 282 */ "trnm ::= nm DOT nm", /* 283 */ "tridxby ::=", /* 284 */ "tridxby ::= INDEXED BY nm", /* 285 */ "tridxby ::= NOT INDEXED", /* 286 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", /* 287 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist", /* 288 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", /* 289 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", /* 290 */ "trigger_cmd ::= select", /* 291 */ "expr ::= RAISE LP IGNORE RP", /* 292 */ "expr ::= RAISE LP raisetype COMMA nm RP", /* 293 */ "raisetype ::= ROLLBACK", /* 294 */ "raisetype ::= ABORT", /* 295 */ "raisetype ::= FAIL", /* 296 */ "cmd ::= DROP TRIGGER ifexists fullname", /* 297 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", /* 298 */ "cmd ::= DETACH database_kw_opt expr", /* 299 */ "key_opt ::=", /* 300 */ "key_opt ::= KEY expr", /* 301 */ "database_kw_opt ::= DATABASE", /* 302 */ "database_kw_opt ::=", /* 303 */ "cmd ::= REINDEX", /* 304 */ "cmd ::= REINDEX nm dbnm", /* 305 */ "cmd ::= ANALYZE", /* 306 */ "cmd ::= ANALYZE nm dbnm", /* 307 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", /* 308 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", /* 309 */ "add_column_fullname ::= fullname", /* 310 */ "kwcolumn_opt ::=", /* 311 */ "kwcolumn_opt ::= COLUMNKW", /* 312 */ "cmd ::= create_vtab", /* 313 */ "cmd ::= create_vtab LP vtabarglist RP", /* 314 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", /* 315 */ "vtabarglist ::= vtabarg", /* 316 */ "vtabarglist ::= vtabarglist COMMA vtabarg", /* 317 */ "vtabarg ::=", /* 318 */ "vtabarg ::= vtabarg vtabargtoken", /* 319 */ "vtabargtoken ::= ANY", /* 320 */ "vtabargtoken ::= lp anylist RP", /* 321 */ "lp ::= LP", /* 322 */ "anylist ::=", /* 323 */ "anylist ::= anylist LP anylist RP", /* 324 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 /* ** Try to increase the size of the parser stack. |
︙ | ︙ | |||
109545 109546 109547 109548 109549 109550 109551 | { 167, 1 }, { 167, 4 }, { 167, 6 }, { 168, 1 }, { 168, 2 }, { 169, 1 }, { 169, 1 }, | | | | | 109914 109915 109916 109917 109918 109919 109920 109921 109922 109923 109924 109925 109926 109927 109928 109929 109930 109931 | { 167, 1 }, { 167, 4 }, { 167, 6 }, { 168, 1 }, { 168, 2 }, { 169, 1 }, { 169, 1 }, { 164, 3 }, { 164, 0 }, { 172, 2 }, { 172, 0 }, { 173, 2 }, { 173, 4 }, { 173, 3 }, { 173, 3 }, { 173, 2 }, { 173, 2 }, { 173, 3 }, |
︙ | ︙ | |||
109582 109583 109584 109585 109586 109587 109588 | { 181, 3 }, { 181, 2 }, { 184, 0 }, { 184, 2 }, { 184, 2 }, { 159, 0 }, { 159, 2 }, | | < < | 109951 109952 109953 109954 109955 109956 109957 109958 109959 109960 109961 109962 109963 109964 109965 109966 | { 181, 3 }, { 181, 2 }, { 184, 0 }, { 184, 2 }, { 184, 2 }, { 159, 0 }, { 159, 2 }, { 185, 4 }, { 185, 2 }, { 186, 7 }, { 186, 5 }, { 186, 5 }, { 186, 10 }, { 188, 0 }, { 188, 1 }, { 176, 0 }, |
︙ | ︙ | |||
109894 109895 109896 109897 109898 109899 109900 | break; case 13: /* transtype ::= */ {yygotominor.yy392 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); | | | | 110261 110262 110263 110264 110265 110266 110267 110268 110269 110270 110271 110272 110273 110274 110275 110276 | break; case 13: /* transtype ::= */ {yygotominor.yy392 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); case 113: /* multiselect_op ::= UNION */ yytestcase(yyruleno==113); case 115: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==115); {yygotominor.yy392 = yymsp[0].major;} break; case 17: /* cmd ::= COMMIT trans_opt */ case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); {sqlite3CommitTransaction(pParse);} break; case 19: /* cmd ::= ROLLBACK trans_opt */ |
︙ | ︙ | |||
109937 109938 109939 109940 109941 109942 109943 | break; case 28: /* ifnotexists ::= */ case 31: /* temp ::= */ yytestcase(yyruleno==31); case 70: /* autoinc ::= */ yytestcase(yyruleno==70); case 83: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83); case 85: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==85); case 87: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==87); | | | | | | | | | | | | 110304 110305 110306 110307 110308 110309 110310 110311 110312 110313 110314 110315 110316 110317 110318 110319 110320 110321 110322 110323 110324 110325 110326 110327 110328 110329 110330 110331 110332 110333 | break; case 28: /* ifnotexists ::= */ case 31: /* temp ::= */ yytestcase(yyruleno==31); case 70: /* autoinc ::= */ yytestcase(yyruleno==70); case 83: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83); case 85: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==85); case 87: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==87); case 96: /* defer_subclause_opt ::= */ yytestcase(yyruleno==96); case 107: /* ifexists ::= */ yytestcase(yyruleno==107); case 118: /* distinct ::= ALL */ yytestcase(yyruleno==118); case 119: /* distinct ::= */ yytestcase(yyruleno==119); case 219: /* between_op ::= BETWEEN */ yytestcase(yyruleno==219); case 222: /* in_op ::= IN */ yytestcase(yyruleno==222); {yygotominor.yy392 = 0;} break; case 29: /* ifnotexists ::= IF NOT EXISTS */ case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71); case 86: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==86); case 106: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==106); case 117: /* distinct ::= DISTINCT */ yytestcase(yyruleno==117); case 220: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==220); case 223: /* in_op ::= NOT IN */ yytestcase(yyruleno==223); {yygotominor.yy392 = 1;} break; case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ { sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0); } break; |
︙ | ︙ | |||
109986 109987 109988 109989 109990 109991 109992 | case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39); case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40); case 41: /* nm ::= id */ yytestcase(yyruleno==41); case 42: /* nm ::= STRING */ yytestcase(yyruleno==42); case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43); case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46); case 49: /* typename ::= ids */ yytestcase(yyruleno==49); | | | | | | | | | | | | | | | | > > > > > > | 110353 110354 110355 110356 110357 110358 110359 110360 110361 110362 110363 110364 110365 110366 110367 110368 110369 110370 110371 110372 110373 110374 110375 110376 110377 110378 110379 110380 110381 110382 110383 110384 110385 110386 110387 110388 110389 110390 110391 110392 110393 110394 110395 110396 110397 110398 110399 110400 110401 110402 110403 110404 110405 110406 | case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39); case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40); case 41: /* nm ::= id */ yytestcase(yyruleno==41); case 42: /* nm ::= STRING */ yytestcase(yyruleno==42); case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43); case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46); case 49: /* typename ::= ids */ yytestcase(yyruleno==49); case 125: /* as ::= AS nm */ yytestcase(yyruleno==125); case 126: /* as ::= ids */ yytestcase(yyruleno==126); case 136: /* dbnm ::= DOT nm */ yytestcase(yyruleno==136); case 145: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==145); case 248: /* collate ::= COLLATE ids */ yytestcase(yyruleno==248); 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 number */ yytestcase(yyruleno==262); case 263: /* plus_num ::= number */ yytestcase(yyruleno==263); case 264: /* minus_num ::= MINUS number */ yytestcase(yyruleno==264); case 265: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==265); case 281: /* trnm ::= nm */ yytestcase(yyruleno==281); {yygotominor.yy0 = yymsp[0].minor.yy0;} break; case 45: /* type ::= typetoken */ {sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);} break; case 47: /* typetoken ::= typename LP signed RP */ { yygotominor.yy0.z = yymsp[-3].minor.yy0.z; yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); } break; case 48: /* typetoken ::= typename LP signed COMMA signed RP */ { yygotominor.yy0.z = yymsp[-5].minor.yy0.z; yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); } break; case 50: /* typename ::= typename ids */ {yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} break; case 55: /* cname ::= CONSTRAINT nm */ {pParse->constraintName = yymsp[0].minor.yy0;} break; case 56: /* cname ::= */ {pParse->constraintName.n = 0;} break; case 57: /* ccons ::= DEFAULT term */ case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); {sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);} break; case 58: /* ccons ::= DEFAULT LP expr RP */ {sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);} |
︙ | ︙ | |||
110097 110098 110099 110100 110101 110102 110103 | case 81: /* refact ::= RESTRICT */ { yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */} break; case 82: /* refact ::= NO ACTION */ { yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */} break; case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 110470 110471 110472 110473 110474 110475 110476 110477 110478 110479 110480 110481 110482 110483 110484 110485 110486 110487 110488 110489 110490 110491 110492 110493 110494 110495 110496 110497 110498 110499 110500 110501 110502 110503 110504 110505 110506 110507 110508 110509 110510 110511 110512 110513 110514 110515 110516 110517 110518 110519 110520 110521 110522 110523 110524 110525 110526 110527 110528 110529 110530 110531 110532 110533 110534 110535 110536 110537 110538 110539 110540 110541 110542 110543 110544 110545 110546 110547 110548 110549 110550 110551 110552 110553 110554 110555 110556 110557 110558 110559 110560 110561 110562 110563 110564 110565 110566 110567 110568 110569 110570 110571 110572 110573 110574 110575 110576 110577 110578 110579 110580 110581 110582 110583 110584 110585 110586 110587 110588 110589 110590 110591 110592 110593 110594 110595 110596 110597 110598 110599 110600 110601 110602 110603 110604 110605 110606 110607 110608 110609 110610 110611 110612 110613 110614 110615 110616 110617 110618 110619 110620 110621 110622 110623 110624 110625 110626 110627 110628 110629 110630 110631 110632 110633 110634 110635 110636 110637 110638 110639 110640 110641 110642 110643 110644 110645 110646 110647 110648 110649 110650 110651 110652 110653 110654 110655 110656 110657 110658 110659 110660 110661 110662 110663 110664 110665 110666 110667 110668 110669 110670 110671 110672 110673 110674 110675 110676 110677 110678 110679 110680 110681 110682 110683 110684 110685 110686 110687 110688 110689 110690 110691 110692 110693 110694 110695 110696 110697 110698 110699 110700 110701 110702 110703 110704 110705 110706 110707 110708 110709 110710 110711 110712 110713 110714 110715 110716 110717 110718 110719 110720 110721 110722 110723 110724 110725 110726 110727 110728 110729 110730 110731 110732 110733 110734 110735 110736 110737 110738 110739 110740 110741 110742 110743 110744 110745 110746 110747 110748 110749 110750 110751 110752 110753 110754 110755 110756 110757 110758 110759 110760 110761 110762 110763 110764 110765 110766 110767 110768 110769 110770 110771 110772 110773 110774 110775 110776 110777 110778 110779 110780 110781 110782 110783 110784 110785 110786 110787 110788 110789 110790 110791 110792 110793 110794 110795 110796 110797 110798 110799 110800 110801 110802 110803 110804 110805 110806 110807 110808 110809 110810 110811 110812 110813 110814 110815 110816 110817 110818 110819 110820 110821 110822 110823 110824 110825 110826 110827 110828 110829 110830 110831 110832 110833 110834 110835 110836 110837 110838 110839 110840 110841 110842 110843 110844 110845 110846 110847 110848 110849 110850 110851 110852 110853 110854 110855 110856 110857 110858 110859 110860 110861 110862 110863 110864 110865 110866 110867 110868 110869 110870 110871 110872 110873 110874 110875 110876 110877 110878 110879 110880 110881 110882 110883 110884 110885 110886 110887 110888 110889 110890 110891 110892 110893 110894 110895 110896 110897 110898 110899 110900 110901 110902 110903 110904 110905 110906 110907 110908 110909 110910 110911 110912 110913 110914 110915 110916 110917 110918 110919 110920 110921 110922 110923 110924 110925 110926 110927 110928 110929 110930 110931 110932 110933 110934 110935 110936 110937 110938 110939 110940 110941 110942 110943 110944 110945 110946 110947 110948 110949 110950 110951 110952 110953 110954 110955 110956 110957 110958 110959 110960 110961 110962 110963 110964 110965 110966 110967 110968 110969 110970 110971 110972 110973 110974 110975 110976 110977 110978 110979 110980 110981 110982 110983 110984 | case 81: /* refact ::= RESTRICT */ { yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */} break; case 82: /* refact ::= NO ACTION */ { yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */} break; case 84: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 97: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==97); case 99: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==99); case 102: /* resolvetype ::= raisetype */ yytestcase(yyruleno==102); {yygotominor.yy392 = yymsp[0].minor.yy392;} break; case 88: /* conslist_opt ::= */ {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} break; case 89: /* conslist_opt ::= COMMA conslist */ {yygotominor.yy0 = yymsp[-1].minor.yy0;} break; case 92: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);} break; case 93: /* tcons ::= UNIQUE LP idxlist RP onconf */ {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);} break; case 94: /* tcons ::= CHECK LP expr RP onconf */ {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);} break; case 95: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ { sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392); sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392); } break; case 98: /* onconf ::= */ {yygotominor.yy392 = OE_Default;} break; case 100: /* orconf ::= */ {yygotominor.yy258 = OE_Default;} break; case 101: /* orconf ::= OR resolvetype */ {yygotominor.yy258 = (u8)yymsp[0].minor.yy392;} break; case 103: /* resolvetype ::= IGNORE */ {yygotominor.yy392 = OE_Ignore;} break; case 104: /* resolvetype ::= REPLACE */ {yygotominor.yy392 = OE_Replace;} break; case 105: /* cmd ::= DROP TABLE ifexists fullname */ { sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392); } break; case 108: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ { sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392); } break; case 109: /* cmd ::= DROP VIEW ifexists fullname */ { sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392); } break; case 110: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, yymsp[0].minor.yy159, &dest); sqlite3ExplainBegin(pParse->pVdbe); sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159); sqlite3ExplainFinish(pParse->pVdbe); sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159); } break; case 111: /* select ::= oneselect */ {yygotominor.yy159 = yymsp[0].minor.yy159;} break; case 112: /* select ::= select multiselect_op oneselect */ { if( yymsp[0].minor.yy159 ){ yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392; yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159; }else{ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159); } yygotominor.yy159 = yymsp[0].minor.yy159; } break; case 114: /* multiselect_op ::= UNION ALL */ {yygotominor.yy392 = TK_ALL;} break; case 116: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset); } break; case 120: /* sclp ::= selcollist COMMA */ case 244: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==244); {yygotominor.yy442 = yymsp[-1].minor.yy442;} break; case 121: /* sclp ::= */ case 149: /* orderby_opt ::= */ yytestcase(yyruleno==149); case 156: /* groupby_opt ::= */ yytestcase(yyruleno==156); case 237: /* exprlist ::= */ yytestcase(yyruleno==237); case 243: /* idxlist_opt ::= */ yytestcase(yyruleno==243); {yygotominor.yy442 = 0;} break; case 122: /* selcollist ::= sclp expr as */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr); if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1); sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342); } break; case 123: /* selcollist ::= sclp STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p); } break; case 124: /* selcollist ::= sclp nm DOT STAR */ { Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot); } break; case 127: /* as ::= */ {yygotominor.yy0.n = 0;} break; case 128: /* from ::= */ {yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));} break; case 129: /* from ::= FROM seltablist */ { yygotominor.yy347 = yymsp[0].minor.yy347; sqlite3SrcListShiftJoinType(yygotominor.yy347); } break; case 130: /* stl_prefix ::= seltablist joinop */ { yygotominor.yy347 = yymsp[-1].minor.yy347; if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392; } break; case 131: /* stl_prefix ::= */ {yygotominor.yy347 = 0;} break; case 132: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0); } break; case 133: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); } break; case 134: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){ yygotominor.yy347 = yymsp[-4].minor.yy347; }else{ Select *pSubquery; sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347); pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0); yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180); } } break; case 135: /* dbnm ::= */ case 144: /* indexed_opt ::= */ yytestcase(yyruleno==144); {yygotominor.yy0.z=0; yygotominor.yy0.n=0;} break; case 137: /* fullname ::= nm dbnm */ {yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; case 138: /* joinop ::= COMMA|JOIN */ { yygotominor.yy392 = JT_INNER; } break; case 139: /* joinop ::= JOIN_KW JOIN */ { yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } break; case 140: /* joinop ::= JOIN_KW nm JOIN */ { yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } break; case 141: /* joinop ::= JOIN_KW nm nm JOIN */ { yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } break; case 142: /* on_opt ::= ON expr */ case 159: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==159); case 166: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==166); case 232: /* case_else ::= ELSE expr */ yytestcase(yyruleno==232); case 234: /* case_operand ::= expr */ yytestcase(yyruleno==234); {yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;} break; case 143: /* on_opt ::= */ case 158: /* having_opt ::= */ yytestcase(yyruleno==158); case 165: /* where_opt ::= */ yytestcase(yyruleno==165); case 233: /* case_else ::= */ yytestcase(yyruleno==233); case 235: /* case_operand ::= */ yytestcase(yyruleno==235); {yygotominor.yy122 = 0;} break; case 146: /* indexed_opt ::= NOT INDEXED */ {yygotominor.yy0.z=0; yygotominor.yy0.n=1;} break; case 147: /* using_opt ::= USING LP inscollist RP */ case 178: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==178); {yygotominor.yy180 = yymsp[-1].minor.yy180;} break; case 148: /* using_opt ::= */ case 177: /* inscollist_opt ::= */ yytestcase(yyruleno==177); {yygotominor.yy180 = 0;} break; case 150: /* orderby_opt ::= ORDER BY sortlist */ case 157: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==157); case 236: /* exprlist ::= nexprlist */ yytestcase(yyruleno==236); {yygotominor.yy442 = yymsp[0].minor.yy442;} break; case 151: /* sortlist ::= sortlist COMMA expr sortorder */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr); if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; } break; case 152: /* sortlist ::= expr sortorder */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr); if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392; } break; case 153: /* sortorder ::= ASC */ case 155: /* sortorder ::= */ yytestcase(yyruleno==155); {yygotominor.yy392 = SQLITE_SO_ASC;} break; case 154: /* sortorder ::= DESC */ {yygotominor.yy392 = SQLITE_SO_DESC;} break; case 160: /* limit_opt ::= */ {yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;} break; case 161: /* limit_opt ::= LIMIT expr */ {yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;} break; case 162: /* limit_opt ::= LIMIT expr OFFSET expr */ {yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;} break; case 163: /* limit_opt ::= LIMIT expr COMMA expr */ {yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;} break; case 164: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ { sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0); sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122); } break; case 167: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ { sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0); sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list"); sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258); } break; case 168: /* setlist ::= setlist COMMA nm EQ expr */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr); sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); } break; case 169: /* setlist ::= nm EQ expr */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr); sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); } break; case 170: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */ {sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);} break; case 171: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ {sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);} break; case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ {sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);} break; case 173: /* insert_cmd ::= INSERT orconf */ {yygotominor.yy258 = yymsp[0].minor.yy258;} break; case 174: /* insert_cmd ::= REPLACE */ {yygotominor.yy258 = OE_Replace;} break; case 175: /* valuelist ::= VALUES LP nexprlist RP */ { yygotominor.yy487.pList = yymsp[-1].minor.yy442; yygotominor.yy487.pSelect = 0; } break; case 176: /* valuelist ::= valuelist COMMA LP exprlist RP */ { Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0); if( yymsp[-4].minor.yy487.pList ){ yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0); yymsp[-4].minor.yy487.pList = 0; } yygotominor.yy487.pList = 0; if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){ sqlite3SelectDelete(pParse->db, pRight); sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect); yygotominor.yy487.pSelect = 0; }else{ pRight->op = TK_ALL; pRight->pPrior = yymsp[-4].minor.yy487.pSelect; pRight->selFlags |= SF_Values; pRight->pPrior->selFlags |= SF_Values; yygotominor.yy487.pSelect = pRight; } } break; case 179: /* inscollist ::= inscollist COMMA nm */ {yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);} break; case 180: /* inscollist ::= nm */ {yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} break; case 181: /* expr ::= term */ {yygotominor.yy342 = yymsp[0].minor.yy342;} break; case 182: /* expr ::= LP expr RP */ {yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} break; case 183: /* term ::= NULL */ case 188: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==188); case 189: /* term ::= STRING */ yytestcase(yyruleno==189); {spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} break; case 184: /* expr ::= id */ case 185: /* expr ::= JOIN_KW */ yytestcase(yyruleno==185); {spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);} break; case 186: /* 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.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } break; case 187: /* 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.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); } break; case 190: /* expr ::= REGISTER */ { /* 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. */ if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); yygotominor.yy342.pExpr = 0; }else{ yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable); } spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 191: /* expr ::= VARIABLE */ { spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr); spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 192: /* expr ::= expr COLLATE ids */ { yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0); yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 193: /* expr ::= CAST LP expr AS typetoken RP */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0); spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } break; case 194: /* expr ::= ID LP distinct exprlist RP */ { if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); } yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0); spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->flags |= EP_Distinct; } } break; case 195: /* expr ::= ID LP STAR RP */ { yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } break; case 196: /* term ::= CTIME_KW */ { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->op = TK_CONST_FUNC; } spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 197: /* expr ::= expr AND expr */ case 198: /* expr ::= expr OR expr */ yytestcase(yyruleno==198); case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200); case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201); case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); {spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);} break; case 205: /* likeop ::= LIKE_KW */ case 207: /* likeop ::= MATCH */ yytestcase(yyruleno==207); {yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;} break; case 206: /* likeop ::= NOT LIKE_KW */ case 208: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==208); {yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;} break; case 209: /* expr ::= expr likeop expr */ { ExprList *pList; pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr); pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr); yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator); if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart; yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc; } break; case 210: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr); yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator); if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc; } break; case 211: /* expr ::= expr ISNULL|NOTNULL */ {spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);} break; case 212: /* expr ::= expr NOT NULL */ {spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);} break; case 213: /* expr ::= expr IS expr */ { spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL); } break; case 214: /* expr ::= expr IS NOT expr */ { spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL); } break; case 215: /* expr ::= NOT expr */ case 216: /* expr ::= BITNOT expr */ yytestcase(yyruleno==216); {spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} break; case 217: /* expr ::= MINUS expr */ {spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} break; case 218: /* expr ::= PLUS expr */ {spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);} break; case 221: /* expr ::= expr between_op expr AND expr */ { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr); yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd; } break; case 224: /* expr ::= expr in_op LP exprlist RP */ { if( yymsp[-1].minor.yy442==0 ){ /* Expressions of the form ** ** expr1 IN () ** expr1 NOT IN () ** |
︙ | ︙ | |||
110624 110625 110626 110627 110628 110629 110630 | } if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); } yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | < < | | | | | | | | | | | | | | 110997 110998 110999 111000 111001 111002 111003 111004 111005 111006 111007 111008 111009 111010 111011 111012 111013 111014 111015 111016 111017 111018 111019 111020 111021 111022 111023 111024 111025 111026 111027 111028 111029 111030 111031 111032 111033 111034 111035 111036 111037 111038 111039 111040 111041 111042 111043 111044 111045 111046 111047 111048 111049 111050 111051 111052 111053 111054 111055 111056 111057 111058 111059 111060 111061 111062 111063 111064 111065 111066 111067 111068 111069 111070 111071 111072 111073 111074 111075 111076 111077 111078 111079 111080 111081 111082 111083 111084 111085 111086 111087 111088 111089 111090 111091 111092 111093 111094 111095 111096 111097 111098 111099 111100 111101 111102 111103 111104 111105 111106 111107 111108 111109 111110 111111 111112 111113 111114 111115 111116 111117 111118 111119 111120 111121 111122 111123 111124 111125 111126 111127 111128 111129 111130 111131 111132 111133 111134 111135 111136 111137 111138 111139 111140 111141 111142 111143 111144 111145 111146 111147 111148 111149 111150 111151 111152 111153 111154 111155 111156 111157 111158 111159 111160 111161 111162 111163 111164 111165 111166 111167 111168 111169 111170 111171 111172 111173 111174 111175 111176 111177 111178 111179 111180 111181 111182 111183 111184 111185 111186 111187 111188 111189 111190 111191 111192 111193 111194 111195 111196 111197 111198 111199 111200 111201 111202 111203 111204 111205 111206 111207 111208 111209 111210 111211 111212 111213 111214 111215 111216 111217 111218 111219 111220 111221 111222 111223 111224 111225 111226 111227 111228 111229 111230 111231 111232 111233 111234 111235 111236 111237 111238 111239 111240 111241 111242 111243 111244 111245 111246 111247 111248 111249 111250 111251 111252 111253 111254 111255 111256 111257 111258 111259 111260 111261 111262 111263 111264 111265 111266 111267 111268 111269 111270 111271 111272 111273 111274 111275 111276 111277 111278 111279 111280 111281 111282 111283 111284 111285 111286 111287 111288 111289 111290 111291 111292 111293 111294 111295 111296 111297 111298 111299 111300 111301 111302 111303 111304 111305 111306 111307 111308 111309 111310 111311 111312 111313 111314 111315 111316 111317 111318 111319 111320 111321 111322 111323 111324 111325 111326 111327 111328 111329 111330 111331 111332 111333 111334 111335 111336 111337 111338 111339 111340 111341 111342 111343 111344 111345 111346 111347 111348 111349 111350 111351 111352 111353 111354 111355 111356 111357 111358 111359 111360 111361 111362 111363 111364 111365 111366 111367 111368 111369 111370 111371 111372 111373 111374 111375 111376 111377 111378 111379 | } if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); } yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 225: /* expr ::= LP select RP */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159; ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); } yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 226: /* expr ::= expr in_op LP select RP */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159; ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); } if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 227: /* expr ::= expr in_op nm dbnm */ { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect); sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); }else{ sqlite3SrcListDelete(pParse->db, pSrc); } if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0); yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart; yygotominor.yy342.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 228: /* expr ::= EXISTS LP select RP */ { Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ p->x.pSelect = yymsp[-1].minor.yy159; ExprSetProperty(p, EP_xIsSelect); sqlite3ExprSetHeight(pParse, p); }else{ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159); } yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 229: /* expr ::= CASE case_operand case_exprlist case_else END */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442; sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); }else{ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442); } yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 230: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr); yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr); } break; case 231: /* case_exprlist ::= WHEN expr THEN expr */ { yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr); yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr); } break; case 238: /* nexprlist ::= nexprlist COMMA expr */ {yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);} break; case 239: /* nexprlist ::= expr */ {yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);} break; case 240: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392, &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392); } break; case 241: /* uniqueflag ::= UNIQUE */ case 294: /* raisetype ::= ABORT */ yytestcase(yyruleno==294); {yygotominor.yy392 = OE_Abort;} break; case 242: /* uniqueflag ::= */ {yygotominor.yy392 = OE_None;} break; case 245: /* idxlist ::= idxlist COMMA nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3Expr(pParse->db, TK_COLUMN, 0); sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p); sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1); sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index"); if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; } break; case 246: /* idxlist ::= nm collate sortorder */ { Expr *p = 0; if( yymsp[-1].minor.yy0.n>0 ){ p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0); } yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p); sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1); sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index"); if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392; } break; case 247: /* collate ::= */ {yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} break; case 249: /* cmd ::= DROP INDEX ifexists fullname */ {sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);} break; case 250: /* cmd ::= VACUUM */ case 251: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==251); {sqlite3Vacuum(pParse);} break; case 252: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; 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 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 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 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 266: /* 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.yy327, &all); } break; case 267: /* 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.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392); yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); } break; case 268: /* trigger_time ::= BEFORE */ case 271: /* trigger_time ::= */ yytestcase(yyruleno==271); { yygotominor.yy392 = TK_BEFORE; } break; case 269: /* trigger_time ::= AFTER */ { yygotominor.yy392 = TK_AFTER; } break; case 270: /* trigger_time ::= INSTEAD OF */ { yygotominor.yy392 = TK_INSTEAD;} break; case 272: /* trigger_event ::= DELETE|INSERT */ case 273: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==273); {yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;} break; case 274: /* trigger_event ::= UPDATE OF inscollist */ {yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;} break; case 277: /* when_clause ::= */ case 299: /* key_opt ::= */ yytestcase(yyruleno==299); { yygotominor.yy122 = 0; } break; case 278: /* when_clause ::= WHEN expr */ case 300: /* key_opt ::= KEY expr */ yytestcase(yyruleno==300); { yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; } break; case 279: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { assert( yymsp[-2].minor.yy327!=0 ); yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327; yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327; yygotominor.yy327 = yymsp[-2].minor.yy327; } break; case 280: /* trigger_cmd_list ::= trigger_cmd SEMI */ { assert( yymsp[-1].minor.yy327!=0 ); yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327; yygotominor.yy327 = yymsp[-1].minor.yy327; } break; case 282: /* 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 284: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; case 285: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; case 286: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ { yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); } break; case 287: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */ {yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);} break; case 288: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ {yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);} break; case 289: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ {yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);} break; case 290: /* trigger_cmd ::= select */ {yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); } break; case 291: /* expr ::= RAISE LP IGNORE RP */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); if( yygotominor.yy342.pExpr ){ yygotominor.yy342.pExpr->affinity = OE_Ignore; } yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 292: /* expr ::= RAISE LP raisetype COMMA nm RP */ { yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); if( yygotominor.yy342.pExpr ) { yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392; } yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z; yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 293: /* raisetype ::= ROLLBACK */ {yygotominor.yy392 = OE_Rollback;} break; case 295: /* raisetype ::= FAIL */ {yygotominor.yy392 = OE_Fail;} break; case 296: /* cmd ::= DROP TRIGGER ifexists fullname */ { sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392); } break; case 297: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122); } break; case 298: /* cmd ::= DETACH database_kw_opt expr */ { sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr); } break; case 303: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; case 304: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; case 305: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; case 306: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; case 307: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0); } break; case 308: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; case 309: /* add_column_fullname ::= fullname */ { pParse->db->lookaside.bEnabled = 0; sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347); } break; case 312: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; case 313: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; case 314: /* 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.yy392); } break; case 317: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; case 319: /* vtabargtoken ::= ANY */ case 320: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==320); case 321: /* lp ::= LP */ yytestcase(yyruleno==321); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; default: /* (0) input ::= cmdlist */ yytestcase(yyruleno==0); /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1); /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2); /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3); /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4); /* (10) trans_opt ::= */ yytestcase(yyruleno==10); /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11); /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12); /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20); /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21); /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25); /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34); /* (35) columnlist ::= column */ yytestcase(yyruleno==35); /* (44) type ::= */ yytestcase(yyruleno==44); /* (51) signed ::= plus_num */ yytestcase(yyruleno==51); /* (52) signed ::= minus_num */ yytestcase(yyruleno==52); /* (53) carglist ::= carglist cname ccons */ yytestcase(yyruleno==53); /* (54) carglist ::= */ yytestcase(yyruleno==54); /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62); /* (90) conslist ::= conslist COMMA cname tcons */ yytestcase(yyruleno==90); /* (91) conslist ::= cname tcons */ yytestcase(yyruleno==91); /* (275) foreach_clause ::= */ yytestcase(yyruleno==275); /* (276) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==276); /* (283) tridxby ::= */ yytestcase(yyruleno==283); /* (301) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==301); /* (302) database_kw_opt ::= */ yytestcase(yyruleno==302); /* (310) kwcolumn_opt ::= */ yytestcase(yyruleno==310); /* (311) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==311); /* (315) vtabarglist ::= vtabarg */ yytestcase(yyruleno==315); /* (316) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==316); /* (318) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==318); /* (322) anylist ::= */ yytestcase(yyruleno==322); /* (323) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==323); /* (324) anylist ::= anylist ANY */ yytestcase(yyruleno==324); break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); if( yyact < YYNSTATE ){ |
︙ | ︙ | |||
115891 115892 115893 115894 115895 115896 115897 | ** ** FTS3 used to optionally store character offsets using a compile-time ** option. But that functionality is no longer supported. ** ** A doclist is stored like this: ** ** array { | | | 116260 116261 116262 116263 116264 116265 116266 116267 116268 116269 116270 116271 116272 116273 116274 | ** ** FTS3 used to optionally store character offsets using a compile-time ** option. But that functionality is no longer supported. ** ** A doclist is stored like this: ** ** array { ** varint docid; (delta from previous doclist) ** array { (position list for column 0) ** varint position; (2 more than the delta from previous position) ** } ** array { ** varint POS_COLUMN; (marks start of position list for new column) ** varint column; (index of new column) ** array { |
︙ | ︙ | |||
115922 115923 115924 115925 115926 115927 115928 | ** value: 123 5 9 1 1 14 35 0 234 72 0 ** ** The 123 value is the first docid. For column zero in this document ** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 ** at D signals the start of a new column; the 1 at E indicates that the ** new column is column number 1. There are two positions at 12 and 45 ** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The | | | | 116291 116292 116293 116294 116295 116296 116297 116298 116299 116300 116301 116302 116303 116304 116305 116306 | ** value: 123 5 9 1 1 14 35 0 234 72 0 ** ** The 123 value is the first docid. For column zero in this document ** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 ** at D signals the start of a new column; the 1 at E indicates that the ** new column is column number 1. There are two positions at 12 and 45 ** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The ** 234 at I is the delta to next docid (357). It has one position 70 ** (72-2) and then terminates with the 0 at K. ** ** A "position-list" is the list of positions for multiple columns for ** a single docid. A "column-list" is the set of positions for a single ** column. Hence, a position-list consists of one or more column-lists, ** a document record consists of a docid followed by a position-list and ** a doclist consists of one or more document records. ** |
︙ | ︙ | |||
116458 116459 116460 116461 116462 116463 116464 116465 116466 116467 116468 116469 116470 116471 | */ #define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) #ifndef MIN # define MIN(x,y) ((x)<(y)?(x):(y)) #endif /* ** Maximum length of a varint encoded integer. The varint format is different ** from that used by SQLite, so the maximum length is 10, not 9. */ #define FTS3_VARINT_MAX 10 | > > > | 116827 116828 116829 116830 116831 116832 116833 116834 116835 116836 116837 116838 116839 116840 116841 116842 116843 | */ #define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) #ifndef MIN # define MIN(x,y) ((x)<(y)?(x):(y)) #endif #ifndef MAX # define MAX(x,y) ((x)>(y)?(x):(y)) #endif /* ** Maximum length of a varint encoded integer. The varint format is different ** from that used by SQLite, so the maximum length is 10, not 9. */ #define FTS3_VARINT_MAX 10 |
︙ | ︙ | |||
116512 116513 116514 116515 116516 116517 116518 | ** false. */ #ifdef SQLITE_COVERAGE_TEST # define ALWAYS(x) (1) # define NEVER(X) (0) #else # define ALWAYS(x) (x) | | > | 116884 116885 116886 116887 116888 116889 116890 116891 116892 116893 116894 116895 116896 116897 116898 116899 116900 116901 116902 116903 116904 116905 116906 116907 116908 | ** false. */ #ifdef SQLITE_COVERAGE_TEST # define ALWAYS(x) (1) # define NEVER(X) (0) #else # define ALWAYS(x) (x) # define NEVER(x) (x) #endif /* ** Internal types used by SQLite. */ typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ typedef short int i16; /* 2-byte (or larger) signed integer */ typedef unsigned int u32; /* 4-byte unsigned integer */ typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ typedef sqlite3_int64 i64; /* 8-byte signed integer */ /* ** Macro used to suppress compiler warnings for unused parameters. */ #define UNUSED_PARAMETER(x) (void)(x) /* |
︙ | ︙ | |||
116584 116585 116586 116587 116588 116589 116590 116591 116592 116593 116594 | const char *zDb; /* logical database name */ const char *zName; /* virtual table name */ int nColumn; /* number of named columns in virtual table */ char **azColumn; /* column names. malloced */ sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ char *zContentTbl; /* content=xxx option, or NULL */ char *zLanguageid; /* languageid=xxx option, or NULL */ /* Precompiled statements used by the implementation. Each of these ** statements is run and reset within a single virtual table API call. */ | > > | > > | < | < < > | < > > > > > > | 116957 116958 116959 116960 116961 116962 116963 116964 116965 116966 116967 116968 116969 116970 116971 116972 116973 116974 116975 116976 116977 116978 116979 116980 116981 116982 116983 116984 116985 116986 116987 116988 116989 116990 116991 116992 116993 116994 116995 116996 116997 116998 116999 117000 117001 117002 117003 117004 117005 117006 117007 | const char *zDb; /* logical database name */ const char *zName; /* virtual table name */ int nColumn; /* number of named columns in virtual table */ char **azColumn; /* column names. malloced */ sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ char *zContentTbl; /* content=xxx option, or NULL */ char *zLanguageid; /* languageid=xxx option, or NULL */ u8 bAutoincrmerge; /* True if automerge=1 */ u32 nLeafAdd; /* Number of leaf blocks added this trans */ /* Precompiled statements used by the implementation. Each of these ** statements is run and reset within a single virtual table API call. */ sqlite3_stmt *aStmt[37]; char *zReadExprlist; char *zWriteExprlist; int nNodeSize; /* Soft limit for node size */ u8 bFts4; /* True for FTS4, false for FTS3 */ u8 bHasStat; /* True if %_stat table exists */ u8 bHasDocsize; /* True if %_docsize table exists */ u8 bDescIdx; /* True if doclists are in reverse order */ u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ /* ** The following array of hash tables is used to buffer pending index ** updates during transactions. All pending updates buffered at any one ** time must share a common language-id (see the FTS4 langid= feature). ** The current language id is stored in variable iPrevLangid. ** ** A single FTS4 table may have multiple full-text indexes. For each index ** there is an entry in the aIndex[] array. Index 0 is an index of all the ** terms that appear in the document set. Each subsequent index in aIndex[] ** is an index of prefixes of a specific length. ** ** Variable nPendingData contains an estimate the memory consumed by the ** pending data structures, including hash table overhead, but not including ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash ** tables are flushed to disk. Variable iPrevDocid is the docid of the most ** recently inserted record. */ int nIndex; /* Size of aIndex[] */ struct Fts3Index { int nPrefix; /* Prefix length (0 for main terms index) */ Fts3Hash hPending; /* Pending terms table for this index */ } *aIndex; int nMaxPendingData; /* Max pending data before flush to disk */ |
︙ | ︙ | |||
116812 116813 116814 116815 116816 116817 116818 116819 116820 116821 116822 116823 116824 116825 | SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); /* Special values interpreted by sqlite3SegReaderCursor() */ #define FTS3_SEGCURSOR_PENDING -1 #define FTS3_SEGCURSOR_ALL -2 SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); | > | 117192 117193 117194 117195 117196 117197 117198 117199 117200 117201 117202 117203 117204 117205 117206 | SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); /* Special values interpreted by sqlite3SegReaderCursor() */ #define FTS3_SEGCURSOR_PENDING -1 #define FTS3_SEGCURSOR_ALL -2 SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); |
︙ | ︙ | |||
116863 116864 116865 116866 116867 116868 116869 116870 116871 116872 116873 116874 116875 116876 116877 116878 116879 116880 116881 116882 116883 116884 116885 | /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ char *zTerm; /* Pointer to term buffer */ int nTerm; /* Size of zTerm in bytes */ char *aDoclist; /* Pointer to doclist buffer */ int nDoclist; /* Size of aDoclist[] in bytes */ }; /* fts3.c */ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); /* fts3_tokenizer.c */ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, sqlite3_tokenizer **, char ** ); | > > > | 117244 117245 117246 117247 117248 117249 117250 117251 117252 117253 117254 117255 117256 117257 117258 117259 117260 117261 117262 117263 117264 117265 117266 117267 117268 117269 | /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ char *zTerm; /* Pointer to term buffer */ int nTerm; /* Size of zTerm in bytes */ char *aDoclist; /* Pointer to doclist buffer */ int nDoclist; /* Size of aDoclist[] in bytes */ }; SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); /* fts3.c */ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); /* fts3_tokenizer.c */ SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, sqlite3_tokenizer **, char ** ); |
︙ | ︙ | |||
117200 117201 117202 117203 117204 117205 117206 117207 117208 117209 117210 117211 117212 117213 | } sqlite3_free(zSql); sqlite3_free(zCols); *pRc = rc; } } /* ** Create the backing store tables (%_content, %_segments and %_segdir) ** required by the FTS3 table passed as the only argument. This is done ** as part of the vtab xCreate() method. ** ** If the p->bHasDocsize boolean is true (indicating that this is an | > > > > > > > > > > > > | 117584 117585 117586 117587 117588 117589 117590 117591 117592 117593 117594 117595 117596 117597 117598 117599 117600 117601 117602 117603 117604 117605 117606 117607 117608 117609 | } sqlite3_free(zSql); sqlite3_free(zCols); *pRc = rc; } } /* ** Create the %_stat table if it does not already exist. */ SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ fts3DbExec(pRc, p->db, "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" "(id INTEGER PRIMARY KEY, value BLOB);", p->zDb, p->zName ); if( (*pRc)==SQLITE_OK ) p->bHasStat = 1; } /* ** Create the backing store tables (%_content, %_segments and %_segdir) ** required by the FTS3 table passed as the only argument. This is done ** as part of the vtab xCreate() method. ** ** If the p->bHasDocsize boolean is true (indicating that this is an |
︙ | ︙ | |||
117261 117262 117263 117264 117265 117266 117267 117268 | ); if( p->bHasDocsize ){ fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", p->zDb, p->zName ); } if( p->bHasStat ){ | > | < < < | 117657 117658 117659 117660 117661 117662 117663 117664 117665 117666 117667 117668 117669 117670 117671 117672 117673 | ); if( p->bHasDocsize ){ fts3DbExec(&rc, db, "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", p->zDb, p->zName ); } assert( p->bHasStat==p->bFts4 ); if( p->bHasStat ){ sqlite3Fts3CreateStatTable(&rc, p); } return rc; } /* ** Store the current database page-size in bytes in p->nPgsz. ** |
︙ | ︙ | |||
117906 117907 117908 117909 117910 117911 117912 117913 117914 117915 117916 117917 117918 117919 117920 | p->nColumn = nCol; p->nPendingData = 0; p->azColumn = (char **)&p[1]; p->pTokenizer = pTokenizer; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; p->bDescIdx = bDescIdx; p->zContentTbl = zContent; p->zLanguageid = zLanguageid; zContent = 0; zLanguageid = 0; TESTONLY( p->inTransaction = -1 ); TESTONLY( p->mxSavepoint = -1 ); | > > | 118300 118301 118302 118303 118304 118305 118306 118307 118308 118309 118310 118311 118312 118313 118314 118315 118316 | p->nColumn = nCol; p->nPendingData = 0; p->azColumn = (char **)&p[1]; p->pTokenizer = pTokenizer; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; p->bFts4 = isFts4; p->bDescIdx = bDescIdx; p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */ p->zContentTbl = zContent; p->zLanguageid = zLanguageid; zContent = 0; zLanguageid = 0; TESTONLY( p->inTransaction = -1 ); TESTONLY( p->mxSavepoint = -1 ); |
︙ | ︙ | |||
117958 117959 117960 117961 117962 117963 117964 117965 117966 117967 117968 117969 117970 117971 | /* If this is an xCreate call, create the underlying tables in the ** database. TODO: For xConnect(), it could verify that said tables exist. */ if( isCreate ){ rc = fts3CreateTables(p); } /* Figure out the page-size for the database. This is required in order to ** estimate the cost of loading large doclists from the database. */ fts3DatabasePageSize(&rc, p); p->nNodeSize = p->nPgsz-35; /* Declare the table schema to SQLite. */ | > > > > > > > > > > | 118354 118355 118356 118357 118358 118359 118360 118361 118362 118363 118364 118365 118366 118367 118368 118369 118370 118371 118372 118373 118374 118375 118376 118377 | /* If this is an xCreate call, create the underlying tables in the ** database. TODO: For xConnect(), it could verify that said tables exist. */ if( isCreate ){ rc = fts3CreateTables(p); } /* Check to see if a legacy fts3 table has been "upgraded" by the ** addition of a %_stat table so that it can use incremental merge. */ if( !isFts4 && !isCreate ){ int rc2 = SQLITE_OK; fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2", p->zDb, p->zName); if( rc2==SQLITE_OK ) p->bHasStat = 1; } /* Figure out the page-size for the database. This is required in order to ** estimate the cost of loading large doclists from the database. */ fts3DatabasePageSize(&rc, p); p->nNodeSize = p->nPgsz-35; /* Declare the table schema to SQLite. */ |
︙ | ︙ | |||
119302 119303 119304 119305 119306 119307 119308 | /* ** Set up a cursor object for iterating through a full-text index or a ** single level therein. */ SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( Fts3Table *p, /* FTS3 table handle */ | | < < < < < | 119708 119709 119710 119711 119712 119713 119714 119715 119716 119717 119718 119719 119720 119721 119722 119723 119724 119725 119726 119727 119728 119729 119730 119731 119732 119733 119734 119735 119736 119737 119738 119739 119740 | /* ** Set up a cursor object for iterating through a full-text index or a ** single level therein. */ SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language-id to search */ int iIndex, /* Index to search (from 0 to p->nIndex-1) */ int iLevel, /* Level of segments to scan */ const char *zTerm, /* Term to query for */ int nTerm, /* Size of zTerm in bytes */ int isPrefix, /* True for a prefix search */ int isScan, /* True to scan from zTerm to EOF */ Fts3MultiSegReader *pCsr /* Cursor object to populate */ ){ assert( iIndex>=0 && iIndex<p->nIndex ); assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel==FTS3_SEGCURSOR_PENDING || iLevel>=0 ); assert( iLevel<FTS3_SEGDIR_MAXLEVEL ); assert( FTS3_SEGCURSOR_ALL<0 && FTS3_SEGCURSOR_PENDING<0 ); assert( isPrefix==0 || isScan==0 ); memset(pCsr, 0, sizeof(Fts3MultiSegReader)); return fts3SegReaderCursor( p, iLangid, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr ); } /* ** In addition to its current configuration, have the Fts3MultiSegReader |
︙ | ︙ | |||
119590 119591 119592 119593 119594 119595 119596 | return SQLITE_NOMEM; } pCsr->iLangid = 0; if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, | | | 119991 119992 119993 119994 119995 119996 119997 119998 119999 120000 120001 120002 120003 120004 120005 | return SQLITE_NOMEM; } pCsr->iLangid = 0; if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr ); if( rc!=SQLITE_OK ){ if( rc==SQLITE_ERROR ){ static const char *zErr = "malformed MATCH expression: [%s]"; p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery); } return rc; |
︙ | ︙ | |||
119733 119734 119735 119736 119737 119738 119739 | } /* ** Implementation of xSync() method. Flush the contents of the pending-terms ** hash-table to the database. */ static int fts3SyncMethod(sqlite3_vtab *pVtab){ | > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > | | > | 120134 120135 120136 120137 120138 120139 120140 120141 120142 120143 120144 120145 120146 120147 120148 120149 120150 120151 120152 120153 120154 120155 120156 120157 120158 120159 120160 120161 120162 120163 120164 120165 120166 120167 120168 120169 120170 120171 120172 120173 120174 120175 120176 120177 120178 120179 120180 120181 120182 120183 120184 120185 120186 120187 120188 120189 120190 120191 120192 120193 120194 120195 120196 120197 120198 | } /* ** Implementation of xSync() method. Flush the contents of the pending-terms ** hash-table to the database. */ static int fts3SyncMethod(sqlite3_vtab *pVtab){ /* Following an incremental-merge operation, assuming that the input ** segments are not completely consumed (the usual case), they are updated ** in place to remove the entries that have already been merged. This ** involves updating the leaf block that contains the smallest unmerged ** entry and each block (if any) between the leaf and the root node. So ** if the height of the input segment b-trees is N, and input segments ** are merged eight at a time, updating the input segments at the end ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually ** small - often between 0 and 2. So the overhead of the incremental ** merge is somewhere between 8 and 24 blocks. To avoid this overhead ** dwarfing the actual productive work accomplished, the incremental merge ** is only attempted if it will write at least 64 leaf blocks. Hence ** nMinMerge. ** ** Of course, updating the input segments also involves deleting a bunch ** of blocks from the segments table. But this is not considered overhead ** as it would also be required by a crisis-merge that used the same input ** segments. */ const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ Fts3Table *p = (Fts3Table*)pVtab; int rc = sqlite3Fts3PendingTermsFlush(p); if( rc==SQLITE_OK && p->bAutoincrmerge==1 && p->nLeafAdd>(nMinMerge/16) ){ int mxLevel = 0; /* Maximum relative level value in db */ int A; /* Incr-merge parameter A */ rc = sqlite3Fts3MaxLevel(p, &mxLevel); assert( rc==SQLITE_OK || mxLevel==0 ); A = p->nLeafAdd * mxLevel; A += (A/2); if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8); } sqlite3Fts3SegmentsClose(p); return rc; } /* ** Implementation of xBegin() method. This is a no-op. */ static int fts3BeginMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(pVtab); assert( p->pSegments==0 ); assert( p->nPendingData==0 ); assert( p->inTransaction!=1 ); TESTONLY( p->inTransaction = 1 ); TESTONLY( p->mxSavepoint = -1; ); p->nLeafAdd = 0; return SQLITE_OK; } /* ** Implementation of xCommit() method. This is a no-op. The contents of ** the pending-terms hash-table have already been flushed into the database ** by fts3SyncMethod(). |
︙ | ︙ | |||
120043 120044 120045 120046 120047 120048 120049 120050 120051 120052 120053 | /* ** The xSavepoint() method. ** ** Flush the contents of the pending-terms table to disk. */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAMETER(iSavepoint); assert( ((Fts3Table *)pVtab)->inTransaction ); assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); | > > | > > | 120479 120480 120481 120482 120483 120484 120485 120486 120487 120488 120489 120490 120491 120492 120493 120494 120495 120496 120497 120498 120499 120500 120501 | /* ** The xSavepoint() method. ** ** Flush the contents of the pending-terms table to disk. */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; UNUSED_PARAMETER(iSavepoint); assert( ((Fts3Table *)pVtab)->inTransaction ); assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ rc = fts3SyncMethod(pVtab); } return rc; } /* ** The xRelease() method. ** ** This is a no-op. */ |
︙ | ︙ | |||
120962 120963 120964 120965 120966 120967 120968 | int nToken = 0; int nOr = 0; /* Allocate a MultiSegReader for each token in the expression. */ fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); /* Determine which, if any, tokens in the expression should be deferred. */ | | | 121402 121403 121404 121405 121406 121407 121408 121409 121410 121411 121412 121413 121414 121415 121416 | int nToken = 0; int nOr = 0; /* Allocate a MultiSegReader for each token in the expression. */ fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); /* Determine which, if any, tokens in the expression should be deferred. */ if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; Fts3Expr **apOr; aTC = (Fts3TokenAndCost *)sqlite3_malloc( sizeof(Fts3TokenAndCost) * nToken + sizeof(Fts3Expr *) * nOr * 2 ); apOr = (Fts3Expr **)&aTC[nToken]; |
︙ | ︙ | |||
121777 121778 121779 121780 121781 121782 121783 121784 121785 121786 121787 121788 121789 121790 | memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); for(i=0; i<pPhrase->nToken; i++){ fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); pPhrase->aToken[i].pSegcsr = 0; } } } /* ** Return SQLITE_CORRUPT_VTAB. */ #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ return SQLITE_CORRUPT_VTAB; | > | 122217 122218 122219 122220 122221 122222 122223 122224 122225 122226 122227 122228 122229 122230 122231 | memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); for(i=0; i<pPhrase->nToken; i++){ fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); pPhrase->aToken[i].pSegcsr = 0; } } } /* ** Return SQLITE_CORRUPT_VTAB. */ #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ return SQLITE_CORRUPT_VTAB; |
︙ | ︙ | |||
125077 125078 125079 125080 125081 125082 125083 125084 125085 125086 125087 125088 125089 125090 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdlib.h> */ /* ** When full-text index nodes are loaded from disk, the buffer that they ** are loaded into has the following number of bytes of padding at the end ** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer ** of 920 bytes is allocated for it. ** ** This means that if we have a pointer into a buffer containing node data, | > > > | 125518 125519 125520 125521 125522 125523 125524 125525 125526 125527 125528 125529 125530 125531 125532 125533 125534 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdlib.h> */ #define FTS_MAX_APPENDABLE_HEIGHT 16 /* ** When full-text index nodes are loaded from disk, the buffer that they ** are loaded into has the following number of bytes of padding at the end ** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer ** of 920 bytes is allocated for it. ** ** This means that if we have a pointer into a buffer containing node data, |
︙ | ︙ | |||
125115 125116 125117 125118 125119 125120 125121 125122 125123 125124 125125 125126 125127 125128 | int test_fts3_node_chunk_threshold = (4*1024)*4; # define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize # define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold #else # define FTS3_NODE_CHUNKSIZE (4*1024) # define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) #endif typedef struct PendingList PendingList; typedef struct SegmentNode SegmentNode; typedef struct SegmentWriter SegmentWriter; /* ** An instance of the following data structure is used to build doclists | > > > > > > > > > > > > > > > > > > > > > > > | 125559 125560 125561 125562 125563 125564 125565 125566 125567 125568 125569 125570 125571 125572 125573 125574 125575 125576 125577 125578 125579 125580 125581 125582 125583 125584 125585 125586 125587 125588 125589 125590 125591 125592 125593 125594 125595 | int test_fts3_node_chunk_threshold = (4*1024)*4; # define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize # define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold #else # define FTS3_NODE_CHUNKSIZE (4*1024) # define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) #endif /* ** The two values that may be meaningfully bound to the :1 parameter in ** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. */ #define FTS_STAT_DOCTOTAL 0 #define FTS_STAT_INCRMERGEHINT 1 #define FTS_STAT_AUTOINCRMERGE 2 /* ** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic ** and incremental merge operation that takes place. This is used for ** debugging FTS only, it should not usually be turned on in production ** systems. */ #ifdef FTS3_LOG_MERGES static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); } #else #define fts3LogMerge(x, y) #endif typedef struct PendingList PendingList; typedef struct SegmentNode SegmentNode; typedef struct SegmentWriter SegmentWriter; /* ** An instance of the following data structure is used to build doclists |
︙ | ︙ | |||
125277 125278 125279 125280 125281 125282 125283 | #define SQL_SELECT_SEGDIR_MAX_LEVEL 15 #define SQL_DELETE_SEGDIR_LEVEL 16 #define SQL_DELETE_SEGMENTS_RANGE 17 #define SQL_CONTENT_INSERT 18 #define SQL_DELETE_DOCSIZE 19 #define SQL_REPLACE_DOCSIZE 20 #define SQL_SELECT_DOCSIZE 21 | | | | > > > | | | > > > > | 125744 125745 125746 125747 125748 125749 125750 125751 125752 125753 125754 125755 125756 125757 125758 125759 125760 125761 125762 125763 125764 125765 125766 125767 125768 125769 125770 125771 125772 125773 | #define SQL_SELECT_SEGDIR_MAX_LEVEL 15 #define SQL_DELETE_SEGDIR_LEVEL 16 #define SQL_DELETE_SEGMENTS_RANGE 17 #define SQL_CONTENT_INSERT 18 #define SQL_DELETE_DOCSIZE 19 #define SQL_REPLACE_DOCSIZE 20 #define SQL_SELECT_DOCSIZE 21 #define SQL_SELECT_STAT 22 #define SQL_REPLACE_STAT 23 #define SQL_SELECT_ALL_PREFIX_LEVEL 24 #define SQL_DELETE_ALL_TERMS_SEGDIR 25 #define SQL_DELETE_SEGDIR_RANGE 26 #define SQL_SELECT_ALL_LANGID 27 #define SQL_FIND_MERGE_LEVEL 28 #define SQL_MAX_LEAF_NODE_ESTIMATE 29 #define SQL_DELETE_SEGDIR_ENTRY 30 #define SQL_SHIFT_SEGDIR_ENTRY 31 #define SQL_SELECT_SEGDIR 32 #define SQL_CHOMP_SEGDIR 33 #define SQL_SEGMENT_IS_APPENDABLE 34 #define SQL_SELECT_INDEXES 35 #define SQL_SELECT_MXLEVEL 36 /* ** This function is used to obtain an SQLite prepared statement handle ** for the statement identified by the second argument. If successful, ** *pp is set to the requested statement handle and SQLITE_OK returned. ** Otherwise, an SQLite error code is returned and *pp is set to 0. ** |
︙ | ︙ | |||
125314 125315 125316 125317 125318 125319 125320 | /* 2 */ "DELETE FROM %Q.'%q_content'", /* 3 */ "DELETE FROM %Q.'%q_segments'", /* 4 */ "DELETE FROM %Q.'%q_segdir'", /* 5 */ "DELETE FROM %Q.'%q_docsize'", /* 6 */ "DELETE FROM %Q.'%q_stat'", /* 7 */ "SELECT %s WHERE rowid=?", /* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 125788 125789 125790 125791 125792 125793 125794 125795 125796 125797 125798 125799 125800 125801 125802 125803 125804 125805 125806 125807 125808 125809 125810 125811 125812 125813 125814 125815 125816 125817 125818 125819 125820 125821 125822 125823 125824 125825 125826 125827 125828 125829 125830 125831 125832 125833 125834 125835 125836 125837 125838 125839 125840 125841 125842 125843 125844 125845 125846 125847 125848 125849 125850 125851 125852 125853 125854 125855 125856 125857 125858 125859 125860 125861 125862 125863 125864 125865 125866 125867 125868 125869 125870 125871 125872 125873 125874 125875 125876 | /* 2 */ "DELETE FROM %Q.'%q_content'", /* 3 */ "DELETE FROM %Q.'%q_segments'", /* 4 */ "DELETE FROM %Q.'%q_segdir'", /* 5 */ "DELETE FROM %Q.'%q_docsize'", /* 6 */ "DELETE FROM %Q.'%q_stat'", /* 7 */ "SELECT %s WHERE rowid=?", /* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", /* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", /* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", /* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", /* Return segments in order from oldest to newest.*/ /* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", /* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" "ORDER BY level DESC, idx ASC", /* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", /* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", /* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", /* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", /* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", /* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", /* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'", /* This statement is used to determine which level to read the input from ** when performing an incremental merge. It returns the absolute level number ** of the oldest level in the db that contains at least ? segments. Or, ** if no level in the FTS index contains more than ? segments, the statement ** returns zero rows. */ /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" " ORDER BY (level %% 1024) ASC LIMIT 1", /* Estimate the upper limit on the number of leaf nodes in a new segment ** created by merging the oldest :2 segments from absolute level :1. See ** function sqlite3Fts3Incrmerge() for details. */ /* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", /* SQL_DELETE_SEGDIR_ENTRY ** Delete the %_segdir entry on absolute level :1 with index :2. */ /* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", /* SQL_SHIFT_SEGDIR_ENTRY ** Modify the idx value for the segment with idx=:3 on absolute level :2 ** to :1. */ /* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?", /* SQL_SELECT_SEGDIR ** Read a single entry from the %_segdir table. The entry from absolute ** level :1 with index value :2. */ /* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root " "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", /* SQL_CHOMP_SEGDIR ** Update the start_block (:1) and root (:2) fields of the %_segdir ** entry located on absolute level :3 with index :4. */ /* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?" "WHERE level = ? AND idx = ?", /* SQL_SEGMENT_IS_APPENDABLE ** Return a single row if the segment with end_block=? is appendable. Or ** no rows otherwise. */ /* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL", /* SQL_SELECT_INDEXES ** Return the list of valid segment indexes for absolute level ? */ /* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", /* SQL_SELECT_MXLEVEL ** Return the largest relative level in the FTS index or indexes. */ /* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'" }; int rc = SQLITE_OK; sqlite3_stmt *pStmt; assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); assert( eStmt<SizeofArray(azSql) && eStmt>=0 ); |
︙ | ︙ | |||
125378 125379 125380 125381 125382 125383 125384 125385 125386 125387 | for(i=0; rc==SQLITE_OK && i<nParam; i++){ rc = sqlite3_bind_value(pStmt, i+1, apVal[i]); } } *pp = pStmt; return rc; } static int fts3SelectDocsize( Fts3Table *pTab, /* FTS3 table handle */ | > < < < | < | < > > | > > > > > > > > > > > > | | 125899 125900 125901 125902 125903 125904 125905 125906 125907 125908 125909 125910 125911 125912 125913 125914 125915 125916 125917 125918 125919 125920 125921 125922 125923 125924 125925 125926 125927 125928 125929 125930 125931 125932 125933 125934 125935 125936 125937 125938 125939 125940 125941 125942 125943 125944 125945 125946 125947 125948 125949 125950 125951 125952 125953 125954 125955 125956 125957 125958 125959 125960 125961 125962 125963 125964 125965 125966 | for(i=0; rc==SQLITE_OK && i<nParam; i++){ rc = sqlite3_bind_value(pStmt, i+1, apVal[i]); } } *pp = pStmt; return rc; } static int fts3SelectDocsize( Fts3Table *pTab, /* FTS3 table handle */ sqlite3_int64 iDocid, /* Docid to bind for SQL_SELECT_DOCSIZE */ sqlite3_stmt **ppStmt /* OUT: Statement handle */ ){ sqlite3_stmt *pStmt = 0; /* Statement requested from fts3SqlStmt() */ int rc; /* Return code */ rc = fts3SqlStmt(pTab, SQL_SELECT_DOCSIZE, &pStmt, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pStmt, 1, iDocid); rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB; pStmt = 0; }else{ rc = SQLITE_OK; } } *ppStmt = pStmt; return rc; } SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal( Fts3Table *pTab, /* Fts3 table handle */ sqlite3_stmt **ppStmt /* OUT: Statement handle */ ){ sqlite3_stmt *pStmt = 0; int rc; rc = fts3SqlStmt(pTab, SQL_SELECT_STAT, &pStmt, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); if( sqlite3_step(pStmt)!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB; pStmt = 0; } } *ppStmt = pStmt; return rc; } SQLITE_PRIVATE int sqlite3Fts3SelectDocsize( Fts3Table *pTab, /* Fts3 table handle */ sqlite3_int64 iDocid, /* Docid to read size data for */ sqlite3_stmt **ppStmt /* OUT: Statement handle */ ){ return fts3SelectDocsize(pTab, iDocid, ppStmt); } /* ** Similar to fts3SqlStmt(). Except, after binding the parameters in ** array apVal[] to the SQL statement identified by eStmt, the statement ** is executed. ** |
︙ | ︙ | |||
125511 125512 125513 125514 125515 125516 125517 | ** Language 1 indexes are allocated immediately following language 0. ** ** So, for a system with nPrefix prefix indexes configured, the block of ** absolute levels that corresponds to language-id iLangid and index ** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). */ static sqlite3_int64 getAbsoluteLevel( | | | | | < | 126042 126043 126044 126045 126046 126047 126048 126049 126050 126051 126052 126053 126054 126055 126056 126057 126058 126059 126060 126061 126062 126063 126064 126065 126066 126067 126068 | ** Language 1 indexes are allocated immediately following language 0. ** ** So, for a system with nPrefix prefix indexes configured, the block of ** absolute levels that corresponds to language-id iLangid and index ** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). */ static sqlite3_int64 getAbsoluteLevel( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language id */ int iIndex, /* Index in p->aIndex[] */ int iLevel /* Level of segments */ ){ sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ assert( iLangid>=0 ); assert( p->nIndex>0 ); assert( iIndex>=0 && iIndex<p->nIndex ); iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; return iBase + iLevel; } /* ** Set *ppStmt to a statement handle that may be used to iterate through ** all rows in the %_segdir table, from oldest to newest. If successful, ** return SQLITE_OK. If an error occurs while preparing the statement, ** return an SQLite error code. ** |
︙ | ︙ | |||
126091 126092 126093 126094 126095 126096 126097 126098 126099 126100 126101 126102 126103 126104 | if( rc==SQLITE_OK ){ /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already ** full, merge all segments in level iLevel into a single iLevel+1 ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. */ if( iNext>=FTS3_MERGE_COUNT ){ rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); *piIdx = 0; }else{ *piIdx = iNext; } } | > | 126621 126622 126623 126624 126625 126626 126627 126628 126629 126630 126631 126632 126633 126634 126635 | if( rc==SQLITE_OK ){ /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already ** full, merge all segments in level iLevel into a single iLevel+1 ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. */ if( iNext>=FTS3_MERGE_COUNT ){ fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); *piIdx = 0; }else{ *piIdx = iNext; } } |
︙ | ︙ | |||
126138 126139 126140 126141 126142 126143 126144 | char **paBlob, /* OUT: Blob data in malloc'd buffer */ int *pnBlob, /* OUT: Size of blob data */ int *pnLoad /* OUT: Bytes actually loaded */ ){ int rc; /* Return code */ /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ | | | 126669 126670 126671 126672 126673 126674 126675 126676 126677 126678 126679 126680 126681 126682 126683 | char **paBlob, /* OUT: Blob data in malloc'd buffer */ int *pnBlob, /* OUT: Size of blob data */ int *pnLoad /* OUT: Bytes actually loaded */ ){ int rc; /* Return code */ /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ assert( pnBlob ); if( p->pSegments ){ rc = sqlite3_blob_reopen(p->pSegments, iBlockid); }else{ if( 0==p->zSegmentsTbl ){ p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; |
︙ | ︙ | |||
126479 126480 126481 126482 126483 126484 126485 | ){ Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; int nOvfl = 0; int ii; int rc = SQLITE_OK; int pgsz = p->nPgsz; | | | 127010 127011 127012 127013 127014 127015 127016 127017 127018 127019 127020 127021 127022 127023 127024 | ){ Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; int nOvfl = 0; int ii; int rc = SQLITE_OK; int pgsz = p->nPgsz; assert( p->bFts4 ); assert( pgsz>0 ); for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){ Fts3SegReader *pReader = pMsr->apSegment[ii]; if( !fts3SegReaderIsPending(pReader) && !fts3SegReaderIsRootOnly(pReader) ){ |
︙ | ︙ | |||
126836 126837 126838 126839 126840 126841 126842 126843 126844 126845 126846 126847 126848 126849 | sqlite3_bind_int64(pStmt, 1, iBlock); sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); } return rc; } /* ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( Fts3Table *p, /* Virtual table handle */ sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ | > > > > > > > > > > > > > > > > > > > > > | 127367 127368 127369 127370 127371 127372 127373 127374 127375 127376 127377 127378 127379 127380 127381 127382 127383 127384 127385 127386 127387 127388 127389 127390 127391 127392 127393 127394 127395 127396 127397 127398 127399 127400 127401 | sqlite3_bind_int64(pStmt, 1, iBlock); sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); } return rc; } /* ** Find the largest relative level number in the table. If successful, set ** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, ** set *pnMax to zero and return an SQLite error code. */ SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ int rc; int mxLevel = 0; sqlite3_stmt *pStmt = 0; rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pStmt) ){ mxLevel = sqlite3_column_int(pStmt, 0); } rc = sqlite3_reset(pStmt); } *pnMax = mxLevel; return rc; } /* ** Insert a record into the %_segdir table. */ static int fts3WriteSegdir( Fts3Table *p, /* Virtual table handle */ sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ |
︙ | ︙ | |||
127153 127154 127155 127156 127157 127158 127159 127160 127161 127162 127163 127164 127165 127166 | if( nData>0 && nData+nReq>p->nNodeSize ){ int rc; /* The current leaf node is full. Write it out to the database. */ rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); if( rc!=SQLITE_OK ) return rc; /* Add the current term to the interior node tree. The term added to ** the interior tree must: ** ** a) be greater than the largest term on the leaf node just written ** to the database (still available in pWriter->zTerm), and ** | > | 127705 127706 127707 127708 127709 127710 127711 127712 127713 127714 127715 127716 127717 127718 127719 | if( nData>0 && nData+nReq>p->nNodeSize ){ int rc; /* The current leaf node is full. Write it out to the database. */ rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); if( rc!=SQLITE_OK ) return rc; p->nLeafAdd++; /* Add the current term to the interior node tree. The term added to ** the interior tree must: ** ** a) be greater than the largest term on the leaf node just written ** to the database (still available in pWriter->zTerm), and ** |
︙ | ︙ | |||
127261 127262 127263 127264 127265 127266 127267 127268 127269 127270 127271 127272 127273 127274 | p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot); } }else{ /* The entire tree fits on the root node. Write it to the segdir table. */ rc = fts3WriteSegdir( p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData); } return rc; } /* ** Release all memory held by the SegmentWriter object passed as the ** first argument. */ | > | 127814 127815 127816 127817 127818 127819 127820 127821 127822 127823 127824 127825 127826 127827 127828 | p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot); } }else{ /* The entire tree fits on the root node. Write it to the segdir table. */ rc = fts3WriteSegdir( p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData); } p->nLeafAdd++; return rc; } /* ** Release all memory held by the SegmentWriter object passed as the ** first argument. */ |
︙ | ︙ | |||
127341 127342 127343 127344 127345 127346 127347 127348 127349 127350 127351 127352 127353 127354 | getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) ); if( SQLITE_ROW==sqlite3_step(pStmt) ){ *pnMax = sqlite3_column_int64(pStmt, 0); } return sqlite3_reset(pStmt); } /* ** This function is used after merging multiple segments into a single large ** segment to delete the old, now redundant, segment b-trees. Specifically, ** it: ** ** 1) Deletes all %_segments entries for the segments associated with | > > > > > > > > > > > > > > > > > > > > > > > | 127895 127896 127897 127898 127899 127900 127901 127902 127903 127904 127905 127906 127907 127908 127909 127910 127911 127912 127913 127914 127915 127916 127917 127918 127919 127920 127921 127922 127923 127924 127925 127926 127927 127928 127929 127930 127931 | getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) ); if( SQLITE_ROW==sqlite3_step(pStmt) ){ *pnMax = sqlite3_column_int64(pStmt, 0); } return sqlite3_reset(pStmt); } /* ** Delete all entries in the %_segments table associated with the segment ** opened with seg-reader pSeg. This function does not affect the contents ** of the %_segdir table. */ static int fts3DeleteSegment( Fts3Table *p, /* FTS table handle */ Fts3SegReader *pSeg /* Segment to delete */ ){ int rc = SQLITE_OK; /* Return code */ if( pSeg->iStartBlock ){ sqlite3_stmt *pDelete; /* SQL statement to delete rows */ rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); sqlite3_step(pDelete); rc = sqlite3_reset(pDelete); } } return rc; } /* ** This function is used after merging multiple segments into a single large ** segment to delete the old, now redundant, segment b-trees. Specifically, ** it: ** ** 1) Deletes all %_segments entries for the segments associated with |
︙ | ︙ | |||
127364 127365 127366 127367 127368 127369 127370 | Fts3Table *p, /* Virtual table handle */ int iLangid, /* Language id */ int iIndex, /* Index for p->aIndex */ int iLevel, /* Level of %_segdir entries to delete */ Fts3SegReader **apSegment, /* Array of SegReader objects */ int nReader /* Size of array apSegment */ ){ | | | < | < < < < < < | 127941 127942 127943 127944 127945 127946 127947 127948 127949 127950 127951 127952 127953 127954 127955 127956 127957 127958 127959 127960 | Fts3Table *p, /* Virtual table handle */ int iLangid, /* Language id */ int iIndex, /* Index for p->aIndex */ int iLevel, /* Level of %_segdir entries to delete */ Fts3SegReader **apSegment, /* Array of SegReader objects */ int nReader /* Size of array apSegment */ ){ int rc = SQLITE_OK; /* Return Code */ int i; /* Iterator variable */ sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ for(i=0; rc==SQLITE_OK && i<nReader; i++){ rc = fts3DeleteSegment(p, apSegment[i]); } if( rc!=SQLITE_OK ){ return rc; } assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL ); if( iLevel==FTS3_SEGCURSOR_ALL ){ |
︙ | ︙ | |||
127952 127953 127954 127955 127956 127957 127958 127959 127960 127961 127962 127963 127964 127965 127966 127967 127968 127969 127970 | /* ** Flush the contents of pendingTerms to level 0 segments. */ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ int rc = SQLITE_OK; int i; for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } sqlite3Fts3PendingTermsClear(p); return rc; } /* ** Encode N integers as varints into a blob. */ static void fts3EncodeIntArray( | > > > > > > > > > > > > > > > > > | 128522 128523 128524 128525 128526 128527 128528 128529 128530 128531 128532 128533 128534 128535 128536 128537 128538 128539 128540 128541 128542 128543 128544 128545 128546 128547 128548 128549 128550 128551 128552 128553 128554 128555 128556 128557 | /* ** Flush the contents of pendingTerms to level 0 segments. */ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ int rc = SQLITE_OK; int i; for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written */ if( rc==SQLITE_OK && p->bHasStat && p->bAutoincrmerge==0xff && p->nLeafAdd>0 ){ sqlite3_stmt *pStmt = 0; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); rc = sqlite3_step(pStmt); p->bAutoincrmerge = (rc==SQLITE_ROW && sqlite3_column_int(pStmt, 0)); rc = sqlite3_reset(pStmt); } } return rc; } /* ** Encode N integers as varints into a blob. */ static void fts3EncodeIntArray( |
︙ | ︙ | |||
128067 128068 128069 128070 128071 128072 128073 | if( *pRC ) return; a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); if( a==0 ){ *pRC = SQLITE_NOMEM; return; } pBlob = (char*)&a[nStat]; | | > | 128654 128655 128656 128657 128658 128659 128660 128661 128662 128663 128664 128665 128666 128667 128668 128669 128670 128671 128672 128673 128674 | if( *pRC ) return; a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); if( a==0 ){ *pRC = SQLITE_NOMEM; return; } pBlob = (char*)&a[nStat]; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); if( rc ){ sqlite3_free(a); *pRC = rc; return; } sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); if( sqlite3_step(pStmt)==SQLITE_ROW ){ fts3DecodeIntArray(nStat, a, sqlite3_column_blob(pStmt, 0), sqlite3_column_bytes(pStmt, 0)); }else{ memset(a, 0, sizeof(u32)*(nStat) ); } |
︙ | ︙ | |||
128096 128097 128098 128099 128100 128101 128102 | x = 0; }else{ x = x + aSzIns[i] - aSzDel[i]; } a[i+1] = x; } fts3EncodeIntArray(nStat, a, pBlob, &nBlob); | | > | | 128684 128685 128686 128687 128688 128689 128690 128691 128692 128693 128694 128695 128696 128697 128698 128699 128700 128701 128702 128703 128704 128705 | x = 0; }else{ x = x + aSzIns[i] - aSzDel[i]; } a[i+1] = x; } fts3EncodeIntArray(nStat, a, pBlob, &nBlob); rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); if( rc ){ sqlite3_free(a); *pRC = rc; return; } sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); sqlite3_step(pStmt); *pRC = sqlite3_reset(pStmt); sqlite3_free(a); } /* ** Merge the entire database so that there is one segment for each |
︙ | ︙ | |||
128207 128208 128209 128210 128211 128212 128213 | }else{ nEntry++; for(iCol=0; iCol<=p->nColumn; iCol++){ aSzIns[iCol] += aSz[iCol]; } } } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 128796 128797 128798 128799 128800 128801 128802 128803 128804 128805 128806 128807 128808 128809 128810 128811 128812 128813 128814 128815 128816 128817 128818 128819 128820 128821 128822 128823 128824 128825 128826 128827 128828 128829 128830 128831 128832 128833 128834 128835 128836 128837 128838 128839 128840 128841 128842 128843 128844 128845 128846 128847 128848 128849 128850 128851 128852 128853 128854 128855 128856 128857 128858 128859 128860 128861 128862 128863 128864 128865 128866 128867 128868 128869 128870 128871 128872 128873 128874 128875 128876 128877 128878 128879 128880 128881 128882 128883 128884 128885 128886 128887 128888 128889 128890 128891 128892 128893 128894 128895 128896 128897 128898 128899 128900 128901 128902 128903 128904 128905 128906 128907 128908 128909 128910 128911 128912 128913 128914 128915 128916 128917 128918 128919 128920 128921 128922 128923 128924 128925 128926 128927 128928 128929 128930 128931 128932 128933 128934 128935 128936 128937 128938 128939 128940 128941 128942 128943 128944 128945 128946 128947 128948 128949 128950 128951 128952 128953 128954 128955 128956 128957 128958 128959 128960 128961 128962 128963 128964 128965 128966 128967 128968 128969 128970 128971 128972 128973 128974 128975 128976 128977 128978 128979 128980 128981 128982 128983 128984 128985 128986 128987 128988 128989 128990 128991 128992 128993 128994 128995 128996 128997 128998 128999 129000 129001 129002 129003 129004 129005 129006 129007 129008 129009 129010 129011 129012 129013 129014 129015 129016 129017 129018 129019 129020 129021 129022 129023 129024 129025 129026 129027 129028 129029 129030 129031 129032 129033 129034 129035 129036 129037 129038 129039 129040 129041 129042 129043 129044 129045 129046 129047 129048 129049 129050 129051 129052 129053 129054 129055 129056 129057 129058 129059 129060 129061 129062 129063 129064 129065 129066 129067 129068 129069 129070 129071 129072 129073 129074 129075 129076 129077 129078 129079 129080 129081 129082 129083 129084 129085 129086 129087 129088 129089 129090 129091 129092 129093 129094 129095 129096 129097 129098 129099 129100 129101 129102 129103 129104 129105 129106 129107 129108 129109 129110 129111 129112 129113 129114 129115 129116 129117 129118 129119 129120 129121 129122 129123 129124 129125 129126 129127 129128 129129 129130 129131 129132 129133 129134 129135 129136 129137 129138 129139 129140 129141 129142 129143 129144 129145 129146 129147 129148 129149 129150 129151 129152 129153 129154 129155 129156 129157 129158 129159 129160 129161 129162 129163 129164 129165 129166 129167 129168 129169 129170 129171 129172 129173 129174 129175 129176 129177 129178 129179 129180 129181 129182 129183 129184 129185 129186 129187 129188 129189 129190 129191 129192 129193 129194 129195 129196 129197 129198 129199 129200 129201 129202 129203 129204 129205 129206 129207 129208 129209 129210 129211 129212 129213 129214 129215 129216 129217 129218 129219 129220 129221 129222 129223 129224 129225 129226 129227 129228 129229 129230 129231 129232 129233 129234 129235 129236 129237 129238 129239 129240 129241 129242 129243 129244 129245 129246 129247 129248 129249 129250 129251 129252 129253 129254 129255 129256 129257 129258 129259 129260 129261 129262 129263 129264 129265 129266 129267 129268 129269 129270 129271 129272 129273 129274 129275 129276 129277 129278 129279 129280 129281 129282 129283 129284 129285 129286 129287 129288 129289 129290 129291 129292 129293 129294 129295 129296 129297 129298 129299 129300 129301 129302 129303 129304 129305 129306 129307 129308 129309 129310 129311 129312 129313 129314 129315 129316 129317 129318 129319 129320 129321 129322 129323 129324 129325 129326 129327 129328 129329 129330 129331 129332 129333 129334 129335 129336 129337 129338 129339 129340 129341 129342 129343 129344 129345 129346 129347 129348 129349 129350 129351 129352 129353 129354 129355 129356 129357 129358 129359 129360 129361 129362 129363 129364 129365 129366 129367 129368 129369 129370 129371 129372 129373 129374 129375 129376 129377 129378 129379 129380 129381 129382 129383 129384 129385 129386 129387 129388 129389 129390 129391 129392 129393 129394 129395 129396 129397 129398 129399 129400 129401 129402 129403 129404 129405 129406 129407 129408 129409 129410 129411 129412 129413 129414 129415 129416 129417 129418 129419 129420 129421 129422 129423 129424 129425 129426 129427 129428 129429 129430 129431 129432 129433 129434 129435 129436 129437 129438 129439 129440 129441 129442 129443 129444 129445 129446 129447 129448 129449 129450 129451 129452 129453 129454 129455 129456 129457 129458 129459 129460 129461 129462 129463 129464 129465 129466 129467 129468 129469 129470 129471 129472 129473 129474 129475 129476 129477 129478 129479 129480 129481 129482 129483 129484 129485 129486 129487 129488 129489 129490 129491 129492 129493 129494 129495 129496 129497 129498 129499 129500 129501 129502 129503 129504 129505 129506 129507 129508 129509 129510 129511 129512 129513 129514 129515 129516 129517 129518 129519 129520 129521 129522 129523 129524 129525 129526 129527 129528 129529 129530 129531 129532 129533 129534 129535 129536 129537 129538 129539 129540 129541 129542 129543 129544 129545 129546 129547 129548 129549 129550 129551 129552 129553 129554 129555 129556 129557 129558 129559 129560 129561 129562 129563 129564 129565 129566 129567 129568 129569 129570 129571 129572 129573 129574 129575 129576 129577 129578 129579 129580 129581 129582 129583 129584 129585 129586 129587 129588 129589 129590 129591 129592 129593 129594 129595 129596 129597 129598 129599 129600 129601 129602 129603 129604 129605 129606 129607 129608 129609 129610 129611 129612 129613 129614 129615 129616 129617 129618 129619 129620 129621 129622 129623 129624 129625 129626 129627 129628 129629 129630 129631 129632 129633 129634 129635 129636 129637 129638 129639 129640 129641 129642 129643 129644 129645 129646 129647 129648 129649 129650 129651 129652 129653 129654 129655 129656 129657 129658 129659 129660 129661 129662 129663 129664 129665 129666 129667 129668 129669 129670 129671 129672 129673 129674 129675 129676 129677 129678 129679 129680 129681 129682 129683 129684 129685 129686 129687 129688 129689 129690 129691 129692 129693 129694 129695 129696 129697 129698 129699 129700 129701 129702 129703 129704 129705 129706 129707 129708 129709 129710 129711 129712 129713 129714 129715 129716 129717 129718 129719 129720 129721 129722 129723 129724 129725 129726 129727 129728 129729 129730 129731 129732 129733 129734 129735 129736 129737 129738 129739 129740 129741 129742 129743 129744 129745 129746 129747 129748 129749 129750 129751 129752 129753 129754 129755 129756 129757 129758 129759 129760 129761 129762 129763 129764 129765 129766 129767 129768 129769 129770 129771 129772 129773 129774 129775 129776 129777 129778 129779 129780 129781 129782 129783 129784 129785 129786 129787 129788 129789 129790 129791 129792 129793 129794 129795 129796 129797 129798 129799 129800 129801 129802 129803 129804 129805 129806 129807 129808 129809 129810 129811 129812 129813 129814 129815 129816 129817 129818 129819 129820 129821 129822 129823 129824 129825 129826 129827 129828 129829 129830 129831 129832 129833 129834 129835 129836 129837 129838 129839 129840 129841 129842 129843 129844 129845 129846 129847 129848 129849 129850 129851 129852 129853 129854 129855 129856 129857 129858 129859 129860 129861 129862 129863 129864 129865 129866 129867 129868 129869 129870 129871 129872 129873 129874 129875 129876 129877 129878 129879 129880 129881 129882 129883 129884 129885 129886 129887 129888 129889 129890 129891 129892 129893 129894 129895 129896 129897 129898 129899 129900 129901 129902 129903 129904 129905 129906 129907 129908 129909 129910 129911 129912 129913 129914 129915 129916 129917 129918 129919 129920 129921 129922 129923 129924 129925 129926 129927 129928 129929 129930 129931 129932 129933 129934 129935 129936 129937 129938 129939 129940 129941 129942 129943 129944 129945 129946 129947 129948 129949 129950 129951 129952 129953 129954 129955 129956 129957 129958 129959 129960 129961 129962 129963 129964 129965 129966 129967 129968 129969 129970 129971 129972 129973 129974 129975 129976 129977 129978 129979 129980 129981 129982 129983 129984 129985 129986 129987 129988 129989 129990 129991 129992 129993 129994 129995 129996 129997 129998 129999 130000 130001 130002 130003 130004 130005 130006 130007 130008 130009 130010 130011 130012 130013 130014 130015 130016 130017 130018 130019 130020 130021 130022 130023 130024 130025 130026 130027 130028 130029 130030 130031 130032 130033 130034 130035 130036 130037 130038 130039 130040 130041 130042 130043 130044 130045 130046 130047 130048 130049 130050 130051 130052 130053 130054 130055 130056 130057 130058 130059 130060 130061 130062 130063 130064 130065 130066 130067 130068 130069 130070 130071 130072 130073 130074 130075 130076 130077 130078 130079 130080 130081 130082 130083 130084 130085 130086 130087 130088 130089 130090 130091 130092 130093 130094 130095 130096 130097 130098 130099 130100 130101 130102 130103 130104 130105 130106 130107 130108 130109 130110 130111 130112 130113 130114 130115 130116 130117 130118 130119 130120 130121 130122 130123 130124 130125 130126 130127 130128 130129 130130 130131 130132 130133 130134 130135 130136 130137 130138 130139 130140 130141 130142 130143 130144 130145 130146 130147 130148 130149 130150 130151 130152 130153 130154 130155 130156 130157 130158 130159 130160 130161 130162 130163 130164 130165 130166 130167 130168 130169 130170 130171 130172 130173 130174 130175 130176 130177 130178 130179 130180 130181 130182 130183 130184 130185 130186 130187 130188 130189 130190 130191 130192 130193 130194 130195 130196 130197 130198 130199 130200 130201 130202 130203 130204 130205 130206 130207 130208 130209 130210 130211 130212 130213 130214 130215 130216 130217 130218 130219 130220 130221 130222 130223 130224 130225 130226 130227 130228 130229 130230 130231 130232 130233 130234 130235 130236 130237 130238 130239 130240 130241 130242 130243 130244 130245 130246 130247 130248 130249 130250 130251 130252 130253 130254 130255 130256 130257 130258 130259 130260 130261 130262 130263 130264 130265 130266 130267 130268 130269 130270 130271 130272 130273 130274 130275 130276 130277 130278 130279 130280 130281 130282 130283 130284 130285 130286 130287 130288 130289 130290 130291 130292 130293 130294 130295 130296 130297 130298 130299 130300 130301 130302 130303 130304 130305 130306 130307 130308 130309 130310 130311 130312 130313 130314 130315 130316 130317 130318 130319 130320 130321 130322 130323 130324 130325 130326 130327 130328 130329 130330 130331 130332 130333 130334 130335 130336 130337 130338 130339 130340 130341 130342 130343 130344 130345 130346 130347 130348 130349 130350 130351 130352 130353 130354 130355 130356 130357 130358 130359 130360 130361 130362 130363 130364 130365 130366 130367 130368 130369 130370 130371 130372 130373 130374 130375 130376 130377 130378 130379 130380 130381 130382 130383 130384 130385 130386 130387 130388 130389 130390 130391 130392 130393 130394 130395 130396 130397 130398 130399 130400 130401 130402 130403 130404 130405 130406 130407 130408 130409 130410 130411 130412 130413 130414 130415 130416 130417 130418 130419 130420 130421 130422 130423 130424 130425 130426 130427 130428 130429 130430 130431 130432 130433 130434 130435 130436 130437 130438 130439 130440 130441 130442 130443 130444 130445 130446 130447 130448 130449 130450 130451 130452 130453 130454 130455 130456 130457 130458 130459 130460 130461 130462 130463 130464 130465 130466 130467 130468 130469 130470 130471 130472 130473 130474 130475 130476 130477 130478 130479 130480 130481 130482 130483 130484 130485 130486 130487 130488 130489 130490 130491 130492 130493 130494 130495 130496 130497 130498 130499 130500 130501 130502 130503 130504 130505 130506 130507 130508 130509 130510 130511 130512 130513 130514 130515 130516 130517 130518 130519 130520 130521 130522 130523 130524 130525 130526 130527 130528 130529 130530 130531 | }else{ nEntry++; for(iCol=0; iCol<=p->nColumn; iCol++){ aSzIns[iCol] += aSz[iCol]; } } } if( p->bFts4 ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); } sqlite3_free(aSz); if( pStmt ){ int rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ rc = rc2; } } } return rc; } /* ** This function opens a cursor used to read the input data for an ** incremental merge operation. Specifically, it opens a cursor to scan ** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute ** level iAbsLevel. */ static int fts3IncrmergeCsr( Fts3Table *p, /* FTS3 table handle */ sqlite3_int64 iAbsLevel, /* Absolute level to open */ int nSeg, /* Number of segments to merge */ Fts3MultiSegReader *pCsr /* Cursor object to populate */ ){ int rc; /* Return Code */ sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ int nByte; /* Bytes allocated at pCsr->apSegment[] */ /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ memset(pCsr, 0, sizeof(*pCsr)); nByte = sizeof(Fts3SegReader *) * nSeg; pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte); if( pCsr->apSegment==0 ){ rc = SQLITE_NOMEM; }else{ memset(pCsr->apSegment, 0, nByte); rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); } if( rc==SQLITE_OK ){ int i; int rc2; sqlite3_bind_int64(pStmt, 1, iAbsLevel); assert( pCsr->nSegment==0 ); for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && i<nSeg; i++){ rc = sqlite3Fts3SegReaderNew(i, 0, sqlite3_column_int64(pStmt, 1), /* segdir.start_block */ sqlite3_column_int64(pStmt, 2), /* segdir.leaves_end_block */ sqlite3_column_int64(pStmt, 3), /* segdir.end_block */ sqlite3_column_blob(pStmt, 4), /* segdir.root */ sqlite3_column_bytes(pStmt, 4), /* segdir.root */ &pCsr->apSegment[i] ); pCsr->nSegment++; } rc2 = sqlite3_reset(pStmt); if( rc==SQLITE_OK ) rc = rc2; } return rc; } typedef struct IncrmergeWriter IncrmergeWriter; typedef struct NodeWriter NodeWriter; typedef struct Blob Blob; typedef struct NodeReader NodeReader; /* ** An instance of the following structure is used as a dynamic buffer ** to build up nodes or other blobs of data in. ** ** The function blobGrowBuffer() is used to extend the allocation. */ struct Blob { char *a; /* Pointer to allocation */ int n; /* Number of valid bytes of data in a[] */ int nAlloc; /* Allocated size of a[] (nAlloc>=n) */ }; /* ** This structure is used to build up buffers containing segment b-tree ** nodes (blocks). */ struct NodeWriter { sqlite3_int64 iBlock; /* Current block id */ Blob key; /* Last key written to the current block */ Blob block; /* Current block image */ }; /* ** An object of this type contains the state required to create or append ** to an appendable b-tree segment. */ struct IncrmergeWriter { int nLeafEst; /* Space allocated for leaf blocks */ int nWork; /* Number of leaf pages flushed */ sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ int iIdx; /* Index of *output* segment in iAbsLevel+1 */ sqlite3_int64 iStart; /* Block number of first allocated block */ sqlite3_int64 iEnd; /* Block number of last allocated block */ NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; }; /* ** An object of the following type is used to read data from a single ** FTS segment node. See the following functions: ** ** nodeReaderInit() ** nodeReaderNext() ** nodeReaderRelease() */ struct NodeReader { const char *aNode; int nNode; int iOff; /* Current offset within aNode[] */ /* Output variables. Containing the current node entry. */ sqlite3_int64 iChild; /* Pointer to child node */ Blob term; /* Current term */ const char *aDoclist; /* Pointer to doclist */ int nDoclist; /* Size of doclist in bytes */ }; /* ** If *pRc is not SQLITE_OK when this function is called, it is a no-op. ** Otherwise, if the allocation at pBlob->a is not already at least nMin ** bytes in size, extend (realloc) it to be so. ** ** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a ** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc ** to reflect the new size of the pBlob->a[] buffer. */ static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ int nAlloc = nMin; char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); if( a ){ pBlob->nAlloc = nAlloc; pBlob->a = a; }else{ *pRc = SQLITE_NOMEM; } } } /* ** Attempt to advance the node-reader object passed as the first argument to ** the next entry on the node. ** ** Return an error code if an error occurs (SQLITE_NOMEM is possible). ** Otherwise return SQLITE_OK. If there is no next entry on the node ** (e.g. because the current entry is the last) set NodeReader->aNode to ** NULL to indicate EOF. Otherwise, populate the NodeReader structure output ** variables for the new entry. */ static int nodeReaderNext(NodeReader *p){ int bFirst = (p->term.n==0); /* True for first term on the node */ int nPrefix = 0; /* Bytes to copy from previous term */ int nSuffix = 0; /* Bytes to append to the prefix */ int rc = SQLITE_OK; /* Return code */ assert( p->aNode ); if( p->iChild && bFirst==0 ) p->iChild++; if( p->iOff>=p->nNode ){ /* EOF */ p->aNode = 0; }else{ if( bFirst==0 ){ p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); } p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); if( rc==SQLITE_OK ){ memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); p->term.n = nPrefix+nSuffix; p->iOff += nSuffix; if( p->iChild==0 ){ p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); p->aDoclist = &p->aNode[p->iOff]; p->iOff += p->nDoclist; } } } assert( p->iOff<=p->nNode ); return rc; } /* ** Release all dynamic resources held by node-reader object *p. */ static void nodeReaderRelease(NodeReader *p){ sqlite3_free(p->term.a); } /* ** Initialize a node-reader object to read the node in buffer aNode/nNode. ** ** If successful, SQLITE_OK is returned and the NodeReader object set to ** point to the first entry on the node (if any). Otherwise, an SQLite ** error code is returned. */ static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ memset(p, 0, sizeof(NodeReader)); p->aNode = aNode; p->nNode = nNode; /* Figure out if this is a leaf or an internal node. */ if( p->aNode[0] ){ /* An internal node. */ p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); }else{ p->iOff = 1; } return nodeReaderNext(p); } /* ** This function is called while writing an FTS segment each time a leaf o ** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed ** to be greater than the largest key on the node just written, but smaller ** than or equal to the first key that will be written to the next leaf ** node. ** ** The block id of the leaf node just written to disk may be found in ** (pWriter->aNodeWriter[0].iBlock) when this function is called. */ static int fts3IncrmergePush( Fts3Table *p, /* Fts3 table handle */ IncrmergeWriter *pWriter, /* Writer object */ const char *zTerm, /* Term to write to internal node */ int nTerm /* Bytes at zTerm */ ){ sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; int iLayer; assert( nTerm>0 ); for(iLayer=1; ALWAYS(iLayer<FTS_MAX_APPENDABLE_HEIGHT); iLayer++){ sqlite3_int64 iNextPtr = 0; NodeWriter *pNode = &pWriter->aNodeWriter[iLayer]; int rc = SQLITE_OK; int nPrefix; int nSuffix; int nSpace; /* Figure out how much space the key will consume if it is written to ** the current node of layer iLayer. Due to the prefix compression, ** the space required changes depending on which node the key is to ** be added to. */ nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; nSpace = sqlite3Fts3VarintLen(nPrefix); nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ /* If the current node of layer iLayer contains zero keys, or if adding ** the key to it will not cause it to grow to larger than nNodeSize ** bytes in size, write the key here. */ Blob *pBlk = &pNode->block; if( pBlk->n==0 ){ blobGrowBuffer(pBlk, p->nNodeSize, &rc); if( rc==SQLITE_OK ){ pBlk->a[0] = (char)iLayer; pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); } } blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); blobGrowBuffer(&pNode->key, nTerm, &rc); if( rc==SQLITE_OK ){ if( pNode->key.n ){ pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); } pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); pBlk->n += nSuffix; memcpy(pNode->key.a, zTerm, nTerm); pNode->key.n = nTerm; } }else{ /* Otherwise, flush the the current node of layer iLayer to disk. ** Then allocate a new, empty sibling node. The key will be written ** into the parent of this node. */ rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); assert( pNode->block.nAlloc>=p->nNodeSize ); pNode->block.a[0] = (char)iLayer; pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); iNextPtr = pNode->iBlock; pNode->iBlock++; pNode->key.n = 0; } if( rc!=SQLITE_OK || iNextPtr==0 ) return rc; iPtr = iNextPtr; } assert( 0 ); return 0; } /* ** Append a term and (optionally) doclist to the FTS segment node currently ** stored in blob *pNode. The node need not contain any terms, but the ** header must be written before this function is called. ** ** A node header is a single 0x00 byte for a leaf node, or a height varint ** followed by the left-hand-child varint for an internal node. ** ** The term to be appended is passed via arguments zTerm/nTerm. For a ** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal ** node, both aDoclist and nDoclist must be passed 0. ** ** If the size of the value in blob pPrev is zero, then this is the first ** term written to the node. Otherwise, pPrev contains a copy of the ** previous term. Before this function returns, it is updated to contain a ** copy of zTerm/nTerm. ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev ** is extended by this function if requrired. ** ** If an error (i.e. OOM condition) occurs, an SQLite error code is ** returned. Otherwise, SQLITE_OK. */ static int fts3AppendToNode( Blob *pNode, /* Current node image to append to */ Blob *pPrev, /* Buffer containing previous term written */ const char *zTerm, /* New term to write */ int nTerm, /* Size of zTerm in bytes */ const char *aDoclist, /* Doclist (or NULL) to write */ int nDoclist /* Size of aDoclist in bytes */ ){ int rc = SQLITE_OK; /* Return code */ int bFirst = (pPrev->n==0); /* True if this is the first term written */ int nPrefix; /* Size of term prefix in bytes */ int nSuffix; /* Size of term suffix in bytes */ /* Node must have already been started. There must be a doclist for a ** leaf node, and there must not be a doclist for an internal node. */ assert( pNode->n>0 ); assert( (pNode->a[0]=='\0')==(aDoclist!=0) ); blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; memcpy(pPrev->a, zTerm, nTerm); pPrev->n = nTerm; if( bFirst==0 ){ pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); } pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); pNode->n += nSuffix; if( aDoclist ){ pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); pNode->n += nDoclist; } assert( pNode->n<=pNode->nAlloc ); return SQLITE_OK; } /* ** Append the current term and doclist pointed to by cursor pCsr to the ** appendable b-tree segment opened for writing by pWriter. ** ** Return SQLITE_OK if successful, or an SQLite error code otherwise. */ static int fts3IncrmergeAppend( Fts3Table *p, /* Fts3 table handle */ IncrmergeWriter *pWriter, /* Writer object */ Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */ ){ const char *zTerm = pCsr->zTerm; int nTerm = pCsr->nTerm; const char *aDoclist = pCsr->aDoclist; int nDoclist = pCsr->nDoclist; int rc = SQLITE_OK; /* Return code */ int nSpace; /* Total space in bytes required on leaf */ int nPrefix; /* Size of prefix shared with previous term */ int nSuffix; /* Size of suffix (nTerm - nPrefix) */ NodeWriter *pLeaf; /* Object used to write leaf nodes */ pLeaf = &pWriter->aNodeWriter[0]; nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; nSpace = sqlite3Fts3VarintLen(nPrefix); nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist ** to the current block would make it larger than Fts3Table.nNodeSize ** bytes, write this block out to the database. */ if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); pWriter->nWork++; /* Add the current term to the parent node. The term added to the ** parent must: ** ** a) be greater than the largest term on the leaf node just written ** to the database (still available in pLeaf->key), and ** ** b) be less than or equal to the term about to be added to the new ** leaf node (zTerm/nTerm). ** ** In other words, it must be the prefix of zTerm 1 byte longer than ** the common prefix (if any) of zTerm and pWriter->zTerm. */ if( rc==SQLITE_OK ){ rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1); } /* Advance to the next output block */ pLeaf->iBlock++; pLeaf->key.n = 0; pLeaf->block.n = 0; nSuffix = nTerm; nSpace = 1; nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; } blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); if( rc==SQLITE_OK ){ if( pLeaf->block.n==0 ){ pLeaf->block.n = 1; pLeaf->block.a[0] = '\0'; } rc = fts3AppendToNode( &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist ); } return rc; } /* ** This function is called to release all dynamic resources held by the ** merge-writer object pWriter, and if no error has occurred, to flush ** all outstanding node buffers held by pWriter to disk. ** ** If *pRc is not SQLITE_OK when this function is called, then no attempt ** is made to write any data to disk. Instead, this function serves only ** to release outstanding resources. ** ** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while ** flushing buffers to disk, *pRc is set to an SQLite error code before ** returning. */ static void fts3IncrmergeRelease( Fts3Table *p, /* FTS3 table handle */ IncrmergeWriter *pWriter, /* Merge-writer object */ int *pRc /* IN/OUT: Error code */ ){ int i; /* Used to iterate through non-root layers */ int iRoot; /* Index of root in pWriter->aNodeWriter */ NodeWriter *pRoot; /* NodeWriter for root node */ int rc = *pRc; /* Error code */ /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment ** root node. If the segment fits entirely on a single leaf node, iRoot ** will be set to 0. If the root node is the parent of the leaves, iRoot ** will be 1. And so on. */ for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){ NodeWriter *pNode = &pWriter->aNodeWriter[iRoot]; if( pNode->block.n>0 ) break; assert( *pRc || pNode->block.nAlloc==0 ); assert( *pRc || pNode->key.nAlloc==0 ); sqlite3_free(pNode->block.a); sqlite3_free(pNode->key.a); } /* Empty output segment. This is a no-op. */ if( iRoot<0 ) return; /* The entire output segment fits on a single node. Normally, this means ** the node would be stored as a blob in the "root" column of the %_segdir ** table. However, this is not permitted in this case. The problem is that ** space has already been reserved in the %_segments table, and so the ** start_block and end_block fields of the %_segdir table must be populated. ** And, by design or by accident, released versions of FTS cannot handle ** segments that fit entirely on the root node with start_block!=0. ** ** Instead, create a synthetic root node that contains nothing but a ** pointer to the single content node. So that the segment consists of a ** single leaf and a single interior (root) node. ** ** Todo: Better might be to defer allocating space in the %_segments ** table until we are sure it is needed. */ if( iRoot==0 ){ Blob *pBlock = &pWriter->aNodeWriter[1].block; blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); if( rc==SQLITE_OK ){ pBlock->a[0] = 0x01; pBlock->n = 1 + sqlite3Fts3PutVarint( &pBlock->a[1], pWriter->aNodeWriter[0].iBlock ); } iRoot = 1; } pRoot = &pWriter->aNodeWriter[iRoot]; /* Flush all currently outstanding nodes to disk. */ for(i=0; i<iRoot; i++){ NodeWriter *pNode = &pWriter->aNodeWriter[i]; if( pNode->block.n>0 && rc==SQLITE_OK ){ rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); } sqlite3_free(pNode->block.a); sqlite3_free(pNode->key.a); } /* Write the %_segdir record. */ if( rc==SQLITE_OK ){ rc = fts3WriteSegdir(p, pWriter->iAbsLevel+1, /* level */ pWriter->iIdx, /* idx */ pWriter->iStart, /* start_block */ pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ pWriter->iEnd, /* end_block */ pRoot->block.a, pRoot->block.n /* root */ ); } sqlite3_free(pRoot->block.a); sqlite3_free(pRoot->key.a); *pRc = rc; } /* ** Compare the term in buffer zLhs (size in bytes nLhs) with that in ** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of ** the other, it is considered to be smaller than the other. ** ** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve ** if it is greater. */ static int fts3TermCmp( const char *zLhs, int nLhs, /* LHS of comparison */ const char *zRhs, int nRhs /* RHS of comparison */ ){ int nCmp = MIN(nLhs, nRhs); int res; res = memcmp(zLhs, zRhs, nCmp); if( res==0 ) res = nLhs - nRhs; return res; } /* ** Query to see if the entry in the %_segments table with blockid iEnd is ** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before ** returning. Otherwise, set *pbRes to 0. ** ** Or, if an error occurs while querying the database, return an SQLite ** error code. The final value of *pbRes is undefined in this case. ** ** This is used to test if a segment is an "appendable" segment. If it ** is, then a NULL entry has been inserted into the %_segments table ** with blockid %_segdir.end_block. */ static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ int bRes = 0; /* Result to set *pbRes to */ sqlite3_stmt *pCheck = 0; /* Statement to query database with */ int rc; /* Return code */ rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pCheck, 1, iEnd); if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; rc = sqlite3_reset(pCheck); } *pbRes = bRes; return rc; } /* ** This function is called when initializing an incremental-merge operation. ** It checks if the existing segment with index value iIdx at absolute level ** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the ** merge-writer object *pWriter is initialized to write to it. ** ** An existing segment can be appended to by an incremental merge if: ** ** * It was initially created as an appendable segment (with all required ** space pre-allocated), and ** ** * The first key read from the input (arguments zKey and nKey) is ** greater than the largest key currently stored in the potential ** output segment. */ static int fts3IncrmergeLoad( Fts3Table *p, /* Fts3 table handle */ sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ int iIdx, /* Index of candidate output segment */ const char *zKey, /* First key to write */ int nKey, /* Number of bytes in nKey */ IncrmergeWriter *pWriter /* Populate this object */ ){ int rc; /* Return code */ sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); if( rc==SQLITE_OK ){ sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ int nRoot = 0; /* Size of aRoot[] in bytes */ int rc2; /* Return code from sqlite3_reset() */ int bAppendable = 0; /* Set to true if segment is appendable */ /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); sqlite3_bind_int(pSelect, 2, iIdx); if( sqlite3_step(pSelect)==SQLITE_ROW ){ iStart = sqlite3_column_int64(pSelect, 1); iLeafEnd = sqlite3_column_int64(pSelect, 2); iEnd = sqlite3_column_int64(pSelect, 3); nRoot = sqlite3_column_bytes(pSelect, 4); aRoot = sqlite3_column_blob(pSelect, 4); }else{ return sqlite3_reset(pSelect); } /* Check for the zero-length marker in the %_segments table */ rc = fts3IsAppendable(p, iEnd, &bAppendable); /* Check that zKey/nKey is larger than the largest key the candidate */ if( rc==SQLITE_OK && bAppendable ){ char *aLeaf = 0; int nLeaf = 0; rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); if( rc==SQLITE_OK ){ NodeReader reader; for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); rc==SQLITE_OK && reader.aNode; rc = nodeReaderNext(&reader) ){ assert( reader.aNode ); } if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){ bAppendable = 0; } nodeReaderRelease(&reader); } sqlite3_free(aLeaf); } if( rc==SQLITE_OK && bAppendable ){ /* It is possible to append to this segment. Set up the IncrmergeWriter ** object to do so. */ int i; int nHeight = (int)aRoot[0]; NodeWriter *pNode; pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; pWriter->iStart = iStart; pWriter->iEnd = iEnd; pWriter->iAbsLevel = iAbsLevel; pWriter->iIdx = iIdx; for(i=nHeight+1; i<FTS_MAX_APPENDABLE_HEIGHT; i++){ pWriter->aNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; } pNode = &pWriter->aNodeWriter[nHeight]; pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight; blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aRoot, nRoot); pNode->block.n = nRoot; } for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ NodeReader reader; pNode = &pWriter->aNodeWriter[i]; rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n); while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); blobGrowBuffer(&pNode->key, reader.term.n, &rc); if( rc==SQLITE_OK ){ memcpy(pNode->key.a, reader.term.a, reader.term.n); pNode->key.n = reader.term.n; if( i>0 ){ char *aBlock = 0; int nBlock = 0; pNode = &pWriter->aNodeWriter[i-1]; pNode->iBlock = reader.iChild; rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; } sqlite3_free(aBlock); } } nodeReaderRelease(&reader); } } rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } return rc; } /* ** Determine the largest segment index value that exists within absolute ** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus ** one before returning SQLITE_OK. Or, if there are no segments at all ** within level iAbsLevel, set *piIdx to zero. ** ** If an error occurs, return an SQLite error code. The final value of ** *piIdx is undefined in this case. */ static int fts3IncrmergeOutputIdx( Fts3Table *p, /* FTS Table handle */ sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ int *piIdx /* OUT: Next free index at iAbsLevel+1 */ ){ int rc; sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); sqlite3_step(pOutputIdx); *piIdx = sqlite3_column_int(pOutputIdx, 0); rc = sqlite3_reset(pOutputIdx); } return rc; } /* ** Allocate an appendable output segment on absolute level iAbsLevel+1 ** with idx value iIdx. ** ** In the %_segdir table, a segment is defined by the values in three ** columns: ** ** start_block ** leaves_end_block ** end_block ** ** When an appendable segment is allocated, it is estimated that the ** maximum number of leaf blocks that may be required is the sum of the ** number of leaf blocks consumed by the input segments, plus the number ** of input segments, multiplied by two. This value is stored in stack ** variable nLeafEst. ** ** A total of 16*nLeafEst blocks are allocated when an appendable segment ** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous ** array of leaf nodes starts at the first block allocated. The array ** of interior nodes that are parents of the leaf nodes start at block ** (start_block + (1 + end_block - start_block) / 16). And so on. ** ** In the actual code below, the value "16" is replaced with the ** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT. */ static int fts3IncrmergeWriter( Fts3Table *p, /* Fts3 table handle */ sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ int iIdx, /* Index of new output segment */ Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ IncrmergeWriter *pWriter /* Populate this object */ ){ int rc; /* Return Code */ int i; /* Iterator variable */ int nLeafEst = 0; /* Blocks allocated for leaf nodes */ sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ /* Calculate nLeafEst. */ rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ nLeafEst = sqlite3_column_int(pLeafEst, 0); } rc = sqlite3_reset(pLeafEst); } if( rc!=SQLITE_OK ) return rc; /* Calculate the first block to use in the output segment */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); pWriter->iEnd = pWriter->iStart - 1; pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; } rc = sqlite3_reset(pFirstBlock); } if( rc!=SQLITE_OK ) return rc; /* Insert the marker in the %_segments table to make sure nobody tries ** to steal the space just allocated. This is also used to identify ** appendable segments. */ rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0); if( rc!=SQLITE_OK ) return rc; pWriter->iAbsLevel = iAbsLevel; pWriter->nLeafEst = nLeafEst; pWriter->iIdx = iIdx; /* Set up the array of NodeWriter objects */ for(i=0; i<FTS_MAX_APPENDABLE_HEIGHT; i++){ pWriter->aNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; } return SQLITE_OK; } /* ** Remove an entry from the %_segdir table. This involves running the ** following two statements: ** ** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx ** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx ** ** The DELETE statement removes the specific %_segdir level. The UPDATE ** statement ensures that the remaining segments have contiguously allocated ** idx values. */ static int fts3RemoveSegdirEntry( Fts3Table *p, /* FTS3 table handle */ sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ int iIdx /* Index of %_segdir entry to delete */ ){ int rc; /* Return code */ sqlite3_stmt *pDelete = 0; /* DELETE statement */ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pDelete, 1, iAbsLevel); sqlite3_bind_int(pDelete, 2, iIdx); sqlite3_step(pDelete); rc = sqlite3_reset(pDelete); } return rc; } /* ** One or more segments have just been removed from absolute level iAbsLevel. ** Update the 'idx' values of the remaining segments in the level so that ** the idx values are a contiguous sequence starting from 0. */ static int fts3RepackSegdirLevel( Fts3Table *p, /* FTS3 table handle */ sqlite3_int64 iAbsLevel /* Absolute level to repack */ ){ int rc; /* Return code */ int *aIdx = 0; /* Array of remaining idx values */ int nIdx = 0; /* Valid entries in aIdx[] */ int nAlloc = 0; /* Allocated size of aIdx[] */ int i; /* Iterator variable */ sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int64(pSelect, 1, iAbsLevel); while( SQLITE_ROW==sqlite3_step(pSelect) ){ if( nIdx>=nAlloc ){ int *aNew; nAlloc += 16; aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); if( !aNew ){ rc = SQLITE_NOMEM; break; } aIdx = aNew; } aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); } rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } if( rc==SQLITE_OK ){ rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); } if( rc==SQLITE_OK ){ sqlite3_bind_int64(pUpdate, 2, iAbsLevel); } assert( p->bIgnoreSavepoint==0 ); p->bIgnoreSavepoint = 1; for(i=0; rc==SQLITE_OK && i<nIdx; i++){ if( aIdx[i]!=i ){ sqlite3_bind_int(pUpdate, 3, aIdx[i]); sqlite3_bind_int(pUpdate, 1, i); sqlite3_step(pUpdate); rc = sqlite3_reset(pUpdate); } } p->bIgnoreSavepoint = 0; sqlite3_free(aIdx); return rc; } static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ pNode->a[0] = (char)iHeight; if( iChild ){ assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); }else{ assert( pNode->nAlloc>=1 ); pNode->n = 1; } } /* ** The first two arguments are a pointer to and the size of a segment b-tree ** node. The node may be a leaf or an internal node. ** ** This function creates a new node image in blob object *pNew by copying ** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes) ** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode. */ static int fts3TruncateNode( const char *aNode, /* Current node image */ int nNode, /* Size of aNode in bytes */ Blob *pNew, /* OUT: Write new node image here */ const char *zTerm, /* Omit all terms smaller than this */ int nTerm, /* Size of zTerm in bytes */ sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ ){ NodeReader reader; /* Reader object */ Blob prev = {0, 0, 0}; /* Previous term written to new node */ int rc = SQLITE_OK; /* Return code */ int bLeaf = aNode[0]=='\0'; /* True for a leaf node */ /* Allocate required output space */ blobGrowBuffer(pNew, nNode, &rc); if( rc!=SQLITE_OK ) return rc; pNew->n = 0; /* Populate new node buffer */ for(rc = nodeReaderInit(&reader, aNode, nNode); rc==SQLITE_OK && reader.aNode; rc = nodeReaderNext(&reader) ){ if( pNew->n==0 ){ int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm); if( res<0 || (bLeaf==0 && res==0) ) continue; fts3StartNode(pNew, (int)aNode[0], reader.iChild); *piBlock = reader.iChild; } rc = fts3AppendToNode( pNew, &prev, reader.term.a, reader.term.n, reader.aDoclist, reader.nDoclist ); if( rc!=SQLITE_OK ) break; } if( pNew->n==0 ){ fts3StartNode(pNew, (int)aNode[0], reader.iChild); *piBlock = reader.iChild; } assert( pNew->n<=pNew->nAlloc ); nodeReaderRelease(&reader); sqlite3_free(prev.a); return rc; } /* ** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute ** level iAbsLevel. This may involve deleting entries from the %_segments ** table, and modifying existing entries in both the %_segments and %_segdir ** tables. ** ** SQLITE_OK is returned if the segment is updated successfully. Or an ** SQLite error code otherwise. */ static int fts3TruncateSegment( Fts3Table *p, /* FTS3 table handle */ sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ int iIdx, /* Index within level of segment to modify */ const char *zTerm, /* Remove terms smaller than this */ int nTerm /* Number of bytes in buffer zTerm */ ){ int rc = SQLITE_OK; /* Return code */ Blob root = {0,0,0}; /* New root page image */ Blob block = {0,0,0}; /* Buffer used for any other block */ sqlite3_int64 iBlock = 0; /* Block id */ sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); if( rc==SQLITE_OK ){ int rc2; /* sqlite3_reset() return code */ sqlite3_bind_int64(pFetch, 1, iAbsLevel); sqlite3_bind_int(pFetch, 2, iIdx); if( SQLITE_ROW==sqlite3_step(pFetch) ){ const char *aRoot = sqlite3_column_blob(pFetch, 4); int nRoot = sqlite3_column_bytes(pFetch, 4); iOldStart = sqlite3_column_int64(pFetch, 1); rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); } rc2 = sqlite3_reset(pFetch); if( rc==SQLITE_OK ) rc = rc2; } while( rc==SQLITE_OK && iBlock ){ char *aBlock = 0; int nBlock = 0; iNewStart = iBlock; rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); if( rc==SQLITE_OK ){ rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); } if( rc==SQLITE_OK ){ rc = fts3WriteSegment(p, iNewStart, block.a, block.n); } sqlite3_free(aBlock); } /* Variable iNewStart now contains the first valid leaf node. */ if( rc==SQLITE_OK && iNewStart ){ sqlite3_stmt *pDel = 0; rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pDel, 1, iOldStart); sqlite3_bind_int64(pDel, 2, iNewStart-1); sqlite3_step(pDel); rc = sqlite3_reset(pDel); } } if( rc==SQLITE_OK ){ sqlite3_stmt *pChomp = 0; rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pChomp, 1, iNewStart); sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); sqlite3_bind_int64(pChomp, 3, iAbsLevel); sqlite3_bind_int(pChomp, 4, iIdx); sqlite3_step(pChomp); rc = sqlite3_reset(pChomp); } } sqlite3_free(root.a); sqlite3_free(block.a); return rc; } /* ** This function is called after an incrmental-merge operation has run to ** merge (or partially merge) two or more segments from absolute level ** iAbsLevel. ** ** Each input segment is either removed from the db completely (if all of ** its data was copied to the output segment by the incrmerge operation) ** or modified in place so that it no longer contains those entries that ** have been duplicated in the output segment. */ static int fts3IncrmergeChomp( Fts3Table *p, /* FTS table handle */ sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ int *pnRem /* Number of segments not deleted */ ){ int i; int nRem = 0; int rc = SQLITE_OK; for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){ Fts3SegReader *pSeg = 0; int j; /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding ** somewhere in the pCsr->apSegment[] array. */ for(j=0; ALWAYS(j<pCsr->nSegment); j++){ pSeg = pCsr->apSegment[j]; if( pSeg->iIdx==i ) break; } assert( j<pCsr->nSegment && pSeg->iIdx==i ); if( pSeg->aNode==0 ){ /* Seg-reader is at EOF. Remove the entire input segment. */ rc = fts3DeleteSegment(p, pSeg); if( rc==SQLITE_OK ){ rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx); } *pnRem = 0; }else{ /* The incremental merge did not copy all the data from this ** segment to the upper level. The segment is modified in place ** so that it contains no keys smaller than zTerm/nTerm. */ const char *zTerm = pSeg->zTerm; int nTerm = pSeg->nTerm; rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm); nRem++; } } if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){ rc = fts3RepackSegdirLevel(p, iAbsLevel); } *pnRem = nRem; return rc; } /* ** Store an incr-merge hint in the database. */ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ sqlite3_stmt *pReplace = 0; int rc; /* Return code */ rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); sqlite3_step(pReplace); rc = sqlite3_reset(pReplace); } return rc; } /* ** Load an incr-merge hint from the database. The incr-merge hint, if one ** exists, is stored in the rowid==1 row of the %_stat table. ** ** If successful, populate blob *pHint with the value read from the %_stat ** table and return SQLITE_OK. Otherwise, if an error occurs, return an ** SQLite error code. */ static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ sqlite3_stmt *pSelect = 0; int rc; pHint->n = 0; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); if( SQLITE_ROW==sqlite3_step(pSelect) ){ const char *aHint = sqlite3_column_blob(pSelect, 0); int nHint = sqlite3_column_bytes(pSelect, 0); if( aHint ){ blobGrowBuffer(pHint, nHint, &rc); if( rc==SQLITE_OK ){ memcpy(pHint->a, aHint, nHint); pHint->n = nHint; } } } rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } return rc; } /* ** If *pRc is not SQLITE_OK when this function is called, it is a no-op. ** Otherwise, append an entry to the hint stored in blob *pHint. Each entry ** consists of two varints, the absolute level number of the input segments ** and the number of input segments. ** ** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs, ** set *pRc to an SQLite error code before returning. */ static void fts3IncrmergeHintPush( Blob *pHint, /* Hint blob to append to */ i64 iAbsLevel, /* First varint to store in hint */ int nInput, /* Second varint to store in hint */ int *pRc /* IN/OUT: Error code */ ){ blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); if( *pRc==SQLITE_OK ){ pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); } } /* ** Read the last entry (most recently pushed) from the hint blob *pHint ** and then remove the entry. Write the two values read to *piAbsLevel and ** *pnInput before returning. ** ** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does ** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB. */ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ const int nHint = pHint->n; int i; i = pHint->n-2; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput); if( i!=nHint ) return SQLITE_CORRUPT_VTAB; return SQLITE_OK; } /* ** Attempt an incremental merge that writes nMerge leaf blocks. ** ** Incremental merges happen nMin segments at a time. The two ** segments to be merged are the nMin oldest segments (the ones with ** the smallest indexes) in the highest level that contains at least ** nMin segments. Multiple merges might occur in an attempt to write the ** quota of nMerge leaf blocks. */ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ int rc; /* Return code */ int nRem = nMerge; /* Number of leaf pages yet to be written */ Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ IncrmergeWriter *pWriter; /* Writer object */ int nSeg = 0; /* Number of input segments */ sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ int bDirtyHint = 0; /* True if blob 'hint' has been modified */ /* Allocate space for the cursor, filter and writer objects */ const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); if( !pWriter ) return SQLITE_NOMEM; pFilter = (Fts3SegFilter *)&pWriter[1]; pCsr = (Fts3MultiSegReader *)&pFilter[1]; rc = fts3IncrmergeHintLoad(p, &hint); while( rc==SQLITE_OK && nRem>0 ){ const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ int bUseHint = 0; /* True if attempting to append */ /* Search the %_segdir table for the absolute level with the smallest ** relative level number that contains at least nMin segments, if any. ** If one is found, set iAbsLevel to the absolute level number and ** nSeg to nMin. If no level with at least nMin segments can be found, ** set nSeg to -1. */ rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); sqlite3_bind_int(pFindLevel, 1, nMin); if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ iAbsLevel = sqlite3_column_int64(pFindLevel, 0); nSeg = nMin; }else{ nSeg = -1; } rc = sqlite3_reset(pFindLevel); /* If the hint read from the %_stat table is not empty, check if the ** last entry in it specifies a relative level smaller than or equal ** to the level identified by the block above (if any). If so, this ** iteration of the loop will work on merging at the hinted level. */ if( rc==SQLITE_OK && hint.n ){ int nHint = hint.n; sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ int nHintSeg = 0; /* Hint number of segments */ rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ iAbsLevel = iHintAbsLevel; nSeg = nHintSeg; bUseHint = 1; bDirtyHint = 1; }else{ /* This undoes the effect of the HintPop() above - so that no entry ** is removed from the hint blob. */ hint.n = nHint; } } /* If nSeg is less that zero, then there is no level with at least ** nMin segments and no hint in the %_stat table. No work to do. ** Exit early in this case. */ if( nSeg<0 ) break; /* Open a cursor to iterate through the contents of the oldest nSeg ** indexes of absolute level iAbsLevel. If this cursor is opened using ** the 'hint' parameters, it is possible that there are less than nSeg ** segments available in level iAbsLevel. In this case, no work is ** done on iAbsLevel - fall through to the next iteration of the loop ** to start work on some other level. */ memset(pWriter, 0, nAlloc); pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; if( rc==SQLITE_OK ){ rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); } if( SQLITE_OK==rc && pCsr->nSegment==nSeg && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) ){ int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); if( rc==SQLITE_OK ){ if( bUseHint && iIdx>0 ){ const char *zKey = pCsr->zTerm; int nKey = pCsr->nTerm; rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); }else{ rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); } } if( rc==SQLITE_OK && pWriter->nLeafEst ){ fts3LogMerge(nSeg, iAbsLevel); do { rc = fts3IncrmergeAppend(p, pWriter, pCsr); if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; }while( rc==SQLITE_ROW ); /* Update or delete the input segments */ if( rc==SQLITE_OK ){ nRem -= (1 + pWriter->nWork); rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg); if( nSeg!=0 ){ bDirtyHint = 1; fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); } } } fts3IncrmergeRelease(p, pWriter, &rc); } sqlite3Fts3SegReaderFinish(pCsr); } /* Write the hint values into the %_stat table for the next incr-merger */ if( bDirtyHint && rc==SQLITE_OK ){ rc = fts3IncrmergeHintStore(p, &hint); } sqlite3_free(pWriter); sqlite3_free(hint.a); return rc; } /* ** Convert the text beginning at *pz into an integer and return ** its value. Advance *pz to point to the first character past ** the integer. */ static int fts3Getint(const char **pz){ const char *z = *pz; int i = 0; while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0'; *pz = z; return i; } /* ** Process statements of the form: ** ** INSERT INTO table(table) VALUES('merge=A,B'); ** ** A and B are integers that decode to be the number of leaf pages ** written for the merge, and the minimum number of segments on a level ** before it will be selected for a merge, respectively. */ static int fts3DoIncrmerge( Fts3Table *p, /* FTS3 table handle */ const char *zParam /* Nul-terminated string containing "A,B" */ ){ int rc; int nMin = (FTS3_MERGE_COUNT / 2); int nMerge = 0; const char *z = zParam; /* Read the first integer value */ nMerge = fts3Getint(&z); /* If the first integer value is followed by a ',', read the second ** integer value. */ if( z[0]==',' && z[1]!='\0' ){ z++; nMin = fts3Getint(&z); } if( z[0]!='\0' || nMin<2 ){ rc = SQLITE_ERROR; }else{ rc = SQLITE_OK; if( !p->bHasStat ){ assert( p->bFts4==0 ); sqlite3Fts3CreateStatTable(&rc, p); } if( rc==SQLITE_OK ){ rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); } sqlite3Fts3SegmentsClose(p); } return rc; } /* ** Process statements of the form: ** ** INSERT INTO table(table) VALUES('automerge=X'); ** ** where X is an integer. X==0 means to turn automerge off. X!=0 means ** turn it on. The setting is persistent. */ static int fts3DoAutoincrmerge( Fts3Table *p, /* FTS3 table handle */ const char *zParam /* Nul-terminated string containing boolean */ ){ int rc = SQLITE_OK; sqlite3_stmt *pStmt = 0; p->bAutoincrmerge = fts3Getint(&zParam)!=0; if( !p->bHasStat ){ assert( p->bFts4==0 ); sqlite3Fts3CreateStatTable(&rc, p); if( rc ) return rc; } rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); if( rc ) return rc;; sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); return rc; } /* ** Return a 64-bit checksum for the FTS index entry specified by the ** arguments to this function. */ static u64 fts3ChecksumEntry( const char *zTerm, /* Pointer to buffer containing term */ int nTerm, /* Size of zTerm in bytes */ int iLangid, /* Language id for current row */ int iIndex, /* Index (0..Fts3Table.nIndex-1) */ i64 iDocid, /* Docid for current row. */ int iCol, /* Column number */ int iPos /* Position */ ){ int i; u64 ret = (u64)iDocid; ret += (ret<<3) + iLangid; ret += (ret<<3) + iIndex; ret += (ret<<3) + iCol; ret += (ret<<3) + iPos; for(i=0; i<nTerm; i++) ret += (ret<<3) + zTerm[i]; return ret; } /* ** Return a checksum of all entries in the FTS index that correspond to ** language id iLangid. The checksum is calculated by XORing the checksums ** of each individual entry (see fts3ChecksumEntry()) together. ** ** If successful, the checksum value is returned and *pRc set to SQLITE_OK. ** Otherwise, if an error occurs, *pRc is set to an SQLite error code. The ** return value is undefined in this case. */ static u64 fts3ChecksumIndex( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language id to return cksum for */ int iIndex, /* Index to cksum (0..p->nIndex-1) */ int *pRc /* OUT: Return code */ ){ Fts3SegFilter filter; Fts3MultiSegReader csr; int rc; u64 cksum = 0; assert( *pRc==SQLITE_OK ); memset(&filter, 0, sizeof(filter)); memset(&csr, 0, sizeof(csr)); filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; filter.flags |= FTS3_SEGMENT_SCAN; rc = sqlite3Fts3SegReaderCursor( p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr ); if( rc==SQLITE_OK ){ rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); } if( rc==SQLITE_OK ){ while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ char *pCsr = csr.aDoclist; char *pEnd = &pCsr[csr.nDoclist]; i64 iDocid = 0; i64 iCol = 0; i64 iPos = 0; pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); while( pCsr<pEnd ){ i64 iVal = 0; pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); if( pCsr<pEnd ){ if( iVal==0 || iVal==1 ){ iCol = 0; iPos = 0; if( iVal ){ pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); }else{ pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); iDocid += iVal; } }else{ iPos += (iVal - 2); cksum = cksum ^ fts3ChecksumEntry( csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid, (int)iCol, (int)iPos ); } } } } } sqlite3Fts3SegReaderFinish(&csr); *pRc = rc; return cksum; } /* ** Check if the contents of the FTS index match the current contents of the ** content table. If no error occurs and the contents do match, set *pbOk ** to true and return SQLITE_OK. Or if the contents do not match, set *pbOk ** to false before returning. ** ** If an error occurs (e.g. an OOM or IO error), return an SQLite error ** code. The final value of *pbOk is undefined in this case. */ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ int rc = SQLITE_OK; /* Return code */ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ /* This block calculates the checksum according to the FTS index. */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int(pAllLangid, 1, p->nIndex); while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ int iLangid = sqlite3_column_int(pAllLangid, 0); int i; for(i=0; i<p->nIndex; i++){ cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); } } rc2 = sqlite3_reset(pAllLangid); if( rc==SQLITE_OK ) rc = rc2; } /* This block calculates the checksum according to the %_content table */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; sqlite3_stmt *pStmt = 0; char *zSql; zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); if( !zSql ){ rc = SQLITE_NOMEM; }else{ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ i64 iDocid = sqlite3_column_int64(pStmt, 0); int iLang = langidFromSelect(p, pStmt); int iCol; for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){ const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); int nText = sqlite3_column_bytes(pStmt, iCol+1); sqlite3_tokenizer_cursor *pT = 0; rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ int nToken; /* Number of bytes in token */ int iDum1, iDum2; /* Dummy variables */ int iPos; /* Position of token in zText */ rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); if( rc==SQLITE_OK ){ int i; cksum2 = cksum2 ^ fts3ChecksumEntry( zToken, nToken, iLang, 0, iDocid, iCol, iPos ); for(i=1; i<p->nIndex; i++){ if( p->aIndex[i].nPrefix<=nToken ){ cksum2 = cksum2 ^ fts3ChecksumEntry( zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos ); } } } } if( pT ) pModule->xClose(pT); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } } sqlite3_finalize(pStmt); } *pbOk = (cksum1==cksum2); return rc; } /* ** Run the integrity-check. If no error occurs and the current contents of ** the FTS index are correct, return SQLITE_OK. Or, if the contents of the ** FTS index are incorrect, return SQLITE_CORRUPT_VTAB. ** ** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite ** error code. ** ** The integrity-check works as follows. For each token and indexed token ** prefix in the document set, a 64-bit checksum is calculated (by code ** in fts3ChecksumEntry()) based on the following: ** ** + The index number (0 for the main index, 1 for the first prefix ** index etc.), ** + The token (or token prefix) text itself, ** + The language-id of the row it appears in, ** + The docid of the row it appears in, ** + The column it appears in, and ** + The tokens position within that column. ** ** The checksums for all entries in the index are XORed together to create ** a single checksum for the entire index. ** ** The integrity-check code calculates the same checksum in two ways: ** ** 1. By scanning the contents of the FTS index, and ** 2. By scanning and tokenizing the content table. ** ** If the two checksums are identical, the integrity-check is deemed to have ** passed. */ static int fts3DoIntegrityCheck( Fts3Table *p /* FTS3 table handle */ ){ int rc; int bOk = 0; rc = fts3IntegrityCheck(p, &bOk); if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB; return rc; } /* ** Handle a 'special' INSERT of the form: ** ** "INSERT INTO tbl(tbl) VALUES(<expr>)" ** ** Argument pVal contains the result of <expr>. Currently the only ** meaningful value to insert is the text 'optimize'. */ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ int rc; /* Return Code */ const char *zVal = (const char *)sqlite3_value_text(pVal); int nVal = sqlite3_value_bytes(pVal); if( !zVal ){ return SQLITE_NOMEM; }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ rc = fts3DoOptimize(p, 0); }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ rc = fts3DoRebuild(p); }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ rc = fts3DoIntegrityCheck(p); }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); #ifdef SQLITE_TEST }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ p->nNodeSize = atoi(&zVal[9]); rc = SQLITE_OK; }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ p->nMaxPendingData = atoi(&zVal[11]); rc = SQLITE_OK; |
︙ | ︙ | |||
128437 128438 128439 128440 128441 128442 128443 | } /* ** This function does the work for the xUpdate method of FTS3 virtual ** tables. The schema of the virtual table being: ** ** CREATE TABLE <table name>( | | | 130713 130714 130715 130716 130717 130718 130719 130720 130721 130722 130723 130724 130725 130726 130727 | } /* ** This function does the work for the xUpdate method of FTS3 virtual ** tables. The schema of the virtual table being: ** ** CREATE TABLE <table name>( ** <user columns>, ** <table name> HIDDEN, ** docid HIDDEN, ** <langid> HIDDEN ** ); ** ** */ |
︙ | ︙ | |||
128569 128570 128571 128572 128573 128574 128575 | } if( p->bHasDocsize ){ fts3InsertDocsize(&rc, p, aSzIns); } nChng++; } | | | 130845 130846 130847 130848 130849 130850 130851 130852 130853 130854 130855 130856 130857 130858 130859 | } if( p->bHasDocsize ){ fts3InsertDocsize(&rc, p, aSzIns); } nChng++; } if( p->bFts4 ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); } update_out: sqlite3_free(aSzIns); sqlite3Fts3SegmentsClose(p); return rc; |
︙ | ︙ | |||
129400 129401 129402 129403 129404 129405 129406 | static int fts3MatchinfoCheck( Fts3Table *pTab, char cArg, char **pzErr ){ if( (cArg==FTS3_MATCHINFO_NPHRASE) || (cArg==FTS3_MATCHINFO_NCOL) | | | | 131676 131677 131678 131679 131680 131681 131682 131683 131684 131685 131686 131687 131688 131689 131690 131691 | static int fts3MatchinfoCheck( Fts3Table *pTab, char cArg, char **pzErr ){ if( (cArg==FTS3_MATCHINFO_NPHRASE) || (cArg==FTS3_MATCHINFO_NCOL) || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) || (cArg==FTS3_MATCHINFO_LCS) || (cArg==FTS3_MATCHINFO_HITS) ){ return SQLITE_OK; } *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg); |
︙ | ︙ | |||
130291 130292 130293 130294 130295 130296 130297 130298 130299 130300 130301 130302 130303 130304 | int eCoordType; }; /* Possible values for eCoordType: */ #define RTREE_COORD_REAL32 0 #define RTREE_COORD_INT32 1 /* ** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: ** ** m = M/3 ** ** If an R*-tree "Reinsert" operation is required, the same number of | > > > > > > > > > > > > > | 132567 132568 132569 132570 132571 132572 132573 132574 132575 132576 132577 132578 132579 132580 132581 132582 132583 132584 132585 132586 132587 132588 132589 132590 132591 132592 132593 | int eCoordType; }; /* Possible values for eCoordType: */ #define RTREE_COORD_REAL32 0 #define RTREE_COORD_INT32 1 /* ** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will ** only deal with integer coordinates. No floating point operations ** will be done. */ #ifdef SQLITE_RTREE_INT_ONLY typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ typedef int RtreeValue; /* Low accuracy coordinate */ #else typedef double RtreeDValue; /* High accuracy coordinate */ typedef float RtreeValue; /* Low accuracy coordinate */ #endif /* ** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: ** ** m = M/3 ** ** If an R*-tree "Reinsert" operation is required, the same number of |
︙ | ︙ | |||
130326 130327 130328 130329 130330 130331 130332 | int iCell; /* Index of current cell in pNode */ int iStrategy; /* Copy of idxNum search parameter */ int nConstraint; /* Number of entries in aConstraint */ RtreeConstraint *aConstraint; /* Search constraints. */ }; union RtreeCoord { | | | | > > > > | | | | | > | | | 132615 132616 132617 132618 132619 132620 132621 132622 132623 132624 132625 132626 132627 132628 132629 132630 132631 132632 132633 132634 132635 132636 132637 132638 132639 132640 132641 132642 132643 132644 132645 132646 132647 132648 132649 132650 132651 132652 132653 132654 132655 132656 | int iCell; /* Index of current cell in pNode */ int iStrategy; /* Copy of idxNum search parameter */ int nConstraint; /* Number of entries in aConstraint */ RtreeConstraint *aConstraint; /* Search constraints. */ }; union RtreeCoord { RtreeValue f; int i; }; /* ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord ** formatted as a RtreeDValue (double or int64). This macro assumes that local ** variable pRtree points to the Rtree structure associated with the ** RtreeCoord. */ #ifdef SQLITE_RTREE_INT_ONLY # define DCOORD(coord) ((RtreeDValue)coord.i) #else # define DCOORD(coord) ( \ (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ ((double)coord.f) : \ ((double)coord.i) \ ) #endif /* ** A search constraint. */ struct RtreeConstraint { int iCoord; /* Index of constrained coordinate */ int op; /* Constraining operation */ RtreeDValue rValue; /* Constraint value. */ int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ }; /* Possible values for RtreeConstraint.op */ #define RTREE_EQ 0x41 #define RTREE_LE 0x42 #define RTREE_LT 0x43 |
︙ | ︙ | |||
130396 130397 130398 130399 130400 130401 130402 | /* ** An instance of this structure must be supplied as a blob argument to ** the right-hand-side of an SQL MATCH operator used to constrain an ** r-tree query. */ struct RtreeMatchArg { u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ | | | | | 132690 132691 132692 132693 132694 132695 132696 132697 132698 132699 132700 132701 132702 132703 132704 132705 132706 132707 132708 132709 132710 132711 132712 132713 132714 132715 132716 132717 132718 132719 | /* ** An instance of this structure must be supplied as a blob argument to ** the right-hand-side of an SQL MATCH operator used to constrain an ** r-tree query. */ struct RtreeMatchArg { u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); void *pContext; int nParam; RtreeDValue aParam[1]; }; /* ** When a geometry callback is created (see sqlite3_rtree_geometry_callback), ** a single instance of the following structure is allocated. It is used ** as the context for the user-function created by by s_r_g_c(). The object ** is eventually deleted by the destructor mechanism provided by ** sqlite3_create_function_v2() (which is called by s_r_g_c() to create ** the geometry callback function). */ struct RtreeGeomCallback { int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); void *pContext; }; #ifndef MAX # define MAX(x,y) ((x) < (y) ? (y) : (x)) #endif #ifndef MIN |
︙ | ︙ | |||
130977 130978 130979 130980 130981 130982 130983 | static int testRtreeGeom( Rtree *pRtree, /* R-Tree object */ RtreeConstraint *pConstraint, /* MATCH constraint to test */ RtreeCell *pCell, /* Cell to test */ int *pbRes /* OUT: Test result */ ){ int i; | | | 133271 133272 133273 133274 133275 133276 133277 133278 133279 133280 133281 133282 133283 133284 133285 | static int testRtreeGeom( Rtree *pRtree, /* R-Tree object */ RtreeConstraint *pConstraint, /* MATCH constraint to test */ RtreeCell *pCell, /* Cell to test */ int *pbRes /* OUT: Test result */ ){ int i; RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; int nCoord = pRtree->nDim*2; assert( pConstraint->op==RTREE_MATCH ); assert( pConstraint->pGeom ); for(i=0; i<nCoord; i++){ aCoord[i] = DCOORD(pCell->aCoord[i]); |
︙ | ︙ | |||
131007 131008 131009 131010 131011 131012 131013 | int ii; int bRes = 0; int rc = SQLITE_OK; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; | | | | 133301 133302 133303 133304 133305 133306 133307 133308 133309 133310 133311 133312 133313 133314 133315 133316 | int ii; int bRes = 0; int rc = SQLITE_OK; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); switch( p->op ){ case RTREE_LE: case RTREE_LT: |
︙ | ︙ | |||
131060 131061 131062 131063 131064 131065 131066 | RtreeCell cell; int ii; *pbEof = 0; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; ii<pCursor->nConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; | | | 133354 133355 133356 133357 133358 133359 133360 133361 133362 133363 133364 133365 133366 133367 133368 | RtreeCell cell; int ii; *pbEof = 0; nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); for(ii=0; ii<pCursor->nConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]); int res; assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); switch( p->op ){ case RTREE_LE: res = (coord<=p->rValue); break; case RTREE_LT: res = (coord<p->rValue); break; |
︙ | ︙ | |||
131258 131259 131260 131261 131262 131263 131264 131265 131266 | if( i==0 ){ i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); sqlite3_result_int64(ctx, iRowid); }else{ RtreeCoord c; nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ sqlite3_result_double(ctx, c.f); | > | > > | 133552 133553 133554 133555 133556 133557 133558 133559 133560 133561 133562 133563 133564 133565 133566 133567 133568 133569 133570 133571 | if( i==0 ){ i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); sqlite3_result_int64(ctx, iRowid); }else{ RtreeCoord c; nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ sqlite3_result_double(ctx, c.f); }else #endif { assert( pRtree->eCoordType==RTREE_COORD_INT32 ); sqlite3_result_int(ctx, c.i); } } return SQLITE_OK; } |
︙ | ︙ | |||
131307 131308 131309 131310 131311 131312 131313 | /* Check that value is actually a blob. */ if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; /* Check that the blob is roughly the right size. */ nBlob = sqlite3_value_bytes(pValue); if( nBlob<(int)sizeof(RtreeMatchArg) | | | | 133604 133605 133606 133607 133608 133609 133610 133611 133612 133613 133614 133615 133616 133617 133618 133619 133620 133621 133622 133623 133624 133625 133626 133627 133628 133629 133630 133631 133632 | /* Check that value is actually a blob. */ if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; /* Check that the blob is roughly the right size. */ nBlob = sqlite3_value_bytes(pValue); if( nBlob<(int)sizeof(RtreeMatchArg) || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 ){ return SQLITE_ERROR; } pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( sizeof(sqlite3_rtree_geometry) + nBlob ); if( !pGeom ) return SQLITE_NOMEM; memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); p = (RtreeMatchArg *)&pGeom[1]; memcpy(p, sqlite3_value_blob(pValue), nBlob); if( p->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue)) ){ sqlite3_free(pGeom); return SQLITE_ERROR; } pGeom->pContext = p->pContext; pGeom->nParam = p->nParam; |
︙ | ︙ | |||
131393 131394 131395 131396 131397 131398 131399 131400 131401 131402 131403 131404 131405 131406 131407 | ** an sqlite3_rtree_geometry_callback() SQL user function. */ rc = deserializeGeometry(argv[ii], p); if( rc!=SQLITE_OK ){ break; } }else{ p->rValue = sqlite3_value_double(argv[ii]); } } } } if( rc==SQLITE_OK ){ pCsr->pNode = 0; | > > > > | 133690 133691 133692 133693 133694 133695 133696 133697 133698 133699 133700 133701 133702 133703 133704 133705 133706 133707 133708 | ** an sqlite3_rtree_geometry_callback() SQL user function. */ rc = deserializeGeometry(argv[ii], p); if( rc!=SQLITE_OK ){ break; } }else{ #ifdef SQLITE_RTREE_INT_ONLY p->rValue = sqlite3_value_int64(argv[ii]); #else p->rValue = sqlite3_value_double(argv[ii]); #endif } } } } if( rc==SQLITE_OK ){ pCsr->pNode = 0; |
︙ | ︙ | |||
131527 131528 131529 131530 131531 131532 131533 | pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); return rc; } /* ** Return the N-dimensional volumn of the cell stored in *p. */ | | | | | | | | 133828 133829 133830 133831 133832 133833 133834 133835 133836 133837 133838 133839 133840 133841 133842 133843 133844 133845 133846 133847 133848 133849 133850 133851 133852 133853 133854 133855 133856 133857 133858 133859 | pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); return rc; } /* ** Return the N-dimensional volumn of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ RtreeDValue area = (RtreeDValue)1; int ii; for(ii=0; ii<(pRtree->nDim*2); ii+=2){ area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); } return area; } /* ** Return the margin length of cell p. The margin length is the sum ** of the objects size in each dimension. */ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ RtreeDValue margin = (RtreeDValue)0; int ii; for(ii=0; ii<(pRtree->nDim*2); ii+=2){ margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); } return margin; } /* ** Store the union of cells p1 and p2 in p1. */ |
︙ | ︙ | |||
131589 131590 131591 131592 131593 131594 131595 | } return 1; } /* ** Return the amount cell p would grow by if it were unioned with pCell. */ | | | | | | | < | | | < | | 133890 133891 133892 133893 133894 133895 133896 133897 133898 133899 133900 133901 133902 133903 133904 133905 133906 133907 133908 133909 133910 133911 133912 133913 133914 133915 133916 133917 133918 133919 133920 133921 133922 133923 133924 133925 133926 133927 133928 133929 133930 133931 133932 133933 133934 133935 133936 133937 133938 133939 133940 133941 133942 133943 133944 133945 133946 133947 133948 133949 133950 133951 133952 133953 133954 133955 133956 133957 133958 133959 133960 133961 133962 133963 133964 133965 133966 | } return 1; } /* ** Return the amount cell p would grow by if it were unioned with pCell. */ static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ RtreeDValue area; RtreeCell cell; memcpy(&cell, p, sizeof(RtreeCell)); area = cellArea(pRtree, &cell); cellUnion(pRtree, &cell, pCell); return (cellArea(pRtree, &cell)-area); } #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT static RtreeDValue cellOverlap( Rtree *pRtree, RtreeCell *p, RtreeCell *aCell, int nCell, int iExclude ){ int ii; RtreeDValue overlap = 0.0; for(ii=0; ii<nCell; ii++){ #if VARIANT_RSTARTREE_CHOOSESUBTREE if( ii!=iExclude ) #else assert( iExclude==-1 ); UNUSED_PARAMETER(iExclude); #endif { int jj; RtreeDValue o = (RtreeDValue)1; for(jj=0; jj<(pRtree->nDim*2); jj+=2){ RtreeDValue x1, x2; x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); if( x2<x1 ){ o = 0.0; break; }else{ o = o * (x2-x1); } } overlap += o; } } return overlap; } #endif #if VARIANT_RSTARTREE_CHOOSESUBTREE static RtreeDValue cellOverlapEnlargement( Rtree *pRtree, RtreeCell *p, RtreeCell *pInsert, RtreeCell *aCell, int nCell, int iExclude ){ RtreeDValue before, after; before = cellOverlap(pRtree, p, aCell, nCell, iExclude); cellUnion(pRtree, p, pInsert); after = cellOverlap(pRtree, p, aCell, nCell, iExclude); return (after-before); } #endif /* ** This function implements the ChooseLeaf algorithm from Gutman[84]. ** ChooseSubTree in r*tree terminology. |
︙ | ︙ | |||
131677 131678 131679 131680 131681 131682 131683 | RtreeNode *pNode; rc = nodeAcquire(pRtree, 1, 0, &pNode); for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; sqlite3_int64 iBest = 0; | | | | | | 133976 133977 133978 133979 133980 133981 133982 133983 133984 133985 133986 133987 133988 133989 133990 133991 133992 133993 133994 | RtreeNode *pNode; rc = nodeAcquire(pRtree, 1, 0, &pNode); for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; sqlite3_int64 iBest = 0; RtreeDValue fMinGrowth = 0.0; RtreeDValue fMinArea = 0.0; #if VARIANT_RSTARTREE_CHOOSESUBTREE RtreeDValue fMinOverlap = 0.0; RtreeDValue overlap; #endif int nCell = NCELL(pNode); RtreeCell cell; RtreeNode *pChild; RtreeCell *aCell = 0; |
︙ | ︙ | |||
131712 131713 131714 131715 131716 131717 131718 | /* Select the child node which will be enlarged the least if pCell ** is inserted into it. Resolve ties by choosing the entry with ** the smallest area. */ for(iCell=0; iCell<nCell; iCell++){ int bBest = 0; | | | | 134011 134012 134013 134014 134015 134016 134017 134018 134019 134020 134021 134022 134023 134024 134025 134026 | /* Select the child node which will be enlarged the least if pCell ** is inserted into it. Resolve ties by choosing the entry with ** the smallest area. */ for(iCell=0; iCell<nCell; iCell++){ int bBest = 0; RtreeDValue growth; RtreeDValue area; nodeGetCell(pRtree, pNode, iCell, &cell); growth = cellGrowth(pRtree, &cell, pCell); area = cellArea(pRtree, &cell); #if VARIANT_RSTARTREE_CHOOSESUBTREE if( ii==(pRtree->iDepth-1) ){ overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); |
︙ | ︙ | |||
131840 131841 131842 131843 131844 131845 131846 | int nCell, int *piLeftSeed, int *piRightSeed ){ int i; int iLeftSeed = 0; int iRightSeed = 1; | | | | | | | | | | 134139 134140 134141 134142 134143 134144 134145 134146 134147 134148 134149 134150 134151 134152 134153 134154 134155 134156 134157 134158 134159 134160 134161 134162 134163 134164 134165 134166 134167 134168 134169 134170 134171 134172 134173 134174 134175 134176 134177 134178 134179 134180 134181 134182 134183 134184 134185 134186 134187 | int nCell, int *piLeftSeed, int *piRightSeed ){ int i; int iLeftSeed = 0; int iRightSeed = 1; RtreeDValue maxNormalInnerWidth = (RtreeDValue)0; /* Pick two "seed" cells from the array of cells. The algorithm used ** here is the LinearPickSeeds algorithm from Gutman[1984]. The ** indices of the two seed cells in the array are stored in local ** variables iLeftSeek and iRightSeed. */ for(i=0; i<pRtree->nDim; i++){ RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]); RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]); RtreeDValue x3 = x1; RtreeDValue x4 = x2; int jj; int iCellLeft = 0; int iCellRight = 0; for(jj=1; jj<nCell; jj++){ RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]); RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]); if( left<x1 ) x1 = left; if( right>x4 ) x4 = right; if( left>x3 ){ x3 = left; iCellRight = jj; } if( right<x2 ){ x2 = right; iCellLeft = jj; } } if( x4!=x1 ){ RtreeDValue normalwidth = (x3 - x2) / (x4 - x1); if( normalwidth>maxNormalInnerWidth ){ iLeftSeed = iCellLeft; iRightSeed = iCellRight; } } } |
︙ | ︙ | |||
131903 131904 131905 131906 131907 131908 131909 | RtreeCell *pLeftBox, RtreeCell *pRightBox, int *aiUsed ){ #define FABS(a) ((a)<0.0?-1.0*(a):(a)) int iSelect = -1; | | | | | | 134202 134203 134204 134205 134206 134207 134208 134209 134210 134211 134212 134213 134214 134215 134216 134217 134218 134219 134220 134221 134222 | RtreeCell *pLeftBox, RtreeCell *pRightBox, int *aiUsed ){ #define FABS(a) ((a)<0.0?-1.0*(a):(a)) int iSelect = -1; RtreeDValue fDiff; int ii; for(ii=0; ii<nCell; ii++){ if( aiUsed[ii]==0 ){ RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); RtreeDValue diff = FABS(right-left); if( iSelect<0 || diff>fDiff ){ fDiff = diff; iSelect = ii; } } } aiUsed[iSelect] = 1; |
︙ | ︙ | |||
131936 131937 131938 131939 131940 131941 131942 | int *piRightSeed ){ int ii; int jj; int iLeftSeed = 0; int iRightSeed = 1; | | | | | | 134235 134236 134237 134238 134239 134240 134241 134242 134243 134244 134245 134246 134247 134248 134249 134250 134251 134252 134253 134254 134255 | int *piRightSeed ){ int ii; int jj; int iLeftSeed = 0; int iRightSeed = 1; RtreeDValue fWaste = 0.0; for(ii=0; ii<nCell; ii++){ for(jj=ii+1; jj<nCell; jj++){ RtreeDValue right = cellArea(pRtree, &aCell[jj]); RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); RtreeDValue waste = growth - right; if( waste>fWaste ){ iLeftSeed = ii; iRightSeed = jj; fWaste = waste; } } |
︙ | ︙ | |||
131977 131978 131979 131980 131981 131982 131983 | ** ** The aSpare array is used as temporary working space by the ** sorting algorithm. */ static void SortByDistance( int *aIdx, int nIdx, | | | 134276 134277 134278 134279 134280 134281 134282 134283 134284 134285 134286 134287 134288 134289 134290 | ** ** The aSpare array is used as temporary working space by the ** sorting algorithm. */ static void SortByDistance( int *aIdx, int nIdx, RtreeDValue *aDistance, int *aSpare ){ if( nIdx>1 ){ int iLeft = 0; int iRight = 0; int nLeft = nIdx/2; |
︙ | ︙ | |||
132003 132004 132005 132006 132007 132008 132009 | if( iLeft==nLeft ){ aIdx[iLeft+iRight] = aRight[iRight]; iRight++; }else if( iRight==nRight ){ aIdx[iLeft+iRight] = aLeft[iLeft]; iLeft++; }else{ | | | | | | 134302 134303 134304 134305 134306 134307 134308 134309 134310 134311 134312 134313 134314 134315 134316 134317 134318 134319 134320 134321 134322 134323 134324 134325 134326 134327 134328 134329 134330 134331 134332 134333 134334 | if( iLeft==nLeft ){ aIdx[iLeft+iRight] = aRight[iRight]; iRight++; }else if( iRight==nRight ){ aIdx[iLeft+iRight] = aLeft[iLeft]; iLeft++; }else{ RtreeDValue fLeft = aDistance[aLeft[iLeft]]; RtreeDValue fRight = aDistance[aRight[iRight]]; if( fLeft<fRight ){ aIdx[iLeft+iRight] = aLeft[iLeft]; iLeft++; }else{ aIdx[iLeft+iRight] = aRight[iRight]; iRight++; } } } #if 0 /* Check that the sort worked */ { int jj; for(jj=1; jj<nIdx; jj++){ RtreeDValue left = aDistance[aIdx[jj-1]]; RtreeDValue right = aDistance[aIdx[jj]]; assert( left<=right ); } } #endif } } |
︙ | ︙ | |||
132064 132065 132066 132067 132068 132069 132070 | SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); memcpy(aSpare, aLeft, sizeof(int)*nLeft); aLeft = aSpare; while( iLeft<nLeft || iRight<nRight ){ | | | | | | | | | | 134363 134364 134365 134366 134367 134368 134369 134370 134371 134372 134373 134374 134375 134376 134377 134378 134379 134380 134381 134382 134383 134384 134385 134386 134387 134388 134389 134390 134391 134392 134393 134394 134395 134396 134397 134398 134399 134400 134401 | SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); memcpy(aSpare, aLeft, sizeof(int)*nLeft); aLeft = aSpare; while( iLeft<nLeft || iRight<nRight ){ RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]); RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]); RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]); RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]); if( (iLeft!=nLeft) && ((iRight==nRight) || (xleft1<xright1) || (xleft1==xright1 && xleft2<xright2) )){ aIdx[iLeft+iRight] = aLeft[iLeft]; iLeft++; }else{ aIdx[iLeft+iRight] = aRight[iRight]; iRight++; } } #if 0 /* Check that the sort worked */ { int jj; for(jj=1; jj<nIdx; jj++){ RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2]; RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1]; RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2]; RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1]; assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) ); } } #endif } } |
︙ | ︙ | |||
132115 132116 132117 132118 132119 132120 132121 | ){ int **aaSorted; int *aSpare; int ii; int iBestDim = 0; int iBestSplit = 0; | | | | | | | | 134414 134415 134416 134417 134418 134419 134420 134421 134422 134423 134424 134425 134426 134427 134428 134429 134430 134431 134432 134433 134434 134435 134436 134437 134438 134439 134440 134441 134442 134443 134444 134445 134446 134447 134448 134449 134450 134451 134452 134453 134454 134455 134456 134457 134458 134459 134460 134461 134462 134463 134464 | ){ int **aaSorted; int *aSpare; int ii; int iBestDim = 0; int iBestSplit = 0; RtreeDValue fBestMargin = 0.0; int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); aaSorted = (int **)sqlite3_malloc(nByte); if( !aaSorted ){ return SQLITE_NOMEM; } aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; memset(aaSorted, 0, nByte); for(ii=0; ii<pRtree->nDim; ii++){ int jj; aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; for(jj=0; jj<nCell; jj++){ aaSorted[ii][jj] = jj; } SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); } for(ii=0; ii<pRtree->nDim; ii++){ RtreeDValue margin = 0.0; RtreeDValue fBestOverlap = 0.0; RtreeDValue fBestArea = 0.0; int iBestLeft = 0; int nLeft; for( nLeft=RTREE_MINCELLS(pRtree); nLeft<=(nCell-RTREE_MINCELLS(pRtree)); nLeft++ ){ RtreeCell left; RtreeCell right; int kk; RtreeDValue overlap; RtreeDValue area; memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); for(kk=1; kk<(nCell-1); kk++){ if( kk<nLeft ){ cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]); }else{ |
︙ | ︙ | |||
132234 132235 132236 132237 132238 132239 132240 | nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); aiUsed[iLeftSeed] = 1; aiUsed[iRightSeed] = 1; for(i=nCell-2; i>0; i--){ RtreeCell *pNext; pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); | | | 134533 134534 134535 134536 134537 134538 134539 134540 134541 134542 134543 134544 134545 134546 134547 | nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); aiUsed[iLeftSeed] = 1; aiUsed[iRightSeed] = 1; for(i=nCell-2; i>0; i--){ RtreeCell *pNext; pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); RtreeDValue diff = cellGrowth(pRtree, pBboxLeft, pNext) - cellGrowth(pRtree, pBboxRight, pNext) ; if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) ){ nodeInsertCell(pRtree, pRight, pNext); |
︙ | ︙ | |||
132567 132568 132569 132570 132571 132572 132573 | RtreeNode *pNode, RtreeCell *pCell, int iHeight ){ int *aOrder; int *aSpare; RtreeCell *aCell; | | | > | > | | | | | | | | | | | | | | 134866 134867 134868 134869 134870 134871 134872 134873 134874 134875 134876 134877 134878 134879 134880 134881 134882 134883 134884 134885 134886 134887 134888 134889 134890 134891 134892 134893 134894 134895 134896 134897 134898 134899 134900 134901 134902 134903 134904 134905 134906 134907 134908 134909 134910 134911 134912 134913 134914 134915 134916 134917 134918 134919 134920 134921 134922 134923 134924 134925 134926 134927 134928 134929 | RtreeNode *pNode, RtreeCell *pCell, int iHeight ){ int *aOrder; int *aSpare; RtreeCell *aCell; RtreeDValue *aDistance; int nCell; RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS]; int iDim; int ii; int rc = SQLITE_OK; int n; memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS); nCell = NCELL(pNode)+1; n = (nCell+1)&(~1); /* Allocate the buffers used by this operation. The allocation is ** relinquished before this function returns. */ aCell = (RtreeCell *)sqlite3_malloc(n * ( sizeof(RtreeCell) + /* aCell array */ sizeof(int) + /* aOrder array */ sizeof(int) + /* aSpare array */ sizeof(RtreeDValue) /* aDistance array */ )); if( !aCell ){ return SQLITE_NOMEM; } aOrder = (int *)&aCell[n]; aSpare = (int *)&aOrder[n]; aDistance = (RtreeDValue *)&aSpare[n]; for(ii=0; ii<nCell; ii++){ if( ii==(nCell-1) ){ memcpy(&aCell[ii], pCell, sizeof(RtreeCell)); }else{ nodeGetCell(pRtree, pNode, ii, &aCell[ii]); } aOrder[ii] = ii; for(iDim=0; iDim<pRtree->nDim; iDim++){ aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); } } for(iDim=0; iDim<pRtree->nDim; iDim++){ aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); } for(ii=0; ii<nCell; ii++){ aDistance[ii] = 0.0; for(iDim=0; iDim<pRtree->nDim; iDim++){ RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - DCOORD(aCell[ii].aCoord[iDim*2])); aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); } } SortByDistance(aOrder, nCell, aDistance, aSpare); nodeZero(pRtree, pNode); |
︙ | ︙ | |||
132856 132857 132858 132859 132860 132861 132862 132863 132864 | ** conflict-handling mode specified by the user. */ if( nData>1 ){ int ii; /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ assert( nData==(pRtree->nDim*2 + 3) ); if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ for(ii=0; ii<(pRtree->nDim*2); ii+=2){ | > | | | > > | 135157 135158 135159 135160 135161 135162 135163 135164 135165 135166 135167 135168 135169 135170 135171 135172 135173 135174 135175 135176 135177 135178 135179 135180 135181 135182 135183 | ** conflict-handling mode specified by the user. */ if( nData>1 ){ int ii; /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ assert( nData==(pRtree->nDim*2 + 3) ); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ for(ii=0; ii<(pRtree->nDim*2); ii+=2){ cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]); cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]); if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ rc = SQLITE_CONSTRAINT; goto constraint; } } }else #endif { for(ii=0; ii<(pRtree->nDim*2); ii+=2){ cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ rc = SQLITE_CONSTRAINT; goto constraint; } |
︙ | ︙ | |||
133263 133264 133265 133266 133267 133268 133269 | RtreeCell cell; int jj; nodeGetCell(&tree, &node, ii, &cell); sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); nCell = (int)strlen(zCell); for(jj=0; jj<tree.nDim*2; jj++){ | > | > > > > > | 135567 135568 135569 135570 135571 135572 135573 135574 135575 135576 135577 135578 135579 135580 135581 135582 135583 135584 135585 135586 135587 | RtreeCell cell; int jj; nodeGetCell(&tree, &node, ii, &cell); sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); nCell = (int)strlen(zCell); for(jj=0; jj<tree.nDim*2; jj++){ #ifndef SQLITE_RTREE_INT_ONLY sqlite3_snprintf(512-nCell,&zCell[nCell], " %f", (double)cell.aCoord[jj].f); #else sqlite3_snprintf(512-nCell,&zCell[nCell], " %d", cell.aCoord[jj].i); #endif nCell = (int)strlen(zCell); } if( zText ){ char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell); sqlite3_free(zText); zText = zTextNew; |
︙ | ︙ | |||
133305 133306 133307 133308 133309 133310 133311 133312 133313 133314 133315 133316 133317 133318 133319 | int rc; rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); } if( rc==SQLITE_OK ){ void *c = (void *)RTREE_COORD_REAL32; rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); } if( rc==SQLITE_OK ){ void *c = (void *)RTREE_COORD_INT32; rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); } | > > > > | 135615 135616 135617 135618 135619 135620 135621 135622 135623 135624 135625 135626 135627 135628 135629 135630 135631 135632 135633 | int rc; rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); } if( rc==SQLITE_OK ){ #ifdef SQLITE_RTREE_INT_ONLY void *c = (void *)RTREE_COORD_INT32; #else void *c = (void *)RTREE_COORD_REAL32; #endif rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); } if( rc==SQLITE_OK ){ void *c = (void *)RTREE_COORD_INT32; rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); } |
︙ | ︙ | |||
133339 133340 133341 133342 133343 133344 133345 | ** table MATCH operators. */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; int nBlob; | | > > > > | | 135653 135654 135655 135656 135657 135658 135659 135660 135661 135662 135663 135664 135665 135666 135667 135668 135669 135670 135671 135672 135673 135674 135675 135676 135677 135678 135679 135680 135681 135682 135683 135684 135685 135686 135687 135688 135689 135690 135691 135692 135693 135694 | ** table MATCH operators. */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; int nBlob; nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue); pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); }else{ int i; pBlob->magic = RTREE_GEOMETRY_MAGIC; pBlob->xGeom = pGeomCtx->xGeom; pBlob->pContext = pGeomCtx->pContext; pBlob->nParam = nArg; for(i=0; i<nArg; i++){ #ifdef SQLITE_RTREE_INT_ONLY pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); #else pBlob->aParam[i] = sqlite3_value_double(aArg[i]); #endif } sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); } } /* ** Register a new geometry function for use with the r-tree MATCH operator. */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *), void *pContext ){ RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ /* Allocate and populate the context object. */ pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); if( !pGeomCtx ) return SQLITE_NOMEM; |
︙ | ︙ | |||
134007 134008 134009 134010 134011 134012 134013 | UChar32 c; int iInput = 0; int iOut = 0; *ppCursor = 0; | > > > | | 136325 136326 136327 136328 136329 136330 136331 136332 136333 136334 136335 136336 136337 136338 136339 136340 136341 136342 | UChar32 c; int iInput = 0; int iOut = 0; *ppCursor = 0; if( zInput==0 ){ nInput = 0; zInput = ""; }else if( nInput<0 ){ nInput = strlen(zInput); } nChar = nInput+1; pCsr = (IcuCursor *)sqlite3_malloc( sizeof(IcuCursor) + /* IcuCursor */ nChar * sizeof(UChar) + /* IcuCursor.aChar[] */ (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ |
︙ | ︙ |
Changes to SQLite.Interop/src/core/sqlite3.h.
︙ | ︙ | |||
103 104 105 106 107 108 109 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.12" #define SQLITE_VERSION_NUMBER 3007012 #define SQLITE_SOURCE_ID "2012-05-01 14:21:57 bfa61e781cb442be641486e7e55a1518e888d830" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] | | | 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE ** <dd> These options are obsolete and should not be used by new code. ** They are retained for backwards compatibility but are now no-ops. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
︙ | ︙ | |||
6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt> ** <dd>This parameter returns the number of pager cache misses that have ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 | > > > > > > > > > > > > | | 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 | ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt> ** <dd>This parameter returns the number of pager cache misses that have ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number |
︙ | ︙ | |||
6969 6970 6971 6972 6973 6974 6975 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, | > > > | > | 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, #ifdef SQLITE_RTREE_INT_ONLY int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), #else int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), #endif void *pContext ); /* ** A pointer to a structure of the following type is passed as the first ** argument to callbacks registered using rtree_geometry_callback(). |
︙ | ︙ |
Changes to readme.htm.
︙ | ︙ | |||
186 187 188 189 190 191 192 193 194 195 196 197 198 199 | <h2><b>Version History</b></h2> <p> <b>1.0.81.0 - June XX, 2012</b> </p> <ul> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> | > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | <h2><b>Version History</b></h2> <p> <b>1.0.81.0 - June XX, 2012</b> </p> <ul> <li>Updated to SQLite 3.7.12.</li> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> |
︙ | ︙ |
Changes to www/news.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <title>News</title> <b>Version History</b> <p> <b>1.0.81.0 - June XX, 2012 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <title>News</title> <b>Version History</b> <p> <b>1.0.81.0 - June XX, 2012 <font color="red">(release scheduled)</font></b> </p> <ul> <li>Updated to SQLite 3.7.12.</li> <li>Support compiling the interop assembly without support for the custom extension functions and the CryptoAPI based codec.</li> <li>Add DefineConstants property to the SQLiteConnection class to return the list of define constants used when compiling the core managed assembly.</li> <li>Add release archive verification tool to the release automation.</li> <li>Fix subtle race condition between threads fetching connection handles from the connection pool any garbage collection (GC) threads that may be running. Fix for [996d13cd87].</li> <li>Add missing call to SetTimeout in the SQLite3_UTF16.Open method.</li> <li>Add checks to prevent the SQLiteConnectionPool.Remove method from returning any connection handles that are closed or invalid.</li> <li>Modify static SQLiteBase helper methods to prevent them from passing IntPtr.Zero to the SQLite native library.</li> |
︙ | ︙ |
Changes to www/support.wiki.
︙ | ︙ | |||
69 70 71 72 73 74 75 | Use the mailing list. Please do <b>not</b> send email directly to the authors of SQLite or System.Data.SQLite unless: </p> <ul> <li> You have or intend to acquire a | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | Use the mailing list. Please do <b>not</b> send email directly to the authors of SQLite or System.Data.SQLite unless: </p> <ul> <li> You have or intend to acquire a <a href="http://www.sqlite.org/support.html"> professional support contract</a>. </li> <li> You are working on an open source project. </li> </ul> |
︙ | ︙ |