diff options
| -rw-r--r-- | c/loadable-ext-sqlite3.h | 448 | ||||
| -rw-r--r-- | c/sqlite3.c | 8395 | ||||
| -rw-r--r-- | c/sqlite3.h | 202 |
3 files changed, 6167 insertions, 2878 deletions
diff --git a/c/loadable-ext-sqlite3.h b/c/loadable-ext-sqlite3.h index 6ca6914..4e93395 100644 --- a/c/loadable-ext-sqlite3.h +++ b/c/loadable-ext-sqlite3.h | |||
| @@ -146,9 +146,9 @@ extern "C" { | |||
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ | 148 | */ |
| 149 | #define SQLITE_VERSION "3.44.0" | 149 | #define SQLITE_VERSION "3.47.1" |
| 150 | #define SQLITE_VERSION_NUMBER 3044000 | 150 | #define SQLITE_VERSION_NUMBER 3047001 |
| 151 | #define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" | 151 | #define SQLITE_SOURCE_ID "2024-11-25 12:07:48 b95d11e958643b969c47a8e5857f3793b9e69700b8f1469371386369a26e577e" |
| 152 | 152 | ||
| 153 | /* | 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| @@ -412,6 +412,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); | |||
| 412 | ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. | 412 | ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. |
| 413 | ** <li> The application must not modify the SQL statement text passed into | 413 | ** <li> The application must not modify the SQL statement text passed into |
| 414 | ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. | 414 | ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. |
| 415 | ** <li> The application must not dereference the arrays or string pointers | ||
| 416 | ** passed as the 3rd and 4th callback parameters after it returns. | ||
| 415 | ** </ul> | 417 | ** </ul> |
| 416 | */ | 418 | */ |
| 417 | 419 | ||
| @@ -635,6 +637,13 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); | |||
| 635 | ** filesystem supports doing multiple write operations atomically when those | 637 | ** filesystem supports doing multiple write operations atomically when those |
| 636 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and | 638 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and |
| 637 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. | 639 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. |
| 640 | ** | ||
| 641 | ** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read | ||
| 642 | ** from the database file in amounts that are not a multiple of the | ||
| 643 | ** page size and that do not begin at a page boundary. Without this | ||
| 644 | ** property, SQLite is careful to only do full-page reads and write | ||
| 645 | ** on aligned pages, with the one exception that it will do a sub-page | ||
| 646 | ** read of the first page to access the database header. | ||
| 638 | */ | 647 | */ |
| 639 | #define SQLITE_IOCAP_ATOMIC 0x00000001 | 648 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 640 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 | 649 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| @@ -651,6 +660,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); | |||
| 651 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 | 660 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 652 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 | 661 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 |
| 653 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 | 662 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 |
| 663 | #define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 | ||
| 654 | 664 | ||
| 655 | /* | 665 | /* |
| 656 | ** CAPI3REF: File Locking Levels | 666 | ** CAPI3REF: File Locking Levels |
| @@ -747,16 +757,16 @@ struct sqlite3_file { | |||
| 747 | ** </ul> | 757 | ** </ul> |
| 748 | ** xLock() upgrades the database file lock. In other words, xLock() moves the | 758 | ** xLock() upgrades the database file lock. In other words, xLock() moves the |
| 749 | ** database file lock in the direction NONE toward EXCLUSIVE. The argument to | 759 | ** database file lock in the direction NONE toward EXCLUSIVE. The argument to |
| 750 | ** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never | 760 | ** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never |
| 751 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the | 761 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the |
| 752 | ** requested lock, then the call to xLock() is a no-op. | 762 | ** requested lock, then the call to xLock() is a no-op. |
| 753 | ** xUnlock() downgrades the database file lock to either SHARED or NONE. | 763 | ** xUnlock() downgrades the database file lock to either SHARED or NONE. |
| 754 | * If the lock is already at or below the requested lock state, then the call | 764 | ** If the lock is already at or below the requested lock state, then the call |
| 755 | ** to xUnlock() is a no-op. | 765 | ** to xUnlock() is a no-op. |
| 756 | ** The xCheckReservedLock() method checks whether any database connection, | 766 | ** The xCheckReservedLock() method checks whether any database connection, |
| 757 | ** either in this process or in some other process, is holding a RESERVED, | 767 | ** either in this process or in some other process, is holding a RESERVED, |
| 758 | ** PENDING, or EXCLUSIVE lock on the file. It returns true | 768 | ** PENDING, or EXCLUSIVE lock on the file. It returns, via its output |
| 759 | ** if such a lock exists and false otherwise. | 769 | ** pointer parameter, true if such a lock exists and false otherwise. |
| 760 | ** | 770 | ** |
| 761 | ** The xFileControl() method is a generic interface that allows custom | 771 | ** The xFileControl() method is a generic interface that allows custom |
| 762 | ** VFS implementations to directly control an open file using the | 772 | ** VFS implementations to directly control an open file using the |
| @@ -797,6 +807,7 @@ struct sqlite3_file { | |||
| 797 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] | 807 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] |
| 798 | ** <li> [SQLITE_IOCAP_IMMUTABLE] | 808 | ** <li> [SQLITE_IOCAP_IMMUTABLE] |
| 799 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] | 809 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] |
| 810 | ** <li> [SQLITE_IOCAP_SUBPAGE_READ] | ||
| 800 | ** </ul> | 811 | ** </ul> |
| 801 | ** | 812 | ** |
| 802 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of | 813 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of |
| @@ -2120,6 +2131,22 @@ struct sqlite3_mem_methods { | |||
| 2120 | ** configuration setting is never used, then the default maximum is determined | 2131 | ** configuration setting is never used, then the default maximum is determined |
| 2121 | ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that | 2132 | ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that |
| 2122 | ** compile-time option is not set, then the default maximum is 1073741824. | 2133 | ** compile-time option is not set, then the default maximum is 1073741824. |
| 2134 | ** | ||
| 2135 | ** [[SQLITE_CONFIG_ROWID_IN_VIEW]] | ||
| 2136 | ** <dt>SQLITE_CONFIG_ROWID_IN_VIEW | ||
| 2137 | ** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability | ||
| 2138 | ** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is | ||
| 2139 | ** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability | ||
| 2140 | ** defaults to on. This configuration option queries the current setting or | ||
| 2141 | ** changes the setting to off or on. The argument is a pointer to an integer. | ||
| 2142 | ** If that integer initially holds a value of 1, then the ability for VIEWs to | ||
| 2143 | ** have ROWIDs is activated. If the integer initially holds zero, then the | ||
| 2144 | ** ability is deactivated. Any other initial value for the integer leaves the | ||
| 2145 | ** setting unchanged. After changes, if any, the integer is written with | ||
| 2146 | ** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite | ||
| 2147 | ** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and | ||
| 2148 | ** recommended case) then the integer is always filled with zero, regardless | ||
| 2149 | ** if its initial value. | ||
| 2123 | ** </dl> | 2150 | ** </dl> |
| 2124 | */ | 2151 | */ |
| 2125 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ | 2152 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| @@ -2151,6 +2178,7 @@ struct sqlite3_mem_methods { | |||
| 2151 | #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ | 2178 | #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ |
| 2152 | #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ | 2179 | #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ |
| 2153 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ | 2180 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ |
| 2181 | #define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ | ||
| 2154 | 2182 | ||
| 2155 | /* | 2183 | /* |
| 2156 | ** CAPI3REF: Database Connection Configuration Options | 2184 | ** CAPI3REF: Database Connection Configuration Options |
| @@ -3225,8 +3253,8 @@ struct sqlite3_mem_methods { | |||
| 3225 | #define SQLITE_RECURSIVE 33 /* NULL NULL */ | 3253 | #define SQLITE_RECURSIVE 33 /* NULL NULL */ |
| 3226 | 3254 | ||
| 3227 | /* | 3255 | /* |
| 3228 | ** CAPI3REF: Tracing And Profiling Functions | 3256 | ** CAPI3REF: Deprecated Tracing And Profiling Functions |
| 3229 | ** METHOD: sqlite3 | 3257 | ** DEPRECATED |
| 3230 | ** | 3258 | ** |
| 3231 | ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface | 3259 | ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface |
| 3232 | ** instead of the routines described here. | 3260 | ** instead of the routines described here. |
| @@ -3479,8 +3507,8 @@ struct sqlite3_mem_methods { | |||
| 3479 | ** | 3507 | ** |
| 3480 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> | 3508 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> |
| 3481 | ** <dd>The database connection comes up in "extended result code mode". | 3509 | ** <dd>The database connection comes up in "extended result code mode". |
| 3482 | ** In other words, the database behaves has if | 3510 | ** In other words, the database behaves as if |
| 3483 | ** [sqlite3_extended_result_codes(db,1)] where called on the database | 3511 | ** [sqlite3_extended_result_codes(db,1)] were called on the database |
| 3484 | ** connection as soon as the connection is created. In addition to setting | 3512 | ** connection as soon as the connection is created. In addition to setting |
| 3485 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] | 3513 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] |
| 3486 | ** to return an extended result code.</dd> | 3514 | ** to return an extended result code.</dd> |
| @@ -3852,15 +3880,17 @@ struct sqlite3_mem_methods { | |||
| 3852 | ** </ul> | 3880 | ** </ul> |
| 3853 | ** | 3881 | ** |
| 3854 | ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language | 3882 | ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language |
| 3855 | ** text that describes the error, as either UTF-8 or UTF-16 respectively. | 3883 | ** text that describes the error, as either UTF-8 or UTF-16 respectively, |
| 3884 | ** or NULL if no error message is available. | ||
| 3856 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) | 3885 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) |
| 3857 | ** ^(Memory to hold the error message string is managed internally. | 3886 | ** ^(Memory to hold the error message string is managed internally. |
| 3858 | ** The application does not need to worry about freeing the result. | 3887 | ** The application does not need to worry about freeing the result. |
| 3859 | ** However, the error string might be overwritten or deallocated by | 3888 | ** However, the error string might be overwritten or deallocated by |
| 3860 | ** subsequent calls to other SQLite interface functions.)^ | 3889 | ** subsequent calls to other SQLite interface functions.)^ |
| 3861 | ** | 3890 | ** |
| 3862 | ** ^The sqlite3_errstr() interface returns the English-language text | 3891 | ** ^The sqlite3_errstr(E) interface returns the English-language text |
| 3863 | ** that describes the [result code], as UTF-8. | 3892 | ** that describes the [result code] E, as UTF-8, or NULL if E is not an |
| 3893 | ** result code for which a text error message is available. | ||
| 3864 | ** ^(Memory to hold the error message string is managed internally | 3894 | ** ^(Memory to hold the error message string is managed internally |
| 3865 | ** and must not be freed by the application)^. | 3895 | ** and must not be freed by the application)^. |
| 3866 | ** | 3896 | ** |
| @@ -4092,13 +4122,17 @@ typedef struct sqlite3_stmt sqlite3_stmt; | |||
| 4092 | ** and sqlite3_prepare16_v3() use UTF-16. | 4122 | ** and sqlite3_prepare16_v3() use UTF-16. |
| 4093 | ** | 4123 | ** |
| 4094 | ** ^If the nByte argument is negative, then zSql is read up to the | 4124 | ** ^If the nByte argument is negative, then zSql is read up to the |
| 4095 | ** first zero terminator. ^If nByte is positive, then it is the | 4125 | ** first zero terminator. ^If nByte is positive, then it is the maximum |
| 4096 | ** number of bytes read from zSql. ^If nByte is zero, then no prepared | 4126 | ** number of bytes read from zSql. When nByte is positive, zSql is read |
| 4127 | ** up to the first zero terminator or until the nByte bytes have been read, | ||
| 4128 | ** whichever comes first. ^If nByte is zero, then no prepared | ||
| 4097 | ** statement is generated. | 4129 | ** statement is generated. |
| 4098 | ** If the caller knows that the supplied string is nul-terminated, then | 4130 | ** If the caller knows that the supplied string is nul-terminated, then |
| 4099 | ** there is a small performance advantage to passing an nByte parameter that | 4131 | ** there is a small performance advantage to passing an nByte parameter that |
| 4100 | ** is the number of bytes in the input string <i>including</i> | 4132 | ** is the number of bytes in the input string <i>including</i> |
| 4101 | ** the nul-terminator. | 4133 | ** the nul-terminator. |
| 4134 | ** Note that nByte measure the length of the input in bytes, not | ||
| 4135 | ** characters, even for the UTF-16 interfaces. | ||
| 4102 | ** | 4136 | ** |
| 4103 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte | 4137 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte |
| 4104 | ** past the end of the first SQL statement in zSql. These routines only | 4138 | ** past the end of the first SQL statement in zSql. These routines only |
| @@ -5326,13 +5360,36 @@ typedef struct sqlite3_context sqlite3_context; | |||
| 5326 | ** </dd> | 5360 | ** </dd> |
| 5327 | ** | 5361 | ** |
| 5328 | ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> | 5362 | ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> |
| 5329 | ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call | 5363 | ** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call |
| 5330 | ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. | 5364 | ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. |
| 5331 | ** Specifying this flag makes no difference for scalar or aggregate user | 5365 | ** This flag instructs SQLite to omit some corner-case optimizations that |
| 5332 | ** functions. However, if it is not specified for a user-defined window | 5366 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, |
| 5333 | ** function, then any sub-types belonging to arguments passed to the window | 5367 | ** causing it to return zero rather than the correct subtype(). |
| 5334 | ** function may be discarded before the window function is called (i.e. | 5368 | ** All SQL functions that invoke [sqlite3_value_subtype()] should have this |
| 5335 | ** sqlite3_value_subtype() will always return 0). | 5369 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return |
| 5370 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though | ||
| 5371 | ** a non-zero subtype was specified by the function argument expression. | ||
| 5372 | ** | ||
| 5373 | ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> | ||
| 5374 | ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call | ||
| 5375 | ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its | ||
| 5376 | ** result. | ||
| 5377 | ** Every function that invokes [sqlite3_result_subtype()] should have this | ||
| 5378 | ** property. If it does not, then the call to [sqlite3_result_subtype()] | ||
| 5379 | ** might become a no-op if the function is used as term in an | ||
| 5380 | ** [expression index]. On the other hand, SQL functions that never invoke | ||
| 5381 | ** [sqlite3_result_subtype()] should avoid setting this property, as the | ||
| 5382 | ** purpose of this property is to disable certain optimizations that are | ||
| 5383 | ** incompatible with subtypes. | ||
| 5384 | ** | ||
| 5385 | ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> | ||
| 5386 | ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate | ||
| 5387 | ** that internally orders the values provided to the first argument. The | ||
| 5388 | ** ordered-set aggregate SQL notation with a single ORDER BY term can be | ||
| 5389 | ** used to invoke this function. If the ordered-set aggregate notation is | ||
| 5390 | ** used on a function that lacks this flag, then an error is raised. Note | ||
| 5391 | ** that the ordered-set aggregate syntax is only available if SQLite is | ||
| 5392 | ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. | ||
| 5336 | ** </dd> | 5393 | ** </dd> |
| 5337 | ** </dl> | 5394 | ** </dl> |
| 5338 | */ | 5395 | */ |
| @@ -5340,6 +5397,8 @@ typedef struct sqlite3_context sqlite3_context; | |||
| 5340 | #define SQLITE_DIRECTONLY 0x000080000 | 5397 | #define SQLITE_DIRECTONLY 0x000080000 |
| 5341 | #define SQLITE_SUBTYPE 0x000100000 | 5398 | #define SQLITE_SUBTYPE 0x000100000 |
| 5342 | #define SQLITE_INNOCUOUS 0x000200000 | 5399 | #define SQLITE_INNOCUOUS 0x000200000 |
| 5400 | #define SQLITE_RESULT_SUBTYPE 0x001000000 | ||
| 5401 | #define SQLITE_SELFORDER1 0x002000000 | ||
| 5343 | 5402 | ||
| 5344 | /* | 5403 | /* |
| 5345 | ** CAPI3REF: Deprecated Functions | 5404 | ** CAPI3REF: Deprecated Functions |
| @@ -5513,6 +5572,12 @@ typedef struct sqlite3_context sqlite3_context; | |||
| 5513 | ** information can be used to pass a limited amount of context from | 5572 | ** information can be used to pass a limited amount of context from |
| 5514 | ** one SQL function to another. Use the [sqlite3_result_subtype()] | 5573 | ** one SQL function to another. Use the [sqlite3_result_subtype()] |
| 5515 | ** routine to set the subtype for the return value of an SQL function. | 5574 | ** routine to set the subtype for the return value of an SQL function. |
| 5575 | ** | ||
| 5576 | ** Every [application-defined SQL function] that invokes this interface | ||
| 5577 | ** should include the [SQLITE_SUBTYPE] property in the text | ||
| 5578 | ** encoding argument when the function is [sqlite3_create_function|registered]. | ||
| 5579 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() | ||
| 5580 | ** might return zero instead of the upstream subtype in some corner cases. | ||
| 5516 | */ | 5581 | */ |
| 5517 | 5582 | ||
| 5518 | /* | 5583 | /* |
| @@ -5637,14 +5702,22 @@ typedef struct sqlite3_context sqlite3_context; | |||
| 5637 | ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same | 5702 | ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same |
| 5638 | ** parameter)^, or | 5703 | ** parameter)^, or |
| 5639 | ** <li> ^(during the original sqlite3_set_auxdata() call when a memory | 5704 | ** <li> ^(during the original sqlite3_set_auxdata() call when a memory |
| 5640 | ** allocation error occurs.)^ </ul> | 5705 | ** allocation error occurs.)^ |
| 5706 | ** <li> ^(during the original sqlite3_set_auxdata() call if the function | ||
| 5707 | ** is evaluated during query planning instead of during query execution, | ||
| 5708 | ** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul> | ||
| 5641 | ** | 5709 | ** |
| 5642 | ** Note the last bullet in particular. The destructor X in | 5710 | ** Note the last two bullets in particular. The destructor X in |
| 5643 | ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the | 5711 | ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the |
| 5644 | ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() | 5712 | ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() |
| 5645 | ** should be called near the end of the function implementation and the | 5713 | ** should be called near the end of the function implementation and the |
| 5646 | ** function implementation should not make any use of P after | 5714 | ** function implementation should not make any use of P after |
| 5647 | ** sqlite3_set_auxdata() has been called. | 5715 | ** sqlite3_set_auxdata() has been called. Furthermore, a call to |
| 5716 | ** sqlite3_get_auxdata() that occurs immediately after a corresponding call | ||
| 5717 | ** to sqlite3_set_auxdata() might still return NULL if an out-of-memory | ||
| 5718 | ** condition occurred during the sqlite3_set_auxdata() call or if the | ||
| 5719 | ** function is being evaluated during query planning rather than during | ||
| 5720 | ** query execution. | ||
| 5648 | ** | 5721 | ** |
| 5649 | ** ^(In practice, auxiliary data is preserved between function calls for | 5722 | ** ^(In practice, auxiliary data is preserved between function calls for |
| 5650 | ** function parameters that are compile-time constants, including literal | 5723 | ** function parameters that are compile-time constants, including literal |
| @@ -5892,6 +5965,20 @@ typedef void (*sqlite3_destructor_type)(void*); | |||
| 5892 | ** higher order bits are discarded. | 5965 | ** higher order bits are discarded. |
| 5893 | ** The number of subtype bytes preserved by SQLite might increase | 5966 | ** The number of subtype bytes preserved by SQLite might increase |
| 5894 | ** in future releases of SQLite. | 5967 | ** in future releases of SQLite. |
| 5968 | ** | ||
| 5969 | ** Every [application-defined SQL function] that invokes this interface | ||
| 5970 | ** should include the [SQLITE_RESULT_SUBTYPE] property in its | ||
| 5971 | ** text encoding argument when the SQL function is | ||
| 5972 | ** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] | ||
| 5973 | ** property is omitted from the function that invokes sqlite3_result_subtype(), | ||
| 5974 | ** then in some cases the sqlite3_result_subtype() might fail to set | ||
| 5975 | ** the result subtype. | ||
| 5976 | ** | ||
| 5977 | ** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any | ||
| 5978 | ** SQL function that invokes the sqlite3_result_subtype() interface | ||
| 5979 | ** and that does not have the SQLITE_RESULT_SUBTYPE property will raise | ||
| 5980 | ** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 | ||
| 5981 | ** by default. | ||
| 5895 | */ | 5982 | */ |
| 5896 | 5983 | ||
| 5897 | /* | 5984 | /* |
| @@ -6463,6 +6550,12 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; | |||
| 6463 | ** The exceptions defined in this paragraph might change in a future | 6550 | ** The exceptions defined in this paragraph might change in a future |
| 6464 | ** release of SQLite. | 6551 | ** release of SQLite. |
| 6465 | ** | 6552 | ** |
| 6553 | ** Whether the update hook is invoked before or after the | ||
| 6554 | ** corresponding change is currently unspecified and may differ | ||
| 6555 | ** depending on the type of change. Do not rely on the order of the | ||
| 6556 | ** hook call with regards to the final result of the operation which | ||
| 6557 | ** triggers the hook. | ||
| 6558 | ** | ||
| 6466 | ** The update hook implementation must not do anything that will modify | 6559 | ** The update hook implementation must not do anything that will modify |
| 6467 | ** the database connection that invoked the update hook. Any actions | 6560 | ** the database connection that invoked the update hook. Any actions |
| 6468 | ** to modify the database connection must be deferred until after the | 6561 | ** to modify the database connection must be deferred until after the |
| @@ -6965,9 +7058,11 @@ struct sqlite3_module { | |||
| 6965 | ** will be returned by the strategy. | 7058 | ** will be returned by the strategy. |
| 6966 | ** | 7059 | ** |
| 6967 | ** The xBestIndex method may optionally populate the idxFlags field with a | 7060 | ** The xBestIndex method may optionally populate the idxFlags field with a |
| 6968 | ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - | 7061 | ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is |
| 6969 | ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite | 7062 | ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] |
| 6970 | ** assumes that the strategy may visit at most one row. | 7063 | ** output to show the idxNum has hex instead of as decimal. Another flag is |
| 7064 | ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will | ||
| 7065 | ** return at most one row. | ||
| 6971 | ** | 7066 | ** |
| 6972 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then | 7067 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then |
| 6973 | ** SQLite also assumes that if a call to the xUpdate() method is made as | 7068 | ** SQLite also assumes that if a call to the xUpdate() method is made as |
| @@ -7031,7 +7126,9 @@ struct sqlite3_index_info { | |||
| 7031 | ** [sqlite3_index_info].idxFlags field to some combination of | 7126 | ** [sqlite3_index_info].idxFlags field to some combination of |
| 7032 | ** these bits. | 7127 | ** these bits. |
| 7033 | */ | 7128 | */ |
| 7034 | #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ | 7129 | #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ |
| 7130 | #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ | ||
| 7131 | /* in EXPLAIN QUERY PLAN */ | ||
| 7035 | 7132 | ||
| 7036 | /* | 7133 | /* |
| 7037 | ** CAPI3REF: Virtual Table Constraint Operator Codes | 7134 | ** CAPI3REF: Virtual Table Constraint Operator Codes |
| @@ -7566,9 +7663,11 @@ typedef struct sqlite3_blob sqlite3_blob; | |||
| 7566 | ** | 7663 | ** |
| 7567 | ** ^(Some systems (for example, Windows 95) do not support the operation | 7664 | ** ^(Some systems (for example, Windows 95) do not support the operation |
| 7568 | ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() | 7665 | ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() |
| 7569 | ** will always return SQLITE_BUSY. The SQLite core only ever uses | 7666 | ** will always return SQLITE_BUSY. In most cases the SQLite core only uses |
| 7570 | ** sqlite3_mutex_try() as an optimization so this is acceptable | 7667 | ** sqlite3_mutex_try() as an optimization, so this is acceptable |
| 7571 | ** behavior.)^ | 7668 | ** behavior. The exceptions are unix builds that set the |
| 7669 | ** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working | ||
| 7670 | ** sqlite3_mutex_try() is required.)^ | ||
| 7572 | ** | 7671 | ** |
| 7573 | ** ^The sqlite3_mutex_leave() routine exits a mutex that was | 7672 | ** ^The sqlite3_mutex_leave() routine exits a mutex that was |
| 7574 | ** previously entered by the same thread. The behavior | 7673 | ** previously entered by the same thread. The behavior |
| @@ -7817,8 +7916,10 @@ struct sqlite3_mutex_methods { | |||
| 7817 | #define SQLITE_TESTCTRL_ASSERT 12 | 7916 | #define SQLITE_TESTCTRL_ASSERT 12 |
| 7818 | #define SQLITE_TESTCTRL_ALWAYS 13 | 7917 | #define SQLITE_TESTCTRL_ALWAYS 13 |
| 7819 | #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ | 7918 | #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ |
| 7919 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 | ||
| 7820 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 | 7920 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 7821 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ | 7921 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ |
| 7922 | #define SQLITE_TESTCTRL_GETOPT 16 | ||
| 7822 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ | 7923 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ |
| 7823 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 | 7924 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 |
| 7824 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 | 7925 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| @@ -7838,7 +7939,7 @@ struct sqlite3_mutex_methods { | |||
| 7838 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 | 7939 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 |
| 7839 | #define SQLITE_TESTCTRL_TUNE 32 | 7940 | #define SQLITE_TESTCTRL_TUNE 32 |
| 7840 | #define SQLITE_TESTCTRL_LOGEST 33 | 7941 | #define SQLITE_TESTCTRL_LOGEST 33 |
| 7841 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 | 7942 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ |
| 7842 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ | 7943 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ |
| 7843 | 7944 | ||
| 7844 | /* | 7945 | /* |
| @@ -7852,7 +7953,7 @@ struct sqlite3_mutex_methods { | |||
| 7852 | ** The sqlite3_keyword_count() interface returns the number of distinct | 7953 | ** The sqlite3_keyword_count() interface returns the number of distinct |
| 7853 | ** keywords understood by SQLite. | 7954 | ** keywords understood by SQLite. |
| 7854 | ** | 7955 | ** |
| 7855 | ** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and | 7956 | ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and |
| 7856 | ** makes *Z point to that keyword expressed as UTF8 and writes the number | 7957 | ** makes *Z point to that keyword expressed as UTF8 and writes the number |
| 7857 | ** of bytes in the keyword into *L. The string that *Z points to is not | 7958 | ** of bytes in the keyword into *L. The string that *Z points to is not |
| 7858 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns | 7959 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns |
| @@ -8791,6 +8892,16 @@ typedef struct sqlite3_backup sqlite3_backup; | |||
| 8791 | ** APIs are not strictly speaking threadsafe. If they are invoked at the | 8892 | ** APIs are not strictly speaking threadsafe. If they are invoked at the |
| 8792 | ** same time as another thread is invoking sqlite3_backup_step() it is | 8893 | ** same time as another thread is invoking sqlite3_backup_step() it is |
| 8793 | ** possible that they return invalid values. | 8894 | ** possible that they return invalid values. |
| 8895 | ** | ||
| 8896 | ** <b>Alternatives To Using The Backup API</b> | ||
| 8897 | ** | ||
| 8898 | ** Other techniques for safely creating a consistent backup of an SQLite | ||
| 8899 | ** database include: | ||
| 8900 | ** | ||
| 8901 | ** <ul> | ||
| 8902 | ** <li> The [VACUUM INTO] command. | ||
| 8903 | ** <li> The [sqlite3_rsync] utility program. | ||
| 8904 | ** </ul> | ||
| 8794 | */ | 8905 | */ |
| 8795 | 8906 | ||
| 8796 | /* | 8907 | /* |
| @@ -9370,24 +9481,45 @@ typedef struct sqlite3_backup sqlite3_backup; | |||
| 9370 | ** <li value="2"><p> | 9481 | ** <li value="2"><p> |
| 9371 | ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means | 9482 | ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means |
| 9372 | ** that the query planner does not need the rows returned in any particular | 9483 | ** that the query planner does not need the rows returned in any particular |
| 9373 | ** order, as long as rows with the same values in all "aOrderBy" columns | 9484 | ** order, as long as rows with the same values in all columns identified |
| 9374 | ** are adjacent.)^ ^(Furthermore, only a single row for each particular | 9485 | ** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows |
| 9375 | ** combination of values in the columns identified by the "aOrderBy" field | 9486 | ** contain the same values for all columns identified by "colUsed", all but |
| 9376 | ** needs to be returned.)^ ^It is always ok for two or more rows with the same | 9487 | ** one such row may optionally be omitted from the result.)^ |
| 9377 | ** values in all "aOrderBy" columns to be returned, as long as all such rows | 9488 | ** The virtual table is not required to omit rows that are duplicates |
| 9378 | ** are adjacent. ^The virtual table may, if it chooses, omit extra rows | 9489 | ** over the "colUsed" columns, but if the virtual table can do that without |
| 9379 | ** that have the same value for all columns identified by "aOrderBy". | 9490 | ** too much extra effort, it could potentially help the query to run faster. |
| 9380 | ** ^However omitting the extra rows is optional. | ||
| 9381 | ** This mode is used for a DISTINCT query. | 9491 | ** This mode is used for a DISTINCT query. |
| 9382 | ** <li value="3"><p> | 9492 | ** <li value="3"><p> |
| 9383 | ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means | 9493 | ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the |
| 9384 | ** that the query planner needs only distinct rows but it does need the | 9494 | ** virtual table must return rows in the order defined by "aOrderBy" as |
| 9385 | ** rows to be sorted.)^ ^The virtual table implementation is free to omit | 9495 | ** if the sqlite3_vtab_distinct() interface had returned 0. However if |
| 9386 | ** rows that are identical in all aOrderBy columns, if it wants to, but | 9496 | ** two or more rows in the result have the same values for all columns |
| 9387 | ** it is not required to omit any rows. This mode is used for queries | 9497 | ** identified by "colUsed", then all but one such row may optionally be |
| 9498 | ** omitted.)^ Like when the return value is 2, the virtual table | ||
| 9499 | ** is not required to omit rows that are duplicates over the "colUsed" | ||
| 9500 | ** columns, but if the virtual table can do that without | ||
| 9501 | ** too much extra effort, it could potentially help the query to run faster. | ||
| 9502 | ** This mode is used for queries | ||
| 9388 | ** that have both DISTINCT and ORDER BY clauses. | 9503 | ** that have both DISTINCT and ORDER BY clauses. |
| 9389 | ** </ol> | 9504 | ** </ol> |
| 9390 | ** | 9505 | ** |
| 9506 | ** <p>The following table summarizes the conditions under which the | ||
| 9507 | ** virtual table is allowed to set the "orderByConsumed" flag based on | ||
| 9508 | ** the value returned by sqlite3_vtab_distinct(). This table is a | ||
| 9509 | ** restatement of the previous four paragraphs: | ||
| 9510 | ** | ||
| 9511 | ** <table border=1 cellspacing=0 cellpadding=10 width="90%"> | ||
| 9512 | ** <tr> | ||
| 9513 | ** <td valign="top">sqlite3_vtab_distinct() return value | ||
| 9514 | ** <td valign="top">Rows are returned in aOrderBy order | ||
| 9515 | ** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent | ||
| 9516 | ** <td valign="top">Duplicates over all colUsed columns may be omitted | ||
| 9517 | ** <tr><td>0<td>yes<td>yes<td>no | ||
| 9518 | ** <tr><td>1<td>no<td>yes<td>no | ||
| 9519 | ** <tr><td>2<td>no<td>yes<td>yes | ||
| 9520 | ** <tr><td>3<td>yes<td>yes<td>yes | ||
| 9521 | ** </table> | ||
| 9522 | ** | ||
| 9391 | ** ^For the purposes of comparing virtual table output values to see if the | 9523 | ** ^For the purposes of comparing virtual table output values to see if the |
| 9392 | ** values are same value for sorting purposes, two NULL values are considered | 9524 | ** values are same value for sorting purposes, two NULL values are considered |
| 9393 | ** to be the same. In other words, the comparison operator is "IS" | 9525 | ** to be the same. In other words, the comparison operator is "IS" |
| @@ -9892,6 +10024,14 @@ typedef struct sqlite3_snapshot { | |||
| 9892 | ** If there is not already a read-transaction open on schema S when | 10024 | ** If there is not already a read-transaction open on schema S when |
| 9893 | ** this function is called, one is opened automatically. | 10025 | ** this function is called, one is opened automatically. |
| 9894 | ** | 10026 | ** |
| 10027 | ** If a read-transaction is opened by this function, then it is guaranteed | ||
| 10028 | ** that the returned snapshot object may not be invalidated by a database | ||
| 10029 | ** writer or checkpointer until after the read-transaction is closed. This | ||
| 10030 | ** is not guaranteed if a read-transaction is already open when this | ||
| 10031 | ** function is called. In that case, any subsequent write or checkpoint | ||
| 10032 | ** operation on the database may invalidate the returned snapshot handle, | ||
| 10033 | ** even while the read-transaction remains open. | ||
| 10034 | ** | ||
| 9895 | ** The following must be true for this function to succeed. If any of | 10035 | ** The following must be true for this function to succeed. If any of |
| 9896 | ** the following statements are false when sqlite3_snapshot_get() is | 10036 | ** the following statements are false when sqlite3_snapshot_get() is |
| 9897 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined | 10037 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined |
| @@ -10170,8 +10310,6 @@ typedef struct sqlite3_snapshot { | |||
| 10170 | #if defined(__wasi__) | 10310 | #if defined(__wasi__) |
| 10171 | # undef SQLITE_WASI | 10311 | # undef SQLITE_WASI |
| 10172 | # define SQLITE_WASI 1 | 10312 | # define SQLITE_WASI 1 |
| 10173 | # undef SQLITE_OMIT_WAL | ||
| 10174 | # define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ | ||
| 10175 | # ifndef SQLITE_OMIT_LOAD_EXTENSION | 10313 | # ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 10176 | # define SQLITE_OMIT_LOAD_EXTENSION | 10314 | # define SQLITE_OMIT_LOAD_EXTENSION |
| 10177 | # endif | 10315 | # endif |
| @@ -11246,6 +11384,26 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; | |||
| 11246 | */ | 11384 | */ |
| 11247 | 11385 | ||
| 11248 | /* | 11386 | /* |
| 11387 | ** CAPI3REF: Add A Single Change To A Changegroup | ||
| 11388 | ** METHOD: sqlite3_changegroup | ||
| 11389 | ** | ||
| 11390 | ** This function adds the single change currently indicated by the iterator | ||
| 11391 | ** passed as the second argument to the changegroup object. The rules for | ||
| 11392 | ** adding the change are just as described for [sqlite3changegroup_add()]. | ||
| 11393 | ** | ||
| 11394 | ** If the change is successfully added to the changegroup, SQLITE_OK is | ||
| 11395 | ** returned. Otherwise, an SQLite error code is returned. | ||
| 11396 | ** | ||
| 11397 | ** The iterator must point to a valid entry when this function is called. | ||
| 11398 | ** If it does not, SQLITE_ERROR is returned and no change is added to the | ||
| 11399 | ** changegroup. Additionally, the iterator must not have been opened with | ||
| 11400 | ** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also | ||
| 11401 | ** returned. | ||
| 11402 | */ | ||
| 11403 | |||
| 11404 | |||
| 11405 | |||
| 11406 | /* | ||
| 11249 | ** CAPI3REF: Obtain A Composite Changeset From A Changegroup | 11407 | ** CAPI3REF: Obtain A Composite Changeset From A Changegroup |
| 11250 | ** METHOD: sqlite3_changegroup | 11408 | ** METHOD: sqlite3_changegroup |
| 11251 | ** | 11409 | ** |
| @@ -11917,8 +12075,8 @@ struct Fts5PhraseIter { | |||
| 11917 | ** EXTENSION API FUNCTIONS | 12075 | ** EXTENSION API FUNCTIONS |
| 11918 | ** | 12076 | ** |
| 11919 | ** xUserData(pFts): | 12077 | ** xUserData(pFts): |
| 11920 | ** Return a copy of the context pointer the extension function was | 12078 | ** Return a copy of the pUserData pointer passed to the xCreateFunction() |
| 11921 | ** registered with. | 12079 | ** API when the extension function was registered. |
| 11922 | ** | 12080 | ** |
| 11923 | ** xColumnTotalSize(pFts, iCol, pnToken): | 12081 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 11924 | ** If parameter iCol is less than zero, set output variable *pnToken | 12082 | ** If parameter iCol is less than zero, set output variable *pnToken |
| @@ -11950,8 +12108,11 @@ struct Fts5PhraseIter { | |||
| 11950 | ** created with the "columnsize=0" option. | 12108 | ** created with the "columnsize=0" option. |
| 11951 | ** | 12109 | ** |
| 11952 | ** xColumnText: | 12110 | ** xColumnText: |
| 11953 | ** This function attempts to retrieve the text of column iCol of the | 12111 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 11954 | ** current document. If successful, (*pz) is set to point to a buffer | 12112 | ** number of columns in the table, SQLITE_RANGE is returned. |
| 12113 | ** | ||
| 12114 | ** Otherwise, this function attempts to retrieve the text of column iCol of | ||
| 12115 | ** the current document. If successful, (*pz) is set to point to a buffer | ||
| 11955 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes | 12116 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes |
| 11956 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, | 12117 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, |
| 11957 | ** if an error occurs, an SQLite error code is returned and the final values | 12118 | ** if an error occurs, an SQLite error code is returned and the final values |
| @@ -11961,8 +12122,10 @@ struct Fts5PhraseIter { | |||
| 11961 | ** Returns the number of phrases in the current query expression. | 12122 | ** Returns the number of phrases in the current query expression. |
| 11962 | ** | 12123 | ** |
| 11963 | ** xPhraseSize: | 12124 | ** xPhraseSize: |
| 11964 | ** Returns the number of tokens in phrase iPhrase of the query. Phrases | 12125 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 11965 | ** are numbered starting from zero. | 12126 | ** number of phrases in the current query, as returned by xPhraseCount, |
| 12127 | ** 0 is returned. Otherwise, this function returns the number of tokens in | ||
| 12128 | ** phrase iPhrase of the query. Phrases are numbered starting from zero. | ||
| 11966 | ** | 12129 | ** |
| 11967 | ** xInstCount: | 12130 | ** xInstCount: |
| 11968 | ** Set *pnInst to the total number of occurrences of all phrases within | 12131 | ** Set *pnInst to the total number of occurrences of all phrases within |
| @@ -11978,12 +12141,13 @@ struct Fts5PhraseIter { | |||
| 11978 | ** Query for the details of phrase match iIdx within the current row. | 12141 | ** Query for the details of phrase match iIdx within the current row. |
| 11979 | ** Phrase matches are numbered starting from zero, so the iIdx argument | 12142 | ** Phrase matches are numbered starting from zero, so the iIdx argument |
| 11980 | ** should be greater than or equal to zero and smaller than the value | 12143 | ** should be greater than or equal to zero and smaller than the value |
| 11981 | ** output by xInstCount(). | 12144 | ** output by xInstCount(). If iIdx is less than zero or greater than |
| 12145 | ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. | ||
| 11982 | ** | 12146 | ** |
| 11983 | ** Usually, output parameter *piPhrase is set to the phrase number, *piCol | 12147 | ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol |
| 11984 | ** to the column in which it occurs and *piOff the token offset of the | 12148 | ** to the column in which it occurs and *piOff the token offset of the |
| 11985 | ** first token of the phrase. Returns SQLITE_OK if successful, or an error | 12149 | ** first token of the phrase. SQLITE_OK is returned if successful, or an |
| 11986 | ** code (i.e. SQLITE_NOMEM) if an error occurs. | 12150 | ** error code (i.e. SQLITE_NOMEM) if an error occurs. |
| 11987 | ** | 12151 | ** |
| 11988 | ** This API can be quite slow if used with an FTS5 table created with the | 12152 | ** This API can be quite slow if used with an FTS5 table created with the |
| 11989 | ** "detail=none" or "detail=column" option. | 12153 | ** "detail=none" or "detail=column" option. |
| @@ -12009,6 +12173,10 @@ struct Fts5PhraseIter { | |||
| 12009 | ** Invoking Api.xUserData() returns a copy of the pointer passed as | 12173 | ** Invoking Api.xUserData() returns a copy of the pointer passed as |
| 12010 | ** the third argument to pUserData. | 12174 | ** the third argument to pUserData. |
| 12011 | ** | 12175 | ** |
| 12176 | ** If parameter iPhrase is less than zero, or greater than or equal to | ||
| 12177 | ** the number of phrases in the query, as returned by xPhraseCount(), | ||
| 12178 | ** this function returns SQLITE_RANGE. | ||
| 12179 | ** | ||
| 12012 | ** If the callback function returns any value other than SQLITE_OK, the | 12180 | ** If the callback function returns any value other than SQLITE_OK, the |
| 12013 | ** query is abandoned and the xQueryPhrase function returns immediately. | 12181 | ** query is abandoned and the xQueryPhrase function returns immediately. |
| 12014 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. | 12182 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. |
| @@ -12090,6 +12258,10 @@ struct Fts5PhraseIter { | |||
| 12090 | ** (i.e. if it is a contentless table), then this API always iterates | 12258 | ** (i.e. if it is a contentless table), then this API always iterates |
| 12091 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). | 12259 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). |
| 12092 | ** | 12260 | ** |
| 12261 | ** In all cases, matches are visited in (column ASC, offset ASC) order. | ||
| 12262 | ** i.e. all those in column 0, sorted by offset, followed by those in | ||
| 12263 | ** column 1, etc. | ||
| 12264 | ** | ||
| 12093 | ** xPhraseNext() | 12265 | ** xPhraseNext() |
| 12094 | ** See xPhraseFirst above. | 12266 | ** See xPhraseFirst above. |
| 12095 | ** | 12267 | ** |
| @@ -12123,9 +12295,65 @@ struct Fts5PhraseIter { | |||
| 12123 | ** | 12295 | ** |
| 12124 | ** xPhraseNextColumn() | 12296 | ** xPhraseNextColumn() |
| 12125 | ** See xPhraseFirstColumn above. | 12297 | ** See xPhraseFirstColumn above. |
| 12298 | ** | ||
| 12299 | ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) | ||
| 12300 | ** This is used to access token iToken of phrase iPhrase of the current | ||
| 12301 | ** query. Before returning, output parameter *ppToken is set to point | ||
| 12302 | ** to a buffer containing the requested token, and *pnToken to the | ||
| 12303 | ** size of this buffer in bytes. | ||
| 12304 | ** | ||
| 12305 | ** If iPhrase or iToken are less than zero, or if iPhrase is greater than | ||
| 12306 | ** or equal to the number of phrases in the query as reported by | ||
| 12307 | ** xPhraseCount(), or if iToken is equal to or greater than the number of | ||
| 12308 | ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken | ||
| 12309 | are both zeroed. | ||
| 12310 | ** | ||
| 12311 | ** The output text is not a copy of the query text that specified the | ||
| 12312 | ** token. It is the output of the tokenizer module. For tokendata=1 | ||
| 12313 | ** tables, this includes any embedded 0x00 and trailing data. | ||
| 12314 | ** | ||
| 12315 | ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) | ||
| 12316 | ** This is used to access token iToken of phrase hit iIdx within the | ||
| 12317 | ** current row. If iIdx is less than zero or greater than or equal to the | ||
| 12318 | ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, | ||
| 12319 | ** output variable (*ppToken) is set to point to a buffer containing the | ||
| 12320 | ** matching document token, and (*pnToken) to the size of that buffer in | ||
| 12321 | ** bytes. This API is not available if the specified token matches a | ||
| 12322 | ** prefix query term. In that case both output variables are always set | ||
| 12323 | ** to 0. | ||
| 12324 | ** | ||
| 12325 | ** The output text is not a copy of the document text that was tokenized. | ||
| 12326 | ** It is the output of the tokenizer module. For tokendata=1 tables, this | ||
| 12327 | ** includes any embedded 0x00 and trailing data. | ||
| 12328 | ** | ||
| 12329 | ** This API can be quite slow if used with an FTS5 table created with the | ||
| 12330 | ** "detail=none" or "detail=column" option. | ||
| 12331 | ** | ||
| 12332 | ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) | ||
| 12333 | ** If parameter iCol is less than zero, or greater than or equal to the | ||
| 12334 | ** number of columns in the table, SQLITE_RANGE is returned. | ||
| 12335 | ** | ||
| 12336 | ** Otherwise, this function attempts to retrieve the locale associated | ||
| 12337 | ** with column iCol of the current row. Usually, there is no associated | ||
| 12338 | ** locale, and output parameters (*pzLocale) and (*pnLocale) are set | ||
| 12339 | ** to NULL and 0, respectively. However, if the fts5_locale() function | ||
| 12340 | ** was used to associate a locale with the value when it was inserted | ||
| 12341 | ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated | ||
| 12342 | ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) | ||
| 12343 | ** is set to the size in bytes of the buffer, not including the | ||
| 12344 | ** nul-terminator. | ||
| 12345 | ** | ||
| 12346 | ** If successful, SQLITE_OK is returned. Or, if an error occurs, an | ||
| 12347 | ** SQLite error code is returned. The final value of the output parameters | ||
| 12348 | ** is undefined in this case. | ||
| 12349 | ** | ||
| 12350 | ** xTokenize_v2: | ||
| 12351 | ** Tokenize text using the tokenizer belonging to the FTS5 table. This | ||
| 12352 | ** API is the same as the xTokenize() API, except that it allows a tokenizer | ||
| 12353 | ** locale to be specified. | ||
| 12126 | */ | 12354 | */ |
| 12127 | struct Fts5ExtensionApi { | 12355 | struct Fts5ExtensionApi { |
| 12128 | int iVersion; /* Currently always set to 2 */ | 12356 | int iVersion; /* Currently always set to 4 */ |
| 12129 | 12357 | ||
| 12130 | void *(*xUserData)(Fts5Context*); | 12358 | void *(*xUserData)(Fts5Context*); |
| 12131 | 12359 | ||
| @@ -12160,6 +12388,22 @@ struct Fts5ExtensionApi { | |||
| 12160 | 12388 | ||
| 12161 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); | 12389 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); |
| 12162 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); | 12390 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); |
| 12391 | |||
| 12392 | /* Below this point are iVersion>=3 only */ | ||
| 12393 | int (*xQueryToken)(Fts5Context*, | ||
| 12394 | int iPhrase, int iToken, | ||
| 12395 | const char **ppToken, int *pnToken | ||
| 12396 | ); | ||
| 12397 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | ||
| 12398 | |||
| 12399 | /* Below this point are iVersion>=4 only */ | ||
| 12400 | int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); | ||
| 12401 | int (*xTokenize_v2)(Fts5Context*, | ||
| 12402 | const char *pText, int nText, /* Text to tokenize */ | ||
| 12403 | const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ | ||
| 12404 | void *pCtx, /* Context passed to xToken() */ | ||
| 12405 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ | ||
| 12406 | ); | ||
| 12163 | }; | 12407 | }; |
| 12164 | 12408 | ||
| 12165 | /* | 12409 | /* |
| @@ -12180,7 +12424,7 @@ struct Fts5ExtensionApi { | |||
| 12180 | ** A tokenizer instance is required to actually tokenize text. | 12424 | ** A tokenizer instance is required to actually tokenize text. |
| 12181 | ** | 12425 | ** |
| 12182 | ** The first argument passed to this function is a copy of the (void*) | 12426 | ** The first argument passed to this function is a copy of the (void*) |
| 12183 | ** pointer provided by the application when the fts5_tokenizer object | 12427 | ** pointer provided by the application when the fts5_tokenizer_v2 object |
| 12184 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). | 12428 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). |
| 12185 | ** The second and third arguments are an array of nul-terminated strings | 12429 | ** The second and third arguments are an array of nul-terminated strings |
| 12186 | ** containing the tokenizer arguments, if any, specified following the | 12430 | ** containing the tokenizer arguments, if any, specified following the |
| @@ -12204,7 +12448,7 @@ struct Fts5ExtensionApi { | |||
| 12204 | ** argument passed to this function is a pointer to an Fts5Tokenizer object | 12448 | ** argument passed to this function is a pointer to an Fts5Tokenizer object |
| 12205 | ** returned by an earlier call to xCreate(). | 12449 | ** returned by an earlier call to xCreate(). |
| 12206 | ** | 12450 | ** |
| 12207 | ** The second argument indicates the reason that FTS5 is requesting | 12451 | ** The third argument indicates the reason that FTS5 is requesting |
| 12208 | ** tokenization of the supplied text. This is always one of the following | 12452 | ** tokenization of the supplied text. This is always one of the following |
| 12209 | ** four values: | 12453 | ** four values: |
| 12210 | ** | 12454 | ** |
| @@ -12228,6 +12472,13 @@ struct Fts5ExtensionApi { | |||
| 12228 | ** on a columnsize=0 database. | 12472 | ** on a columnsize=0 database. |
| 12229 | ** </ul> | 12473 | ** </ul> |
| 12230 | ** | 12474 | ** |
| 12475 | ** The sixth and seventh arguments passed to xTokenize() - pLocale and | ||
| 12476 | ** nLocale - are a pointer to a buffer containing the locale to use for | ||
| 12477 | ** tokenization (e.g. "en_US") and its size in bytes, respectively. The | ||
| 12478 | ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in | ||
| 12479 | ** which case nLocale is always 0) to indicate that the tokenizer should | ||
| 12480 | ** use its default locale. | ||
| 12481 | ** | ||
| 12231 | ** For each token in the input string, the supplied callback xToken() must | 12482 | ** For each token in the input string, the supplied callback xToken() must |
| 12232 | ** be invoked. The first argument to it should be a copy of the pointer | 12483 | ** be invoked. The first argument to it should be a copy of the pointer |
| 12233 | ** passed as the second argument to xTokenize(). The third and fourth | 12484 | ** passed as the second argument to xTokenize(). The third and fourth |
| @@ -12251,6 +12502,30 @@ struct Fts5ExtensionApi { | |||
| 12251 | ** may abandon the tokenization and return any error code other than | 12502 | ** may abandon the tokenization and return any error code other than |
| 12252 | ** SQLITE_OK or SQLITE_DONE. | 12503 | ** SQLITE_OK or SQLITE_DONE. |
| 12253 | ** | 12504 | ** |
| 12505 | ** If the tokenizer is registered using an fts5_tokenizer_v2 object, | ||
| 12506 | ** then the xTokenize() method has two additional arguments - pLocale | ||
| 12507 | ** and nLocale. These specify the locale that the tokenizer should use | ||
| 12508 | ** for the current request. If pLocale and nLocale are both 0, then the | ||
| 12509 | ** tokenizer should use its default locale. Otherwise, pLocale points to | ||
| 12510 | ** an nLocale byte buffer containing the name of the locale to use as utf-8 | ||
| 12511 | ** text. pLocale is not nul-terminated. | ||
| 12512 | ** | ||
| 12513 | ** FTS5_TOKENIZER | ||
| 12514 | ** | ||
| 12515 | ** There is also an fts5_tokenizer object. This is an older, deprecated, | ||
| 12516 | ** version of fts5_tokenizer_v2. It is similar except that: | ||
| 12517 | ** | ||
| 12518 | ** <ul> | ||
| 12519 | ** <li> There is no "iVersion" field, and | ||
| 12520 | ** <li> The xTokenize() method does not take a locale argument. | ||
| 12521 | ** </ul> | ||
| 12522 | ** | ||
| 12523 | ** Legacy fts5_tokenizer tokenizers must be registered using the | ||
| 12524 | ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). | ||
| 12525 | ** | ||
| 12526 | ** Tokenizer implementations registered using either API may be retrieved | ||
| 12527 | ** using both xFindTokenizer() and xFindTokenizer_v2(). | ||
| 12528 | ** | ||
| 12254 | ** SYNONYM SUPPORT | 12529 | ** SYNONYM SUPPORT |
| 12255 | ** | 12530 | ** |
| 12256 | ** Custom tokenizers may also support synonyms. Consider a case in which a | 12531 | ** Custom tokenizers may also support synonyms. Consider a case in which a |
| @@ -12359,6 +12634,33 @@ struct Fts5ExtensionApi { | |||
| 12359 | ** inefficient. | 12634 | ** inefficient. |
| 12360 | */ | 12635 | */ |
| 12361 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 12636 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 12637 | typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; | ||
| 12638 | struct fts5_tokenizer_v2 { | ||
| 12639 | int iVersion; /* Currently always 2 */ | ||
| 12640 | |||
| 12641 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | ||
| 12642 | void (*xDelete)(Fts5Tokenizer*); | ||
| 12643 | int (*xTokenize)(Fts5Tokenizer*, | ||
| 12644 | void *pCtx, | ||
| 12645 | int flags, /* Mask of FTS5_TOKENIZE_* flags */ | ||
| 12646 | const char *pText, int nText, | ||
| 12647 | const char *pLocale, int nLocale, | ||
| 12648 | int (*xToken)( | ||
| 12649 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ | ||
| 12650 | int tflags, /* Mask of FTS5_TOKEN_* flags */ | ||
| 12651 | const char *pToken, /* Pointer to buffer containing token */ | ||
| 12652 | int nToken, /* Size of token in bytes */ | ||
| 12653 | int iStart, /* Byte offset of token within input text */ | ||
| 12654 | int iEnd /* Byte offset of end of token within input text */ | ||
| 12655 | ) | ||
| 12656 | ); | ||
| 12657 | }; | ||
| 12658 | |||
| 12659 | /* | ||
| 12660 | ** New code should use the fts5_tokenizer_v2 type to define tokenizer | ||
| 12661 | ** implementations. The following type is included for legacy applications | ||
| 12662 | ** that still use it. | ||
| 12663 | */ | ||
| 12362 | typedef struct fts5_tokenizer fts5_tokenizer; | 12664 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 12363 | struct fts5_tokenizer { | 12665 | struct fts5_tokenizer { |
| 12364 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | 12666 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); |
| @@ -12378,6 +12680,7 @@ struct fts5_tokenizer { | |||
| 12378 | ); | 12680 | ); |
| 12379 | }; | 12681 | }; |
| 12380 | 12682 | ||
| 12683 | |||
| 12381 | /* Flags that may be passed as the third argument to xTokenize() */ | 12684 | /* Flags that may be passed as the third argument to xTokenize() */ |
| 12382 | #define FTS5_TOKENIZE_QUERY 0x0001 | 12685 | #define FTS5_TOKENIZE_QUERY 0x0001 |
| 12383 | #define FTS5_TOKENIZE_PREFIX 0x0002 | 12686 | #define FTS5_TOKENIZE_PREFIX 0x0002 |
| @@ -12397,7 +12700,7 @@ struct fts5_tokenizer { | |||
| 12397 | */ | 12700 | */ |
| 12398 | typedef struct fts5_api fts5_api; | 12701 | typedef struct fts5_api fts5_api; |
| 12399 | struct fts5_api { | 12702 | struct fts5_api { |
| 12400 | int iVersion; /* Currently always set to 2 */ | 12703 | int iVersion; /* Currently always set to 3 */ |
| 12401 | 12704 | ||
| 12402 | /* Create a new tokenizer */ | 12705 | /* Create a new tokenizer */ |
| 12403 | int (*xCreateTokenizer)( | 12706 | int (*xCreateTokenizer)( |
| @@ -12424,6 +12727,25 @@ struct fts5_api { | |||
| 12424 | fts5_extension_function xFunction, | 12727 | fts5_extension_function xFunction, |
| 12425 | void (*xDestroy)(void*) | 12728 | void (*xDestroy)(void*) |
| 12426 | ); | 12729 | ); |
| 12730 | |||
| 12731 | /* APIs below this point are only available if iVersion>=3 */ | ||
| 12732 | |||
| 12733 | /* Create a new tokenizer */ | ||
| 12734 | int (*xCreateTokenizer_v2)( | ||
| 12735 | fts5_api *pApi, | ||
| 12736 | const char *zName, | ||
| 12737 | void *pUserData, | ||
| 12738 | fts5_tokenizer_v2 *pTokenizer, | ||
| 12739 | void (*xDestroy)(void*) | ||
| 12740 | ); | ||
| 12741 | |||
| 12742 | /* Find an existing tokenizer */ | ||
| 12743 | int (*xFindTokenizer_v2)( | ||
| 12744 | fts5_api *pApi, | ||
| 12745 | const char *zName, | ||
| 12746 | void **ppUserData, | ||
| 12747 | fts5_tokenizer_v2 **ppTokenizer | ||
| 12748 | ); | ||
| 12427 | }; | 12749 | }; |
| 12428 | 12750 | ||
| 12429 | /* | 12751 | /* |
diff --git a/c/sqlite3.c b/c/sqlite3.c index 946815f..099c548 100644 --- a/c/sqlite3.c +++ b/c/sqlite3.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.46.1. By combining all the individual C code files into this | 3 | ** version 3.47.1. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements | 6 | ** possible if the files were compiled separately. Performance improvements |
| @@ -18,7 +18,7 @@ | |||
| 18 | ** separate file. This file contains only code for the core SQLite library. | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** | 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** c9c2ab54ba1f5f46360f1b4f35d849cd3f08. | 21 | ** b95d11e958643b969c47a8e5857f3793b9e6. |
| 22 | */ | 22 | */ |
| 23 | #define SQLITE_CORE 1 | 23 | #define SQLITE_CORE 1 |
| 24 | #define SQLITE_AMALGAMATION 1 | 24 | #define SQLITE_AMALGAMATION 1 |
| @@ -256,10 +256,13 @@ | |||
| 256 | /* | 256 | /* |
| 257 | ** Macro to disable warnings about missing "break" at the end of a "case". | 257 | ** Macro to disable warnings about missing "break" at the end of a "case". |
| 258 | */ | 258 | */ |
| 259 | #if GCC_VERSION>=7000000 | 259 | #if defined(__has_attribute) |
| 260 | # define deliberate_fall_through __attribute__((fallthrough)); | 260 | # if __has_attribute(fallthrough) |
| 261 | #else | 261 | # define deliberate_fall_through __attribute__((fallthrough)); |
| 262 | # define deliberate_fall_through | 262 | # endif |
| 263 | #endif | ||
| 264 | #if !defined(deliberate_fall_through) | ||
| 265 | # define deliberate_fall_through | ||
| 263 | #endif | 266 | #endif |
| 264 | 267 | ||
| 265 | /* | 268 | /* |
| @@ -459,9 +462,9 @@ extern "C" { | |||
| 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | 462 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 460 | ** [sqlite_version()] and [sqlite_source_id()]. | 463 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 461 | */ | 464 | */ |
| 462 | #define SQLITE_VERSION "3.46.1" | 465 | #define SQLITE_VERSION "3.47.1" |
| 463 | #define SQLITE_VERSION_NUMBER 3046001 | 466 | #define SQLITE_VERSION_NUMBER 3047001 |
| 464 | #define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" | 467 | #define SQLITE_SOURCE_ID "2024-11-25 12:07:48 b95d11e958643b969c47a8e5857f3793b9e69700b8f1469371386369a26e577e" |
| 465 | 468 | ||
| 466 | /* | 469 | /* |
| 467 | ** CAPI3REF: Run-Time Library Version Numbers | 470 | ** CAPI3REF: Run-Time Library Version Numbers |
| @@ -965,6 +968,13 @@ SQLITE_API int sqlite3_exec( | |||
| 965 | ** filesystem supports doing multiple write operations atomically when those | 968 | ** filesystem supports doing multiple write operations atomically when those |
| 966 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and | 969 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and |
| 967 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. | 970 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. |
| 971 | ** | ||
| 972 | ** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read | ||
| 973 | ** from the database file in amounts that are not a multiple of the | ||
| 974 | ** page size and that do not begin at a page boundary. Without this | ||
| 975 | ** property, SQLite is careful to only do full-page reads and write | ||
| 976 | ** on aligned pages, with the one exception that it will do a sub-page | ||
| 977 | ** read of the first page to access the database header. | ||
| 968 | */ | 978 | */ |
| 969 | #define SQLITE_IOCAP_ATOMIC 0x00000001 | 979 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 970 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 | 980 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| @@ -981,6 +991,7 @@ SQLITE_API int sqlite3_exec( | |||
| 981 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 | 991 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 982 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 | 992 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 |
| 983 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 | 993 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 |
| 994 | #define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 | ||
| 984 | 995 | ||
| 985 | /* | 996 | /* |
| 986 | ** CAPI3REF: File Locking Levels | 997 | ** CAPI3REF: File Locking Levels |
| @@ -1085,8 +1096,8 @@ struct sqlite3_file { | |||
| 1085 | ** to xUnlock() is a no-op. | 1096 | ** to xUnlock() is a no-op. |
| 1086 | ** The xCheckReservedLock() method checks whether any database connection, | 1097 | ** The xCheckReservedLock() method checks whether any database connection, |
| 1087 | ** either in this process or in some other process, is holding a RESERVED, | 1098 | ** either in this process or in some other process, is holding a RESERVED, |
| 1088 | ** PENDING, or EXCLUSIVE lock on the file. It returns true | 1099 | ** PENDING, or EXCLUSIVE lock on the file. It returns, via its output |
| 1089 | ** if such a lock exists and false otherwise. | 1100 | ** pointer parameter, true if such a lock exists and false otherwise. |
| 1090 | ** | 1101 | ** |
| 1091 | ** The xFileControl() method is a generic interface that allows custom | 1102 | ** The xFileControl() method is a generic interface that allows custom |
| 1092 | ** VFS implementations to directly control an open file using the | 1103 | ** VFS implementations to directly control an open file using the |
| @@ -1127,6 +1138,7 @@ struct sqlite3_file { | |||
| 1127 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] | 1138 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] |
| 1128 | ** <li> [SQLITE_IOCAP_IMMUTABLE] | 1139 | ** <li> [SQLITE_IOCAP_IMMUTABLE] |
| 1129 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] | 1140 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] |
| 1141 | ** <li> [SQLITE_IOCAP_SUBPAGE_READ] | ||
| 1130 | ** </ul> | 1142 | ** </ul> |
| 1131 | ** | 1143 | ** |
| 1132 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of | 1144 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of |
| @@ -3883,8 +3895,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | |||
| 3883 | ** | 3895 | ** |
| 3884 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> | 3896 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> |
| 3885 | ** <dd>The database connection comes up in "extended result code mode". | 3897 | ** <dd>The database connection comes up in "extended result code mode". |
| 3886 | ** In other words, the database behaves has if | 3898 | ** In other words, the database behaves as if |
| 3887 | ** [sqlite3_extended_result_codes(db,1)] where called on the database | 3899 | ** [sqlite3_extended_result_codes(db,1)] were called on the database |
| 3888 | ** connection as soon as the connection is created. In addition to setting | 3900 | ** connection as soon as the connection is created. In addition to setting |
| 3889 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] | 3901 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] |
| 3890 | ** to return an extended result code.</dd> | 3902 | ** to return an extended result code.</dd> |
| @@ -4535,13 +4547,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); | |||
| 4535 | ** and sqlite3_prepare16_v3() use UTF-16. | 4547 | ** and sqlite3_prepare16_v3() use UTF-16. |
| 4536 | ** | 4548 | ** |
| 4537 | ** ^If the nByte argument is negative, then zSql is read up to the | 4549 | ** ^If the nByte argument is negative, then zSql is read up to the |
| 4538 | ** first zero terminator. ^If nByte is positive, then it is the | 4550 | ** first zero terminator. ^If nByte is positive, then it is the maximum |
| 4539 | ** number of bytes read from zSql. ^If nByte is zero, then no prepared | 4551 | ** number of bytes read from zSql. When nByte is positive, zSql is read |
| 4552 | ** up to the first zero terminator or until the nByte bytes have been read, | ||
| 4553 | ** whichever comes first. ^If nByte is zero, then no prepared | ||
| 4540 | ** statement is generated. | 4554 | ** statement is generated. |
| 4541 | ** If the caller knows that the supplied string is nul-terminated, then | 4555 | ** If the caller knows that the supplied string is nul-terminated, then |
| 4542 | ** there is a small performance advantage to passing an nByte parameter that | 4556 | ** there is a small performance advantage to passing an nByte parameter that |
| 4543 | ** is the number of bytes in the input string <i>including</i> | 4557 | ** is the number of bytes in the input string <i>including</i> |
| 4544 | ** the nul-terminator. | 4558 | ** the nul-terminator. |
| 4559 | ** Note that nByte measure the length of the input in bytes, not | ||
| 4560 | ** characters, even for the UTF-16 interfaces. | ||
| 4545 | ** | 4561 | ** |
| 4546 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte | 4562 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte |
| 4547 | ** past the end of the first SQL statement in zSql. These routines only | 4563 | ** past the end of the first SQL statement in zSql. These routines only |
| @@ -5912,7 +5928,7 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5912 | ** This flag instructs SQLite to omit some corner-case optimizations that | 5928 | ** This flag instructs SQLite to omit some corner-case optimizations that |
| 5913 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, | 5929 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, |
| 5914 | ** causing it to return zero rather than the correct subtype(). | 5930 | ** causing it to return zero rather than the correct subtype(). |
| 5915 | ** SQL functions that invokes [sqlite3_value_subtype()] should have this | 5931 | ** All SQL functions that invoke [sqlite3_value_subtype()] should have this |
| 5916 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return | 5932 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return |
| 5917 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though | 5933 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though |
| 5918 | ** a non-zero subtype was specified by the function argument expression. | 5934 | ** a non-zero subtype was specified by the function argument expression. |
| @@ -5928,6 +5944,15 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5928 | ** [sqlite3_result_subtype()] should avoid setting this property, as the | 5944 | ** [sqlite3_result_subtype()] should avoid setting this property, as the |
| 5929 | ** purpose of this property is to disable certain optimizations that are | 5945 | ** purpose of this property is to disable certain optimizations that are |
| 5930 | ** incompatible with subtypes. | 5946 | ** incompatible with subtypes. |
| 5947 | ** | ||
| 5948 | ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> | ||
| 5949 | ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate | ||
| 5950 | ** that internally orders the values provided to the first argument. The | ||
| 5951 | ** ordered-set aggregate SQL notation with a single ORDER BY term can be | ||
| 5952 | ** used to invoke this function. If the ordered-set aggregate notation is | ||
| 5953 | ** used on a function that lacks this flag, then an error is raised. Note | ||
| 5954 | ** that the ordered-set aggregate syntax is only available if SQLite is | ||
| 5955 | ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. | ||
| 5931 | ** </dd> | 5956 | ** </dd> |
| 5932 | ** </dl> | 5957 | ** </dl> |
| 5933 | */ | 5958 | */ |
| @@ -5936,6 +5961,7 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5936 | #define SQLITE_SUBTYPE 0x000100000 | 5961 | #define SQLITE_SUBTYPE 0x000100000 |
| 5937 | #define SQLITE_INNOCUOUS 0x000200000 | 5962 | #define SQLITE_INNOCUOUS 0x000200000 |
| 5938 | #define SQLITE_RESULT_SUBTYPE 0x001000000 | 5963 | #define SQLITE_RESULT_SUBTYPE 0x001000000 |
| 5964 | #define SQLITE_SELFORDER1 0x002000000 | ||
| 5939 | 5965 | ||
| 5940 | /* | 5966 | /* |
| 5941 | ** CAPI3REF: Deprecated Functions | 5967 | ** CAPI3REF: Deprecated Functions |
| @@ -6133,7 +6159,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); | |||
| 6133 | ** one SQL function to another. Use the [sqlite3_result_subtype()] | 6159 | ** one SQL function to another. Use the [sqlite3_result_subtype()] |
| 6134 | ** routine to set the subtype for the return value of an SQL function. | 6160 | ** routine to set the subtype for the return value of an SQL function. |
| 6135 | ** | 6161 | ** |
| 6136 | ** Every [application-defined SQL function] that invoke this interface | 6162 | ** Every [application-defined SQL function] that invokes this interface |
| 6137 | ** should include the [SQLITE_SUBTYPE] property in the text | 6163 | ** should include the [SQLITE_SUBTYPE] property in the text |
| 6138 | ** encoding argument when the function is [sqlite3_create_function|registered]. | 6164 | ** encoding argument when the function is [sqlite3_create_function|registered]. |
| 6139 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() | 6165 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() |
| @@ -7740,9 +7766,11 @@ struct sqlite3_module { | |||
| 7740 | ** will be returned by the strategy. | 7766 | ** will be returned by the strategy. |
| 7741 | ** | 7767 | ** |
| 7742 | ** The xBestIndex method may optionally populate the idxFlags field with a | 7768 | ** The xBestIndex method may optionally populate the idxFlags field with a |
| 7743 | ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - | 7769 | ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is |
| 7744 | ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite | 7770 | ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] |
| 7745 | ** assumes that the strategy may visit at most one row. | 7771 | ** output to show the idxNum has hex instead of as decimal. Another flag is |
| 7772 | ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will | ||
| 7773 | ** return at most one row. | ||
| 7746 | ** | 7774 | ** |
| 7747 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then | 7775 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then |
| 7748 | ** SQLite also assumes that if a call to the xUpdate() method is made as | 7776 | ** SQLite also assumes that if a call to the xUpdate() method is made as |
| @@ -7806,7 +7834,9 @@ struct sqlite3_index_info { | |||
| 7806 | ** [sqlite3_index_info].idxFlags field to some combination of | 7834 | ** [sqlite3_index_info].idxFlags field to some combination of |
| 7807 | ** these bits. | 7835 | ** these bits. |
| 7808 | */ | 7836 | */ |
| 7809 | #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ | 7837 | #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ |
| 7838 | #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ | ||
| 7839 | /* in EXPLAIN QUERY PLAN */ | ||
| 7810 | 7840 | ||
| 7811 | /* | 7841 | /* |
| 7812 | ** CAPI3REF: Virtual Table Constraint Operator Codes | 7842 | ** CAPI3REF: Virtual Table Constraint Operator Codes |
| @@ -8643,6 +8673,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8643 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 | 8673 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 |
| 8644 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 | 8674 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 8645 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ | 8675 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ |
| 8676 | #define SQLITE_TESTCTRL_GETOPT 16 | ||
| 8646 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ | 8677 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ |
| 8647 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 | 8678 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 |
| 8648 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 | 8679 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| @@ -8662,7 +8693,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8662 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 | 8693 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 |
| 8663 | #define SQLITE_TESTCTRL_TUNE 32 | 8694 | #define SQLITE_TESTCTRL_TUNE 32 |
| 8664 | #define SQLITE_TESTCTRL_LOGEST 33 | 8695 | #define SQLITE_TESTCTRL_LOGEST 33 |
| 8665 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 | 8696 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ |
| 8666 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ | 8697 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ |
| 8667 | 8698 | ||
| 8668 | /* | 8699 | /* |
| @@ -9638,6 +9669,16 @@ typedef struct sqlite3_backup sqlite3_backup; | |||
| 9638 | ** APIs are not strictly speaking threadsafe. If they are invoked at the | 9669 | ** APIs are not strictly speaking threadsafe. If they are invoked at the |
| 9639 | ** same time as another thread is invoking sqlite3_backup_step() it is | 9670 | ** same time as another thread is invoking sqlite3_backup_step() it is |
| 9640 | ** possible that they return invalid values. | 9671 | ** possible that they return invalid values. |
| 9672 | ** | ||
| 9673 | ** <b>Alternatives To Using The Backup API</b> | ||
| 9674 | ** | ||
| 9675 | ** Other techniques for safely creating a consistent backup of an SQLite | ||
| 9676 | ** database include: | ||
| 9677 | ** | ||
| 9678 | ** <ul> | ||
| 9679 | ** <li> The [VACUUM INTO] command. | ||
| 9680 | ** <li> The [sqlite3_rsync] utility program. | ||
| 9681 | ** </ul> | ||
| 9641 | */ | 9682 | */ |
| 9642 | SQLITE_API sqlite3_backup *sqlite3_backup_init( | 9683 | SQLITE_API sqlite3_backup *sqlite3_backup_init( |
| 9643 | sqlite3 *pDest, /* Destination database handle */ | 9684 | sqlite3 *pDest, /* Destination database handle */ |
| @@ -10837,6 +10878,14 @@ typedef struct sqlite3_snapshot { | |||
| 10837 | ** If there is not already a read-transaction open on schema S when | 10878 | ** If there is not already a read-transaction open on schema S when |
| 10838 | ** this function is called, one is opened automatically. | 10879 | ** this function is called, one is opened automatically. |
| 10839 | ** | 10880 | ** |
| 10881 | ** If a read-transaction is opened by this function, then it is guaranteed | ||
| 10882 | ** that the returned snapshot object may not be invalidated by a database | ||
| 10883 | ** writer or checkpointer until after the read-transaction is closed. This | ||
| 10884 | ** is not guaranteed if a read-transaction is already open when this | ||
| 10885 | ** function is called. In that case, any subsequent write or checkpoint | ||
| 10886 | ** operation on the database may invalidate the returned snapshot handle, | ||
| 10887 | ** even while the read-transaction remains open. | ||
| 10888 | ** | ||
| 10840 | ** The following must be true for this function to succeed. If any of | 10889 | ** The following must be true for this function to succeed. If any of |
| 10841 | ** the following statements are false when sqlite3_snapshot_get() is | 10890 | ** the following statements are false when sqlite3_snapshot_get() is |
| 10842 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined | 10891 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined |
| @@ -11145,8 +11194,6 @@ SQLITE_API int sqlite3_deserialize( | |||
| 11145 | #if defined(__wasi__) | 11194 | #if defined(__wasi__) |
| 11146 | # undef SQLITE_WASI | 11195 | # undef SQLITE_WASI |
| 11147 | # define SQLITE_WASI 1 | 11196 | # define SQLITE_WASI 1 |
| 11148 | # undef SQLITE_OMIT_WAL | ||
| 11149 | # define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ | ||
| 11150 | # ifndef SQLITE_OMIT_LOAD_EXTENSION | 11197 | # ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 11151 | # define SQLITE_OMIT_LOAD_EXTENSION | 11198 | # define SQLITE_OMIT_LOAD_EXTENSION |
| 11152 | # endif | 11199 | # endif |
| @@ -13349,6 +13396,10 @@ struct Fts5PhraseIter { | |||
| 13349 | ** (i.e. if it is a contentless table), then this API always iterates | 13396 | ** (i.e. if it is a contentless table), then this API always iterates |
| 13350 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). | 13397 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). |
| 13351 | ** | 13398 | ** |
| 13399 | ** In all cases, matches are visited in (column ASC, offset ASC) order. | ||
| 13400 | ** i.e. all those in column 0, sorted by offset, followed by those in | ||
| 13401 | ** column 1, etc. | ||
| 13402 | ** | ||
| 13352 | ** xPhraseNext() | 13403 | ** xPhraseNext() |
| 13353 | ** See xPhraseFirst above. | 13404 | ** See xPhraseFirst above. |
| 13354 | ** | 13405 | ** |
| @@ -13415,9 +13466,32 @@ struct Fts5PhraseIter { | |||
| 13415 | ** | 13466 | ** |
| 13416 | ** This API can be quite slow if used with an FTS5 table created with the | 13467 | ** This API can be quite slow if used with an FTS5 table created with the |
| 13417 | ** "detail=none" or "detail=column" option. | 13468 | ** "detail=none" or "detail=column" option. |
| 13469 | ** | ||
| 13470 | ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) | ||
| 13471 | ** If parameter iCol is less than zero, or greater than or equal to the | ||
| 13472 | ** number of columns in the table, SQLITE_RANGE is returned. | ||
| 13473 | ** | ||
| 13474 | ** Otherwise, this function attempts to retrieve the locale associated | ||
| 13475 | ** with column iCol of the current row. Usually, there is no associated | ||
| 13476 | ** locale, and output parameters (*pzLocale) and (*pnLocale) are set | ||
| 13477 | ** to NULL and 0, respectively. However, if the fts5_locale() function | ||
| 13478 | ** was used to associate a locale with the value when it was inserted | ||
| 13479 | ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated | ||
| 13480 | ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) | ||
| 13481 | ** is set to the size in bytes of the buffer, not including the | ||
| 13482 | ** nul-terminator. | ||
| 13483 | ** | ||
| 13484 | ** If successful, SQLITE_OK is returned. Or, if an error occurs, an | ||
| 13485 | ** SQLite error code is returned. The final value of the output parameters | ||
| 13486 | ** is undefined in this case. | ||
| 13487 | ** | ||
| 13488 | ** xTokenize_v2: | ||
| 13489 | ** Tokenize text using the tokenizer belonging to the FTS5 table. This | ||
| 13490 | ** API is the same as the xTokenize() API, except that it allows a tokenizer | ||
| 13491 | ** locale to be specified. | ||
| 13418 | */ | 13492 | */ |
| 13419 | struct Fts5ExtensionApi { | 13493 | struct Fts5ExtensionApi { |
| 13420 | int iVersion; /* Currently always set to 3 */ | 13494 | int iVersion; /* Currently always set to 4 */ |
| 13421 | 13495 | ||
| 13422 | void *(*xUserData)(Fts5Context*); | 13496 | void *(*xUserData)(Fts5Context*); |
| 13423 | 13497 | ||
| @@ -13459,6 +13533,15 @@ struct Fts5ExtensionApi { | |||
| 13459 | const char **ppToken, int *pnToken | 13533 | const char **ppToken, int *pnToken |
| 13460 | ); | 13534 | ); |
| 13461 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | 13535 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); |
| 13536 | |||
| 13537 | /* Below this point are iVersion>=4 only */ | ||
| 13538 | int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); | ||
| 13539 | int (*xTokenize_v2)(Fts5Context*, | ||
| 13540 | const char *pText, int nText, /* Text to tokenize */ | ||
| 13541 | const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ | ||
| 13542 | void *pCtx, /* Context passed to xToken() */ | ||
| 13543 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ | ||
| 13544 | ); | ||
| 13462 | }; | 13545 | }; |
| 13463 | 13546 | ||
| 13464 | /* | 13547 | /* |
| @@ -13479,7 +13562,7 @@ struct Fts5ExtensionApi { | |||
| 13479 | ** A tokenizer instance is required to actually tokenize text. | 13562 | ** A tokenizer instance is required to actually tokenize text. |
| 13480 | ** | 13563 | ** |
| 13481 | ** The first argument passed to this function is a copy of the (void*) | 13564 | ** The first argument passed to this function is a copy of the (void*) |
| 13482 | ** pointer provided by the application when the fts5_tokenizer object | 13565 | ** pointer provided by the application when the fts5_tokenizer_v2 object |
| 13483 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). | 13566 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). |
| 13484 | ** The second and third arguments are an array of nul-terminated strings | 13567 | ** The second and third arguments are an array of nul-terminated strings |
| 13485 | ** containing the tokenizer arguments, if any, specified following the | 13568 | ** containing the tokenizer arguments, if any, specified following the |
| @@ -13503,7 +13586,7 @@ struct Fts5ExtensionApi { | |||
| 13503 | ** argument passed to this function is a pointer to an Fts5Tokenizer object | 13586 | ** argument passed to this function is a pointer to an Fts5Tokenizer object |
| 13504 | ** returned by an earlier call to xCreate(). | 13587 | ** returned by an earlier call to xCreate(). |
| 13505 | ** | 13588 | ** |
| 13506 | ** The second argument indicates the reason that FTS5 is requesting | 13589 | ** The third argument indicates the reason that FTS5 is requesting |
| 13507 | ** tokenization of the supplied text. This is always one of the following | 13590 | ** tokenization of the supplied text. This is always one of the following |
| 13508 | ** four values: | 13591 | ** four values: |
| 13509 | ** | 13592 | ** |
| @@ -13527,6 +13610,13 @@ struct Fts5ExtensionApi { | |||
| 13527 | ** on a columnsize=0 database. | 13610 | ** on a columnsize=0 database. |
| 13528 | ** </ul> | 13611 | ** </ul> |
| 13529 | ** | 13612 | ** |
| 13613 | ** The sixth and seventh arguments passed to xTokenize() - pLocale and | ||
| 13614 | ** nLocale - are a pointer to a buffer containing the locale to use for | ||
| 13615 | ** tokenization (e.g. "en_US") and its size in bytes, respectively. The | ||
| 13616 | ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in | ||
| 13617 | ** which case nLocale is always 0) to indicate that the tokenizer should | ||
| 13618 | ** use its default locale. | ||
| 13619 | ** | ||
| 13530 | ** For each token in the input string, the supplied callback xToken() must | 13620 | ** For each token in the input string, the supplied callback xToken() must |
| 13531 | ** be invoked. The first argument to it should be a copy of the pointer | 13621 | ** be invoked. The first argument to it should be a copy of the pointer |
| 13532 | ** passed as the second argument to xTokenize(). The third and fourth | 13622 | ** passed as the second argument to xTokenize(). The third and fourth |
| @@ -13550,6 +13640,30 @@ struct Fts5ExtensionApi { | |||
| 13550 | ** may abandon the tokenization and return any error code other than | 13640 | ** may abandon the tokenization and return any error code other than |
| 13551 | ** SQLITE_OK or SQLITE_DONE. | 13641 | ** SQLITE_OK or SQLITE_DONE. |
| 13552 | ** | 13642 | ** |
| 13643 | ** If the tokenizer is registered using an fts5_tokenizer_v2 object, | ||
| 13644 | ** then the xTokenize() method has two additional arguments - pLocale | ||
| 13645 | ** and nLocale. These specify the locale that the tokenizer should use | ||
| 13646 | ** for the current request. If pLocale and nLocale are both 0, then the | ||
| 13647 | ** tokenizer should use its default locale. Otherwise, pLocale points to | ||
| 13648 | ** an nLocale byte buffer containing the name of the locale to use as utf-8 | ||
| 13649 | ** text. pLocale is not nul-terminated. | ||
| 13650 | ** | ||
| 13651 | ** FTS5_TOKENIZER | ||
| 13652 | ** | ||
| 13653 | ** There is also an fts5_tokenizer object. This is an older, deprecated, | ||
| 13654 | ** version of fts5_tokenizer_v2. It is similar except that: | ||
| 13655 | ** | ||
| 13656 | ** <ul> | ||
| 13657 | ** <li> There is no "iVersion" field, and | ||
| 13658 | ** <li> The xTokenize() method does not take a locale argument. | ||
| 13659 | ** </ul> | ||
| 13660 | ** | ||
| 13661 | ** Legacy fts5_tokenizer tokenizers must be registered using the | ||
| 13662 | ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). | ||
| 13663 | ** | ||
| 13664 | ** Tokenizer implementations registered using either API may be retrieved | ||
| 13665 | ** using both xFindTokenizer() and xFindTokenizer_v2(). | ||
| 13666 | ** | ||
| 13553 | ** SYNONYM SUPPORT | 13667 | ** SYNONYM SUPPORT |
| 13554 | ** | 13668 | ** |
| 13555 | ** Custom tokenizers may also support synonyms. Consider a case in which a | 13669 | ** Custom tokenizers may also support synonyms. Consider a case in which a |
| @@ -13658,6 +13772,33 @@ struct Fts5ExtensionApi { | |||
| 13658 | ** inefficient. | 13772 | ** inefficient. |
| 13659 | */ | 13773 | */ |
| 13660 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 13774 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 13775 | typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; | ||
| 13776 | struct fts5_tokenizer_v2 { | ||
| 13777 | int iVersion; /* Currently always 2 */ | ||
| 13778 | |||
| 13779 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | ||
| 13780 | void (*xDelete)(Fts5Tokenizer*); | ||
| 13781 | int (*xTokenize)(Fts5Tokenizer*, | ||
| 13782 | void *pCtx, | ||
| 13783 | int flags, /* Mask of FTS5_TOKENIZE_* flags */ | ||
| 13784 | const char *pText, int nText, | ||
| 13785 | const char *pLocale, int nLocale, | ||
| 13786 | int (*xToken)( | ||
| 13787 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ | ||
| 13788 | int tflags, /* Mask of FTS5_TOKEN_* flags */ | ||
| 13789 | const char *pToken, /* Pointer to buffer containing token */ | ||
| 13790 | int nToken, /* Size of token in bytes */ | ||
| 13791 | int iStart, /* Byte offset of token within input text */ | ||
| 13792 | int iEnd /* Byte offset of end of token within input text */ | ||
| 13793 | ) | ||
| 13794 | ); | ||
| 13795 | }; | ||
| 13796 | |||
| 13797 | /* | ||
| 13798 | ** New code should use the fts5_tokenizer_v2 type to define tokenizer | ||
| 13799 | ** implementations. The following type is included for legacy applications | ||
| 13800 | ** that still use it. | ||
| 13801 | */ | ||
| 13661 | typedef struct fts5_tokenizer fts5_tokenizer; | 13802 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 13662 | struct fts5_tokenizer { | 13803 | struct fts5_tokenizer { |
| 13663 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | 13804 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); |
| @@ -13677,6 +13818,7 @@ struct fts5_tokenizer { | |||
| 13677 | ); | 13818 | ); |
| 13678 | }; | 13819 | }; |
| 13679 | 13820 | ||
| 13821 | |||
| 13680 | /* Flags that may be passed as the third argument to xTokenize() */ | 13822 | /* Flags that may be passed as the third argument to xTokenize() */ |
| 13681 | #define FTS5_TOKENIZE_QUERY 0x0001 | 13823 | #define FTS5_TOKENIZE_QUERY 0x0001 |
| 13682 | #define FTS5_TOKENIZE_PREFIX 0x0002 | 13824 | #define FTS5_TOKENIZE_PREFIX 0x0002 |
| @@ -13696,7 +13838,7 @@ struct fts5_tokenizer { | |||
| 13696 | */ | 13838 | */ |
| 13697 | typedef struct fts5_api fts5_api; | 13839 | typedef struct fts5_api fts5_api; |
| 13698 | struct fts5_api { | 13840 | struct fts5_api { |
| 13699 | int iVersion; /* Currently always set to 2 */ | 13841 | int iVersion; /* Currently always set to 3 */ |
| 13700 | 13842 | ||
| 13701 | /* Create a new tokenizer */ | 13843 | /* Create a new tokenizer */ |
| 13702 | int (*xCreateTokenizer)( | 13844 | int (*xCreateTokenizer)( |
| @@ -13723,6 +13865,25 @@ struct fts5_api { | |||
| 13723 | fts5_extension_function xFunction, | 13865 | fts5_extension_function xFunction, |
| 13724 | void (*xDestroy)(void*) | 13866 | void (*xDestroy)(void*) |
| 13725 | ); | 13867 | ); |
| 13868 | |||
| 13869 | /* APIs below this point are only available if iVersion>=3 */ | ||
| 13870 | |||
| 13871 | /* Create a new tokenizer */ | ||
| 13872 | int (*xCreateTokenizer_v2)( | ||
| 13873 | fts5_api *pApi, | ||
| 13874 | const char *zName, | ||
| 13875 | void *pUserData, | ||
| 13876 | fts5_tokenizer_v2 *pTokenizer, | ||
| 13877 | void (*xDestroy)(void*) | ||
| 13878 | ); | ||
| 13879 | |||
| 13880 | /* Find an existing tokenizer */ | ||
| 13881 | int (*xFindTokenizer_v2)( | ||
| 13882 | fts5_api *pApi, | ||
| 13883 | const char *zName, | ||
| 13884 | void **ppUserData, | ||
| 13885 | fts5_tokenizer_v2 **ppTokenizer | ||
| 13886 | ); | ||
| 13726 | }; | 13887 | }; |
| 13727 | 13888 | ||
| 13728 | /* | 13889 | /* |
| @@ -14532,132 +14693,132 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14532 | #define TK_OR 43 | 14693 | #define TK_OR 43 |
| 14533 | #define TK_AND 44 | 14694 | #define TK_AND 44 |
| 14534 | #define TK_IS 45 | 14695 | #define TK_IS 45 |
| 14535 | #define TK_MATCH 46 | 14696 | #define TK_ISNOT 46 |
| 14536 | #define TK_LIKE_KW 47 | 14697 | #define TK_MATCH 47 |
| 14537 | #define TK_BETWEEN 48 | 14698 | #define TK_LIKE_KW 48 |
| 14538 | #define TK_IN 49 | 14699 | #define TK_BETWEEN 49 |
| 14539 | #define TK_ISNULL 50 | 14700 | #define TK_IN 50 |
| 14540 | #define TK_NOTNULL 51 | 14701 | #define TK_ISNULL 51 |
| 14541 | #define TK_NE 52 | 14702 | #define TK_NOTNULL 52 |
| 14542 | #define TK_EQ 53 | 14703 | #define TK_NE 53 |
| 14543 | #define TK_GT 54 | 14704 | #define TK_EQ 54 |
| 14544 | #define TK_LE 55 | 14705 | #define TK_GT 55 |
| 14545 | #define TK_LT 56 | 14706 | #define TK_LE 56 |
| 14546 | #define TK_GE 57 | 14707 | #define TK_LT 57 |
| 14547 | #define TK_ESCAPE 58 | 14708 | #define TK_GE 58 |
| 14548 | #define TK_ID 59 | 14709 | #define TK_ESCAPE 59 |
| 14549 | #define TK_COLUMNKW 60 | 14710 | #define TK_ID 60 |
| 14550 | #define TK_DO 61 | 14711 | #define TK_COLUMNKW 61 |
| 14551 | #define TK_FOR 62 | 14712 | #define TK_DO 62 |
| 14552 | #define TK_IGNORE 63 | 14713 | #define TK_FOR 63 |
| 14553 | #define TK_INITIALLY 64 | 14714 | #define TK_IGNORE 64 |
| 14554 | #define TK_INSTEAD 65 | 14715 | #define TK_INITIALLY 65 |
| 14555 | #define TK_NO 66 | 14716 | #define TK_INSTEAD 66 |
| 14556 | #define TK_KEY 67 | 14717 | #define TK_NO 67 |
| 14557 | #define TK_OF 68 | 14718 | #define TK_KEY 68 |
| 14558 | #define TK_OFFSET 69 | 14719 | #define TK_OF 69 |
| 14559 | #define TK_PRAGMA 70 | 14720 | #define TK_OFFSET 70 |
| 14560 | #define TK_RAISE 71 | 14721 | #define TK_PRAGMA 71 |
| 14561 | #define TK_RECURSIVE 72 | 14722 | #define TK_RAISE 72 |
| 14562 | #define TK_REPLACE 73 | 14723 | #define TK_RECURSIVE 73 |
| 14563 | #define TK_RESTRICT 74 | 14724 | #define TK_REPLACE 74 |
| 14564 | #define TK_ROW 75 | 14725 | #define TK_RESTRICT 75 |
| 14565 | #define TK_ROWS 76 | 14726 | #define TK_ROW 76 |
| 14566 | #define TK_TRIGGER 77 | 14727 | #define TK_ROWS 77 |
| 14567 | #define TK_VACUUM 78 | 14728 | #define TK_TRIGGER 78 |
| 14568 | #define TK_VIEW 79 | 14729 | #define TK_VACUUM 79 |
| 14569 | #define TK_VIRTUAL 80 | 14730 | #define TK_VIEW 80 |
| 14570 | #define TK_WITH 81 | 14731 | #define TK_VIRTUAL 81 |
| 14571 | #define TK_NULLS 82 | 14732 | #define TK_WITH 82 |
| 14572 | #define TK_FIRST 83 | 14733 | #define TK_NULLS 83 |
| 14573 | #define TK_LAST 84 | 14734 | #define TK_FIRST 84 |
| 14574 | #define TK_CURRENT 85 | 14735 | #define TK_LAST 85 |
| 14575 | #define TK_FOLLOWING 86 | 14736 | #define TK_CURRENT 86 |
| 14576 | #define TK_PARTITION 87 | 14737 | #define TK_FOLLOWING 87 |
| 14577 | #define TK_PRECEDING 88 | 14738 | #define TK_PARTITION 88 |
| 14578 | #define TK_RANGE 89 | 14739 | #define TK_PRECEDING 89 |
| 14579 | #define TK_UNBOUNDED 90 | 14740 | #define TK_RANGE 90 |
| 14580 | #define TK_EXCLUDE 91 | 14741 | #define TK_UNBOUNDED 91 |
| 14581 | #define TK_GROUPS 92 | 14742 | #define TK_EXCLUDE 92 |
| 14582 | #define TK_OTHERS 93 | 14743 | #define TK_GROUPS 93 |
| 14583 | #define TK_TIES 94 | 14744 | #define TK_OTHERS 94 |
| 14584 | #define TK_GENERATED 95 | 14745 | #define TK_TIES 95 |
| 14585 | #define TK_ALWAYS 96 | 14746 | #define TK_GENERATED 96 |
| 14586 | #define TK_MATERIALIZED 97 | 14747 | #define TK_ALWAYS 97 |
| 14587 | #define TK_REINDEX 98 | 14748 | #define TK_MATERIALIZED 98 |
| 14588 | #define TK_RENAME 99 | 14749 | #define TK_REINDEX 99 |
| 14589 | #define TK_CTIME_KW 100 | 14750 | #define TK_RENAME 100 |
| 14590 | #define TK_ANY 101 | 14751 | #define TK_CTIME_KW 101 |
| 14591 | #define TK_BITAND 102 | 14752 | #define TK_ANY 102 |
| 14592 | #define TK_BITOR 103 | 14753 | #define TK_BITAND 103 |
| 14593 | #define TK_LSHIFT 104 | 14754 | #define TK_BITOR 104 |
| 14594 | #define TK_RSHIFT 105 | 14755 | #define TK_LSHIFT 105 |
| 14595 | #define TK_PLUS 106 | 14756 | #define TK_RSHIFT 106 |
| 14596 | #define TK_MINUS 107 | 14757 | #define TK_PLUS 107 |
| 14597 | #define TK_STAR 108 | 14758 | #define TK_MINUS 108 |
| 14598 | #define TK_SLASH 109 | 14759 | #define TK_STAR 109 |
| 14599 | #define TK_REM 110 | 14760 | #define TK_SLASH 110 |
| 14600 | #define TK_CONCAT 111 | 14761 | #define TK_REM 111 |
| 14601 | #define TK_PTR 112 | 14762 | #define TK_CONCAT 112 |
| 14602 | #define TK_COLLATE 113 | 14763 | #define TK_PTR 113 |
| 14603 | #define TK_BITNOT 114 | 14764 | #define TK_COLLATE 114 |
| 14604 | #define TK_ON 115 | 14765 | #define TK_BITNOT 115 |
| 14605 | #define TK_INDEXED 116 | 14766 | #define TK_ON 116 |
| 14606 | #define TK_STRING 117 | 14767 | #define TK_INDEXED 117 |
| 14607 | #define TK_JOIN_KW 118 | 14768 | #define TK_STRING 118 |
| 14608 | #define TK_CONSTRAINT 119 | 14769 | #define TK_JOIN_KW 119 |
| 14609 | #define TK_DEFAULT 120 | 14770 | #define TK_CONSTRAINT 120 |
| 14610 | #define TK_NULL 121 | 14771 | #define TK_DEFAULT 121 |
| 14611 | #define TK_PRIMARY 122 | 14772 | #define TK_NULL 122 |
| 14612 | #define TK_UNIQUE 123 | 14773 | #define TK_PRIMARY 123 |
| 14613 | #define TK_CHECK 124 | 14774 | #define TK_UNIQUE 124 |
| 14614 | #define TK_REFERENCES 125 | 14775 | #define TK_CHECK 125 |
| 14615 | #define TK_AUTOINCR 126 | 14776 | #define TK_REFERENCES 126 |
| 14616 | #define TK_INSERT 127 | 14777 | #define TK_AUTOINCR 127 |
| 14617 | #define TK_DELETE 128 | 14778 | #define TK_INSERT 128 |
| 14618 | #define TK_UPDATE 129 | 14779 | #define TK_DELETE 129 |
| 14619 | #define TK_SET 130 | 14780 | #define TK_UPDATE 130 |
| 14620 | #define TK_DEFERRABLE 131 | 14781 | #define TK_SET 131 |
| 14621 | #define TK_FOREIGN 132 | 14782 | #define TK_DEFERRABLE 132 |
| 14622 | #define TK_DROP 133 | 14783 | #define TK_FOREIGN 133 |
| 14623 | #define TK_UNION 134 | 14784 | #define TK_DROP 134 |
| 14624 | #define TK_ALL 135 | 14785 | #define TK_UNION 135 |
| 14625 | #define TK_EXCEPT 136 | 14786 | #define TK_ALL 136 |
| 14626 | #define TK_INTERSECT 137 | 14787 | #define TK_EXCEPT 137 |
| 14627 | #define TK_SELECT 138 | 14788 | #define TK_INTERSECT 138 |
| 14628 | #define TK_VALUES 139 | 14789 | #define TK_SELECT 139 |
| 14629 | #define TK_DISTINCT 140 | 14790 | #define TK_VALUES 140 |
| 14630 | #define TK_DOT 141 | 14791 | #define TK_DISTINCT 141 |
| 14631 | #define TK_FROM 142 | 14792 | #define TK_DOT 142 |
| 14632 | #define TK_JOIN 143 | 14793 | #define TK_FROM 143 |
| 14633 | #define TK_USING 144 | 14794 | #define TK_JOIN 144 |
| 14634 | #define TK_ORDER 145 | 14795 | #define TK_USING 145 |
| 14635 | #define TK_GROUP 146 | 14796 | #define TK_ORDER 146 |
| 14636 | #define TK_HAVING 147 | 14797 | #define TK_GROUP 147 |
| 14637 | #define TK_LIMIT 148 | 14798 | #define TK_HAVING 148 |
| 14638 | #define TK_WHERE 149 | 14799 | #define TK_LIMIT 149 |
| 14639 | #define TK_RETURNING 150 | 14800 | #define TK_WHERE 150 |
| 14640 | #define TK_INTO 151 | 14801 | #define TK_RETURNING 151 |
| 14641 | #define TK_NOTHING 152 | 14802 | #define TK_INTO 152 |
| 14642 | #define TK_FLOAT 153 | 14803 | #define TK_NOTHING 153 |
| 14643 | #define TK_BLOB 154 | 14804 | #define TK_FLOAT 154 |
| 14644 | #define TK_INTEGER 155 | 14805 | #define TK_BLOB 155 |
| 14645 | #define TK_VARIABLE 156 | 14806 | #define TK_INTEGER 156 |
| 14646 | #define TK_CASE 157 | 14807 | #define TK_VARIABLE 157 |
| 14647 | #define TK_WHEN 158 | 14808 | #define TK_CASE 158 |
| 14648 | #define TK_THEN 159 | 14809 | #define TK_WHEN 159 |
| 14649 | #define TK_ELSE 160 | 14810 | #define TK_THEN 160 |
| 14650 | #define TK_INDEX 161 | 14811 | #define TK_ELSE 161 |
| 14651 | #define TK_ALTER 162 | 14812 | #define TK_INDEX 162 |
| 14652 | #define TK_ADD 163 | 14813 | #define TK_ALTER 163 |
| 14653 | #define TK_WINDOW 164 | 14814 | #define TK_ADD 164 |
| 14654 | #define TK_OVER 165 | 14815 | #define TK_WINDOW 165 |
| 14655 | #define TK_FILTER 166 | 14816 | #define TK_OVER 166 |
| 14656 | #define TK_COLUMN 167 | 14817 | #define TK_FILTER 167 |
| 14657 | #define TK_AGG_FUNCTION 168 | 14818 | #define TK_COLUMN 168 |
| 14658 | #define TK_AGG_COLUMN 169 | 14819 | #define TK_AGG_FUNCTION 169 |
| 14659 | #define TK_TRUEFALSE 170 | 14820 | #define TK_AGG_COLUMN 170 |
| 14660 | #define TK_ISNOT 171 | 14821 | #define TK_TRUEFALSE 171 |
| 14661 | #define TK_FUNCTION 172 | 14822 | #define TK_FUNCTION 172 |
| 14662 | #define TK_UPLUS 173 | 14823 | #define TK_UPLUS 173 |
| 14663 | #define TK_UMINUS 174 | 14824 | #define TK_UMINUS 174 |
| @@ -14680,6 +14841,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14680 | #include <string.h> | 14841 | #include <string.h> |
| 14681 | #include <assert.h> | 14842 | #include <assert.h> |
| 14682 | #include <stddef.h> | 14843 | #include <stddef.h> |
| 14844 | #include <ctype.h> | ||
| 14683 | 14845 | ||
| 14684 | /* | 14846 | /* |
| 14685 | ** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. | 14847 | ** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. |
| @@ -14700,7 +14862,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14700 | #ifdef SQLITE_OMIT_FLOATING_POINT | 14862 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 14701 | # define double sqlite_int64 | 14863 | # define double sqlite_int64 |
| 14702 | # define float sqlite_int64 | 14864 | # define float sqlite_int64 |
| 14703 | # define LONGDOUBLE_TYPE sqlite_int64 | 14865 | # define fabs(X) ((X)<0?-(X):(X)) |
| 14866 | # define sqlite3IsOverflow(X) 0 | ||
| 14704 | # ifndef SQLITE_BIG_DBL | 14867 | # ifndef SQLITE_BIG_DBL |
| 14705 | # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) | 14868 | # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) |
| 14706 | # endif | 14869 | # endif |
| @@ -14875,9 +15038,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14875 | # define INT8_TYPE signed char | 15038 | # define INT8_TYPE signed char |
| 14876 | # endif | 15039 | # endif |
| 14877 | #endif | 15040 | #endif |
| 14878 | #ifndef LONGDOUBLE_TYPE | ||
| 14879 | # define LONGDOUBLE_TYPE long double | ||
| 14880 | #endif | ||
| 14881 | typedef sqlite_int64 i64; /* 8-byte signed integer */ | 15041 | typedef sqlite_int64 i64; /* 8-byte signed integer */ |
| 14882 | typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ | 15042 | typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ |
| 14883 | typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ | 15043 | typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ |
| @@ -15377,6 +15537,7 @@ typedef struct Savepoint Savepoint; | |||
| 15377 | typedef struct Select Select; | 15537 | typedef struct Select Select; |
| 15378 | typedef struct SQLiteThread SQLiteThread; | 15538 | typedef struct SQLiteThread SQLiteThread; |
| 15379 | typedef struct SelectDest SelectDest; | 15539 | typedef struct SelectDest SelectDest; |
| 15540 | typedef struct Subquery Subquery; | ||
| 15380 | typedef struct SrcItem SrcItem; | 15541 | typedef struct SrcItem SrcItem; |
| 15381 | typedef struct SrcList SrcList; | 15542 | typedef struct SrcList SrcList; |
| 15382 | typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ | 15543 | typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ |
| @@ -16259,6 +16420,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( | |||
| 16259 | ); | 16420 | ); |
| 16260 | SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); | 16421 | SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); |
| 16261 | SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); | 16422 | SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); |
| 16423 | #ifdef SQLITE_DEBUG | ||
| 16424 | SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*); | ||
| 16425 | #endif | ||
| 16262 | SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); | 16426 | SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); |
| 16263 | SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); | 16427 | SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); |
| 16264 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 16428 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| @@ -16477,6 +16641,19 @@ typedef struct Vdbe Vdbe; | |||
| 16477 | */ | 16641 | */ |
| 16478 | typedef struct sqlite3_value Mem; | 16642 | typedef struct sqlite3_value Mem; |
| 16479 | typedef struct SubProgram SubProgram; | 16643 | typedef struct SubProgram SubProgram; |
| 16644 | typedef struct SubrtnSig SubrtnSig; | ||
| 16645 | |||
| 16646 | /* | ||
| 16647 | ** A signature for a reusable subroutine that materializes the RHS of | ||
| 16648 | ** an IN operator. | ||
| 16649 | */ | ||
| 16650 | struct SubrtnSig { | ||
| 16651 | int selId; /* SELECT-id for the SELECT statement on the RHS */ | ||
| 16652 | char *zAff; /* Affinity of the overall IN expression */ | ||
| 16653 | int iTable; /* Ephemeral table generated by the subroutine */ | ||
| 16654 | int iAddr; /* Subroutine entry address */ | ||
| 16655 | int regReturn; /* Register used to hold return address */ | ||
| 16656 | }; | ||
| 16480 | 16657 | ||
| 16481 | /* | 16658 | /* |
| 16482 | ** A single instruction of the virtual machine has an opcode | 16659 | ** A single instruction of the virtual machine has an opcode |
| @@ -16505,6 +16682,7 @@ struct VdbeOp { | |||
| 16505 | u32 *ai; /* Used when p4type is P4_INTARRAY */ | 16682 | u32 *ai; /* Used when p4type is P4_INTARRAY */ |
| 16506 | SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ | 16683 | SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ |
| 16507 | Table *pTab; /* Used when p4type is P4_TABLE */ | 16684 | Table *pTab; /* Used when p4type is P4_TABLE */ |
| 16685 | SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ | ||
| 16508 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 16686 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 16509 | Expr *pExpr; /* Used when p4type is P4_EXPR */ | 16687 | Expr *pExpr; /* Used when p4type is P4_EXPR */ |
| 16510 | #endif | 16688 | #endif |
| @@ -16572,6 +16750,7 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16572 | #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ | 16750 | #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ |
| 16573 | #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ | 16751 | #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ |
| 16574 | #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ | 16752 | #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ |
| 16753 | #define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ | ||
| 16575 | 16754 | ||
| 16576 | /* Error message codes for OP_Halt */ | 16755 | /* Error message codes for OP_Halt */ |
| 16577 | #define P5_ConstraintNotNull 1 | 16756 | #define P5_ConstraintNotNull 1 |
| @@ -16663,16 +16842,16 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16663 | #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ | 16842 | #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 16664 | #define OP_Program 48 /* jump0 */ | 16843 | #define OP_Program 48 /* jump0 */ |
| 16665 | #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ | 16844 | #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 16666 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ | 16845 | #define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 16667 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ | 16846 | #define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 16668 | #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ | 16847 | #define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 16669 | #define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ | 16848 | #define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ |
| 16670 | #define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ | 16849 | #define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ |
| 16671 | #define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ | 16850 | #define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ |
| 16672 | #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ | 16851 | #define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ |
| 16673 | #define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ | 16852 | #define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ |
| 16674 | #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ | 16853 | #define OP_Ge 58 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ |
| 16675 | #define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ | 16854 | #define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ |
| 16676 | #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ | 16855 | #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 16677 | #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ | 16856 | #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 16678 | #define OP_IncrVacuum 62 /* jump */ | 16857 | #define OP_IncrVacuum 62 /* jump */ |
| @@ -16715,23 +16894,23 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16715 | #define OP_ReadCookie 99 | 16894 | #define OP_ReadCookie 99 |
| 16716 | #define OP_SetCookie 100 | 16895 | #define OP_SetCookie 100 |
| 16717 | #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ | 16896 | #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ |
| 16718 | #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ | 16897 | #define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ |
| 16719 | #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ | 16898 | #define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 16720 | #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ | 16899 | #define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 16721 | #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ | 16900 | #define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 16722 | #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ | 16901 | #define OP_ShiftRight 106 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 16723 | #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ | 16902 | #define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| 16724 | #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ | 16903 | #define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 16725 | #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ | 16904 | #define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 16726 | #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ | 16905 | #define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 16727 | #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ | 16906 | #define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 16728 | #define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ | 16907 | #define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 16729 | #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ | 16908 | #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ |
| 16730 | #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ | 16909 | #define OP_OpenDup 114 |
| 16731 | #define OP_OpenDup 115 | 16910 | #define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ |
| 16732 | #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ | 16911 | #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ |
| 16733 | #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ | 16912 | #define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ |
| 16734 | #define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ | 16913 | #define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 16735 | #define OP_SorterOpen 119 | 16914 | #define OP_SorterOpen 119 |
| 16736 | #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ | 16915 | #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ |
| 16737 | #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ | 16916 | #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ |
| @@ -16766,8 +16945,8 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16766 | #define OP_LoadAnalysis 150 | 16945 | #define OP_LoadAnalysis 150 |
| 16767 | #define OP_DropTable 151 | 16946 | #define OP_DropTable 151 |
| 16768 | #define OP_DropIndex 152 | 16947 | #define OP_DropIndex 152 |
| 16769 | #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ | 16948 | #define OP_DropTrigger 153 |
| 16770 | #define OP_DropTrigger 154 | 16949 | #define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 16771 | #define OP_IntegrityCk 155 | 16950 | #define OP_IntegrityCk 155 |
| 16772 | #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ | 16951 | #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ |
| 16773 | #define OP_Param 157 | 16952 | #define OP_Param 157 |
| @@ -16823,20 +17002,20 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16823 | /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ | 17002 | /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ |
| 16824 | /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ | 17003 | /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ |
| 16825 | /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ | 17004 | /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ |
| 16826 | /* 48 */ 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ | 17005 | /* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ |
| 16827 | /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ | 17006 | /* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ |
| 16828 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ | 17007 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ |
| 16829 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ | 17008 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ |
| 16830 | /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ | 17009 | /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ |
| 16831 | /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ | 17010 | /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ |
| 16832 | /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ | 17011 | /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ |
| 16833 | /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ | 17012 | /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ |
| 16834 | /* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ | 17013 | /* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ |
| 16835 | /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ | 17014 | /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ |
| 16836 | /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ | 17015 | /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ |
| 16837 | /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ | 17016 | /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ |
| 16838 | /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ | 17017 | /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 16839 | /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ | 17018 | /* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ |
| 16840 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ | 17019 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 16841 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ | 17020 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ |
| 16842 | /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ | 17021 | /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ |
| @@ -17897,6 +18076,7 @@ struct sqlite3 { | |||
| 17897 | #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ | 18076 | #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ |
| 17898 | #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ | 18077 | #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ |
| 17899 | #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ | 18078 | #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ |
| 18079 | #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ | ||
| 17900 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ | 18080 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17901 | 18081 | ||
| 17902 | /* | 18082 | /* |
| @@ -18884,9 +19064,15 @@ struct AggInfo { | |||
| 18884 | ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. | 19064 | ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. |
| 18885 | ** The assert()s that are part of this macro verify that constraint. | 19065 | ** The assert()s that are part of this macro verify that constraint. |
| 18886 | */ | 19066 | */ |
| 19067 | #ifndef NDEBUG | ||
| 18887 | #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) | 19068 | #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) |
| 18888 | #define AggInfoFuncReg(A,I) \ | 19069 | #define AggInfoFuncReg(A,I) \ |
| 18889 | (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) | 19070 | (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) |
| 19071 | #else | ||
| 19072 | #define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) | ||
| 19073 | #define AggInfoFuncReg(A,I) \ | ||
| 19074 | ((A)->iFirstReg+(A)->nColumn+(I)) | ||
| 19075 | #endif | ||
| 18890 | 19076 | ||
| 18891 | /* | 19077 | /* |
| 18892 | ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. | 19078 | ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. |
| @@ -19067,7 +19253,7 @@ struct Expr { | |||
| 19067 | #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ | 19253 | #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ |
| 19068 | #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ | 19254 | #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ |
| 19069 | #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ | 19255 | #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ |
| 19070 | /* 0x80000000 // Available */ | 19256 | #define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */ |
| 19071 | 19257 | ||
| 19072 | /* The EP_Propagate mask is a set of properties that automatically propagate | 19258 | /* The EP_Propagate mask is a set of properties that automatically propagate |
| 19073 | ** upwards into parent nodes. | 19259 | ** upwards into parent nodes. |
| @@ -19239,6 +19425,16 @@ struct IdList { | |||
| 19239 | #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ | 19425 | #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ |
| 19240 | 19426 | ||
| 19241 | /* | 19427 | /* |
| 19428 | ** Details of the implementation of a subquery. | ||
| 19429 | */ | ||
| 19430 | struct Subquery { | ||
| 19431 | Select *pSelect; /* A SELECT statement used in place of a table name */ | ||
| 19432 | int addrFillSub; /* Address of subroutine to initialize a subquery */ | ||
| 19433 | int regReturn; /* Register holding return address of addrFillSub */ | ||
| 19434 | int regResult; /* Registers holding results of a co-routine */ | ||
| 19435 | }; | ||
| 19436 | |||
| 19437 | /* | ||
| 19242 | ** The SrcItem object represents a single term in the FROM clause of a query. | 19438 | ** The SrcItem object represents a single term in the FROM clause of a query. |
| 19243 | ** The SrcList object is mostly an array of SrcItems. | 19439 | ** The SrcList object is mostly an array of SrcItems. |
| 19244 | ** | 19440 | ** |
| @@ -19250,29 +19446,40 @@ struct IdList { | |||
| 19250 | ** In the colUsed field, the high-order bit (bit 63) is set if the table | 19446 | ** In the colUsed field, the high-order bit (bit 63) is set if the table |
| 19251 | ** contains more than 63 columns and the 64-th or later column is used. | 19447 | ** contains more than 63 columns and the 64-th or later column is used. |
| 19252 | ** | 19448 | ** |
| 19253 | ** Union member validity: | 19449 | ** Aggressive use of "union" helps keep the size of the object small. This |
| 19450 | ** has been shown to boost performance, in addition to saving memory. | ||
| 19451 | ** Access to union elements is gated by the following rules which should | ||
| 19452 | ** always be checked, either by an if-statement or by an assert(). | ||
| 19254 | ** | 19453 | ** |
| 19255 | ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc | 19454 | ** Field Only access if this is true |
| 19256 | ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy | 19455 | ** --------------- ----------------------------------- |
| 19456 | ** u1.zIndexedBy fg.isIndexedBy | ||
| 19457 | ** u1.pFuncArg fg.isTabFunc | ||
| 19257 | ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy | 19458 | ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy |
| 19258 | ** | 19459 | ** |
| 19259 | ** u2.pIBIndex fg.isIndexedBy && !fg.isCte | 19460 | ** u2.pIBIndex fg.isIndexedBy |
| 19260 | ** u2.pCteUse fg.isCte && !fg.isIndexedBy | 19461 | ** u2.pCteUse fg.isCte |
| 19462 | ** | ||
| 19463 | ** u3.pOn !fg.isUsing | ||
| 19464 | ** u3.pUsing fg.isUsing | ||
| 19465 | ** | ||
| 19466 | ** u4.zDatabase !fg.fixedSchema && !fg.isSubquery | ||
| 19467 | ** u4.pSchema fg.fixedSchema | ||
| 19468 | ** u4.pSubq fg.isSubquery | ||
| 19469 | ** | ||
| 19470 | ** See also the sqlite3SrcListDelete() routine for assert() statements that | ||
| 19471 | ** check invariants on the fields of this object, especially the flags | ||
| 19472 | ** inside the fg struct. | ||
| 19261 | */ | 19473 | */ |
| 19262 | struct SrcItem { | 19474 | struct SrcItem { |
| 19263 | Schema *pSchema; /* Schema to which this item is fixed */ | ||
| 19264 | char *zDatabase; /* Name of database holding this table */ | ||
| 19265 | char *zName; /* Name of the table */ | 19475 | char *zName; /* Name of the table */ |
| 19266 | char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ | 19476 | char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ |
| 19267 | Table *pTab; /* An SQL table corresponding to zName */ | 19477 | Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ |
| 19268 | Select *pSelect; /* A SELECT statement used in place of a table name */ | ||
| 19269 | int addrFillSub; /* Address of subroutine to manifest a subquery */ | ||
| 19270 | int regReturn; /* Register holding return address of addrFillSub */ | ||
| 19271 | int regResult; /* Registers holding results of a co-routine */ | ||
| 19272 | struct { | 19478 | struct { |
| 19273 | u8 jointype; /* Type of join between this table and the previous */ | 19479 | u8 jointype; /* Type of join between this table and the previous */ |
| 19274 | unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ | 19480 | unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ |
| 19275 | unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ | 19481 | unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ |
| 19482 | unsigned isSubquery :1; /* True if this term is a subquery */ | ||
| 19276 | unsigned isTabFunc :1; /* True if table-valued-function syntax */ | 19483 | unsigned isTabFunc :1; /* True if table-valued-function syntax */ |
| 19277 | unsigned isCorrelated :1; /* True if sub-query is correlated */ | 19484 | unsigned isCorrelated :1; /* True if sub-query is correlated */ |
| 19278 | unsigned isMaterialized:1; /* This is a materialized view */ | 19485 | unsigned isMaterialized:1; /* This is a materialized view */ |
| @@ -19286,12 +19493,10 @@ struct SrcItem { | |||
| 19286 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ | 19493 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ |
| 19287 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ | 19494 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ |
| 19288 | unsigned rowidUsed :1; /* The ROWID of this table is referenced */ | 19495 | unsigned rowidUsed :1; /* The ROWID of this table is referenced */ |
| 19496 | unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ | ||
| 19497 | unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ | ||
| 19289 | } fg; | 19498 | } fg; |
| 19290 | int iCursor; /* The VDBE cursor number used to access this table */ | 19499 | int iCursor; /* The VDBE cursor number used to access this table */ |
| 19291 | union { | ||
| 19292 | Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ | ||
| 19293 | IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ | ||
| 19294 | } u3; | ||
| 19295 | Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ | 19500 | Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ |
| 19296 | union { | 19501 | union { |
| 19297 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ | 19502 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ |
| @@ -19302,6 +19507,15 @@ struct SrcItem { | |||
| 19302 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ | 19507 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ |
| 19303 | CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ | 19508 | CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ |
| 19304 | } u2; | 19509 | } u2; |
| 19510 | union { | ||
| 19511 | Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ | ||
| 19512 | IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ | ||
| 19513 | } u3; | ||
| 19514 | union { | ||
| 19515 | Schema *pSchema; /* Schema to which this item is fixed */ | ||
| 19516 | char *zDatabase; /* Name of database holding this table */ | ||
| 19517 | Subquery *pSubq; /* Description of a subquery */ | ||
| 19518 | } u4; | ||
| 19305 | }; | 19519 | }; |
| 19306 | 19520 | ||
| 19307 | /* | 19521 | /* |
| @@ -19433,7 +19647,7 @@ struct NameContext { | |||
| 19433 | #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ | 19647 | #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ |
| 19434 | #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ | 19648 | #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ |
| 19435 | #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ | 19649 | #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ |
| 19436 | #define NC_Complex 0x002000 /* True if a function or subquery seen */ | 19650 | /* 0x002000 // available for reuse */ |
| 19437 | #define NC_AllowWin 0x004000 /* Window functions are allowed here */ | 19651 | #define NC_AllowWin 0x004000 /* Window functions are allowed here */ |
| 19438 | #define NC_HasWin 0x008000 /* One or more window functions seen */ | 19652 | #define NC_HasWin 0x008000 /* One or more window functions seen */ |
| 19439 | #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ | 19653 | #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ |
| @@ -19561,8 +19775,10 @@ struct Select { | |||
| 19561 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ | 19775 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ |
| 19562 | #define SF_Correlated 0x20000000 /* True if references the outer context */ | 19776 | #define SF_Correlated 0x20000000 /* True if references the outer context */ |
| 19563 | 19777 | ||
| 19564 | /* True if S exists and has SF_NestedFrom */ | 19778 | /* True if SrcItem X is a subquery that has SF_NestedFrom */ |
| 19565 | #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) | 19779 | #define IsNestedFrom(X) \ |
| 19780 | ((X)->fg.isSubquery && \ | ||
| 19781 | ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) | ||
| 19566 | 19782 | ||
| 19567 | /* | 19783 | /* |
| 19568 | ** The results of a SELECT can be distributed in several ways, as defined | 19784 | ** The results of a SELECT can be distributed in several ways, as defined |
| @@ -19592,7 +19808,11 @@ struct Select { | |||
| 19592 | ** SRT_Set The result must be a single column. Store each | 19808 | ** SRT_Set The result must be a single column. Store each |
| 19593 | ** row of result as the key in table pDest->iSDParm. | 19809 | ** row of result as the key in table pDest->iSDParm. |
| 19594 | ** Apply the affinity pDest->affSdst before storing | 19810 | ** Apply the affinity pDest->affSdst before storing |
| 19595 | ** results. Used to implement "IN (SELECT ...)". | 19811 | ** results. if pDest->iSDParm2 is positive, then it is |
| 19812 | ** a register holding a Bloom filter for the IN operator | ||
| 19813 | ** that should be populated in addition to the | ||
| 19814 | ** pDest->iSDParm table. This SRT is used to | ||
| 19815 | ** implement "IN (SELECT ...)". | ||
| 19596 | ** | 19816 | ** |
| 19597 | ** SRT_EphemTab Create an temporary table pDest->iSDParm and store | 19817 | ** SRT_EphemTab Create an temporary table pDest->iSDParm and store |
| 19598 | ** the result there. The cursor is left open after | 19818 | ** the result there. The cursor is left open after |
| @@ -19800,6 +20020,7 @@ struct Parse { | |||
| 19800 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ | 20020 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ |
| 19801 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ | 20021 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ |
| 19802 | u8 bHasWith; /* True if statement contains WITH */ | 20022 | u8 bHasWith; /* True if statement contains WITH */ |
| 20023 | u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ | ||
| 19803 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) | 20024 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 19804 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ | 20025 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ |
| 19805 | #endif | 20026 | #endif |
| @@ -20095,7 +20316,7 @@ struct Returning { | |||
| 20095 | }; | 20316 | }; |
| 20096 | 20317 | ||
| 20097 | /* | 20318 | /* |
| 20098 | ** An objected used to accumulate the text of a string where we | 20319 | ** An object used to accumulate the text of a string where we |
| 20099 | ** do not necessarily know how big the string will be in the end. | 20320 | ** do not necessarily know how big the string will be in the end. |
| 20100 | */ | 20321 | */ |
| 20101 | struct sqlite3_str { | 20322 | struct sqlite3_str { |
| @@ -20109,7 +20330,7 @@ struct sqlite3_str { | |||
| 20109 | }; | 20330 | }; |
| 20110 | #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ | 20331 | #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ |
| 20111 | #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ | 20332 | #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ |
| 20112 | #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ | 20333 | #define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */ |
| 20113 | 20334 | ||
| 20114 | #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) | 20335 | #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) |
| 20115 | 20336 | ||
| @@ -20187,7 +20408,6 @@ struct Sqlite3Config { | |||
| 20187 | u8 bUseCis; /* Use covering indices for full-scans */ | 20408 | u8 bUseCis; /* Use covering indices for full-scans */ |
| 20188 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ | 20409 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ |
| 20189 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ | 20410 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ |
| 20190 | u8 bUseLongDouble; /* Make use of long double */ | ||
| 20191 | #ifdef SQLITE_DEBUG | 20411 | #ifdef SQLITE_DEBUG |
| 20192 | u8 bJsonSelfcheck; /* Double-check JSON parsing */ | 20412 | u8 bJsonSelfcheck; /* Double-check JSON parsing */ |
| 20193 | #endif | 20413 | #endif |
| @@ -20563,15 +20783,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); | |||
| 20563 | #endif | 20783 | #endif |
| 20564 | 20784 | ||
| 20565 | /* | 20785 | /* |
| 20566 | ** The ctype.h header is needed for non-ASCII systems. It is also | ||
| 20567 | ** needed by FTS3 when FTS3 is included in the amalgamation. | ||
| 20568 | */ | ||
| 20569 | #if !defined(SQLITE_ASCII) || \ | ||
| 20570 | (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) | ||
| 20571 | # include <ctype.h> | ||
| 20572 | #endif | ||
| 20573 | |||
| 20574 | /* | ||
| 20575 | ** The following macros mimic the standard library functions toupper(), | 20786 | ** The following macros mimic the standard library functions toupper(), |
| 20576 | ** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The | 20787 | ** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The |
| 20577 | ** sqlite versions only work for ASCII characters, regardless of locale. | 20788 | ** sqlite versions only work for ASCII characters, regardless of locale. |
| @@ -20949,6 +21160,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); | |||
| 20949 | SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); | 21160 | SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); |
| 20950 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); | 21161 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); |
| 20951 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); | 21162 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); |
| 21163 | SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); | ||
| 21164 | SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); | ||
| 21165 | SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); | ||
| 20952 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, | 21166 | SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, |
| 20953 | Token*, Select*, OnOrUsing*); | 21167 | Token*, Select*, OnOrUsing*); |
| 20954 | SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); | 21168 | SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); |
| @@ -20998,6 +21212,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int | |||
| 20998 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); | 21212 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 20999 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); | 21213 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| 21000 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); | 21214 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); |
| 21215 | SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); | ||
| 21001 | SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); | 21216 | SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); |
| 21002 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS | 21217 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS |
| 21003 | SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); | 21218 | SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); |
| @@ -21060,7 +21275,7 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,i | |||
| 21060 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 21275 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 21061 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); | 21276 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 21062 | #endif | 21277 | #endif |
| 21063 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); | 21278 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); |
| 21064 | SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); | 21279 | SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); |
| 21065 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); | 21280 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 21066 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); | 21281 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| @@ -21188,7 +21403,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); | |||
| 21188 | SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); | 21403 | SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); |
| 21189 | SQLITE_PRIVATE int sqlite3Atoi(const char*); | 21404 | SQLITE_PRIVATE int sqlite3Atoi(const char*); |
| 21190 | #ifndef SQLITE_OMIT_UTF16 | 21405 | #ifndef SQLITE_OMIT_UTF16 |
| 21191 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); | 21406 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); |
| 21192 | #endif | 21407 | #endif |
| 21193 | SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); | 21408 | SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); |
| 21194 | SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); | 21409 | SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); |
| @@ -22174,6 +22389,9 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 22174 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC | 22389 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC |
| 22175 | "ENABLE_OFFSET_SQL_FUNC", | 22390 | "ENABLE_OFFSET_SQL_FUNC", |
| 22176 | #endif | 22391 | #endif |
| 22392 | #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES | ||
| 22393 | "ENABLE_ORDERED_SET_AGGREGATES", | ||
| 22394 | #endif | ||
| 22177 | #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK | 22395 | #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK |
| 22178 | "ENABLE_OVERSIZE_CELL_CHECK", | 22396 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 22179 | #endif | 22397 | #endif |
| @@ -22921,7 +23139,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { | |||
| 22921 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ | 23139 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ |
| 22922 | 0, /* bSmallMalloc */ | 23140 | 0, /* bSmallMalloc */ |
| 22923 | 1, /* bExtraSchemaChecks */ | 23141 | 1, /* bExtraSchemaChecks */ |
| 22924 | sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ | ||
| 22925 | #ifdef SQLITE_DEBUG | 23142 | #ifdef SQLITE_DEBUG |
| 22926 | 0, /* bJsonSelfcheck */ | 23143 | 0, /* bJsonSelfcheck */ |
| 22927 | #endif | 23144 | #endif |
| @@ -23644,6 +23861,7 @@ struct PreUpdate { | |||
| 23644 | Mem *aNew; /* Array of new.* values */ | 23861 | Mem *aNew; /* Array of new.* values */ |
| 23645 | Table *pTab; /* Schema object being updated */ | 23862 | Table *pTab; /* Schema object being updated */ |
| 23646 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ | 23863 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 23864 | sqlite3_value **apDflt; /* Array of default values, if required */ | ||
| 23647 | }; | 23865 | }; |
| 23648 | 23866 | ||
| 23649 | /* | 23867 | /* |
| @@ -24490,8 +24708,8 @@ static void computeJD(DateTime *p){ | |||
| 24490 | Y--; | 24708 | Y--; |
| 24491 | M += 12; | 24709 | M += 12; |
| 24492 | } | 24710 | } |
| 24493 | A = Y/100; | 24711 | A = (Y+4800)/100; |
| 24494 | B = 2 - A + (A/4); | 24712 | B = 38 - A + (A/4); |
| 24495 | X1 = 36525*(Y+4716)/100; | 24713 | X1 = 36525*(Y+4716)/100; |
| 24496 | X2 = 306001*(M+1)/10000; | 24714 | X2 = 306001*(M+1)/10000; |
| 24497 | p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); | 24715 | p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); |
| @@ -24675,7 +24893,7 @@ static int validJulianDay(sqlite3_int64 iJD){ | |||
| 24675 | ** Compute the Year, Month, and Day from the julian day number. | 24893 | ** Compute the Year, Month, and Day from the julian day number. |
| 24676 | */ | 24894 | */ |
| 24677 | static void computeYMD(DateTime *p){ | 24895 | static void computeYMD(DateTime *p){ |
| 24678 | int Z, A, B, C, D, E, X1; | 24896 | int Z, alpha, A, B, C, D, E, X1; |
| 24679 | if( p->validYMD ) return; | 24897 | if( p->validYMD ) return; |
| 24680 | if( !p->validJD ){ | 24898 | if( !p->validJD ){ |
| 24681 | p->Y = 2000; | 24899 | p->Y = 2000; |
| @@ -24686,8 +24904,8 @@ static void computeYMD(DateTime *p){ | |||
| 24686 | return; | 24904 | return; |
| 24687 | }else{ | 24905 | }else{ |
| 24688 | Z = (int)((p->iJD + 43200000)/86400000); | 24906 | Z = (int)((p->iJD + 43200000)/86400000); |
| 24689 | A = (int)((Z - 1867216.25)/36524.25); | 24907 | alpha = (int)((Z + 32044.75)/36524.25) - 52; |
| 24690 | A = Z + 1 + A - (A/4); | 24908 | A = Z + 1 + alpha - ((alpha+100)/4) + 25; |
| 24691 | B = A + 1524; | 24909 | B = A + 1524; |
| 24692 | C = (int)((B - 122.1)/365.25); | 24910 | C = (int)((B - 122.1)/365.25); |
| 24693 | D = (36525*(C&32767))/100; | 24911 | D = (36525*(C&32767))/100; |
| @@ -24886,8 +25104,8 @@ static const struct { | |||
| 24886 | /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, | 25104 | /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, |
| 24887 | /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, | 25105 | /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, |
| 24888 | /* 3 */ { 3, "day", 5373485.0, 86400.0 }, | 25106 | /* 3 */ { 3, "day", 5373485.0, 86400.0 }, |
| 24889 | /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 }, | 25107 | /* 4 */ { 5, "month", 176546.0, 2592000.0 }, |
| 24890 | /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 }, | 25108 | /* 5 */ { 4, "year", 14713.0, 31536000.0 }, |
| 24891 | }; | 25109 | }; |
| 24892 | 25110 | ||
| 24893 | /* | 25111 | /* |
| @@ -29089,16 +29307,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ | |||
| 29089 | /* | 29307 | /* |
| 29090 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are | 29308 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 29091 | ** intended for use inside assert() statements. | 29309 | ** intended for use inside assert() statements. |
| 29310 | ** | ||
| 29311 | ** Because these routines raise false-positive alerts in TSAN, disable | ||
| 29312 | ** them (make them always return 1) when compiling with TSAN. | ||
| 29092 | */ | 29313 | */ |
| 29093 | SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ | 29314 | SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ |
| 29315 | # if defined(__has_feature) | ||
| 29316 | # if __has_feature(thread_sanitizer) | ||
| 29317 | p = 0; | ||
| 29318 | # endif | ||
| 29319 | # endif | ||
| 29094 | assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); | 29320 | assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); |
| 29095 | return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); | 29321 | return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); |
| 29096 | } | 29322 | } |
| 29097 | SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ | 29323 | SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ |
| 29324 | # if defined(__has_feature) | ||
| 29325 | # if __has_feature(thread_sanitizer) | ||
| 29326 | p = 0; | ||
| 29327 | # endif | ||
| 29328 | # endif | ||
| 29098 | assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); | 29329 | assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); |
| 29099 | return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); | 29330 | return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); |
| 29100 | } | 29331 | } |
| 29101 | #endif | 29332 | #endif /* NDEBUG */ |
| 29102 | 29333 | ||
| 29103 | #endif /* !defined(SQLITE_MUTEX_OMIT) */ | 29334 | #endif /* !defined(SQLITE_MUTEX_OMIT) */ |
| 29104 | 29335 | ||
| @@ -31986,16 +32217,19 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 31986 | if( pItem->zAlias && !flag_altform2 ){ | 32217 | if( pItem->zAlias && !flag_altform2 ){ |
| 31987 | sqlite3_str_appendall(pAccum, pItem->zAlias); | 32218 | sqlite3_str_appendall(pAccum, pItem->zAlias); |
| 31988 | }else if( pItem->zName ){ | 32219 | }else if( pItem->zName ){ |
| 31989 | if( pItem->zDatabase ){ | 32220 | if( pItem->fg.fixedSchema==0 |
| 31990 | sqlite3_str_appendall(pAccum, pItem->zDatabase); | 32221 | && pItem->fg.isSubquery==0 |
| 32222 | && pItem->u4.zDatabase!=0 | ||
| 32223 | ){ | ||
| 32224 | sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); | ||
| 31991 | sqlite3_str_append(pAccum, ".", 1); | 32225 | sqlite3_str_append(pAccum, ".", 1); |
| 31992 | } | 32226 | } |
| 31993 | sqlite3_str_appendall(pAccum, pItem->zName); | 32227 | sqlite3_str_appendall(pAccum, pItem->zName); |
| 31994 | }else if( pItem->zAlias ){ | 32228 | }else if( pItem->zAlias ){ |
| 31995 | sqlite3_str_appendall(pAccum, pItem->zAlias); | 32229 | sqlite3_str_appendall(pAccum, pItem->zAlias); |
| 31996 | }else{ | 32230 | }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ |
| 31997 | Select *pSel = pItem->pSelect; | 32231 | Select *pSel = pItem->u4.pSubq->pSelect; |
| 31998 | assert( pSel!=0 ); /* Because of tag-20240424-1 */ | 32232 | assert( pSel!=0 ); |
| 31999 | if( pSel->selFlags & SF_NestedFrom ){ | 32233 | if( pSel->selFlags & SF_NestedFrom ){ |
| 32000 | sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); | 32234 | sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); |
| 32001 | }else if( pSel->selFlags & SF_MultiValue ){ | 32235 | }else if( pSel->selFlags & SF_MultiValue ){ |
| @@ -32073,6 +32307,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp | |||
| 32073 | pExpr = pExpr->pLeft; | 32307 | pExpr = pExpr->pLeft; |
| 32074 | } | 32308 | } |
| 32075 | if( pExpr==0 ) return; | 32309 | if( pExpr==0 ) return; |
| 32310 | if( ExprHasProperty(pExpr, EP_FromDDL) ) return; | ||
| 32076 | db->errByteOffset = pExpr->w.iOfst; | 32311 | db->errByteOffset = pExpr->w.iOfst; |
| 32077 | } | 32312 | } |
| 32078 | 32313 | ||
| @@ -32777,9 +33012,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) | |||
| 32777 | sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); | 33012 | sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); |
| 32778 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; | 33013 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; |
| 32779 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); | 33014 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); |
| 32780 | if( pItem->pTab ){ | 33015 | if( pItem->pSTab ){ |
| 32781 | sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", | 33016 | sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", |
| 32782 | pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, | 33017 | pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, |
| 32783 | pItem->colUsed, | 33018 | pItem->colUsed, |
| 32784 | pItem->fg.rowidUsed ? "+rowid" : ""); | 33019 | pItem->fg.rowidUsed ? "+rowid" : ""); |
| 32785 | } | 33020 | } |
| @@ -32810,25 +33045,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) | |||
| 32810 | if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); | 33045 | if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); |
| 32811 | if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); | 33046 | if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); |
| 32812 | if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); | 33047 | if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); |
| 33048 | if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); | ||
| 33049 | if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); | ||
| 33050 | if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); | ||
| 32813 | 33051 | ||
| 32814 | sqlite3StrAccumFinish(&x); | 33052 | sqlite3StrAccumFinish(&x); |
| 32815 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); | 33053 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 32816 | n = 0; | 33054 | n = 0; |
| 32817 | if( pItem->pSelect ) n++; | 33055 | if( pItem->fg.isSubquery ) n++; |
| 32818 | if( pItem->fg.isTabFunc ) n++; | 33056 | if( pItem->fg.isTabFunc ) n++; |
| 32819 | if( pItem->fg.isUsing ) n++; | 33057 | if( pItem->fg.isUsing ) n++; |
| 32820 | if( pItem->fg.isUsing ){ | 33058 | if( pItem->fg.isUsing ){ |
| 32821 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); | 33059 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); |
| 32822 | } | 33060 | } |
| 32823 | if( pItem->pSelect ){ | 33061 | if( pItem->fg.isSubquery ){ |
| 32824 | sqlite3TreeViewPush(&pView, i+1<pSrc->nSrc); | 33062 | assert( n==1 ); |
| 32825 | if( pItem->pTab ){ | 33063 | if( pItem->pSTab ){ |
| 32826 | Table *pTab = pItem->pTab; | 33064 | Table *pTab = pItem->pSTab; |
| 32827 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); | 33065 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); |
| 32828 | } | 33066 | } |
| 32829 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); | 33067 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); |
| 32830 | sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); | 33068 | sqlite3TreeViewPush(&pView, 0); |
| 33069 | sqlite3TreeViewLine(pView, "SUBQUERY"); | ||
| 32831 | sqlite3TreeViewPop(&pView); | 33070 | sqlite3TreeViewPop(&pView); |
| 33071 | sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); | ||
| 32832 | } | 33072 | } |
| 32833 | if( pItem->fg.isTabFunc ){ | 33073 | if( pItem->fg.isTabFunc ){ |
| 32834 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); | 33074 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| @@ -32870,7 +33110,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m | |||
| 32870 | n = 1000; | 33110 | n = 1000; |
| 32871 | }else{ | 33111 | }else{ |
| 32872 | n = 0; | 33112 | n = 0; |
| 32873 | if( p->pSrc && p->pSrc->nSrc ) n++; | 33113 | if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; |
| 32874 | if( p->pWhere ) n++; | 33114 | if( p->pWhere ) n++; |
| 32875 | if( p->pGroupBy ) n++; | 33115 | if( p->pGroupBy ) n++; |
| 32876 | if( p->pHaving ) n++; | 33116 | if( p->pHaving ) n++; |
| @@ -32896,7 +33136,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m | |||
| 32896 | sqlite3TreeViewPop(&pView); | 33136 | sqlite3TreeViewPop(&pView); |
| 32897 | } | 33137 | } |
| 32898 | #endif | 33138 | #endif |
| 32899 | if( p->pSrc && p->pSrc->nSrc ){ | 33139 | if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ |
| 32900 | sqlite3TreeViewPush(&pView, (n--)>0); | 33140 | sqlite3TreeViewPush(&pView, (n--)>0); |
| 32901 | sqlite3TreeViewLine(pView, "FROM"); | 33141 | sqlite3TreeViewLine(pView, "FROM"); |
| 32902 | sqlite3TreeViewSrcList(pView, p->pSrc); | 33142 | sqlite3TreeViewSrcList(pView, p->pSrc); |
| @@ -33404,7 +33644,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m | |||
| 33404 | case OE_Ignore: zType = "ignore"; break; | 33644 | case OE_Ignore: zType = "ignore"; break; |
| 33405 | } | 33645 | } |
| 33406 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 33646 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 33407 | sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); | 33647 | sqlite3TreeViewLine(pView, "RAISE %s", zType); |
| 33648 | sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); | ||
| 33408 | break; | 33649 | break; |
| 33409 | } | 33650 | } |
| 33410 | #endif | 33651 | #endif |
| @@ -33484,9 +33725,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( | |||
| 33484 | sqlite3TreeViewLine(pView, "%s", zLabel); | 33725 | sqlite3TreeViewLine(pView, "%s", zLabel); |
| 33485 | for(i=0; i<pList->nExpr; i++){ | 33726 | for(i=0; i<pList->nExpr; i++){ |
| 33486 | int j = pList->a[i].u.x.iOrderByCol; | 33727 | int j = pList->a[i].u.x.iOrderByCol; |
| 33728 | u8 sortFlags = pList->a[i].fg.sortFlags; | ||
| 33487 | char *zName = pList->a[i].zEName; | 33729 | char *zName = pList->a[i].zEName; |
| 33488 | int moreToFollow = i<pList->nExpr - 1; | 33730 | int moreToFollow = i<pList->nExpr - 1; |
| 33489 | if( j || zName ){ | 33731 | if( j || zName || sortFlags ){ |
| 33490 | sqlite3TreeViewPush(&pView, moreToFollow); | 33732 | sqlite3TreeViewPush(&pView, moreToFollow); |
| 33491 | moreToFollow = 0; | 33733 | moreToFollow = 0; |
| 33492 | sqlite3TreeViewLine(pView, 0); | 33734 | sqlite3TreeViewLine(pView, 0); |
| @@ -33507,13 +33749,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( | |||
| 33507 | } | 33749 | } |
| 33508 | } | 33750 | } |
| 33509 | if( j ){ | 33751 | if( j ){ |
| 33510 | fprintf(stdout, "iOrderByCol=%d", j); | 33752 | fprintf(stdout, "iOrderByCol=%d ", j); |
| 33753 | } | ||
| 33754 | if( sortFlags & KEYINFO_ORDER_DESC ){ | ||
| 33755 | fprintf(stdout, "DESC "); | ||
| 33756 | }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ | ||
| 33757 | fprintf(stdout, "NULLS-LAST"); | ||
| 33511 | } | 33758 | } |
| 33512 | fprintf(stdout, "\n"); | 33759 | fprintf(stdout, "\n"); |
| 33513 | fflush(stdout); | 33760 | fflush(stdout); |
| 33514 | } | 33761 | } |
| 33515 | sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); | 33762 | sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); |
| 33516 | if( j || zName ){ | 33763 | if( j || zName || sortFlags ){ |
| 33517 | sqlite3TreeViewPop(&pView); | 33764 | sqlite3TreeViewPop(&pView); |
| 33518 | } | 33765 | } |
| 33519 | } | 33766 | } |
| @@ -34476,7 +34723,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { | |||
| 34476 | c = *(zIn++); \ | 34723 | c = *(zIn++); \ |
| 34477 | if( c>=0xc0 ){ \ | 34724 | if( c>=0xc0 ){ \ |
| 34478 | c = sqlite3Utf8Trans1[c-0xc0]; \ | 34725 | c = sqlite3Utf8Trans1[c-0xc0]; \ |
| 34479 | while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ | 34726 | while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \ |
| 34480 | c = (c<<6) + (0x3f & *(zIn++)); \ | 34727 | c = (c<<6) + (0x3f & *(zIn++)); \ |
| 34481 | } \ | 34728 | } \ |
| 34482 | if( c<0x80 \ | 34729 | if( c<0x80 \ |
| @@ -34854,20 +35101,22 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e | |||
| 34854 | } | 35101 | } |
| 34855 | 35102 | ||
| 34856 | /* | 35103 | /* |
| 34857 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. | 35104 | ** zIn is a UTF-16 encoded unicode string at least nByte bytes long. |
| 34858 | ** Return the number of bytes in the first nChar unicode characters | 35105 | ** Return the number of bytes in the first nChar unicode characters |
| 34859 | ** in pZ. nChar must be non-negative. | 35106 | ** in pZ. nChar must be non-negative. Surrogate pairs count as a single |
| 35107 | ** character. | ||
| 34860 | */ | 35108 | */ |
| 34861 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ | 35109 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ |
| 34862 | int c; | 35110 | int c; |
| 34863 | unsigned char const *z = zIn; | 35111 | unsigned char const *z = zIn; |
| 35112 | unsigned char const *zEnd = &z[nByte-1]; | ||
| 34864 | int n = 0; | 35113 | int n = 0; |
| 34865 | 35114 | ||
| 34866 | if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; | 35115 | if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; |
| 34867 | while( n<nChar ){ | 35116 | while( n<nChar && ALWAYS(z<=zEnd) ){ |
| 34868 | c = z[0]; | 35117 | c = z[0]; |
| 34869 | z += 2; | 35118 | z += 2; |
| 34870 | if( c>=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; | 35119 | if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; |
| 34871 | n++; | 35120 | n++; |
| 34872 | } | 35121 | } |
| 34873 | return (int)(z-(unsigned char const *)zIn) | 35122 | return (int)(z-(unsigned char const *)zIn) |
| @@ -35448,6 +35697,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en | |||
| 35448 | int eValid = 1; /* True exponent is either not used or is well-formed */ | 35697 | int eValid = 1; /* True exponent is either not used or is well-formed */ |
| 35449 | int nDigit = 0; /* Number of digits processed */ | 35698 | int nDigit = 0; /* Number of digits processed */ |
| 35450 | int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ | 35699 | int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ |
| 35700 | double rr[2]; | ||
| 35701 | u64 s2; | ||
| 35451 | 35702 | ||
| 35452 | assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); | 35703 | assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); |
| 35453 | *pResult = 0.0; /* Default return value, in case of an error */ | 35704 | *pResult = 0.0; /* Default return value, in case of an error */ |
| @@ -35559,68 +35810,41 @@ do_atof_calc: | |||
| 35559 | e++; | 35810 | e++; |
| 35560 | } | 35811 | } |
| 35561 | 35812 | ||
| 35562 | if( e==0 ){ | 35813 | rr[0] = (double)s; |
| 35563 | *pResult = s; | 35814 | s2 = (u64)rr[0]; |
| 35564 | }else if( sqlite3Config.bUseLongDouble ){ | 35815 | #if defined(_MSC_VER) && _MSC_VER<1700 |
| 35565 | LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; | 35816 | if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } |
| 35566 | if( e>0 ){ | ||
| 35567 | while( e>=100 ){ e-=100; r *= 1.0e+100L; } | ||
| 35568 | while( e>=10 ){ e-=10; r *= 1.0e+10L; } | ||
| 35569 | while( e>=1 ){ e-=1; r *= 1.0e+01L; } | ||
| 35570 | }else{ | ||
| 35571 | while( e<=-100 ){ e+=100; r *= 1.0e-100L; } | ||
| 35572 | while( e<=-10 ){ e+=10; r *= 1.0e-10L; } | ||
| 35573 | while( e<=-1 ){ e+=1; r *= 1.0e-01L; } | ||
| 35574 | } | ||
| 35575 | assert( r>=0.0 ); | ||
| 35576 | if( r>+1.7976931348623157081452742373e+308L ){ | ||
| 35577 | #ifdef INFINITY | ||
| 35578 | *pResult = +INFINITY; | ||
| 35579 | #else | ||
| 35580 | *pResult = 1.0e308*10.0; | ||
| 35581 | #endif | 35817 | #endif |
| 35582 | }else{ | 35818 | rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); |
| 35583 | *pResult = (double)r; | 35819 | if( e>0 ){ |
| 35820 | while( e>=100 ){ | ||
| 35821 | e -= 100; | ||
| 35822 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); | ||
| 35823 | } | ||
| 35824 | while( e>=10 ){ | ||
| 35825 | e -= 10; | ||
| 35826 | dekkerMul2(rr, 1.0e+10, 0.0); | ||
| 35827 | } | ||
| 35828 | while( e>=1 ){ | ||
| 35829 | e -= 1; | ||
| 35830 | dekkerMul2(rr, 1.0e+01, 0.0); | ||
| 35584 | } | 35831 | } |
| 35585 | }else{ | 35832 | }else{ |
| 35586 | double rr[2]; | 35833 | while( e<=-100 ){ |
| 35587 | u64 s2; | 35834 | e += 100; |
| 35588 | rr[0] = (double)s; | 35835 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); |
| 35589 | s2 = (u64)rr[0]; | 35836 | } |
| 35590 | #if defined(_MSC_VER) && _MSC_VER<1700 | 35837 | while( e<=-10 ){ |
| 35591 | if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } | 35838 | e += 10; |
| 35592 | #endif | 35839 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); |
| 35593 | rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); | 35840 | } |
| 35594 | if( e>0 ){ | 35841 | while( e<=-1 ){ |
| 35595 | while( e>=100 ){ | 35842 | e += 1; |
| 35596 | e -= 100; | 35843 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); |
| 35597 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); | ||
| 35598 | } | ||
| 35599 | while( e>=10 ){ | ||
| 35600 | e -= 10; | ||
| 35601 | dekkerMul2(rr, 1.0e+10, 0.0); | ||
| 35602 | } | ||
| 35603 | while( e>=1 ){ | ||
| 35604 | e -= 1; | ||
| 35605 | dekkerMul2(rr, 1.0e+01, 0.0); | ||
| 35606 | } | ||
| 35607 | }else{ | ||
| 35608 | while( e<=-100 ){ | ||
| 35609 | e += 100; | ||
| 35610 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); | ||
| 35611 | } | ||
| 35612 | while( e<=-10 ){ | ||
| 35613 | e += 10; | ||
| 35614 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); | ||
| 35615 | } | ||
| 35616 | while( e<=-1 ){ | ||
| 35617 | e += 1; | ||
| 35618 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); | ||
| 35619 | } | ||
| 35620 | } | 35844 | } |
| 35621 | *pResult = rr[0]+rr[1]; | ||
| 35622 | if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; | ||
| 35623 | } | 35845 | } |
| 35846 | *pResult = rr[0]+rr[1]; | ||
| 35847 | if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; | ||
| 35624 | if( sign<0 ) *pResult = -*pResult; | 35848 | if( sign<0 ) *pResult = -*pResult; |
| 35625 | assert( !sqlite3IsNaN(*pResult) ); | 35849 | assert( !sqlite3IsNaN(*pResult) ); |
| 35626 | 35850 | ||
| @@ -35924,10 +36148,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ | |||
| 35924 | ** Decode a floating-point value into an approximate decimal | 36148 | ** Decode a floating-point value into an approximate decimal |
| 35925 | ** representation. | 36149 | ** representation. |
| 35926 | ** | 36150 | ** |
| 35927 | ** Round the decimal representation to n significant digits if | 36151 | ** If iRound<=0 then round to -iRound significant digits to the |
| 35928 | ** n is positive. Or round to -n signficant digits after the | 36152 | ** the left of the decimal point, or to a maximum of mxRound total |
| 35929 | ** decimal point if n is negative. No rounding is performed if | 36153 | ** significant digits. |
| 35930 | ** n is zero. | 36154 | ** |
| 36155 | ** If iRound>0 round to min(iRound,mxRound) significant digits total. | ||
| 36156 | ** | ||
| 36157 | ** mxRound must be positive. | ||
| 35931 | ** | 36158 | ** |
| 35932 | ** The significant digits of the decimal representation are | 36159 | ** The significant digits of the decimal representation are |
| 35933 | ** stored in p->z[] which is a often (but not always) a pointer | 36160 | ** stored in p->z[] which is a often (but not always) a pointer |
| @@ -35938,8 +36165,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou | |||
| 35938 | int i; | 36165 | int i; |
| 35939 | u64 v; | 36166 | u64 v; |
| 35940 | int e, exp = 0; | 36167 | int e, exp = 0; |
| 36168 | double rr[2]; | ||
| 36169 | |||
| 35941 | p->isSpecial = 0; | 36170 | p->isSpecial = 0; |
| 35942 | p->z = p->zBuf; | 36171 | p->z = p->zBuf; |
| 36172 | assert( mxRound>0 ); | ||
| 35943 | 36173 | ||
| 35944 | /* Convert negative numbers to positive. Deal with Infinity, 0.0, and | 36174 | /* Convert negative numbers to positive. Deal with Infinity, 0.0, and |
| 35945 | ** NaN. */ | 36175 | ** NaN. */ |
| @@ -35966,62 +36196,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou | |||
| 35966 | 36196 | ||
| 35967 | /* Multiply r by powers of ten until it lands somewhere in between | 36197 | /* Multiply r by powers of ten until it lands somewhere in between |
| 35968 | ** 1.0e+19 and 1.0e+17. | 36198 | ** 1.0e+19 and 1.0e+17. |
| 36199 | ** | ||
| 36200 | ** Use Dekker-style double-double computation to increase the | ||
| 36201 | ** precision. | ||
| 36202 | ** | ||
| 36203 | ** The error terms on constants like 1.0e+100 computed using the | ||
| 36204 | ** decimal extension, for example as follows: | ||
| 36205 | ** | ||
| 36206 | ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); | ||
| 35969 | */ | 36207 | */ |
| 35970 | if( sqlite3Config.bUseLongDouble ){ | 36208 | rr[0] = r; |
| 35971 | LONGDOUBLE_TYPE rr = r; | 36209 | rr[1] = 0.0; |
| 35972 | if( rr>=1.0e+19 ){ | 36210 | if( rr[0]>9.223372036854774784e+18 ){ |
| 35973 | while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } | 36211 | while( rr[0]>9.223372036854774784e+118 ){ |
| 35974 | while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } | 36212 | exp += 100; |
| 35975 | while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } | 36213 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); |
| 35976 | }else{ | 36214 | } |
| 35977 | while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } | 36215 | while( rr[0]>9.223372036854774784e+28 ){ |
| 35978 | while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } | 36216 | exp += 10; |
| 35979 | while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } | 36217 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); |
| 36218 | } | ||
| 36219 | while( rr[0]>9.223372036854774784e+18 ){ | ||
| 36220 | exp += 1; | ||
| 36221 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); | ||
| 35980 | } | 36222 | } |
| 35981 | v = (u64)rr; | ||
| 35982 | }else{ | 36223 | }else{ |
| 35983 | /* If high-precision floating point is not available using "long double", | 36224 | while( rr[0]<9.223372036854774784e-83 ){ |
| 35984 | ** then use Dekker-style double-double computation to increase the | 36225 | exp -= 100; |
| 35985 | ** precision. | 36226 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); |
| 35986 | ** | 36227 | } |
| 35987 | ** The error terms on constants like 1.0e+100 computed using the | 36228 | while( rr[0]<9.223372036854774784e+07 ){ |
| 35988 | ** decimal extension, for example as follows: | 36229 | exp -= 10; |
| 35989 | ** | 36230 | dekkerMul2(rr, 1.0e+10, 0.0); |
| 35990 | ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); | 36231 | } |
| 35991 | */ | 36232 | while( rr[0]<9.22337203685477478e+17 ){ |
| 35992 | double rr[2]; | 36233 | exp -= 1; |
| 35993 | rr[0] = r; | 36234 | dekkerMul2(rr, 1.0e+01, 0.0); |
| 35994 | rr[1] = 0.0; | ||
| 35995 | if( rr[0]>9.223372036854774784e+18 ){ | ||
| 35996 | while( rr[0]>9.223372036854774784e+118 ){ | ||
| 35997 | exp += 100; | ||
| 35998 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); | ||
| 35999 | } | ||
| 36000 | while( rr[0]>9.223372036854774784e+28 ){ | ||
| 36001 | exp += 10; | ||
| 36002 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); | ||
| 36003 | } | ||
| 36004 | while( rr[0]>9.223372036854774784e+18 ){ | ||
| 36005 | exp += 1; | ||
| 36006 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); | ||
| 36007 | } | ||
| 36008 | }else{ | ||
| 36009 | while( rr[0]<9.223372036854774784e-83 ){ | ||
| 36010 | exp -= 100; | ||
| 36011 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); | ||
| 36012 | } | ||
| 36013 | while( rr[0]<9.223372036854774784e+07 ){ | ||
| 36014 | exp -= 10; | ||
| 36015 | dekkerMul2(rr, 1.0e+10, 0.0); | ||
| 36016 | } | ||
| 36017 | while( rr[0]<9.22337203685477478e+17 ){ | ||
| 36018 | exp -= 1; | ||
| 36019 | dekkerMul2(rr, 1.0e+01, 0.0); | ||
| 36020 | } | ||
| 36021 | } | 36235 | } |
| 36022 | v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; | ||
| 36023 | } | 36236 | } |
| 36024 | 36237 | v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; | |
| 36025 | 36238 | ||
| 36026 | /* Extract significant digits. */ | 36239 | /* Extract significant digits. */ |
| 36027 | i = sizeof(p->zBuf)-1; | 36240 | i = sizeof(p->zBuf)-1; |
| @@ -36792,104 +37005,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam | |||
| 36792 | return 0; | 37005 | return 0; |
| 36793 | } | 37006 | } |
| 36794 | 37007 | ||
| 36795 | /* | ||
| 36796 | ** High-resolution hardware timer used for debugging and testing only. | ||
| 36797 | */ | ||
| 36798 | #if defined(VDBE_PROFILE) \ | ||
| 36799 | || defined(SQLITE_PERFORMANCE_TRACE) \ | ||
| 36800 | || defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 36801 | /************** Include hwtime.h in the middle of util.c *********************/ | ||
| 36802 | /************** Begin file hwtime.h ******************************************/ | ||
| 36803 | /* | ||
| 36804 | ** 2008 May 27 | ||
| 36805 | ** | ||
| 36806 | ** The author disclaims copyright to this source code. In place of | ||
| 36807 | ** a legal notice, here is a blessing: | ||
| 36808 | ** | ||
| 36809 | ** May you do good and not evil. | ||
| 36810 | ** May you find forgiveness for yourself and forgive others. | ||
| 36811 | ** May you share freely, never taking more than you give. | ||
| 36812 | ** | ||
| 36813 | ****************************************************************************** | ||
| 36814 | ** | ||
| 36815 | ** This file contains inline asm code for retrieving "high-performance" | ||
| 36816 | ** counters for x86 and x86_64 class CPUs. | ||
| 36817 | */ | ||
| 36818 | #ifndef SQLITE_HWTIME_H | ||
| 36819 | #define SQLITE_HWTIME_H | ||
| 36820 | |||
| 36821 | /* | ||
| 36822 | ** The following routine only works on Pentium-class (or newer) processors. | ||
| 36823 | ** It uses the RDTSC opcode to read the cycle count value out of the | ||
| 36824 | ** processor and returns that value. This can be used for high-res | ||
| 36825 | ** profiling. | ||
| 36826 | */ | ||
| 36827 | #if !defined(__STRICT_ANSI__) && \ | ||
| 36828 | (defined(__GNUC__) || defined(_MSC_VER)) && \ | ||
| 36829 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) | ||
| 36830 | |||
| 36831 | #if defined(__GNUC__) | ||
| 36832 | |||
| 36833 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36834 | unsigned int lo, hi; | ||
| 36835 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 36836 | return (sqlite_uint64)hi << 32 | lo; | ||
| 36837 | } | ||
| 36838 | |||
| 36839 | #elif defined(_MSC_VER) | ||
| 36840 | |||
| 36841 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | ||
| 36842 | __asm { | ||
| 36843 | rdtsc | ||
| 36844 | ret ; return value at EDX:EAX | ||
| 36845 | } | ||
| 36846 | } | ||
| 36847 | |||
| 36848 | #endif | ||
| 36849 | |||
| 36850 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) | ||
| 36851 | |||
| 36852 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36853 | unsigned int lo, hi; | ||
| 36854 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 36855 | return (sqlite_uint64)hi << 32 | lo; | ||
| 36856 | } | ||
| 36857 | |||
| 36858 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) | ||
| 36859 | |||
| 36860 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36861 | unsigned long long retval; | ||
| 36862 | unsigned long junk; | ||
| 36863 | __asm__ __volatile__ ("\n\ | ||
| 36864 | 1: mftbu %1\n\ | ||
| 36865 | mftb %L0\n\ | ||
| 36866 | mftbu %0\n\ | ||
| 36867 | cmpw %0,%1\n\ | ||
| 36868 | bne 1b" | ||
| 36869 | : "=r" (retval), "=r" (junk)); | ||
| 36870 | return retval; | ||
| 36871 | } | ||
| 36872 | |||
| 36873 | #else | ||
| 36874 | |||
| 36875 | /* | ||
| 36876 | ** asm() is needed for hardware timing support. Without asm(), | ||
| 36877 | ** disable the sqlite3Hwtime() routine. | ||
| 36878 | ** | ||
| 36879 | ** sqlite3Hwtime() is only used for some obscure debugging | ||
| 36880 | ** and analysis configurations, not in any deliverable, so this | ||
| 36881 | ** should not be a great loss. | ||
| 36882 | */ | ||
| 36883 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | ||
| 36884 | |||
| 36885 | #endif | ||
| 36886 | |||
| 36887 | #endif /* !defined(SQLITE_HWTIME_H) */ | ||
| 36888 | |||
| 36889 | /************** End of hwtime.h **********************************************/ | ||
| 36890 | /************** Continuing where we left off in util.c ***********************/ | ||
| 36891 | #endif | ||
| 36892 | |||
| 36893 | /************** End of util.c ************************************************/ | 37008 | /************** End of util.c ************************************************/ |
| 36894 | /************** Begin file hash.c ********************************************/ | 37009 | /************** Begin file hash.c ********************************************/ |
| 36895 | /* | 37010 | /* |
| @@ -37227,16 +37342,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 37227 | /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | 37342 | /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 37228 | /* 48 */ "Program" OpHelp(""), | 37343 | /* 48 */ "Program" OpHelp(""), |
| 37229 | /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | 37344 | /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 37230 | /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), | 37345 | /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 37231 | /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), | 37346 | /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 37232 | /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), | 37347 | /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 37233 | /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), | 37348 | /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), |
| 37234 | /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), | 37349 | /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), |
| 37235 | /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), | 37350 | /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), |
| 37236 | /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), | 37351 | /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), |
| 37237 | /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), | 37352 | /* 57 */ "Lt" OpHelp("IF r[P3]<r[P1]"), |
| 37238 | /* 58 */ "ElseEq" OpHelp(""), | 37353 | /* 58 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), |
| 37239 | /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), | 37354 | /* 59 */ "ElseEq" OpHelp(""), |
| 37240 | /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), | 37355 | /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 37241 | /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), | 37356 | /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 37242 | /* 62 */ "IncrVacuum" OpHelp(""), | 37357 | /* 62 */ "IncrVacuum" OpHelp(""), |
| @@ -37279,23 +37394,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 37279 | /* 99 */ "ReadCookie" OpHelp(""), | 37394 | /* 99 */ "ReadCookie" OpHelp(""), |
| 37280 | /* 100 */ "SetCookie" OpHelp(""), | 37395 | /* 100 */ "SetCookie" OpHelp(""), |
| 37281 | /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), | 37396 | /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 37282 | /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), | 37397 | /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 37283 | /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), | 37398 | /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 37284 | /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), | 37399 | /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 37285 | /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), | 37400 | /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 37286 | /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), | 37401 | /* 106 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 37287 | /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), | 37402 | /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| 37288 | /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), | 37403 | /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 37289 | /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), | 37404 | /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 37290 | /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), | 37405 | /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 37291 | /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), | 37406 | /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 37292 | /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), | 37407 | /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 37293 | /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), | 37408 | /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 37294 | /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), | 37409 | /* 114 */ "OpenDup" OpHelp(""), |
| 37295 | /* 115 */ "OpenDup" OpHelp(""), | 37410 | /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), |
| 37296 | /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), | 37411 | /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 37297 | /* 117 */ "String8" OpHelp("r[P2]='P4'"), | 37412 | /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 37298 | /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), | 37413 | /* 118 */ "String8" OpHelp("r[P2]='P4'"), |
| 37299 | /* 119 */ "SorterOpen" OpHelp(""), | 37414 | /* 119 */ "SorterOpen" OpHelp(""), |
| 37300 | /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), | 37415 | /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), |
| 37301 | /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), | 37416 | /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| @@ -37330,8 +37445,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 37330 | /* 150 */ "LoadAnalysis" OpHelp(""), | 37445 | /* 150 */ "LoadAnalysis" OpHelp(""), |
| 37331 | /* 151 */ "DropTable" OpHelp(""), | 37446 | /* 151 */ "DropTable" OpHelp(""), |
| 37332 | /* 152 */ "DropIndex" OpHelp(""), | 37447 | /* 152 */ "DropIndex" OpHelp(""), |
| 37333 | /* 153 */ "Real" OpHelp("r[P2]=P4"), | 37448 | /* 153 */ "DropTrigger" OpHelp(""), |
| 37334 | /* 154 */ "DropTrigger" OpHelp(""), | 37449 | /* 154 */ "Real" OpHelp("r[P2]=P4"), |
| 37335 | /* 155 */ "IntegrityCk" OpHelp(""), | 37450 | /* 155 */ "IntegrityCk" OpHelp(""), |
| 37336 | /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), | 37451 | /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 37337 | /* 157 */ "Param" OpHelp(""), | 37452 | /* 157 */ "Param" OpHelp(""), |
| @@ -38680,7 +38795,7 @@ static pid_t randomnessPid = 0; | |||
| 38680 | #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ | 38795 | #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ |
| 38681 | #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ | 38796 | #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ |
| 38682 | #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ | 38797 | #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ |
| 38683 | #ifndef SQLITE_DISABLE_DIRSYNC | 38798 | #if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) |
| 38684 | # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ | 38799 | # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ |
| 38685 | #else | 38800 | #else |
| 38686 | # define UNIXFILE_DIRSYNC 0x00 | 38801 | # define UNIXFILE_DIRSYNC 0x00 |
| @@ -40637,26 +40752,22 @@ static int nolockClose(sqlite3_file *id) { | |||
| 40637 | 40752 | ||
| 40638 | /* | 40753 | /* |
| 40639 | ** This routine checks if there is a RESERVED lock held on the specified | 40754 | ** This routine checks if there is a RESERVED lock held on the specified |
| 40640 | ** file by this or any other process. If such a lock is held, set *pResOut | 40755 | ** file by this or any other process. If the caller holds a SHARED |
| 40641 | ** to a non-zero value otherwise *pResOut is set to zero. The return value | 40756 | ** or greater lock when it is called, then it is assumed that no other |
| 40642 | ** is set to SQLITE_OK unless an I/O error occurs during lock checking. | 40757 | ** client may hold RESERVED. Or, if the caller holds no lock, then it |
| 40643 | ** | 40758 | ** is assumed another client holds RESERVED if the lock-file exists. |
| 40644 | ** In dotfile locking, either a lock exists or it does not. So in this | ||
| 40645 | ** variation of CheckReservedLock(), *pResOut is set to true if any lock | ||
| 40646 | ** is held on the file and false if the file is unlocked. | ||
| 40647 | */ | 40759 | */ |
| 40648 | static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { | 40760 | static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { |
| 40649 | int rc = SQLITE_OK; | ||
| 40650 | int reserved = 0; | ||
| 40651 | unixFile *pFile = (unixFile*)id; | 40761 | unixFile *pFile = (unixFile*)id; |
| 40652 | |||
| 40653 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | 40762 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 40654 | 40763 | ||
| 40655 | assert( pFile ); | 40764 | if( pFile->eFileLock>=SHARED_LOCK ){ |
| 40656 | reserved = osAccess((const char*)pFile->lockingContext, 0)==0; | 40765 | *pResOut = 0; |
| 40657 | OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); | 40766 | }else{ |
| 40658 | *pResOut = reserved; | 40767 | *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; |
| 40659 | return rc; | 40768 | } |
| 40769 | OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); | ||
| 40770 | return SQLITE_OK; | ||
| 40660 | } | 40771 | } |
| 40661 | 40772 | ||
| 40662 | /* | 40773 | /* |
| @@ -40826,54 +40937,33 @@ static int robust_flock(int fd, int op){ | |||
| 40826 | ** is set to SQLITE_OK unless an I/O error occurs during lock checking. | 40937 | ** is set to SQLITE_OK unless an I/O error occurs during lock checking. |
| 40827 | */ | 40938 | */ |
| 40828 | static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ | 40939 | static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 40829 | int rc = SQLITE_OK; | 40940 | #ifdef SQLITE_DEBUG |
| 40830 | int reserved = 0; | ||
| 40831 | unixFile *pFile = (unixFile*)id; | 40941 | unixFile *pFile = (unixFile*)id; |
| 40942 | #else | ||
| 40943 | UNUSED_PARAMETER(id); | ||
| 40944 | #endif | ||
| 40832 | 40945 | ||
| 40833 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | 40946 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 40834 | 40947 | ||
| 40835 | assert( pFile ); | 40948 | assert( pFile ); |
| 40949 | assert( pFile->eFileLock<=SHARED_LOCK ); | ||
| 40836 | 40950 | ||
| 40837 | /* Check if a thread in this process holds such a lock */ | 40951 | /* The flock VFS only ever takes exclusive locks (see function flockLock). |
| 40838 | if( pFile->eFileLock>SHARED_LOCK ){ | 40952 | ** Therefore, if this connection is holding any lock at all, no other |
| 40839 | reserved = 1; | 40953 | ** connection may be holding a RESERVED lock. So set *pResOut to 0 |
| 40840 | } | 40954 | ** in this case. |
| 40841 | 40955 | ** | |
| 40842 | /* Otherwise see if some other process holds it. */ | 40956 | ** Or, this connection may be holding no lock. In that case, set *pResOut to |
| 40843 | if( !reserved ){ | 40957 | ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the |
| 40844 | /* attempt to get the lock */ | 40958 | ** db in order to roll the hot journal back. If there is another connection |
| 40845 | int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); | 40959 | ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to |
| 40846 | if( !lrc ){ | 40960 | ** the user. With other VFS, we try to avoid this, in order to allow a reader |
| 40847 | /* got the lock, unlock it */ | 40961 | ** to proceed while a writer is preparing its transaction. But that won't |
| 40848 | lrc = robust_flock(pFile->h, LOCK_UN); | 40962 | ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is |
| 40849 | if ( lrc ) { | 40963 | ** not a problem in this case. */ |
| 40850 | int tErrno = errno; | 40964 | *pResOut = 0; |
| 40851 | /* unlock failed with an error */ | ||
| 40852 | lrc = SQLITE_IOERR_UNLOCK; | ||
| 40853 | storeLastErrno(pFile, tErrno); | ||
| 40854 | rc = lrc; | ||
| 40855 | } | ||
| 40856 | } else { | ||
| 40857 | int tErrno = errno; | ||
| 40858 | reserved = 1; | ||
| 40859 | /* someone else might have it reserved */ | ||
| 40860 | lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | ||
| 40861 | if( IS_LOCK_ERROR(lrc) ){ | ||
| 40862 | storeLastErrno(pFile, tErrno); | ||
| 40863 | rc = lrc; | ||
| 40864 | } | ||
| 40865 | } | ||
| 40866 | } | ||
| 40867 | OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); | ||
| 40868 | 40965 | ||
| 40869 | #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS | 40966 | return SQLITE_OK; |
| 40870 | if( (rc & 0xff) == SQLITE_IOERR ){ | ||
| 40871 | rc = SQLITE_OK; | ||
| 40872 | reserved=1; | ||
| 40873 | } | ||
| 40874 | #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ | ||
| 40875 | *pResOut = reserved; | ||
| 40876 | return rc; | ||
| 40877 | } | 40967 | } |
| 40878 | 40968 | ||
| 40879 | /* | 40969 | /* |
| @@ -42345,7 +42435,7 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ | |||
| 42345 | 42435 | ||
| 42346 | /* Forward declaration */ | 42436 | /* Forward declaration */ |
| 42347 | static int unixGetTempname(int nBuf, char *zBuf); | 42437 | static int unixGetTempname(int nBuf, char *zBuf); |
| 42348 | #ifndef SQLITE_OMIT_WAL | 42438 | #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) |
| 42349 | static int unixFcntlExternalReader(unixFile*, int*); | 42439 | static int unixFcntlExternalReader(unixFile*, int*); |
| 42350 | #endif | 42440 | #endif |
| 42351 | 42441 | ||
| @@ -42472,7 +42562,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ | |||
| 42472 | #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ | 42562 | #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ |
| 42473 | 42563 | ||
| 42474 | case SQLITE_FCNTL_EXTERNAL_READER: { | 42564 | case SQLITE_FCNTL_EXTERNAL_READER: { |
| 42475 | #ifndef SQLITE_OMIT_WAL | 42565 | #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) |
| 42476 | return unixFcntlExternalReader((unixFile*)id, (int*)pArg); | 42566 | return unixFcntlExternalReader((unixFile*)id, (int*)pArg); |
| 42477 | #else | 42567 | #else |
| 42478 | *(int*)pArg = 0; | 42568 | *(int*)pArg = 0; |
| @@ -42511,6 +42601,7 @@ static void setDeviceCharacteristics(unixFile *pFd){ | |||
| 42511 | if( pFd->ctrlFlags & UNIXFILE_PSOW ){ | 42601 | if( pFd->ctrlFlags & UNIXFILE_PSOW ){ |
| 42512 | pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; | 42602 | pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; |
| 42513 | } | 42603 | } |
| 42604 | pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; | ||
| 42514 | 42605 | ||
| 42515 | pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; | 42606 | pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; |
| 42516 | } | 42607 | } |
| @@ -42561,7 +42652,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ | |||
| 42561 | pFile->sectorSize = fsInfo.f_bsize; | 42652 | pFile->sectorSize = fsInfo.f_bsize; |
| 42562 | pFile->deviceCharacteristics = | 42653 | pFile->deviceCharacteristics = |
| 42563 | /* full bitset of atomics from max sector size and smaller */ | 42654 | /* full bitset of atomics from max sector size and smaller */ |
| 42564 | ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | | 42655 | (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | |
| 42565 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind | 42656 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 42566 | ** so it is ordered */ | 42657 | ** so it is ordered */ |
| 42567 | 0; | 42658 | 0; |
| @@ -42569,7 +42660,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ | |||
| 42569 | pFile->sectorSize = fsInfo.f_bsize; | 42660 | pFile->sectorSize = fsInfo.f_bsize; |
| 42570 | pFile->deviceCharacteristics = | 42661 | pFile->deviceCharacteristics = |
| 42571 | /* full bitset of atomics from max sector size and smaller */ | 42662 | /* full bitset of atomics from max sector size and smaller */ |
| 42572 | ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | | 42663 | (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | |
| 42573 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind | 42664 | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind |
| 42574 | ** so it is ordered */ | 42665 | ** so it is ordered */ |
| 42575 | 0; | 42666 | 0; |
| @@ -42645,7 +42736,7 @@ static int unixGetpagesize(void){ | |||
| 42645 | 42736 | ||
| 42646 | #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ | 42737 | #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ |
| 42647 | 42738 | ||
| 42648 | #ifndef SQLITE_OMIT_WAL | 42739 | #if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) |
| 42649 | 42740 | ||
| 42650 | /* | 42741 | /* |
| 42651 | ** Object used to represent an shared memory buffer. | 42742 | ** Object used to represent an shared memory buffer. |
| @@ -50311,7 +50402,7 @@ static int winSectorSize(sqlite3_file *id){ | |||
| 50311 | */ | 50402 | */ |
| 50312 | static int winDeviceCharacteristics(sqlite3_file *id){ | 50403 | static int winDeviceCharacteristics(sqlite3_file *id){ |
| 50313 | winFile *p = (winFile*)id; | 50404 | winFile *p = (winFile*)id; |
| 50314 | return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | | 50405 | return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | |
| 50315 | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); | 50406 | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); |
| 50316 | } | 50407 | } |
| 50317 | 50408 | ||
| @@ -51699,7 +51790,7 @@ static int winOpen( | |||
| 51699 | 51790 | ||
| 51700 | int rc = SQLITE_OK; /* Function Return Code */ | 51791 | int rc = SQLITE_OK; /* Function Return Code */ |
| 51701 | #if !defined(NDEBUG) || SQLITE_OS_WINCE | 51792 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 51702 | int eType = flags&0xFFFFFF00; /* Type of file to open */ | 51793 | int eType = flags&0x0FFF00; /* Type of file to open */ |
| 51703 | #endif | 51794 | #endif |
| 51704 | 51795 | ||
| 51705 | int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); | 51796 | int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); |
| @@ -54730,6 +54821,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( | |||
| 54730 | pPgHdr->pData = pPage->pBuf; | 54821 | pPgHdr->pData = pPage->pBuf; |
| 54731 | pPgHdr->pExtra = (void *)&pPgHdr[1]; | 54822 | pPgHdr->pExtra = (void *)&pPgHdr[1]; |
| 54732 | memset(pPgHdr->pExtra, 0, 8); | 54823 | memset(pPgHdr->pExtra, 0, 8); |
| 54824 | assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); | ||
| 54733 | pPgHdr->pCache = pCache; | 54825 | pPgHdr->pCache = pCache; |
| 54734 | pPgHdr->pgno = pgno; | 54826 | pPgHdr->pgno = pgno; |
| 54735 | pPgHdr->flags = PGHDR_CLEAN; | 54827 | pPgHdr->flags = PGHDR_CLEAN; |
| @@ -55476,7 +55568,8 @@ static int pcache1InitBulk(PCache1 *pCache){ | |||
| 55476 | do{ | 55568 | do{ |
| 55477 | PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; | 55569 | PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; |
| 55478 | pX->page.pBuf = zBulk; | 55570 | pX->page.pBuf = zBulk; |
| 55479 | pX->page.pExtra = &pX[1]; | 55571 | pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); |
| 55572 | assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); | ||
| 55480 | pX->isBulkLocal = 1; | 55573 | pX->isBulkLocal = 1; |
| 55481 | pX->isAnchor = 0; | 55574 | pX->isAnchor = 0; |
| 55482 | pX->pNext = pCache->pFree; | 55575 | pX->pNext = pCache->pFree; |
| @@ -55613,7 +55706,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ | |||
| 55613 | if( pPg==0 ) return 0; | 55706 | if( pPg==0 ) return 0; |
| 55614 | p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; | 55707 | p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; |
| 55615 | p->page.pBuf = pPg; | 55708 | p->page.pBuf = pPg; |
| 55616 | p->page.pExtra = &p[1]; | 55709 | p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); |
| 55710 | assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); | ||
| 55617 | p->isBulkLocal = 0; | 55711 | p->isBulkLocal = 0; |
| 55618 | p->isAnchor = 0; | 55712 | p->isAnchor = 0; |
| 55619 | p->pLruPrev = 0; /* Initializing this saves a valgrind error */ | 55713 | p->pLruPrev = 0; /* Initializing this saves a valgrind error */ |
| @@ -57916,18 +58010,26 @@ static const unsigned char aJournalMagic[] = { | |||
| 57916 | ** Return true if page pgno can be read directly from the database file | 58010 | ** Return true if page pgno can be read directly from the database file |
| 57917 | ** by the b-tree layer. This is the case if: | 58011 | ** by the b-tree layer. This is the case if: |
| 57918 | ** | 58012 | ** |
| 57919 | ** * the database file is open, | 58013 | ** (1) the database file is open |
| 57920 | ** * there are no dirty pages in the cache, and | 58014 | ** (2) the VFS for the database is able to do unaligned sub-page reads |
| 57921 | ** * the desired page is not currently in the wal file. | 58015 | ** (3) there are no dirty pages in the cache, and |
| 58016 | ** (4) the desired page is not currently in the wal file. | ||
| 57922 | */ | 58017 | */ |
| 57923 | SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ | 58018 | SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ |
| 57924 | if( pPager->fd->pMethods==0 ) return 0; | 58019 | assert( pPager!=0 ); |
| 57925 | if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; | 58020 | assert( pPager->fd!=0 ); |
| 58021 | if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ | ||
| 58022 | assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); | ||
| 58023 | if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) | ||
| 58024 | & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ | ||
| 58025 | return 0; /* Case (2) */ | ||
| 58026 | } | ||
| 58027 | if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ | ||
| 57926 | #ifndef SQLITE_OMIT_WAL | 58028 | #ifndef SQLITE_OMIT_WAL |
| 57927 | if( pPager->pWal ){ | 58029 | if( pPager->pWal ){ |
| 57928 | u32 iRead = 0; | 58030 | u32 iRead = 0; |
| 57929 | (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); | 58031 | (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); |
| 57930 | return iRead==0; | 58032 | return iRead==0; /* Condition (4) */ |
| 57931 | } | 58033 | } |
| 57932 | #endif | 58034 | #endif |
| 57933 | return 1; | 58035 | return 1; |
| @@ -61172,6 +61274,7 @@ static int pagerAcquireMapPage( | |||
| 61172 | return SQLITE_NOMEM_BKPT; | 61274 | return SQLITE_NOMEM_BKPT; |
| 61173 | } | 61275 | } |
| 61174 | p->pExtra = (void *)&p[1]; | 61276 | p->pExtra = (void *)&p[1]; |
| 61277 | assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); | ||
| 61175 | p->flags = PGHDR_MMAP; | 61278 | p->flags = PGHDR_MMAP; |
| 61176 | p->nRef = 1; | 61279 | p->nRef = 1; |
| 61177 | p->pPager = pPager; | 61280 | p->pPager = pPager; |
| @@ -64955,7 +65058,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ | |||
| 64955 | ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). | 65058 | ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). |
| 64956 | ** | 65059 | ** |
| 64957 | ** Immediately following the wal-header are zero or more frames. Each | 65060 | ** Immediately following the wal-header are zero or more frames. Each |
| 64958 | ** frame consists of a 24-byte frame-header followed by a <page-size> bytes | 65061 | ** frame consists of a 24-byte frame-header followed by <page-size> bytes |
| 64959 | ** of page data. The frame-header is six big-endian 32-bit unsigned | 65062 | ** of page data. The frame-header is six big-endian 32-bit unsigned |
| 64960 | ** integer values, as follows: | 65063 | ** integer values, as follows: |
| 64961 | ** | 65064 | ** |
| @@ -65452,6 +65555,7 @@ struct Wal { | |||
| 65452 | #endif | 65555 | #endif |
| 65453 | #ifdef SQLITE_ENABLE_SNAPSHOT | 65556 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 65454 | WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ | 65557 | WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ |
| 65558 | int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ | ||
| 65455 | #endif | 65559 | #endif |
| 65456 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | 65560 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 65457 | sqlite3 *db; | 65561 | sqlite3 *db; |
| @@ -67344,7 +67448,7 @@ static int walHandleException(Wal *pWal){ | |||
| 67344 | 67448 | ||
| 67345 | /* | 67449 | /* |
| 67346 | ** Assert that the Wal.lockMask mask, which indicates the locks held | 67450 | ** Assert that the Wal.lockMask mask, which indicates the locks held |
| 67347 | ** by the connenction, is consistent with the Wal.readLock, Wal.writeLock | 67451 | ** by the connection, is consistent with the Wal.readLock, Wal.writeLock |
| 67348 | ** and Wal.ckptLock variables. To be used as: | 67452 | ** and Wal.ckptLock variables. To be used as: |
| 67349 | ** | 67453 | ** |
| 67350 | ** assert( walAssertLockmask(pWal) ); | 67454 | ** assert( walAssertLockmask(pWal) ); |
| @@ -68008,7 +68112,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ | |||
| 68008 | SEH_INJECT_FAULT; | 68112 | SEH_INJECT_FAULT; |
| 68009 | if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame | 68113 | if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame |
| 68010 | #ifdef SQLITE_ENABLE_SNAPSHOT | 68114 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 68011 | && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) | 68115 | && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) |
| 68012 | #endif | 68116 | #endif |
| 68013 | ){ | 68117 | ){ |
| 68014 | /* The WAL has been completely backfilled (or it is empty). | 68118 | /* The WAL has been completely backfilled (or it is empty). |
| @@ -69408,7 +69512,20 @@ SQLITE_PRIVATE void sqlite3WalSnapshotOpen( | |||
| 69408 | Wal *pWal, | 69512 | Wal *pWal, |
| 69409 | sqlite3_snapshot *pSnapshot | 69513 | sqlite3_snapshot *pSnapshot |
| 69410 | ){ | 69514 | ){ |
| 69411 | pWal->pSnapshot = (WalIndexHdr*)pSnapshot; | 69515 | if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ |
| 69516 | /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In | ||
| 69517 | ** this case set the bGetSnapshot flag so that if the call to | ||
| 69518 | ** sqlite3_snapshot_get() is about to read transaction on this wal | ||
| 69519 | ** file, it does not take read-lock 0 if the wal file has been completely | ||
| 69520 | ** checkpointed. Taking read-lock 0 would work, but then it would be | ||
| 69521 | ** possible for a subsequent writer to destroy the snapshot even while | ||
| 69522 | ** this connection is holding its read-transaction open. This is contrary | ||
| 69523 | ** to user expectations, so we avoid it by not taking read-lock 0. */ | ||
| 69524 | pWal->bGetSnapshot = 1; | ||
| 69525 | }else{ | ||
| 69526 | pWal->pSnapshot = (WalIndexHdr*)pSnapshot; | ||
| 69527 | pWal->bGetSnapshot = 0; | ||
| 69528 | } | ||
| 69412 | } | 69529 | } |
| 69413 | 69530 | ||
| 69414 | /* | 69531 | /* |
| @@ -75289,6 +75406,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ | |||
| 75289 | return ROUND8(sizeof(BtCursor)); | 75406 | return ROUND8(sizeof(BtCursor)); |
| 75290 | } | 75407 | } |
| 75291 | 75408 | ||
| 75409 | #ifdef SQLITE_DEBUG | ||
| 75410 | /* | ||
| 75411 | ** Return true if and only if the Btree object will be automatically | ||
| 75412 | ** closed with the BtCursor closes. This is used within assert() statements | ||
| 75413 | ** only. | ||
| 75414 | */ | ||
| 75415 | SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor( | ||
| 75416 | Btree *pBtree, /* the btree object */ | ||
| 75417 | BtCursor *pCur /* Corresponding cursor */ | ||
| 75418 | ){ | ||
| 75419 | BtShared *pBt = pBtree->pBt; | ||
| 75420 | if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0; | ||
| 75421 | if( pBt->pCursor!=pCur ) return 0; | ||
| 75422 | if( pCur->pNext!=0 ) return 0; | ||
| 75423 | if( pCur->pBtree!=pBtree ) return 0; | ||
| 75424 | return 1; | ||
| 75425 | } | ||
| 75426 | #endif | ||
| 75427 | |||
| 75292 | /* | 75428 | /* |
| 75293 | ** Initialize memory that will be converted into a BtCursor object. | 75429 | ** Initialize memory that will be converted into a BtCursor object. |
| 75294 | ** | 75430 | ** |
| @@ -76532,7 +76668,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( | |||
| 76532 | && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 | 76668 | && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 |
| 76533 | && pIdxKey->errCode==SQLITE_OK | 76669 | && pIdxKey->errCode==SQLITE_OK |
| 76534 | ){ | 76670 | ){ |
| 76535 | pCur->curFlags &= ~BTCF_ValidOvfl; | 76671 | pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); |
| 76536 | if( !pCur->pPage->isInit ){ | 76672 | if( !pCur->pPage->isInit ){ |
| 76537 | return SQLITE_CORRUPT_BKPT; | 76673 | return SQLITE_CORRUPT_BKPT; |
| 76538 | } | 76674 | } |
| @@ -78110,7 +78246,8 @@ static int rebuildPage( | |||
| 78110 | if( j>(u32)usableSize ){ j = 0; } | 78246 | if( j>(u32)usableSize ){ j = 0; } |
| 78111 | memcpy(&pTmp[j], &aData[j], usableSize - j); | 78247 | memcpy(&pTmp[j], &aData[j], usableSize - j); |
| 78112 | 78248 | ||
| 78113 | for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i; k++){} | 78249 | assert( pCArray->ixNx[NB*2-1]>i ); |
| 78250 | for(k=0; pCArray->ixNx[k]<=i; k++){} | ||
| 78114 | pSrcEnd = pCArray->apEnd[k]; | 78251 | pSrcEnd = pCArray->apEnd[k]; |
| 78115 | 78252 | ||
| 78116 | pData = pEnd; | 78253 | pData = pEnd; |
| @@ -78193,7 +78330,8 @@ static int pageInsertArray( | |||
| 78193 | u8 *pEnd; /* Maximum extent of cell data */ | 78330 | u8 *pEnd; /* Maximum extent of cell data */ |
| 78194 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ | 78331 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ |
| 78195 | if( iEnd<=iFirst ) return 0; | 78332 | if( iEnd<=iFirst ) return 0; |
| 78196 | for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i ; k++){} | 78333 | assert( pCArray->ixNx[NB*2-1]>i ); |
| 78334 | for(k=0; pCArray->ixNx[k]<=i ; k++){} | ||
| 78197 | pEnd = pCArray->apEnd[k]; | 78335 | pEnd = pCArray->apEnd[k]; |
| 78198 | while( 1 /*Exit by break*/ ){ | 78336 | while( 1 /*Exit by break*/ ){ |
| 78199 | int sz, rc; | 78337 | int sz, rc; |
| @@ -78478,6 +78616,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ | |||
| 78478 | b.szCell = &szCell; | 78616 | b.szCell = &szCell; |
| 78479 | b.apEnd[0] = pPage->aDataEnd; | 78617 | b.apEnd[0] = pPage->aDataEnd; |
| 78480 | b.ixNx[0] = 2; | 78618 | b.ixNx[0] = 2; |
| 78619 | b.ixNx[NB*2-1] = 0x7fffffff; | ||
| 78481 | rc = rebuildPage(&b, 0, 1, pNew); | 78620 | rc = rebuildPage(&b, 0, 1, pNew); |
| 78482 | if( NEVER(rc) ){ | 78621 | if( NEVER(rc) ){ |
| 78483 | releasePage(pNew); | 78622 | releasePage(pNew); |
| @@ -78713,7 +78852,9 @@ static int balance_nonroot( | |||
| 78713 | CellArray b; /* Parsed information on cells being balanced */ | 78852 | CellArray b; /* Parsed information on cells being balanced */ |
| 78714 | 78853 | ||
| 78715 | memset(abDone, 0, sizeof(abDone)); | 78854 | memset(abDone, 0, sizeof(abDone)); |
| 78716 | memset(&b, 0, sizeof(b)); | 78855 | assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); |
| 78856 | memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); | ||
| 78857 | b.ixNx[NB*2-1] = 0x7fffffff; | ||
| 78717 | pBt = pParent->pBt; | 78858 | pBt = pParent->pBt; |
| 78718 | assert( sqlite3_mutex_held(pBt->mutex) ); | 78859 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 78719 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); | 78860 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| @@ -79304,7 +79445,8 @@ static int balance_nonroot( | |||
| 79304 | iOvflSpace += sz; | 79445 | iOvflSpace += sz; |
| 79305 | assert( sz<=pBt->maxLocal+23 ); | 79446 | assert( sz<=pBt->maxLocal+23 ); |
| 79306 | assert( iOvflSpace <= (int)pBt->pageSize ); | 79447 | assert( iOvflSpace <= (int)pBt->pageSize ); |
| 79307 | for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){} | 79448 | assert( b.ixNx[NB*2-1]>j ); |
| 79449 | for(k=0; b.ixNx[k]<=j; k++){} | ||
| 79308 | pSrcEnd = b.apEnd[k]; | 79450 | pSrcEnd = b.apEnd[k]; |
| 79309 | if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ | 79451 | if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ |
| 79310 | rc = SQLITE_CORRUPT_BKPT; | 79452 | rc = SQLITE_CORRUPT_BKPT; |
| @@ -84316,7 +84458,8 @@ static int valueFromFunction( | |||
| 84316 | goto value_from_function_out; | 84458 | goto value_from_function_out; |
| 84317 | } | 84459 | } |
| 84318 | for(i=0; i<nVal; i++){ | 84460 | for(i=0; i<nVal; i++){ |
| 84319 | rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]); | 84461 | rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff, |
| 84462 | &apVal[i]); | ||
| 84320 | if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; | 84463 | if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; |
| 84321 | } | 84464 | } |
| 84322 | } | 84465 | } |
| @@ -86250,6 +86393,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ | |||
| 86250 | if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); | 86393 | if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); |
| 86251 | break; | 86394 | break; |
| 86252 | } | 86395 | } |
| 86396 | case P4_SUBRTNSIG: { | ||
| 86397 | SubrtnSig *pSig = (SubrtnSig*)p4; | ||
| 86398 | sqlite3DbFree(db, pSig->zAff); | ||
| 86399 | sqlite3DbFree(db, pSig); | ||
| 86400 | break; | ||
| 86401 | } | ||
| 86253 | } | 86402 | } |
| 86254 | } | 86403 | } |
| 86255 | 86404 | ||
| @@ -86829,6 +86978,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ | |||
| 86829 | zP4 = pOp->p4.pTab->zName; | 86978 | zP4 = pOp->p4.pTab->zName; |
| 86830 | break; | 86979 | break; |
| 86831 | } | 86980 | } |
| 86981 | case P4_SUBRTNSIG: { | ||
| 86982 | SubrtnSig *pSig = pOp->p4.pSubrtnSig; | ||
| 86983 | sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); | ||
| 86984 | break; | ||
| 86985 | } | ||
| 86832 | default: { | 86986 | default: { |
| 86833 | zP4 = pOp->p4.z; | 86987 | zP4 = pOp->p4.z; |
| 86834 | } | 86988 | } |
| @@ -89338,7 +89492,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem | |||
| 89338 | ** We must use separate SQLITE_NOINLINE functions here, since otherwise | 89492 | ** We must use separate SQLITE_NOINLINE functions here, since otherwise |
| 89339 | ** optimizer code movement causes gcov to become very confused. | 89493 | ** optimizer code movement causes gcov to become very confused. |
| 89340 | */ | 89494 | */ |
| 89341 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) | 89495 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) |
| 89342 | static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; } | 89496 | static int SQLITE_NOINLINE doubleLt(double a, double b){ return a<b; } |
| 89343 | static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; } | 89497 | static int SQLITE_NOINLINE doubleEq(double a, double b){ return a==b; } |
| 89344 | #endif | 89498 | #endif |
| @@ -89353,13 +89507,6 @@ SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ | |||
| 89353 | /* SQLite considers NaN to be a NULL. And all integer values are greater | 89507 | /* SQLite considers NaN to be a NULL. And all integer values are greater |
| 89354 | ** than NULL */ | 89508 | ** than NULL */ |
| 89355 | return 1; | 89509 | return 1; |
| 89356 | } | ||
| 89357 | if( sqlite3Config.bUseLongDouble ){ | ||
| 89358 | LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; | ||
| 89359 | testcase( x<r ); | ||
| 89360 | testcase( x>r ); | ||
| 89361 | testcase( x==r ); | ||
| 89362 | return (x<r) ? -1 : (x>r); | ||
| 89363 | }else{ | 89510 | }else{ |
| 89364 | i64 y; | 89511 | i64 y; |
| 89365 | if( r<-9223372036854775808.0 ) return +1; | 89512 | if( r<-9223372036854775808.0 ) return +1; |
| @@ -90369,6 +90516,13 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( | |||
| 90369 | } | 90516 | } |
| 90370 | sqlite3DbNNFreeNN(db, preupdate.aNew); | 90517 | sqlite3DbNNFreeNN(db, preupdate.aNew); |
| 90371 | } | 90518 | } |
| 90519 | if( preupdate.apDflt ){ | ||
| 90520 | int i; | ||
| 90521 | for(i=0; i<pTab->nCol; i++){ | ||
| 90522 | sqlite3ValueFree(preupdate.apDflt[i]); | ||
| 90523 | } | ||
| 90524 | sqlite3DbFree(db, preupdate.apDflt); | ||
| 90525 | } | ||
| 90372 | } | 90526 | } |
| 90373 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ | 90527 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ |
| 90374 | 90528 | ||
| @@ -91997,6 +92151,17 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ | |||
| 91997 | ** | 92151 | ** |
| 91998 | ** The error code stored in database p->db is overwritten with the return | 92152 | ** The error code stored in database p->db is overwritten with the return |
| 91999 | ** value in any case. | 92153 | ** value in any case. |
| 92154 | ** | ||
| 92155 | ** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, | ||
| 92156 | ** that means all of the the following will be true: | ||
| 92157 | ** | ||
| 92158 | ** p!=0 | ||
| 92159 | ** p->pVar!=0 | ||
| 92160 | ** i>0 | ||
| 92161 | ** i<=p->nVar | ||
| 92162 | ** | ||
| 92163 | ** An assert() is normally added after vdbeUnbind() to help static analyzers | ||
| 92164 | ** realize this. | ||
| 92000 | */ | 92165 | */ |
| 92001 | static int vdbeUnbind(Vdbe *p, unsigned int i){ | 92166 | static int vdbeUnbind(Vdbe *p, unsigned int i){ |
| 92002 | Mem *pVar; | 92167 | Mem *pVar; |
| @@ -92054,6 +92219,7 @@ static int bindText( | |||
| 92054 | 92219 | ||
| 92055 | rc = vdbeUnbind(p, (u32)(i-1)); | 92220 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92056 | if( rc==SQLITE_OK ){ | 92221 | if( rc==SQLITE_OK ){ |
| 92222 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92057 | if( zData!=0 ){ | 92223 | if( zData!=0 ){ |
| 92058 | pVar = &p->aVar[i-1]; | 92224 | pVar = &p->aVar[i-1]; |
| 92059 | rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); | 92225 | rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); |
| @@ -92103,6 +92269,7 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ | |||
| 92103 | Vdbe *p = (Vdbe *)pStmt; | 92269 | Vdbe *p = (Vdbe *)pStmt; |
| 92104 | rc = vdbeUnbind(p, (u32)(i-1)); | 92270 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92105 | if( rc==SQLITE_OK ){ | 92271 | if( rc==SQLITE_OK ){ |
| 92272 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92106 | sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); | 92273 | sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); |
| 92107 | sqlite3_mutex_leave(p->db->mutex); | 92274 | sqlite3_mutex_leave(p->db->mutex); |
| 92108 | } | 92275 | } |
| @@ -92116,6 +92283,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu | |||
| 92116 | Vdbe *p = (Vdbe *)pStmt; | 92283 | Vdbe *p = (Vdbe *)pStmt; |
| 92117 | rc = vdbeUnbind(p, (u32)(i-1)); | 92284 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92118 | if( rc==SQLITE_OK ){ | 92285 | if( rc==SQLITE_OK ){ |
| 92286 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92119 | sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); | 92287 | sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); |
| 92120 | sqlite3_mutex_leave(p->db->mutex); | 92288 | sqlite3_mutex_leave(p->db->mutex); |
| 92121 | } | 92289 | } |
| @@ -92126,6 +92294,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ | |||
| 92126 | Vdbe *p = (Vdbe*)pStmt; | 92294 | Vdbe *p = (Vdbe*)pStmt; |
| 92127 | rc = vdbeUnbind(p, (u32)(i-1)); | 92295 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92128 | if( rc==SQLITE_OK ){ | 92296 | if( rc==SQLITE_OK ){ |
| 92297 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92129 | sqlite3_mutex_leave(p->db->mutex); | 92298 | sqlite3_mutex_leave(p->db->mutex); |
| 92130 | } | 92299 | } |
| 92131 | return rc; | 92300 | return rc; |
| @@ -92141,6 +92310,7 @@ SQLITE_API int sqlite3_bind_pointer( | |||
| 92141 | Vdbe *p = (Vdbe*)pStmt; | 92310 | Vdbe *p = (Vdbe*)pStmt; |
| 92142 | rc = vdbeUnbind(p, (u32)(i-1)); | 92311 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92143 | if( rc==SQLITE_OK ){ | 92312 | if( rc==SQLITE_OK ){ |
| 92313 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92144 | sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); | 92314 | sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); |
| 92145 | sqlite3_mutex_leave(p->db->mutex); | 92315 | sqlite3_mutex_leave(p->db->mutex); |
| 92146 | }else if( xDestructor ){ | 92316 | }else if( xDestructor ){ |
| @@ -92222,6 +92392,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ | |||
| 92222 | Vdbe *p = (Vdbe *)pStmt; | 92392 | Vdbe *p = (Vdbe *)pStmt; |
| 92223 | rc = vdbeUnbind(p, (u32)(i-1)); | 92393 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 92224 | if( rc==SQLITE_OK ){ | 92394 | if( rc==SQLITE_OK ){ |
| 92395 | assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ | ||
| 92225 | #ifndef SQLITE_OMIT_INCRBLOB | 92396 | #ifndef SQLITE_OMIT_INCRBLOB |
| 92226 | sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); | 92397 | sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); |
| 92227 | #else | 92398 | #else |
| @@ -92581,7 +92752,30 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa | |||
| 92581 | if( iIdx==p->pTab->iPKey ){ | 92752 | if( iIdx==p->pTab->iPKey ){ |
| 92582 | sqlite3VdbeMemSetInt64(pMem, p->iKey1); | 92753 | sqlite3VdbeMemSetInt64(pMem, p->iKey1); |
| 92583 | }else if( iIdx>=p->pUnpacked->nField ){ | 92754 | }else if( iIdx>=p->pUnpacked->nField ){ |
| 92584 | *ppValue = (sqlite3_value *)columnNullValue(); | 92755 | /* This occurs when the table has been extended using ALTER TABLE |
| 92756 | ** ADD COLUMN. The value to return is the default value of the column. */ | ||
| 92757 | Column *pCol = &p->pTab->aCol[iIdx]; | ||
| 92758 | if( pCol->iDflt>0 ){ | ||
| 92759 | if( p->apDflt==0 ){ | ||
| 92760 | int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; | ||
| 92761 | p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); | ||
| 92762 | if( p->apDflt==0 ) goto preupdate_old_out; | ||
| 92763 | } | ||
| 92764 | if( p->apDflt[iIdx]==0 ){ | ||
| 92765 | sqlite3_value *pVal = 0; | ||
| 92766 | Expr *pDflt; | ||
| 92767 | assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); | ||
| 92768 | pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; | ||
| 92769 | rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); | ||
| 92770 | if( rc==SQLITE_OK && pVal==0 ){ | ||
| 92771 | rc = SQLITE_CORRUPT_BKPT; | ||
| 92772 | } | ||
| 92773 | p->apDflt[iIdx] = pVal; | ||
| 92774 | } | ||
| 92775 | *ppValue = p->apDflt[iIdx]; | ||
| 92776 | }else{ | ||
| 92777 | *ppValue = (sqlite3_value *)columnNullValue(); | ||
| 92778 | } | ||
| 92585 | }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ | 92779 | }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ |
| 92586 | if( pMem->flags & (MEM_Int|MEM_IntReal) ){ | 92780 | if( pMem->flags & (MEM_Int|MEM_IntReal) ){ |
| 92587 | testcase( pMem->flags & MEM_Int ); | 92781 | testcase( pMem->flags & MEM_Int ); |
| @@ -93135,6 +93329,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( | |||
| 93135 | /* #include "vdbeInt.h" */ | 93329 | /* #include "vdbeInt.h" */ |
| 93136 | 93330 | ||
| 93137 | /* | 93331 | /* |
| 93332 | ** High-resolution hardware timer used for debugging and testing only. | ||
| 93333 | */ | ||
| 93334 | #if defined(VDBE_PROFILE) \ | ||
| 93335 | || defined(SQLITE_PERFORMANCE_TRACE) \ | ||
| 93336 | || defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 93337 | /************** Include hwtime.h in the middle of vdbe.c *********************/ | ||
| 93338 | /************** Begin file hwtime.h ******************************************/ | ||
| 93339 | /* | ||
| 93340 | ** 2008 May 27 | ||
| 93341 | ** | ||
| 93342 | ** The author disclaims copyright to this source code. In place of | ||
| 93343 | ** a legal notice, here is a blessing: | ||
| 93344 | ** | ||
| 93345 | ** May you do good and not evil. | ||
| 93346 | ** May you find forgiveness for yourself and forgive others. | ||
| 93347 | ** May you share freely, never taking more than you give. | ||
| 93348 | ** | ||
| 93349 | ****************************************************************************** | ||
| 93350 | ** | ||
| 93351 | ** This file contains inline asm code for retrieving "high-performance" | ||
| 93352 | ** counters for x86 and x86_64 class CPUs. | ||
| 93353 | */ | ||
| 93354 | #ifndef SQLITE_HWTIME_H | ||
| 93355 | #define SQLITE_HWTIME_H | ||
| 93356 | |||
| 93357 | /* | ||
| 93358 | ** The following routine only works on Pentium-class (or newer) processors. | ||
| 93359 | ** It uses the RDTSC opcode to read the cycle count value out of the | ||
| 93360 | ** processor and returns that value. This can be used for high-res | ||
| 93361 | ** profiling. | ||
| 93362 | */ | ||
| 93363 | #if !defined(__STRICT_ANSI__) && \ | ||
| 93364 | (defined(__GNUC__) || defined(_MSC_VER)) && \ | ||
| 93365 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) | ||
| 93366 | |||
| 93367 | #if defined(__GNUC__) | ||
| 93368 | |||
| 93369 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 93370 | unsigned int lo, hi; | ||
| 93371 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 93372 | return (sqlite_uint64)hi << 32 | lo; | ||
| 93373 | } | ||
| 93374 | |||
| 93375 | #elif defined(_MSC_VER) | ||
| 93376 | |||
| 93377 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | ||
| 93378 | __asm { | ||
| 93379 | rdtsc | ||
| 93380 | ret ; return value at EDX:EAX | ||
| 93381 | } | ||
| 93382 | } | ||
| 93383 | |||
| 93384 | #endif | ||
| 93385 | |||
| 93386 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) | ||
| 93387 | |||
| 93388 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 93389 | unsigned int lo, hi; | ||
| 93390 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 93391 | return (sqlite_uint64)hi << 32 | lo; | ||
| 93392 | } | ||
| 93393 | |||
| 93394 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) | ||
| 93395 | |||
| 93396 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 93397 | unsigned long long retval; | ||
| 93398 | unsigned long junk; | ||
| 93399 | __asm__ __volatile__ ("\n\ | ||
| 93400 | 1: mftbu %1\n\ | ||
| 93401 | mftb %L0\n\ | ||
| 93402 | mftbu %0\n\ | ||
| 93403 | cmpw %0,%1\n\ | ||
| 93404 | bne 1b" | ||
| 93405 | : "=r" (retval), "=r" (junk)); | ||
| 93406 | return retval; | ||
| 93407 | } | ||
| 93408 | |||
| 93409 | #else | ||
| 93410 | |||
| 93411 | /* | ||
| 93412 | ** asm() is needed for hardware timing support. Without asm(), | ||
| 93413 | ** disable the sqlite3Hwtime() routine. | ||
| 93414 | ** | ||
| 93415 | ** sqlite3Hwtime() is only used for some obscure debugging | ||
| 93416 | ** and analysis configurations, not in any deliverable, so this | ||
| 93417 | ** should not be a great loss. | ||
| 93418 | */ | ||
| 93419 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | ||
| 93420 | |||
| 93421 | #endif | ||
| 93422 | |||
| 93423 | #endif /* !defined(SQLITE_HWTIME_H) */ | ||
| 93424 | |||
| 93425 | /************** End of hwtime.h **********************************************/ | ||
| 93426 | /************** Continuing where we left off in vdbe.c ***********************/ | ||
| 93427 | #endif | ||
| 93428 | |||
| 93429 | /* | ||
| 93138 | ** Invoke this macro on memory cells just prior to changing the | 93430 | ** Invoke this macro on memory cells just prior to changing the |
| 93139 | ** value of the cell. This macro verifies that shallow copies are | 93431 | ** value of the cell. This macro verifies that shallow copies are |
| 93140 | ** not misused. A shallow copy of a string or blob just copies a | 93432 | ** not misused. A shallow copy of a string or blob just copies a |
| @@ -94327,7 +94619,7 @@ case OP_HaltIfNull: { /* in3 */ | |||
| 94327 | /* no break */ deliberate_fall_through | 94619 | /* no break */ deliberate_fall_through |
| 94328 | } | 94620 | } |
| 94329 | 94621 | ||
| 94330 | /* Opcode: Halt P1 P2 * P4 P5 | 94622 | /* Opcode: Halt P1 P2 P3 P4 P5 |
| 94331 | ** | 94623 | ** |
| 94332 | ** Exit immediately. All open cursors, etc are closed | 94624 | ** Exit immediately. All open cursors, etc are closed |
| 94333 | ** automatically. | 94625 | ** automatically. |
| @@ -94340,18 +94632,22 @@ case OP_HaltIfNull: { /* in3 */ | |||
| 94340 | ** then back out all changes that have occurred during this execution of the | 94632 | ** then back out all changes that have occurred during this execution of the |
| 94341 | ** VDBE, but do not rollback the transaction. | 94633 | ** VDBE, but do not rollback the transaction. |
| 94342 | ** | 94634 | ** |
| 94343 | ** If P4 is not null then it is an error message string. | 94635 | ** If P3 is not zero and P4 is NULL, then P3 is a register that holds the |
| 94636 | ** text of an error message. | ||
| 94344 | ** | 94637 | ** |
| 94345 | ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. | 94638 | ** If P3 is zero and P4 is not null then the error message string is held |
| 94639 | ** in P4. | ||
| 94640 | ** | ||
| 94641 | ** P5 is a value between 1 and 4, inclusive, then the P4 error message | ||
| 94642 | ** string is modified as follows: | ||
| 94346 | ** | 94643 | ** |
| 94347 | ** 0: (no change) | ||
| 94348 | ** 1: NOT NULL constraint failed: P4 | 94644 | ** 1: NOT NULL constraint failed: P4 |
| 94349 | ** 2: UNIQUE constraint failed: P4 | 94645 | ** 2: UNIQUE constraint failed: P4 |
| 94350 | ** 3: CHECK constraint failed: P4 | 94646 | ** 3: CHECK constraint failed: P4 |
| 94351 | ** 4: FOREIGN KEY constraint failed: P4 | 94647 | ** 4: FOREIGN KEY constraint failed: P4 |
| 94352 | ** | 94648 | ** |
| 94353 | ** If P5 is not zero and P4 is NULL, then everything after the ":" is | 94649 | ** If P3 is zero and P5 is not zero and P4 is NULL, then everything after |
| 94354 | ** omitted. | 94650 | ** the ":" is omitted. |
| 94355 | ** | 94651 | ** |
| 94356 | ** There is an implied "Halt 0 0 0" instruction inserted at the very end of | 94652 | ** There is an implied "Halt 0 0 0" instruction inserted at the very end of |
| 94357 | ** every program. So a jump past the last instruction of the program | 94653 | ** every program. So a jump past the last instruction of the program |
| @@ -94364,6 +94660,9 @@ case OP_Halt: { | |||
| 94364 | #ifdef SQLITE_DEBUG | 94660 | #ifdef SQLITE_DEBUG |
| 94365 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } | 94661 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } |
| 94366 | #endif | 94662 | #endif |
| 94663 | assert( pOp->p4type==P4_NOTUSED | ||
| 94664 | || pOp->p4type==P4_STATIC | ||
| 94665 | || pOp->p4type==P4_DYNAMIC ); | ||
| 94367 | 94666 | ||
| 94368 | /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates | 94667 | /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates |
| 94369 | ** something is wrong with the code generator. Raise an assertion in order | 94668 | ** something is wrong with the code generator. Raise an assertion in order |
| @@ -94394,7 +94693,12 @@ case OP_Halt: { | |||
| 94394 | p->errorAction = (u8)pOp->p2; | 94693 | p->errorAction = (u8)pOp->p2; |
| 94395 | assert( pOp->p5<=4 ); | 94694 | assert( pOp->p5<=4 ); |
| 94396 | if( p->rc ){ | 94695 | if( p->rc ){ |
| 94397 | if( pOp->p5 ){ | 94696 | if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ |
| 94697 | const char *zErr; | ||
| 94698 | assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); | ||
| 94699 | zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); | ||
| 94700 | sqlite3VdbeError(p, "%s", zErr); | ||
| 94701 | }else if( pOp->p5 ){ | ||
| 94398 | static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", | 94702 | static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", |
| 94399 | "FOREIGN KEY" }; | 94703 | "FOREIGN KEY" }; |
| 94400 | testcase( pOp->p5==1 ); | 94704 | testcase( pOp->p5==1 ); |
| @@ -95197,7 +95501,7 @@ case OP_RealAffinity: { /* in1 */ | |||
| 95197 | } | 95501 | } |
| 95198 | #endif | 95502 | #endif |
| 95199 | 95503 | ||
| 95200 | #if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE) | 95504 | #if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) |
| 95201 | /* Opcode: Cast P1 P2 * * * | 95505 | /* Opcode: Cast P1 P2 * * * |
| 95202 | ** Synopsis: affinity(r[P1]) | 95506 | ** Synopsis: affinity(r[P1]) |
| 95203 | ** | 95507 | ** |
| @@ -97437,23 +97741,23 @@ case OP_OpenWrite: | |||
| 97437 | if( pDb->pSchema->file_format < p->minWriteFileFormat ){ | 97741 | if( pDb->pSchema->file_format < p->minWriteFileFormat ){ |
| 97438 | p->minWriteFileFormat = pDb->pSchema->file_format; | 97742 | p->minWriteFileFormat = pDb->pSchema->file_format; |
| 97439 | } | 97743 | } |
| 97744 | if( pOp->p5 & OPFLAG_P2ISREG ){ | ||
| 97745 | assert( p2>0 ); | ||
| 97746 | assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); | ||
| 97747 | pIn2 = &aMem[p2]; | ||
| 97748 | assert( memIsValid(pIn2) ); | ||
| 97749 | assert( (pIn2->flags & MEM_Int)!=0 ); | ||
| 97750 | sqlite3VdbeMemIntegerify(pIn2); | ||
| 97751 | p2 = (int)pIn2->u.i; | ||
| 97752 | /* The p2 value always comes from a prior OP_CreateBtree opcode and | ||
| 97753 | ** that opcode will always set the p2 value to 2 or more or else fail. | ||
| 97754 | ** If there were a failure, the prepared statement would have halted | ||
| 97755 | ** before reaching this instruction. */ | ||
| 97756 | assert( p2>=2 ); | ||
| 97757 | } | ||
| 97440 | }else{ | 97758 | }else{ |
| 97441 | wrFlag = 0; | 97759 | wrFlag = 0; |
| 97442 | } | 97760 | assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); |
| 97443 | if( pOp->p5 & OPFLAG_P2ISREG ){ | ||
| 97444 | assert( p2>0 ); | ||
| 97445 | assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); | ||
| 97446 | assert( pOp->opcode==OP_OpenWrite ); | ||
| 97447 | pIn2 = &aMem[p2]; | ||
| 97448 | assert( memIsValid(pIn2) ); | ||
| 97449 | assert( (pIn2->flags & MEM_Int)!=0 ); | ||
| 97450 | sqlite3VdbeMemIntegerify(pIn2); | ||
| 97451 | p2 = (int)pIn2->u.i; | ||
| 97452 | /* The p2 value always comes from a prior OP_CreateBtree opcode and | ||
| 97453 | ** that opcode will always set the p2 value to 2 or more or else fail. | ||
| 97454 | ** If there were a failure, the prepared statement would have halted | ||
| 97455 | ** before reaching this instruction. */ | ||
| 97456 | assert( p2>=2 ); | ||
| 97457 | } | 97761 | } |
| 97458 | if( pOp->p4type==P4_KEYINFO ){ | 97762 | if( pOp->p4type==P4_KEYINFO ){ |
| 97459 | pKeyInfo = pOp->p4.pKeyInfo; | 97763 | pKeyInfo = pOp->p4.pKeyInfo; |
| @@ -97631,7 +97935,10 @@ case OP_OpenEphemeral: { /* ncycle */ | |||
| 97631 | } | 97935 | } |
| 97632 | pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); | 97936 | pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 97633 | if( rc ){ | 97937 | if( rc ){ |
| 97938 | assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); | ||
| 97634 | sqlite3BtreeClose(pCx->ub.pBtx); | 97939 | sqlite3BtreeClose(pCx->ub.pBtx); |
| 97940 | }else{ | ||
| 97941 | assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); | ||
| 97635 | } | 97942 | } |
| 97636 | } | 97943 | } |
| 97637 | } | 97944 | } |
| @@ -98409,6 +98716,7 @@ case OP_Found: { /* jump, in3, ncycle */ | |||
| 98409 | r.pKeyInfo = pC->pKeyInfo; | 98716 | r.pKeyInfo = pC->pKeyInfo; |
| 98410 | r.default_rc = 0; | 98717 | r.default_rc = 0; |
| 98411 | #ifdef SQLITE_DEBUG | 98718 | #ifdef SQLITE_DEBUG |
| 98719 | (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ | ||
| 98412 | for(ii=0; ii<r.nField; ii++){ | 98720 | for(ii=0; ii<r.nField; ii++){ |
| 98413 | assert( memIsValid(&r.aMem[ii]) ); | 98721 | assert( memIsValid(&r.aMem[ii]) ); |
| 98414 | assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); | 98722 | assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); |
| @@ -100771,18 +101079,29 @@ case OP_AggInverse: | |||
| 100771 | case OP_AggStep: { | 101079 | case OP_AggStep: { |
| 100772 | int n; | 101080 | int n; |
| 100773 | sqlite3_context *pCtx; | 101081 | sqlite3_context *pCtx; |
| 101082 | u64 nAlloc; | ||
| 100774 | 101083 | ||
| 100775 | assert( pOp->p4type==P4_FUNCDEF ); | 101084 | assert( pOp->p4type==P4_FUNCDEF ); |
| 100776 | n = pOp->p5; | 101085 | n = pOp->p5; |
| 100777 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | 101086 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 100778 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); | 101087 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); |
| 100779 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); | 101088 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 100780 | pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + | 101089 | |
| 100781 | (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); | 101090 | /* Allocate space for (a) the context object and (n-1) extra pointers |
| 101091 | ** to append to the sqlite3_context.argv[1] array, and (b) a memory | ||
| 101092 | ** cell in which to store the accumulation. Be careful that the memory | ||
| 101093 | ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. | ||
| 101094 | ** | ||
| 101095 | ** Note: We could avoid this by using a regular memory cell from aMem[] for | ||
| 101096 | ** the accumulator, instead of allocating one here. */ | ||
| 101097 | nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); | ||
| 101098 | pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); | ||
| 100782 | if( pCtx==0 ) goto no_mem; | 101099 | if( pCtx==0 ) goto no_mem; |
| 100783 | pCtx->pMem = 0; | 101100 | pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); |
| 100784 | pCtx->pOut = (Mem*)&(pCtx->argv[n]); | 101101 | assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); |
| 101102 | |||
| 100785 | sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); | 101103 | sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); |
| 101104 | pCtx->pMem = 0; | ||
| 100786 | pCtx->pFunc = pOp->p4.pFunc; | 101105 | pCtx->pFunc = pOp->p4.pFunc; |
| 100787 | pCtx->iOp = (int)(pOp - aOp); | 101106 | pCtx->iOp = (int)(pOp - aOp); |
| 100788 | pCtx->pVdbe = p; | 101107 | pCtx->pVdbe = p; |
| @@ -102116,14 +102435,29 @@ case OP_ReleaseReg: { | |||
| 102116 | 102435 | ||
| 102117 | /* Opcode: Noop * * * * * | 102436 | /* Opcode: Noop * * * * * |
| 102118 | ** | 102437 | ** |
| 102119 | ** Do nothing. This instruction is often useful as a jump | 102438 | ** Do nothing. Continue downward to the next opcode. |
| 102120 | ** destination. | ||
| 102121 | */ | 102439 | */ |
| 102122 | /* | 102440 | /* Opcode: Explain P1 P2 P3 P4 * |
| 102123 | ** The magic Explain opcode are only inserted when explain==2 (which | 102441 | ** |
| 102124 | ** is to say when the EXPLAIN QUERY PLAN syntax is used.) | 102442 | ** This is the same as OP_Noop during normal query execution. The |
| 102125 | ** This opcode records information from the optimizer. It is the | 102443 | ** purpose of this opcode is to hold information about the query |
| 102126 | ** the same as a no-op. This opcodesnever appears in a real VM program. | 102444 | ** plan for the purpose of EXPLAIN QUERY PLAN output. |
| 102445 | ** | ||
| 102446 | ** The P4 value is human-readable text that describes the query plan | ||
| 102447 | ** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". | ||
| 102448 | ** | ||
| 102449 | ** The P1 value is the ID of the current element and P2 is the parent | ||
| 102450 | ** element for the case of nested query plan elements. If P2 is zero | ||
| 102451 | ** then this element is a top-level element. | ||
| 102452 | ** | ||
| 102453 | ** For loop elements, P3 is the estimated code of each invocation of this | ||
| 102454 | ** element. | ||
| 102455 | ** | ||
| 102456 | ** As with all opcodes, the meanings of the parameters for OP_Explain | ||
| 102457 | ** are subject to change from one release to the next. Applications | ||
| 102458 | ** should not attempt to interpret or use any of the information | ||
| 102459 | ** contained in the OP_Explain opcode. The information provided by this | ||
| 102460 | ** opcode is intended for testing and debugging use only. | ||
| 102127 | */ | 102461 | */ |
| 102128 | default: { /* This is really OP_Noop, OP_Explain */ | 102462 | default: { /* This is really OP_Noop, OP_Explain */ |
| 102129 | assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); | 102463 | assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); |
| @@ -102450,6 +102784,11 @@ SQLITE_API int sqlite3_blob_open( | |||
| 102450 | pTab = 0; | 102784 | pTab = 0; |
| 102451 | sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); | 102785 | sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); |
| 102452 | } | 102786 | } |
| 102787 | if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ | ||
| 102788 | pTab = 0; | ||
| 102789 | sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", | ||
| 102790 | zTable); | ||
| 102791 | } | ||
| 102453 | #ifndef SQLITE_OMIT_VIEW | 102792 | #ifndef SQLITE_OMIT_VIEW |
| 102454 | if( pTab && IsView(pTab) ){ | 102793 | if( pTab && IsView(pTab) ){ |
| 102455 | pTab = 0; | 102794 | pTab = 0; |
| @@ -103357,13 +103696,14 @@ static int vdbePmaReadBlob( | |||
| 103357 | while( nRem>0 ){ | 103696 | while( nRem>0 ){ |
| 103358 | int rc; /* vdbePmaReadBlob() return code */ | 103697 | int rc; /* vdbePmaReadBlob() return code */ |
| 103359 | int nCopy; /* Number of bytes to copy */ | 103698 | int nCopy; /* Number of bytes to copy */ |
| 103360 | u8 *aNext; /* Pointer to buffer to copy data from */ | 103699 | u8 *aNext = 0; /* Pointer to buffer to copy data from */ |
| 103361 | 103700 | ||
| 103362 | nCopy = nRem; | 103701 | nCopy = nRem; |
| 103363 | if( nRem>p->nBuffer ) nCopy = p->nBuffer; | 103702 | if( nRem>p->nBuffer ) nCopy = p->nBuffer; |
| 103364 | rc = vdbePmaReadBlob(p, nCopy, &aNext); | 103703 | rc = vdbePmaReadBlob(p, nCopy, &aNext); |
| 103365 | if( rc!=SQLITE_OK ) return rc; | 103704 | if( rc!=SQLITE_OK ) return rc; |
| 103366 | assert( aNext!=p->aAlloc ); | 103705 | assert( aNext!=p->aAlloc ); |
| 103706 | assert( aNext!=0 ); | ||
| 103367 | memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); | 103707 | memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); |
| 103368 | nRem -= nCopy; | 103708 | nRem -= nCopy; |
| 103369 | } | 103709 | } |
| @@ -106633,7 +106973,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ | |||
| 106633 | pSrc = p->pSrc; | 106973 | pSrc = p->pSrc; |
| 106634 | if( ALWAYS(pSrc) ){ | 106974 | if( ALWAYS(pSrc) ){ |
| 106635 | for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ | 106975 | for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ |
| 106636 | if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ | 106976 | if( pItem->fg.isSubquery |
| 106977 | && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) | ||
| 106978 | ){ | ||
| 106637 | return WRC_Abort; | 106979 | return WRC_Abort; |
| 106638 | } | 106980 | } |
| 106639 | if( pItem->fg.isTabFunc | 106981 | if( pItem->fg.isTabFunc |
| @@ -106939,7 +107281,7 @@ static void extendFJMatch( | |||
| 106939 | if( pNew ){ | 107281 | if( pNew ){ |
| 106940 | pNew->iTable = pMatch->iCursor; | 107282 | pNew->iTable = pMatch->iCursor; |
| 106941 | pNew->iColumn = iColumn; | 107283 | pNew->iColumn = iColumn; |
| 106942 | pNew->y.pTab = pMatch->pTab; | 107284 | pNew->y.pTab = pMatch->pSTab; |
| 106943 | assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); | 107285 | assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); |
| 106944 | ExprSetProperty(pNew, EP_CanBeNull); | 107286 | ExprSetProperty(pNew, EP_CanBeNull); |
| 106945 | *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); | 107287 | *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); |
| @@ -107070,10 +107412,10 @@ static int lookupName( | |||
| 107070 | if( pSrcList ){ | 107412 | if( pSrcList ){ |
| 107071 | for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ | 107413 | for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){ |
| 107072 | u8 hCol; | 107414 | u8 hCol; |
| 107073 | pTab = pItem->pTab; | 107415 | pTab = pItem->pSTab; |
| 107074 | assert( pTab!=0 && pTab->zName!=0 ); | 107416 | assert( pTab!=0 && pTab->zName!=0 ); |
| 107075 | assert( pTab->nCol>0 || pParse->nErr ); | 107417 | assert( pTab->nCol>0 || pParse->nErr ); |
| 107076 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); | 107418 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); |
| 107077 | if( pItem->fg.isNestedFrom ){ | 107419 | if( pItem->fg.isNestedFrom ){ |
| 107078 | /* In this case, pItem is a subquery that has been formed from a | 107420 | /* In this case, pItem is a subquery that has been formed from a |
| 107079 | ** parenthesized subset of the FROM clause terms. Example: | 107421 | ** parenthesized subset of the FROM clause terms. Example: |
| @@ -107082,8 +107424,12 @@ static int lookupName( | |||
| 107082 | ** This pItem -------------^ | 107424 | ** This pItem -------------^ |
| 107083 | */ | 107425 | */ |
| 107084 | int hit = 0; | 107426 | int hit = 0; |
| 107085 | assert( pItem->pSelect!=0 ); | 107427 | Select *pSel; |
| 107086 | pEList = pItem->pSelect->pEList; | 107428 | assert( pItem->fg.isSubquery ); |
| 107429 | assert( pItem->u4.pSubq!=0 ); | ||
| 107430 | pSel = pItem->u4.pSubq->pSelect; | ||
| 107431 | assert( pSel!=0 ); | ||
| 107432 | pEList = pSel->pEList; | ||
| 107087 | assert( pEList!=0 ); | 107433 | assert( pEList!=0 ); |
| 107088 | assert( pEList->nExpr==pTab->nCol ); | 107434 | assert( pEList->nExpr==pTab->nCol ); |
| 107089 | for(j=0; j<pEList->nExpr; j++){ | 107435 | for(j=0; j<pEList->nExpr; j++){ |
| @@ -107206,9 +107552,9 @@ static int lookupName( | |||
| 107206 | */ | 107552 | */ |
| 107207 | if( cntTab==0 | 107553 | if( cntTab==0 |
| 107208 | || (cntTab==1 | 107554 | || (cntTab==1 |
| 107209 | && ALWAYS(pMatch!=0) | 107555 | && pMatch!=0 |
| 107210 | && ALWAYS(pMatch->pTab!=0) | 107556 | && ALWAYS(pMatch->pSTab!=0) |
| 107211 | && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 | 107557 | && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 |
| 107212 | && (pTab->tabFlags & TF_Ephemeral)==0) | 107558 | && (pTab->tabFlags & TF_Ephemeral)==0) |
| 107213 | ){ | 107559 | ){ |
| 107214 | cntTab = 1; | 107560 | cntTab = 1; |
| @@ -107229,7 +107575,7 @@ static int lookupName( | |||
| 107229 | if( pMatch ){ | 107575 | if( pMatch ){ |
| 107230 | pExpr->iTable = pMatch->iCursor; | 107576 | pExpr->iTable = pMatch->iCursor; |
| 107231 | assert( ExprUseYTab(pExpr) ); | 107577 | assert( ExprUseYTab(pExpr) ); |
| 107232 | pExpr->y.pTab = pMatch->pTab; | 107578 | pExpr->y.pTab = pMatch->pSTab; |
| 107233 | if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ | 107579 | if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ |
| 107234 | ExprSetProperty(pExpr, EP_CanBeNull); | 107580 | ExprSetProperty(pExpr, EP_CanBeNull); |
| 107235 | } | 107581 | } |
| @@ -107271,7 +107617,7 @@ static int lookupName( | |||
| 107271 | if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ | 107617 | if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ |
| 107272 | Upsert *pUpsert = pNC->uNC.pUpsert; | 107618 | Upsert *pUpsert = pNC->uNC.pUpsert; |
| 107273 | if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ | 107619 | if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ |
| 107274 | pTab = pUpsert->pUpsertSrc->a[0].pTab; | 107620 | pTab = pUpsert->pUpsertSrc->a[0].pSTab; |
| 107275 | pExpr->iTable = EXCLUDED_TABLE_NUMBER; | 107621 | pExpr->iTable = EXCLUDED_TABLE_NUMBER; |
| 107276 | } | 107622 | } |
| 107277 | } | 107623 | } |
| @@ -107354,11 +107700,11 @@ static int lookupName( | |||
| 107354 | && pMatch | 107700 | && pMatch |
| 107355 | && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 | 107701 | && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 |
| 107356 | && sqlite3IsRowid(zCol) | 107702 | && sqlite3IsRowid(zCol) |
| 107357 | && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) | 107703 | && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) |
| 107358 | ){ | 107704 | ){ |
| 107359 | cnt = cntTab; | 107705 | cnt = cntTab; |
| 107360 | #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 | 107706 | #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 |
| 107361 | if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){ | 107707 | if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ |
| 107362 | eNewExprOp = TK_NULL; | 107708 | eNewExprOp = TK_NULL; |
| 107363 | } | 107709 | } |
| 107364 | #endif | 107710 | #endif |
| @@ -107595,7 +107941,7 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr | |||
| 107595 | SrcItem *pItem = &pSrc->a[iSrc]; | 107941 | SrcItem *pItem = &pSrc->a[iSrc]; |
| 107596 | Table *pTab; | 107942 | Table *pTab; |
| 107597 | assert( ExprUseYTab(p) ); | 107943 | assert( ExprUseYTab(p) ); |
| 107598 | pTab = p->y.pTab = pItem->pTab; | 107944 | pTab = p->y.pTab = pItem->pSTab; |
| 107599 | p->iTable = pItem->iCursor; | 107945 | p->iTable = pItem->iCursor; |
| 107600 | if( p->y.pTab->iPKey==iCol ){ | 107946 | if( p->y.pTab->iPKey==iCol ){ |
| 107601 | p->iColumn = -1; | 107947 | p->iColumn = -1; |
| @@ -107714,7 +108060,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 107714 | pItem = pSrcList->a; | 108060 | pItem = pSrcList->a; |
| 107715 | pExpr->op = TK_COLUMN; | 108061 | pExpr->op = TK_COLUMN; |
| 107716 | assert( ExprUseYTab(pExpr) ); | 108062 | assert( ExprUseYTab(pExpr) ); |
| 107717 | pExpr->y.pTab = pItem->pTab; | 108063 | pExpr->y.pTab = pItem->pSTab; |
| 107718 | pExpr->iTable = pItem->iCursor; | 108064 | pExpr->iTable = pItem->iCursor; |
| 107719 | pExpr->iColumn--; | 108065 | pExpr->iColumn--; |
| 107720 | pExpr->affExpr = SQLITE_AFF_INTEGER; | 108066 | pExpr->affExpr = SQLITE_AFF_INTEGER; |
| @@ -107839,8 +108185,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 107839 | /* Resolve function names | 108185 | /* Resolve function names |
| 107840 | */ | 108186 | */ |
| 107841 | case TK_FUNCTION: { | 108187 | case TK_FUNCTION: { |
| 107842 | ExprList *pList = pExpr->x.pList; /* The argument list */ | 108188 | ExprList *pList; /* The argument list */ |
| 107843 | int n = pList ? pList->nExpr : 0; /* Number of arguments */ | 108189 | int n; /* Number of arguments */ |
| 107844 | int no_such_func = 0; /* True if no such function exists */ | 108190 | int no_such_func = 0; /* True if no such function exists */ |
| 107845 | int wrong_num_args = 0; /* True if wrong number of arguments */ | 108191 | int wrong_num_args = 0; /* True if wrong number of arguments */ |
| 107846 | int is_agg = 0; /* True if is an aggregate function */ | 108192 | int is_agg = 0; /* True if is an aggregate function */ |
| @@ -107853,6 +108199,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 107853 | #endif | 108199 | #endif |
| 107854 | assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); | 108200 | assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); |
| 107855 | assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); | 108201 | assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); |
| 108202 | pList = pExpr->x.pList; | ||
| 108203 | n = pList ? pList->nExpr : 0; | ||
| 107856 | zId = pExpr->u.zToken; | 108204 | zId = pExpr->u.zToken; |
| 107857 | pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); | 108205 | pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); |
| 107858 | if( pDef==0 ){ | 108206 | if( pDef==0 ){ |
| @@ -107901,6 +108249,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 107901 | } | 108249 | } |
| 107902 | } | 108250 | } |
| 107903 | #endif | 108251 | #endif |
| 108252 | |||
| 108253 | /* If the function may call sqlite3_value_subtype(), then set the | ||
| 108254 | ** EP_SubtArg flag on all of its argument expressions. This prevents | ||
| 108255 | ** where.c from replacing the expression with a value read from an | ||
| 108256 | ** index on the same expression, which will not have the correct | ||
| 108257 | ** subtype. Also set the flag if the function expression itself is | ||
| 108258 | ** an EP_SubtArg expression. In this case subtypes are required as | ||
| 108259 | ** the function may return a value with a subtype back to its | ||
| 108260 | ** caller using sqlite3_result_value(). */ | ||
| 108261 | if( (pDef->funcFlags & SQLITE_SUBTYPE) | ||
| 108262 | || ExprHasProperty(pExpr, EP_SubtArg) | ||
| 108263 | ){ | ||
| 108264 | int ii; | ||
| 108265 | for(ii=0; ii<n; ii++){ | ||
| 108266 | ExprSetProperty(pList->a[ii].pExpr, EP_SubtArg); | ||
| 108267 | } | ||
| 108268 | } | ||
| 108269 | |||
| 107904 | if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ | 108270 | if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ |
| 107905 | /* For the purposes of the EP_ConstFunc flag, date and time | 108271 | /* For the purposes of the EP_ConstFunc flag, date and time |
| 107906 | ** functions and other functions that change slowly are considered | 108272 | ** functions and other functions that change slowly are considered |
| @@ -108020,9 +108386,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 108020 | sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); | 108386 | sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); |
| 108021 | } | 108387 | } |
| 108022 | #ifndef SQLITE_OMIT_WINDOWFUNC | 108388 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 108023 | if( pWin ){ | 108389 | if( pWin && pParse->nErr==0 ){ |
| 108024 | Select *pSel = pNC->pWinSelect; | 108390 | Select *pSel = pNC->pWinSelect; |
| 108025 | assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); | 108391 | assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); |
| 108026 | if( IN_RENAME_OBJECT==0 ){ | 108392 | if( IN_RENAME_OBJECT==0 ){ |
| 108027 | sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); | 108393 | sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); |
| 108028 | if( pParse->db->mallocFailed ) break; | 108394 | if( pParse->db->mallocFailed ) break; |
| @@ -108229,7 +108595,7 @@ static int resolveOrderByTermToExprList( | |||
| 108229 | int rc; /* Return code from subprocedures */ | 108595 | int rc; /* Return code from subprocedures */ |
| 108230 | u8 savedSuppErr; /* Saved value of db->suppressErr */ | 108596 | u8 savedSuppErr; /* Saved value of db->suppressErr */ |
| 108231 | 108597 | ||
| 108232 | assert( sqlite3ExprIsInteger(pE, &i)==0 ); | 108598 | assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); |
| 108233 | pEList = pSelect->pEList; | 108599 | pEList = pSelect->pEList; |
| 108234 | 108600 | ||
| 108235 | /* Resolve all names in the ORDER BY term expression | 108601 | /* Resolve all names in the ORDER BY term expression |
| @@ -108328,7 +108694,7 @@ static int resolveCompoundOrderBy( | |||
| 108328 | if( pItem->fg.done ) continue; | 108694 | if( pItem->fg.done ) continue; |
| 108329 | pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); | 108695 | pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); |
| 108330 | if( NEVER(pE==0) ) continue; | 108696 | if( NEVER(pE==0) ) continue; |
| 108331 | if( sqlite3ExprIsInteger(pE, &iCol) ){ | 108697 | if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ |
| 108332 | if( iCol<=0 || iCol>pEList->nExpr ){ | 108698 | if( iCol<=0 || iCol>pEList->nExpr ){ |
| 108333 | resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); | 108699 | resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); |
| 108334 | return 1; | 108700 | return 1; |
| @@ -108513,7 +108879,7 @@ static int resolveOrderGroupBy( | |||
| 108513 | continue; | 108879 | continue; |
| 108514 | } | 108880 | } |
| 108515 | } | 108881 | } |
| 108516 | if( sqlite3ExprIsInteger(pE2, &iCol) ){ | 108882 | if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ |
| 108517 | /* The ORDER BY term is an integer constant. Again, set the column | 108883 | /* The ORDER BY term is an integer constant. Again, set the column |
| 108518 | ** number so that sqlite3ResolveOrderGroupBy() will convert the | 108884 | ** number so that sqlite3ResolveOrderGroupBy() will convert the |
| 108519 | ** order-by term to a copy of the result-set expression */ | 108885 | ** order-by term to a copy of the result-set expression */ |
| @@ -108604,7 +108970,11 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 108604 | ** moves the pOrderBy down to the sub-query. It will be moved back | 108970 | ** moves the pOrderBy down to the sub-query. It will be moved back |
| 108605 | ** after the names have been resolved. */ | 108971 | ** after the names have been resolved. */ |
| 108606 | if( p->selFlags & SF_Converted ){ | 108972 | if( p->selFlags & SF_Converted ){ |
| 108607 | Select *pSub = p->pSrc->a[0].pSelect; | 108973 | Select *pSub; |
| 108974 | assert( p->pSrc->a[0].fg.isSubquery ); | ||
| 108975 | assert( p->pSrc->a[0].u4.pSubq!=0 ); | ||
| 108976 | pSub = p->pSrc->a[0].u4.pSubq->pSelect; | ||
| 108977 | assert( pSub!=0 ); | ||
| 108608 | assert( p->pSrc->nSrc==1 && p->pOrderBy ); | 108978 | assert( p->pSrc->nSrc==1 && p->pOrderBy ); |
| 108609 | assert( pSub->pPrior && pSub->pOrderBy==0 ); | 108979 | assert( pSub->pPrior && pSub->pOrderBy==0 ); |
| 108610 | pSub->pOrderBy = p->pOrderBy; | 108980 | pSub->pOrderBy = p->pOrderBy; |
| @@ -108616,13 +108986,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 108616 | if( pOuterNC ) pOuterNC->nNestedSelect++; | 108986 | if( pOuterNC ) pOuterNC->nNestedSelect++; |
| 108617 | for(i=0; i<p->pSrc->nSrc; i++){ | 108987 | for(i=0; i<p->pSrc->nSrc; i++){ |
| 108618 | SrcItem *pItem = &p->pSrc->a[i]; | 108988 | SrcItem *pItem = &p->pSrc->a[i]; |
| 108619 | assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/ | 108989 | assert( pItem->zName!=0 |
| 108620 | if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ | 108990 | || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ |
| 108991 | if( pItem->fg.isSubquery | ||
| 108992 | && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 | ||
| 108993 | ){ | ||
| 108621 | int nRef = pOuterNC ? pOuterNC->nRef : 0; | 108994 | int nRef = pOuterNC ? pOuterNC->nRef : 0; |
| 108622 | const char *zSavedContext = pParse->zAuthContext; | 108995 | const char *zSavedContext = pParse->zAuthContext; |
| 108623 | 108996 | ||
| 108624 | if( pItem->zName ) pParse->zAuthContext = pItem->zName; | 108997 | if( pItem->zName ) pParse->zAuthContext = pItem->zName; |
| 108625 | sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); | 108998 | sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); |
| 108626 | pParse->zAuthContext = zSavedContext; | 108999 | pParse->zAuthContext = zSavedContext; |
| 108627 | if( pParse->nErr ) return WRC_Abort; | 109000 | if( pParse->nErr ) return WRC_Abort; |
| 108628 | assert( db->mallocFailed==0 ); | 109001 | assert( db->mallocFailed==0 ); |
| @@ -108724,7 +109097,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 108724 | ** These integers will be replaced by copies of the corresponding result | 109097 | ** These integers will be replaced by copies of the corresponding result |
| 108725 | ** set expressions by the call to resolveOrderGroupBy() below. */ | 109098 | ** set expressions by the call to resolveOrderGroupBy() below. */ |
| 108726 | if( p->selFlags & SF_Converted ){ | 109099 | if( p->selFlags & SF_Converted ){ |
| 108727 | Select *pSub = p->pSrc->a[0].pSelect; | 109100 | Select *pSub; |
| 109101 | assert( p->pSrc->a[0].fg.isSubquery ); | ||
| 109102 | pSub = p->pSrc->a[0].u4.pSubq->pSelect; | ||
| 109103 | assert( pSub!=0 ); | ||
| 108728 | p->pOrderBy = pSub->pOrderBy; | 109104 | p->pOrderBy = pSub->pOrderBy; |
| 108729 | pSub->pOrderBy = 0; | 109105 | pSub->pOrderBy = 0; |
| 108730 | } | 109106 | } |
| @@ -108991,7 +109367,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( | |||
| 108991 | if( pTab ){ | 109367 | if( pTab ){ |
| 108992 | sSrc.nSrc = 1; | 109368 | sSrc.nSrc = 1; |
| 108993 | sSrc.a[0].zName = pTab->zName; | 109369 | sSrc.a[0].zName = pTab->zName; |
| 108994 | sSrc.a[0].pTab = pTab; | 109370 | sSrc.a[0].pSTab = pTab; |
| 108995 | sSrc.a[0].iCursor = -1; | 109371 | sSrc.a[0].iCursor = -1; |
| 108996 | if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ | 109372 | if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ |
| 108997 | /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP | 109373 | /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP |
| @@ -109096,7 +109472,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ | |||
| 109096 | op = pExpr->op; | 109472 | op = pExpr->op; |
| 109097 | continue; | 109473 | continue; |
| 109098 | } | 109474 | } |
| 109099 | if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; | 109475 | if( op!=TK_REGISTER ) break; |
| 109476 | op = pExpr->op2; | ||
| 109477 | if( NEVER( op==TK_REGISTER ) ) break; | ||
| 109100 | } | 109478 | } |
| 109101 | return pExpr->affExpr; | 109479 | return pExpr->affExpr; |
| 109102 | } | 109480 | } |
| @@ -110886,15 +111264,30 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla | |||
| 110886 | SrcItem *pNewItem = &pNew->a[i]; | 111264 | SrcItem *pNewItem = &pNew->a[i]; |
| 110887 | const SrcItem *pOldItem = &p->a[i]; | 111265 | const SrcItem *pOldItem = &p->a[i]; |
| 110888 | Table *pTab; | 111266 | Table *pTab; |
| 110889 | pNewItem->pSchema = pOldItem->pSchema; | 111267 | pNewItem->fg = pOldItem->fg; |
| 110890 | pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); | 111268 | if( pOldItem->fg.isSubquery ){ |
| 111269 | Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); | ||
| 111270 | if( pNewSubq==0 ){ | ||
| 111271 | assert( db->mallocFailed ); | ||
| 111272 | pNewItem->fg.isSubquery = 0; | ||
| 111273 | }else{ | ||
| 111274 | memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); | ||
| 111275 | pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); | ||
| 111276 | if( pNewSubq->pSelect==0 ){ | ||
| 111277 | sqlite3DbFree(db, pNewSubq); | ||
| 111278 | pNewSubq = 0; | ||
| 111279 | pNewItem->fg.isSubquery = 0; | ||
| 111280 | } | ||
| 111281 | } | ||
| 111282 | pNewItem->u4.pSubq = pNewSubq; | ||
| 111283 | }else if( pOldItem->fg.fixedSchema ){ | ||
| 111284 | pNewItem->u4.pSchema = pOldItem->u4.pSchema; | ||
| 111285 | }else{ | ||
| 111286 | pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); | ||
| 111287 | } | ||
| 110891 | pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); | 111288 | pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 110892 | pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); | 111289 | pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); |
| 110893 | pNewItem->fg = pOldItem->fg; | ||
| 110894 | pNewItem->iCursor = pOldItem->iCursor; | 111290 | pNewItem->iCursor = pOldItem->iCursor; |
| 110895 | pNewItem->addrFillSub = pOldItem->addrFillSub; | ||
| 110896 | pNewItem->regReturn = pOldItem->regReturn; | ||
| 110897 | pNewItem->regResult = pOldItem->regResult; | ||
| 110898 | if( pNewItem->fg.isIndexedBy ){ | 111291 | if( pNewItem->fg.isIndexedBy ){ |
| 110899 | pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); | 111292 | pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); |
| 110900 | }else if( pNewItem->fg.isTabFunc ){ | 111293 | }else if( pNewItem->fg.isTabFunc ){ |
| @@ -110907,11 +111300,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla | |||
| 110907 | if( pNewItem->fg.isCte ){ | 111300 | if( pNewItem->fg.isCte ){ |
| 110908 | pNewItem->u2.pCteUse->nUse++; | 111301 | pNewItem->u2.pCteUse->nUse++; |
| 110909 | } | 111302 | } |
| 110910 | pTab = pNewItem->pTab = pOldItem->pTab; | 111303 | pTab = pNewItem->pSTab = pOldItem->pSTab; |
| 110911 | if( pTab ){ | 111304 | if( pTab ){ |
| 110912 | pTab->nTabRef++; | 111305 | pTab->nTabRef++; |
| 110913 | } | 111306 | } |
| 110914 | pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); | ||
| 110915 | if( pOldItem->fg.isUsing ){ | 111307 | if( pOldItem->fg.isUsing ){ |
| 110916 | assert( pNewItem->fg.isUsing ); | 111308 | assert( pNewItem->fg.isUsing ); |
| 110917 | pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); | 111309 | pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); |
| @@ -110985,7 +111377,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla | |||
| 110985 | pp = &pNew->pPrior; | 111377 | pp = &pNew->pPrior; |
| 110986 | pNext = pNew; | 111378 | pNext = pNew; |
| 110987 | } | 111379 | } |
| 110988 | |||
| 110989 | return pRet; | 111380 | return pRet; |
| 110990 | } | 111381 | } |
| 110991 | #else | 111382 | #else |
| @@ -111800,8 +112191,12 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ | |||
| 111800 | ** to fit in a 32-bit integer, return 1 and put the value of the integer | 112191 | ** to fit in a 32-bit integer, return 1 and put the value of the integer |
| 111801 | ** in *pValue. If the expression is not an integer or if it is too big | 112192 | ** in *pValue. If the expression is not an integer or if it is too big |
| 111802 | ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. | 112193 | ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. |
| 112194 | ** | ||
| 112195 | ** If the pParse pointer is provided, then allow the expression p to be | ||
| 112196 | ** a parameter (TK_VARIABLE) that is bound to an integer. | ||
| 112197 | ** But if pParse is NULL, then p must be a pure integer literal. | ||
| 111803 | */ | 112198 | */ |
| 111804 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ | 112199 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ |
| 111805 | int rc = 0; | 112200 | int rc = 0; |
| 111806 | if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ | 112201 | if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ |
| 111807 | 112202 | ||
| @@ -111816,18 +112211,38 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ | |||
| 111816 | } | 112211 | } |
| 111817 | switch( p->op ){ | 112212 | switch( p->op ){ |
| 111818 | case TK_UPLUS: { | 112213 | case TK_UPLUS: { |
| 111819 | rc = sqlite3ExprIsInteger(p->pLeft, pValue); | 112214 | rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); |
| 111820 | break; | 112215 | break; |
| 111821 | } | 112216 | } |
| 111822 | case TK_UMINUS: { | 112217 | case TK_UMINUS: { |
| 111823 | int v = 0; | 112218 | int v = 0; |
| 111824 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ | 112219 | if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ |
| 111825 | assert( ((unsigned int)v)!=0x80000000 ); | 112220 | assert( ((unsigned int)v)!=0x80000000 ); |
| 111826 | *pValue = -v; | 112221 | *pValue = -v; |
| 111827 | rc = 1; | 112222 | rc = 1; |
| 111828 | } | 112223 | } |
| 111829 | break; | 112224 | break; |
| 111830 | } | 112225 | } |
| 112226 | case TK_VARIABLE: { | ||
| 112227 | sqlite3_value *pVal; | ||
| 112228 | if( pParse==0 ) break; | ||
| 112229 | if( NEVER(pParse->pVdbe==0) ) break; | ||
| 112230 | if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; | ||
| 112231 | sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); | ||
| 112232 | pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, | ||
| 112233 | SQLITE_AFF_BLOB); | ||
| 112234 | if( pVal ){ | ||
| 112235 | if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ | ||
| 112236 | sqlite3_int64 vv = sqlite3_value_int64(pVal); | ||
| 112237 | if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ | ||
| 112238 | *pValue = (int)vv; | ||
| 112239 | rc = 1; | ||
| 112240 | } | ||
| 112241 | } | ||
| 112242 | sqlite3ValueFree(pVal); | ||
| 112243 | } | ||
| 112244 | break; | ||
| 112245 | } | ||
| 111831 | default: break; | 112246 | default: break; |
| 111832 | } | 112247 | } |
| 111833 | return rc; | 112248 | return rc; |
| @@ -111981,8 +112396,8 @@ static Select *isCandidateForInOpt(const Expr *pX){ | |||
| 111981 | pSrc = p->pSrc; | 112396 | pSrc = p->pSrc; |
| 111982 | assert( pSrc!=0 ); | 112397 | assert( pSrc!=0 ); |
| 111983 | if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ | 112398 | if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ |
| 111984 | if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ | 112399 | if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ |
| 111985 | pTab = pSrc->a[0].pTab; | 112400 | pTab = pSrc->a[0].pSTab; |
| 111986 | assert( pTab!=0 ); | 112401 | assert( pTab!=0 ); |
| 111987 | assert( !IsView(pTab) ); /* FROM clause is not a view */ | 112402 | assert( !IsView(pTab) ); /* FROM clause is not a view */ |
| 111988 | if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ | 112403 | if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ |
| @@ -112165,7 +112580,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( | |||
| 112165 | assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ | 112580 | assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ |
| 112166 | assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ | 112581 | assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ |
| 112167 | assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ | 112582 | assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ |
| 112168 | pTab = p->pSrc->a[0].pTab; | 112583 | pTab = p->pSrc->a[0].pSTab; |
| 112169 | 112584 | ||
| 112170 | /* Code an OP_Transaction and OP_TableLock for <table>. */ | 112585 | /* Code an OP_Transaction and OP_TableLock for <table>. */ |
| 112171 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 112586 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| @@ -112407,6 +112822,49 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ | |||
| 112407 | 112822 | ||
| 112408 | #ifndef SQLITE_OMIT_SUBQUERY | 112823 | #ifndef SQLITE_OMIT_SUBQUERY |
| 112409 | /* | 112824 | /* |
| 112825 | ** Scan all previously generated bytecode looking for an OP_BeginSubrtn | ||
| 112826 | ** that is compatible with pExpr. If found, add the y.sub values | ||
| 112827 | ** to pExpr and return true. If not found, return false. | ||
| 112828 | */ | ||
| 112829 | static int findCompatibleInRhsSubrtn( | ||
| 112830 | Parse *pParse, /* Parsing context */ | ||
| 112831 | Expr *pExpr, /* IN operator with RHS that we want to reuse */ | ||
| 112832 | SubrtnSig *pNewSig /* Signature for the IN operator */ | ||
| 112833 | ){ | ||
| 112834 | VdbeOp *pOp, *pEnd; | ||
| 112835 | SubrtnSig *pSig; | ||
| 112836 | Vdbe *v; | ||
| 112837 | |||
| 112838 | if( pNewSig==0 ) return 0; | ||
| 112839 | if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; | ||
| 112840 | assert( pExpr->op==TK_IN ); | ||
| 112841 | assert( !ExprUseYSub(pExpr) ); | ||
| 112842 | assert( ExprUseXSelect(pExpr) ); | ||
| 112843 | assert( pExpr->x.pSelect!=0 ); | ||
| 112844 | assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); | ||
| 112845 | v = pParse->pVdbe; | ||
| 112846 | assert( v!=0 ); | ||
| 112847 | pOp = sqlite3VdbeGetOp(v, 1); | ||
| 112848 | pEnd = sqlite3VdbeGetLastOp(v); | ||
| 112849 | for(; pOp<pEnd; pOp++){ | ||
| 112850 | if( pOp->p4type!=P4_SUBRTNSIG ) continue; | ||
| 112851 | assert( pOp->opcode==OP_BeginSubrtn ); | ||
| 112852 | pSig = pOp->p4.pSubrtnSig; | ||
| 112853 | assert( pSig!=0 ); | ||
| 112854 | if( pNewSig->selId!=pSig->selId ) continue; | ||
| 112855 | if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; | ||
| 112856 | pExpr->y.sub.iAddr = pSig->iAddr; | ||
| 112857 | pExpr->y.sub.regReturn = pSig->regReturn; | ||
| 112858 | pExpr->iTable = pSig->iTable; | ||
| 112859 | ExprSetProperty(pExpr, EP_Subrtn); | ||
| 112860 | return 1; | ||
| 112861 | } | ||
| 112862 | return 0; | ||
| 112863 | } | ||
| 112864 | #endif /* SQLITE_OMIT_SUBQUERY */ | ||
| 112865 | |||
| 112866 | #ifndef SQLITE_OMIT_SUBQUERY | ||
| 112867 | /* | ||
| 112410 | ** Generate code that will construct an ephemeral table containing all terms | 112868 | ** Generate code that will construct an ephemeral table containing all terms |
| 112411 | ** in the RHS of an IN operator. The IN operator can be in either of two | 112869 | ** in the RHS of an IN operator. The IN operator can be in either of two |
| 112412 | ** forms: | 112870 | ** forms: |
| @@ -112454,11 +112912,28 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 112454 | ** and reuse it many names. | 112912 | ** and reuse it many names. |
| 112455 | */ | 112913 | */ |
| 112456 | if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ | 112914 | if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ |
| 112457 | /* Reuse of the RHS is allowed */ | 112915 | /* Reuse of the RHS is allowed |
| 112458 | /* If this routine has already been coded, but the previous code | 112916 | ** |
| 112459 | ** might not have been invoked yet, so invoke it now as a subroutine. | 112917 | ** Compute a signature for the RHS of the IN operator to facility |
| 112918 | ** finding and reusing prior instances of the same IN operator. | ||
| 112460 | */ | 112919 | */ |
| 112461 | if( ExprHasProperty(pExpr, EP_Subrtn) ){ | 112920 | SubrtnSig *pSig = 0; |
| 112921 | assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); | ||
| 112922 | if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ | ||
| 112923 | pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); | ||
| 112924 | if( pSig ){ | ||
| 112925 | pSig->selId = pExpr->x.pSelect->selId; | ||
| 112926 | pSig->zAff = exprINAffinity(pParse, pExpr); | ||
| 112927 | } | ||
| 112928 | } | ||
| 112929 | |||
| 112930 | /* Check to see if there is a prior materialization of the RHS of | ||
| 112931 | ** this IN operator. If there is, then make use of that prior | ||
| 112932 | ** materialization rather than recomputing it. | ||
| 112933 | */ | ||
| 112934 | if( ExprHasProperty(pExpr, EP_Subrtn) | ||
| 112935 | || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) | ||
| 112936 | ){ | ||
| 112462 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | 112937 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 112463 | if( ExprUseXSelect(pExpr) ){ | 112938 | if( ExprUseXSelect(pExpr) ){ |
| 112464 | ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", | 112939 | ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", |
| @@ -112470,6 +112945,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 112470 | assert( iTab!=pExpr->iTable ); | 112945 | assert( iTab!=pExpr->iTable ); |
| 112471 | sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); | 112946 | sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); |
| 112472 | sqlite3VdbeJumpHere(v, addrOnce); | 112947 | sqlite3VdbeJumpHere(v, addrOnce); |
| 112948 | if( pSig ){ | ||
| 112949 | sqlite3DbFree(pParse->db, pSig->zAff); | ||
| 112950 | sqlite3DbFree(pParse->db, pSig); | ||
| 112951 | } | ||
| 112473 | return; | 112952 | return; |
| 112474 | } | 112953 | } |
| 112475 | 112954 | ||
| @@ -112480,7 +112959,13 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 112480 | pExpr->y.sub.regReturn = ++pParse->nMem; | 112959 | pExpr->y.sub.regReturn = ++pParse->nMem; |
| 112481 | pExpr->y.sub.iAddr = | 112960 | pExpr->y.sub.iAddr = |
| 112482 | sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; | 112961 | sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; |
| 112483 | 112962 | if( pSig ){ | |
| 112963 | pSig->iAddr = pExpr->y.sub.iAddr; | ||
| 112964 | pSig->regReturn = pExpr->y.sub.regReturn; | ||
| 112965 | pSig->iTable = iTab; | ||
| 112966 | pParse->mSubrtnSig = 1 << (pSig->selId&7); | ||
| 112967 | sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); | ||
| 112968 | } | ||
| 112484 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | 112969 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 112485 | } | 112970 | } |
| 112486 | 112971 | ||
| @@ -112521,15 +113006,30 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 112521 | SelectDest dest; | 113006 | SelectDest dest; |
| 112522 | int i; | 113007 | int i; |
| 112523 | int rc; | 113008 | int rc; |
| 113009 | int addrBloom = 0; | ||
| 112524 | sqlite3SelectDestInit(&dest, SRT_Set, iTab); | 113010 | sqlite3SelectDestInit(&dest, SRT_Set, iTab); |
| 112525 | dest.zAffSdst = exprINAffinity(pParse, pExpr); | 113011 | dest.zAffSdst = exprINAffinity(pParse, pExpr); |
| 112526 | pSelect->iLimit = 0; | 113012 | pSelect->iLimit = 0; |
| 113013 | if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ | ||
| 113014 | int regBloom = ++pParse->nMem; | ||
| 113015 | addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); | ||
| 113016 | VdbeComment((v, "Bloom filter")); | ||
| 113017 | dest.iSDParm2 = regBloom; | ||
| 113018 | } | ||
| 112527 | testcase( pSelect->selFlags & SF_Distinct ); | 113019 | testcase( pSelect->selFlags & SF_Distinct ); |
| 112528 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ | 113020 | testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ |
| 112529 | pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); | 113021 | pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); |
| 112530 | rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); | 113022 | rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); |
| 112531 | sqlite3SelectDelete(pParse->db, pCopy); | 113023 | sqlite3SelectDelete(pParse->db, pCopy); |
| 112532 | sqlite3DbFree(pParse->db, dest.zAffSdst); | 113024 | sqlite3DbFree(pParse->db, dest.zAffSdst); |
| 113025 | if( addrBloom ){ | ||
| 113026 | sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; | ||
| 113027 | if( dest.iSDParm2==0 ){ | ||
| 113028 | sqlite3VdbeChangeToNoop(v, addrBloom); | ||
| 113029 | }else{ | ||
| 113030 | sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; | ||
| 113031 | } | ||
| 113032 | } | ||
| 112533 | if( rc ){ | 113033 | if( rc ){ |
| 112534 | sqlite3KeyInfoUnref(pKeyInfo); | 113034 | sqlite3KeyInfoUnref(pKeyInfo); |
| 112535 | return; | 113035 | return; |
| @@ -112827,9 +113327,7 @@ static void sqlite3ExprCodeIN( | |||
| 112827 | if( sqlite3ExprCheckIN(pParse, pExpr) ) return; | 113327 | if( sqlite3ExprCheckIN(pParse, pExpr) ) return; |
| 112828 | zAff = exprINAffinity(pParse, pExpr); | 113328 | zAff = exprINAffinity(pParse, pExpr); |
| 112829 | nVector = sqlite3ExprVectorSize(pExpr->pLeft); | 113329 | nVector = sqlite3ExprVectorSize(pExpr->pLeft); |
| 112830 | aiMap = (int*)sqlite3DbMallocZero( | 113330 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); |
| 112831 | pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 | ||
| 112832 | ); | ||
| 112833 | if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; | 113331 | if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; |
| 112834 | 113332 | ||
| 112835 | /* Attempt to compute the RHS. After this step, if anything other than | 113333 | /* Attempt to compute the RHS. After this step, if anything other than |
| @@ -112972,6 +113470,15 @@ static void sqlite3ExprCodeIN( | |||
| 112972 | sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); | 113470 | sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); |
| 112973 | if( destIfFalse==destIfNull ){ | 113471 | if( destIfFalse==destIfNull ){ |
| 112974 | /* Combine Step 3 and Step 5 into a single opcode */ | 113472 | /* Combine Step 3 and Step 5 into a single opcode */ |
| 113473 | if( ExprHasProperty(pExpr, EP_Subrtn) ){ | ||
| 113474 | const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); | ||
| 113475 | assert( pOp->opcode==OP_Once || pParse->nErr ); | ||
| 113476 | if( pOp->opcode==OP_Once && pOp->p3>0 ){ | ||
| 113477 | assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); | ||
| 113478 | sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, | ||
| 113479 | rLhs, nVector); VdbeCoverage(v); | ||
| 113480 | } | ||
| 113481 | } | ||
| 112975 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, | 113482 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, |
| 112976 | rLhs, nVector); VdbeCoverage(v); | 113483 | rLhs, nVector); VdbeCoverage(v); |
| 112977 | goto sqlite3ExprCodeIN_finished; | 113484 | goto sqlite3ExprCodeIN_finished; |
| @@ -113254,13 +113761,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n | |||
| 113254 | ** register iReg. The caller must ensure that iReg already contains | 113761 | ** register iReg. The caller must ensure that iReg already contains |
| 113255 | ** the correct value for the expression. | 113762 | ** the correct value for the expression. |
| 113256 | */ | 113763 | */ |
| 113257 | static void exprToRegister(Expr *pExpr, int iReg){ | 113764 | SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ |
| 113258 | Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); | 113765 | Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); |
| 113259 | if( NEVER(p==0) ) return; | 113766 | if( NEVER(p==0) ) return; |
| 113260 | p->op2 = p->op; | 113767 | if( p->op==TK_REGISTER ){ |
| 113261 | p->op = TK_REGISTER; | 113768 | assert( p->iTable==iReg ); |
| 113262 | p->iTable = iReg; | 113769 | }else{ |
| 113263 | ExprClearProperty(p, EP_Skip); | 113770 | p->op2 = p->op; |
| 113771 | p->op = TK_REGISTER; | ||
| 113772 | p->iTable = iReg; | ||
| 113773 | ExprClearProperty(p, EP_Skip); | ||
| 113774 | } | ||
| 113264 | } | 113775 | } |
| 113265 | 113776 | ||
| 113266 | /* | 113777 | /* |
| @@ -113431,6 +113942,59 @@ static int exprCodeInlineFunction( | |||
| 113431 | } | 113942 | } |
| 113432 | 113943 | ||
| 113433 | /* | 113944 | /* |
| 113945 | ** Expression Node callback for sqlite3ExprCanReturnSubtype(). | ||
| 113946 | ** | ||
| 113947 | ** Only a function call is able to return a subtype. So if the node | ||
| 113948 | ** is not a function call, return WRC_Prune immediately. | ||
| 113949 | ** | ||
| 113950 | ** A function call is able to return a subtype if it has the | ||
| 113951 | ** SQLITE_RESULT_SUBTYPE property. | ||
| 113952 | ** | ||
| 113953 | ** Assume that every function is able to pass-through a subtype from | ||
| 113954 | ** one of its argument (using sqlite3_result_value()). Most functions | ||
| 113955 | ** are not this way, but we don't have a mechanism to distinguish those | ||
| 113956 | ** that are from those that are not, so assume they all work this way. | ||
| 113957 | ** That means that if one of its arguments is another function and that | ||
| 113958 | ** other function is able to return a subtype, then this function is | ||
| 113959 | ** able to return a subtype. | ||
| 113960 | */ | ||
| 113961 | static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ | ||
| 113962 | int n; | ||
| 113963 | FuncDef *pDef; | ||
| 113964 | sqlite3 *db; | ||
| 113965 | if( pExpr->op!=TK_FUNCTION ){ | ||
| 113966 | return WRC_Prune; | ||
| 113967 | } | ||
| 113968 | assert( ExprUseXList(pExpr) ); | ||
| 113969 | db = pWalker->pParse->db; | ||
| 113970 | n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; | ||
| 113971 | pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); | ||
| 113972 | if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ | ||
| 113973 | pWalker->eCode = 1; | ||
| 113974 | return WRC_Prune; | ||
| 113975 | } | ||
| 113976 | return WRC_Continue; | ||
| 113977 | } | ||
| 113978 | |||
| 113979 | /* | ||
| 113980 | ** Return TRUE if expression pExpr is able to return a subtype. | ||
| 113981 | ** | ||
| 113982 | ** A TRUE return does not guarantee that a subtype will be returned. | ||
| 113983 | ** It only indicates that a subtype return is possible. False positives | ||
| 113984 | ** are acceptable as they only disable an optimization. False negatives, | ||
| 113985 | ** on the other hand, can lead to incorrect answers. | ||
| 113986 | */ | ||
| 113987 | static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ | ||
| 113988 | Walker w; | ||
| 113989 | memset(&w, 0, sizeof(w)); | ||
| 113990 | w.pParse = pParse; | ||
| 113991 | w.xExprCallback = exprNodeCanReturnSubtype; | ||
| 113992 | sqlite3WalkExpr(&w, pExpr); | ||
| 113993 | return w.eCode; | ||
| 113994 | } | ||
| 113995 | |||
| 113996 | |||
| 113997 | /* | ||
| 113434 | ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. | 113998 | ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. |
| 113435 | ** If it is, then resolve the expression by reading from the index and | 113999 | ** If it is, then resolve the expression by reading from the index and |
| 113436 | ** return the register into which the value has been read. If pExpr is | 114000 | ** return the register into which the value has been read. If pExpr is |
| @@ -113462,6 +114026,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( | |||
| 113462 | continue; | 114026 | continue; |
| 113463 | } | 114027 | } |
| 113464 | 114028 | ||
| 114029 | |||
| 114030 | /* Functions that might set a subtype should not be replaced by the | ||
| 114031 | ** value taken from an expression index if they are themselves an | ||
| 114032 | ** argument to another scalar function or aggregate. | ||
| 114033 | ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */ | ||
| 114034 | if( ExprHasProperty(pExpr, EP_SubtArg) | ||
| 114035 | && sqlite3ExprCanReturnSubtype(pParse, pExpr) | ||
| 114036 | ){ | ||
| 114037 | continue; | ||
| 114038 | } | ||
| 114039 | |||
| 113465 | v = pParse->pVdbe; | 114040 | v = pParse->pVdbe; |
| 113466 | assert( v!=0 ); | 114041 | assert( v!=0 ); |
| 113467 | if( p->bMaybeNullRow ){ | 114042 | if( p->bMaybeNullRow ){ |
| @@ -114263,7 +114838,7 @@ expr_code_doover: | |||
| 114263 | break; | 114838 | break; |
| 114264 | } | 114839 | } |
| 114265 | testcase( pX->op==TK_COLUMN ); | 114840 | testcase( pX->op==TK_COLUMN ); |
| 114266 | exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); | 114841 | sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); |
| 114267 | testcase( regFree1==0 ); | 114842 | testcase( regFree1==0 ); |
| 114268 | memset(&opCompare, 0, sizeof(opCompare)); | 114843 | memset(&opCompare, 0, sizeof(opCompare)); |
| 114269 | opCompare.op = TK_EQ; | 114844 | opCompare.op = TK_EQ; |
| @@ -114317,15 +114892,14 @@ expr_code_doover: | |||
| 114317 | } | 114892 | } |
| 114318 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 114893 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 114319 | if( pExpr->affExpr==OE_Ignore ){ | 114894 | if( pExpr->affExpr==OE_Ignore ){ |
| 114320 | sqlite3VdbeAddOp4( | 114895 | sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); |
| 114321 | v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); | ||
| 114322 | VdbeCoverage(v); | 114896 | VdbeCoverage(v); |
| 114323 | }else{ | 114897 | }else{ |
| 114324 | sqlite3HaltConstraint(pParse, | 114898 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 114899 | sqlite3VdbeAddOp3(v, OP_Halt, | ||
| 114325 | pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, | 114900 | pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, |
| 114326 | pExpr->affExpr, pExpr->u.zToken, 0, 0); | 114901 | pExpr->affExpr, r1); |
| 114327 | } | 114902 | } |
| 114328 | |||
| 114329 | break; | 114903 | break; |
| 114330 | } | 114904 | } |
| 114331 | #endif | 114905 | #endif |
| @@ -114614,7 +115188,7 @@ static void exprCodeBetween( | |||
| 114614 | compRight.op = TK_LE; | 115188 | compRight.op = TK_LE; |
| 114615 | compRight.pLeft = pDel; | 115189 | compRight.pLeft = pDel; |
| 114616 | compRight.pRight = pExpr->x.pList->a[1].pExpr; | 115190 | compRight.pRight = pExpr->x.pList->a[1].pExpr; |
| 114617 | exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); | 115191 | sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); |
| 114618 | if( xJump ){ | 115192 | if( xJump ){ |
| 114619 | xJump(pParse, &exprAnd, dest, jumpIfNull); | 115193 | xJump(pParse, &exprAnd, dest, jumpIfNull); |
| 114620 | }else{ | 115194 | }else{ |
| @@ -117508,8 +118082,9 @@ static int renameResolveTrigger(Parse *pParse){ | |||
| 117508 | int i; | 118082 | int i; |
| 117509 | for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){ | 118083 | for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){ |
| 117510 | SrcItem *p = &pStep->pFrom->a[i]; | 118084 | SrcItem *p = &pStep->pFrom->a[i]; |
| 117511 | if( p->pSelect ){ | 118085 | if( p->fg.isSubquery ){ |
| 117512 | sqlite3SelectPrep(pParse, p->pSelect, 0); | 118086 | assert( p->u4.pSubq!=0 ); |
| 118087 | sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); | ||
| 117513 | } | 118088 | } |
| 117514 | } | 118089 | } |
| 117515 | } | 118090 | } |
| @@ -117577,8 +118152,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ | |||
| 117577 | } | 118152 | } |
| 117578 | if( pStep->pFrom ){ | 118153 | if( pStep->pFrom ){ |
| 117579 | int i; | 118154 | int i; |
| 117580 | for(i=0; i<pStep->pFrom->nSrc; i++){ | 118155 | SrcList *pFrom = pStep->pFrom; |
| 117581 | sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); | 118156 | for(i=0; i<pFrom->nSrc; i++){ |
| 118157 | if( pFrom->a[i].fg.isSubquery ){ | ||
| 118158 | assert( pFrom->a[i].u4.pSubq!=0 ); | ||
| 118159 | sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); | ||
| 118160 | } | ||
| 117582 | } | 118161 | } |
| 117583 | } | 118162 | } |
| 117584 | } | 118163 | } |
| @@ -117825,7 +118404,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ | |||
| 117825 | } | 118404 | } |
| 117826 | for(i=0; i<pSrc->nSrc; i++){ | 118405 | for(i=0; i<pSrc->nSrc; i++){ |
| 117827 | SrcItem *pItem = &pSrc->a[i]; | 118406 | SrcItem *pItem = &pSrc->a[i]; |
| 117828 | if( pItem->pTab==p->pTab ){ | 118407 | if( pItem->pSTab==p->pTab ){ |
| 117829 | renameTokenFind(pWalker->pParse, p, pItem->zName); | 118408 | renameTokenFind(pWalker->pParse, p, pItem->zName); |
| 117830 | } | 118409 | } |
| 117831 | } | 118410 | } |
| @@ -120253,12 +120832,13 @@ static int loadStatTbl( | |||
| 120253 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ | 120832 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 120254 | int nIdxCol = 1; /* Number of columns in stat4 records */ | 120833 | int nIdxCol = 1; /* Number of columns in stat4 records */ |
| 120255 | 120834 | ||
| 120256 | char *zIndex; /* Index name */ | 120835 | char *zIndex; /* Index name */ |
| 120257 | Index *pIdx; /* Pointer to the index object */ | 120836 | Index *pIdx; /* Pointer to the index object */ |
| 120258 | int nSample; /* Number of samples */ | 120837 | int nSample; /* Number of samples */ |
| 120259 | int nByte; /* Bytes of space required */ | 120838 | i64 nByte; /* Bytes of space required */ |
| 120260 | int i; /* Bytes of space required */ | 120839 | i64 i; /* Bytes of space required */ |
| 120261 | tRowcnt *pSpace; | 120840 | tRowcnt *pSpace; /* Available allocated memory space */ |
| 120841 | u8 *pPtr; /* Available memory as a u8 for easier manipulation */ | ||
| 120262 | 120842 | ||
| 120263 | zIndex = (char *)sqlite3_column_text(pStmt, 0); | 120843 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 120264 | if( zIndex==0 ) continue; | 120844 | if( zIndex==0 ) continue; |
| @@ -120278,7 +120858,7 @@ static int loadStatTbl( | |||
| 120278 | } | 120858 | } |
| 120279 | pIdx->nSampleCol = nIdxCol; | 120859 | pIdx->nSampleCol = nIdxCol; |
| 120280 | pIdx->mxSample = nSample; | 120860 | pIdx->mxSample = nSample; |
| 120281 | nByte = sizeof(IndexSample) * nSample; | 120861 | nByte = ROUND8(sizeof(IndexSample) * nSample); |
| 120282 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; | 120862 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 120283 | nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ | 120863 | nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 120284 | 120864 | ||
| @@ -120287,7 +120867,10 @@ static int loadStatTbl( | |||
| 120287 | sqlite3_finalize(pStmt); | 120867 | sqlite3_finalize(pStmt); |
| 120288 | return SQLITE_NOMEM_BKPT; | 120868 | return SQLITE_NOMEM_BKPT; |
| 120289 | } | 120869 | } |
| 120290 | pSpace = (tRowcnt*)&pIdx->aSample[nSample]; | 120870 | pPtr = (u8*)pIdx->aSample; |
| 120871 | pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); | ||
| 120872 | pSpace = (tRowcnt*)pPtr; | ||
| 120873 | assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); | ||
| 120291 | pIdx->aAvgEq = pSpace; pSpace += nIdxCol; | 120874 | pIdx->aAvgEq = pSpace; pSpace += nIdxCol; |
| 120292 | pIdx->pTable->tabFlags |= TF_HasStat4; | 120875 | pIdx->pTable->tabFlags |= TF_HasStat4; |
| 120293 | for(i=0; i<nSample; i++){ | 120876 | for(i=0; i<nSample; i++){ |
| @@ -120955,20 +121538,21 @@ static int fixSelectCb(Walker *p, Select *pSelect){ | |||
| 120955 | 121538 | ||
| 120956 | if( NEVER(pList==0) ) return WRC_Continue; | 121539 | if( NEVER(pList==0) ) return WRC_Continue; |
| 120957 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ | 121540 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ |
| 120958 | if( pFix->bTemp==0 ){ | 121541 | if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ |
| 120959 | if( pItem->zDatabase ){ | 121542 | if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ |
| 120960 | if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ | 121543 | if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ |
| 120961 | sqlite3ErrorMsg(pFix->pParse, | 121544 | sqlite3ErrorMsg(pFix->pParse, |
| 120962 | "%s %T cannot reference objects in database %s", | 121545 | "%s %T cannot reference objects in database %s", |
| 120963 | pFix->zType, pFix->pName, pItem->zDatabase); | 121546 | pFix->zType, pFix->pName, pItem->u4.zDatabase); |
| 120964 | return WRC_Abort; | 121547 | return WRC_Abort; |
| 120965 | } | 121548 | } |
| 120966 | sqlite3DbFree(db, pItem->zDatabase); | 121549 | sqlite3DbFree(db, pItem->u4.zDatabase); |
| 120967 | pItem->zDatabase = 0; | ||
| 120968 | pItem->fg.notCte = 1; | 121550 | pItem->fg.notCte = 1; |
| 121551 | pItem->fg.hadSchema = 1; | ||
| 120969 | } | 121552 | } |
| 120970 | pItem->pSchema = pFix->pSchema; | 121553 | pItem->u4.pSchema = pFix->pSchema; |
| 120971 | pItem->fg.fromDDL = 1; | 121554 | pItem->fg.fromDDL = 1; |
| 121555 | pItem->fg.fixedSchema = 1; | ||
| 120972 | } | 121556 | } |
| 120973 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) | 121557 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) |
| 120974 | if( pList->a[i].fg.isUsing==0 | 121558 | if( pList->a[i].fg.isUsing==0 |
| @@ -121261,7 +121845,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( | |||
| 121261 | assert( pTabList ); | 121845 | assert( pTabList ); |
| 121262 | for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ | 121846 | for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ |
| 121263 | if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ | 121847 | if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ |
| 121264 | pTab = pTabList->a[iSrc].pTab; | 121848 | pTab = pTabList->a[iSrc].pSTab; |
| 121265 | break; | 121849 | break; |
| 121266 | } | 121850 | } |
| 121267 | } | 121851 | } |
| @@ -121864,12 +122448,12 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( | |||
| 121864 | SrcItem *p | 122448 | SrcItem *p |
| 121865 | ){ | 122449 | ){ |
| 121866 | const char *zDb; | 122450 | const char *zDb; |
| 121867 | assert( p->pSchema==0 || p->zDatabase==0 ); | 122451 | if( p->fg.fixedSchema ){ |
| 121868 | if( p->pSchema ){ | 122452 | int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); |
| 121869 | int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); | ||
| 121870 | zDb = pParse->db->aDb[iDb].zDbSName; | 122453 | zDb = pParse->db->aDb[iDb].zDbSName; |
| 121871 | }else{ | 122454 | }else{ |
| 121872 | zDb = p->zDatabase; | 122455 | assert( !p->fg.isSubquery ); |
| 122456 | zDb = p->u4.zDatabase; | ||
| 121873 | } | 122457 | } |
| 121874 | return sqlite3LocateTable(pParse, flags, p->zName, zDb); | 122458 | return sqlite3LocateTable(pParse, flags, p->zName, zDb); |
| 121875 | } | 122459 | } |
| @@ -124854,6 +125438,8 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, | |||
| 124854 | } | 125438 | } |
| 124855 | assert( pParse->nErr==0 ); | 125439 | assert( pParse->nErr==0 ); |
| 124856 | assert( pName->nSrc==1 ); | 125440 | assert( pName->nSrc==1 ); |
| 125441 | assert( pName->a[0].fg.fixedSchema==0 ); | ||
| 125442 | assert( pName->a[0].fg.isSubquery==0 ); | ||
| 124857 | if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; | 125443 | if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; |
| 124858 | if( noErr ) db->suppressErr++; | 125444 | if( noErr ) db->suppressErr++; |
| 124859 | assert( isView==0 || isView==LOCATE_VIEW ); | 125445 | assert( isView==0 || isView==LOCATE_VIEW ); |
| @@ -124862,7 +125448,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, | |||
| 124862 | 125448 | ||
| 124863 | if( pTab==0 ){ | 125449 | if( pTab==0 ){ |
| 124864 | if( noErr ){ | 125450 | if( noErr ){ |
| 124865 | sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); | 125451 | sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); |
| 124866 | sqlite3ForceNotReadOnly(pParse); | 125452 | sqlite3ForceNotReadOnly(pParse); |
| 124867 | } | 125453 | } |
| 124868 | goto exit_drop_table; | 125454 | goto exit_drop_table; |
| @@ -125953,15 +126539,17 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists | |||
| 125953 | } | 126539 | } |
| 125954 | assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ | 126540 | assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ |
| 125955 | assert( pName->nSrc==1 ); | 126541 | assert( pName->nSrc==1 ); |
| 126542 | assert( pName->a[0].fg.fixedSchema==0 ); | ||
| 126543 | assert( pName->a[0].fg.isSubquery==0 ); | ||
| 125956 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ | 126544 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| 125957 | goto exit_drop_index; | 126545 | goto exit_drop_index; |
| 125958 | } | 126546 | } |
| 125959 | pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); | 126547 | pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); |
| 125960 | if( pIndex==0 ){ | 126548 | if( pIndex==0 ){ |
| 125961 | if( !ifExists ){ | 126549 | if( !ifExists ){ |
| 125962 | sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); | 126550 | sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); |
| 125963 | }else{ | 126551 | }else{ |
| 125964 | sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); | 126552 | sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); |
| 125965 | sqlite3ForceNotReadOnly(pParse); | 126553 | sqlite3ForceNotReadOnly(pParse); |
| 125966 | } | 126554 | } |
| 125967 | pParse->checkSchema = 1; | 126555 | pParse->checkSchema = 1; |
| @@ -126258,12 +126846,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( | |||
| 126258 | if( pDatabase && pDatabase->z==0 ){ | 126846 | if( pDatabase && pDatabase->z==0 ){ |
| 126259 | pDatabase = 0; | 126847 | pDatabase = 0; |
| 126260 | } | 126848 | } |
| 126849 | assert( pItem->fg.fixedSchema==0 ); | ||
| 126850 | assert( pItem->fg.isSubquery==0 ); | ||
| 126261 | if( pDatabase ){ | 126851 | if( pDatabase ){ |
| 126262 | pItem->zName = sqlite3NameFromToken(db, pDatabase); | 126852 | pItem->zName = sqlite3NameFromToken(db, pDatabase); |
| 126263 | pItem->zDatabase = sqlite3NameFromToken(db, pTable); | 126853 | pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); |
| 126264 | }else{ | 126854 | }else{ |
| 126265 | pItem->zName = sqlite3NameFromToken(db, pTable); | 126855 | pItem->zName = sqlite3NameFromToken(db, pTable); |
| 126266 | pItem->zDatabase = 0; | 126856 | pItem->u4.zDatabase = 0; |
| 126267 | } | 126857 | } |
| 126268 | return pList; | 126858 | return pList; |
| 126269 | } | 126859 | } |
| @@ -126279,14 +126869,41 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ | |||
| 126279 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ | 126869 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ |
| 126280 | if( pItem->iCursor>=0 ) continue; | 126870 | if( pItem->iCursor>=0 ) continue; |
| 126281 | pItem->iCursor = pParse->nTab++; | 126871 | pItem->iCursor = pParse->nTab++; |
| 126282 | if( pItem->pSelect ){ | 126872 | if( pItem->fg.isSubquery ){ |
| 126283 | sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); | 126873 | assert( pItem->u4.pSubq!=0 ); |
| 126874 | assert( pItem->u4.pSubq->pSelect!=0 ); | ||
| 126875 | assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); | ||
| 126876 | sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); | ||
| 126284 | } | 126877 | } |
| 126285 | } | 126878 | } |
| 126286 | } | 126879 | } |
| 126287 | } | 126880 | } |
| 126288 | 126881 | ||
| 126289 | /* | 126882 | /* |
| 126883 | ** Delete a Subquery object and its substructure. | ||
| 126884 | */ | ||
| 126885 | SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ | ||
| 126886 | assert( pSubq!=0 && pSubq->pSelect!=0 ); | ||
| 126887 | sqlite3SelectDelete(db, pSubq->pSelect); | ||
| 126888 | sqlite3DbFree(db, pSubq); | ||
| 126889 | } | ||
| 126890 | |||
| 126891 | /* | ||
| 126892 | ** Remove a Subquery from a SrcItem. Return the associated Select object. | ||
| 126893 | ** The returned Select becomes the responsibility of the caller. | ||
| 126894 | */ | ||
| 126895 | SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ | ||
| 126896 | Select *pSel; | ||
| 126897 | assert( pItem!=0 ); | ||
| 126898 | assert( pItem->fg.isSubquery ); | ||
| 126899 | pSel = pItem->u4.pSubq->pSelect; | ||
| 126900 | sqlite3DbFree(db, pItem->u4.pSubq); | ||
| 126901 | pItem->u4.pSubq = 0; | ||
| 126902 | pItem->fg.isSubquery = 0; | ||
| 126903 | return pSel; | ||
| 126904 | } | ||
| 126905 | |||
| 126906 | /* | ||
| 126290 | ** Delete an entire SrcList including all its substructure. | 126907 | ** Delete an entire SrcList including all its substructure. |
| 126291 | */ | 126908 | */ |
| 126292 | SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ | 126909 | SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ |
| @@ -126295,13 +126912,24 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ | |||
| 126295 | assert( db!=0 ); | 126912 | assert( db!=0 ); |
| 126296 | if( pList==0 ) return; | 126913 | if( pList==0 ) return; |
| 126297 | for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ | 126914 | for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ |
| 126298 | if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); | 126915 | |
| 126916 | /* Check invariants on SrcItem */ | ||
| 126917 | assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); | ||
| 126918 | assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); | ||
| 126919 | assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); | ||
| 126920 | assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && | ||
| 126921 | pItem->u4.pSubq->pSelect!=0) ); | ||
| 126922 | |||
| 126299 | if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); | 126923 | if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); |
| 126300 | if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); | 126924 | if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); |
| 126925 | if( pItem->fg.isSubquery ){ | ||
| 126926 | sqlite3SubqueryDelete(db, pItem->u4.pSubq); | ||
| 126927 | }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ | ||
| 126928 | sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); | ||
| 126929 | } | ||
| 126301 | if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); | 126930 | if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); |
| 126302 | if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); | 126931 | if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); |
| 126303 | sqlite3DeleteTable(db, pItem->pTab); | 126932 | sqlite3DeleteTable(db, pItem->pSTab); |
| 126304 | if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); | ||
| 126305 | if( pItem->fg.isUsing ){ | 126933 | if( pItem->fg.isUsing ){ |
| 126306 | sqlite3IdListDelete(db, pItem->u3.pUsing); | 126934 | sqlite3IdListDelete(db, pItem->u3.pUsing); |
| 126307 | }else if( pItem->u3.pOn ){ | 126935 | }else if( pItem->u3.pOn ){ |
| @@ -126312,6 +126940,54 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ | |||
| 126312 | } | 126940 | } |
| 126313 | 126941 | ||
| 126314 | /* | 126942 | /* |
| 126943 | ** Attach a Subquery object to pItem->uv.pSubq. Set the | ||
| 126944 | ** pSelect value but leave all the other values initialized | ||
| 126945 | ** to zero. | ||
| 126946 | ** | ||
| 126947 | ** A copy of the Select object is made if dupSelect is true, and the | ||
| 126948 | ** SrcItem takes responsibility for deleting the copy. If dupSelect is | ||
| 126949 | ** false, ownership of the Select passes to the SrcItem. Either way, | ||
| 126950 | ** the SrcItem will take responsibility for deleting the Select. | ||
| 126951 | ** | ||
| 126952 | ** When dupSelect is zero, that means the Select might get deleted right | ||
| 126953 | ** away if there is an OOM error. Beware. | ||
| 126954 | ** | ||
| 126955 | ** Return non-zero on success. Return zero on an OOM error. | ||
| 126956 | */ | ||
| 126957 | SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( | ||
| 126958 | Parse *pParse, /* Parsing context */ | ||
| 126959 | SrcItem *pItem, /* Item to which the subquery is to be attached */ | ||
| 126960 | Select *pSelect, /* The subquery SELECT. Must be non-NULL */ | ||
| 126961 | int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ | ||
| 126962 | ){ | ||
| 126963 | Subquery *p; | ||
| 126964 | assert( pSelect!=0 ); | ||
| 126965 | assert( pItem->fg.isSubquery==0 ); | ||
| 126966 | if( pItem->fg.fixedSchema ){ | ||
| 126967 | pItem->u4.pSchema = 0; | ||
| 126968 | pItem->fg.fixedSchema = 0; | ||
| 126969 | }else if( pItem->u4.zDatabase!=0 ){ | ||
| 126970 | sqlite3DbFree(pParse->db, pItem->u4.zDatabase); | ||
| 126971 | pItem->u4.zDatabase = 0; | ||
| 126972 | } | ||
| 126973 | if( dupSelect ){ | ||
| 126974 | pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); | ||
| 126975 | if( pSelect==0 ) return 0; | ||
| 126976 | } | ||
| 126977 | p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); | ||
| 126978 | if( p==0 ){ | ||
| 126979 | sqlite3SelectDelete(pParse->db, pSelect); | ||
| 126980 | return 0; | ||
| 126981 | } | ||
| 126982 | pItem->fg.isSubquery = 1; | ||
| 126983 | p->pSelect = pSelect; | ||
| 126984 | assert( offsetof(Subquery, pSelect)==0 ); | ||
| 126985 | memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); | ||
| 126986 | return 1; | ||
| 126987 | } | ||
| 126988 | |||
| 126989 | |||
| 126990 | /* | ||
| 126315 | ** This routine is called by the parser to add a new term to the | 126991 | ** This routine is called by the parser to add a new term to the |
| 126316 | ** end of a growing FROM clause. The "p" parameter is the part of | 126992 | ** end of a growing FROM clause. The "p" parameter is the part of |
| 126317 | ** the FROM clause that has already been constructed. "p" is NULL | 126993 | ** the FROM clause that has already been constructed. "p" is NULL |
| @@ -126360,10 +127036,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( | |||
| 126360 | if( pAlias->n ){ | 127036 | if( pAlias->n ){ |
| 126361 | pItem->zAlias = sqlite3NameFromToken(db, pAlias); | 127037 | pItem->zAlias = sqlite3NameFromToken(db, pAlias); |
| 126362 | } | 127038 | } |
| 127039 | assert( pSubquery==0 || pDatabase==0 ); | ||
| 126363 | if( pSubquery ){ | 127040 | if( pSubquery ){ |
| 126364 | pItem->pSelect = pSubquery; | 127041 | if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ |
| 126365 | if( pSubquery->selFlags & SF_NestedFrom ){ | 127042 | if( pSubquery->selFlags & SF_NestedFrom ){ |
| 126366 | pItem->fg.isNestedFrom = 1; | 127043 | pItem->fg.isNestedFrom = 1; |
| 127044 | } | ||
| 126367 | } | 127045 | } |
| 126368 | } | 127046 | } |
| 126369 | assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); | 127047 | assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); |
| @@ -127641,8 +128319,8 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ | |||
| 127641 | ** | 128319 | ** |
| 127642 | ** The following fields are initialized appropriate in pSrc: | 128320 | ** The following fields are initialized appropriate in pSrc: |
| 127643 | ** | 128321 | ** |
| 127644 | ** pSrc->a[0].pTab Pointer to the Table object | 128322 | ** pSrc->a[0].spTab Pointer to the Table object |
| 127645 | ** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one | 128323 | ** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one |
| 127646 | ** | 128324 | ** |
| 127647 | */ | 128325 | */ |
| 127648 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ | 128326 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ |
| @@ -127650,8 +128328,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ | |||
| 127650 | Table *pTab; | 128328 | Table *pTab; |
| 127651 | assert( pItem && pSrc->nSrc>=1 ); | 128329 | assert( pItem && pSrc->nSrc>=1 ); |
| 127652 | pTab = sqlite3LocateTableItem(pParse, 0, pItem); | 128330 | pTab = sqlite3LocateTableItem(pParse, 0, pItem); |
| 127653 | if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); | 128331 | if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); |
| 127654 | pItem->pTab = pTab; | 128332 | pItem->pSTab = pTab; |
| 127655 | pItem->fg.notCte = 1; | 128333 | pItem->fg.notCte = 1; |
| 127656 | if( pTab ){ | 128334 | if( pTab ){ |
| 127657 | pTab->nTabRef++; | 128335 | pTab->nTabRef++; |
| @@ -127692,6 +128370,7 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char * | |||
| 127692 | ** is for a top-level SQL statement. | 128370 | ** is for a top-level SQL statement. |
| 127693 | */ | 128371 | */ |
| 127694 | static int vtabIsReadOnly(Parse *pParse, Table *pTab){ | 128372 | static int vtabIsReadOnly(Parse *pParse, Table *pTab){ |
| 128373 | assert( IsVirtual(pTab) ); | ||
| 127695 | if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ | 128374 | if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ |
| 127696 | return 1; | 128375 | return 1; |
| 127697 | } | 128376 | } |
| @@ -127773,7 +128452,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView( | |||
| 127773 | if( pFrom ){ | 128452 | if( pFrom ){ |
| 127774 | assert( pFrom->nSrc==1 ); | 128453 | assert( pFrom->nSrc==1 ); |
| 127775 | pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); | 128454 | pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); |
| 127776 | pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); | 128455 | assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); |
| 128456 | pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); | ||
| 127777 | assert( pFrom->a[0].fg.isUsing==0 ); | 128457 | assert( pFrom->a[0].fg.isUsing==0 ); |
| 127778 | assert( pFrom->a[0].u3.pOn==0 ); | 128458 | assert( pFrom->a[0].u3.pOn==0 ); |
| 127779 | } | 128459 | } |
| @@ -127835,7 +128515,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( | |||
| 127835 | ** ); | 128515 | ** ); |
| 127836 | */ | 128516 | */ |
| 127837 | 128517 | ||
| 127838 | pTab = pSrc->a[0].pTab; | 128518 | pTab = pSrc->a[0].pSTab; |
| 127839 | if( HasRowid(pTab) ){ | 128519 | if( HasRowid(pTab) ){ |
| 127840 | pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); | 128520 | pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); |
| 127841 | pEList = sqlite3ExprListAppend( | 128521 | pEList = sqlite3ExprListAppend( |
| @@ -127868,9 +128548,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( | |||
| 127868 | 128548 | ||
| 127869 | /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree | 128549 | /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree |
| 127870 | ** and the SELECT subtree. */ | 128550 | ** and the SELECT subtree. */ |
| 127871 | pSrc->a[0].pTab = 0; | 128551 | pSrc->a[0].pSTab = 0; |
| 127872 | pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); | 128552 | pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); |
| 127873 | pSrc->a[0].pTab = pTab; | 128553 | pSrc->a[0].pSTab = pTab; |
| 127874 | if( pSrc->a[0].fg.isIndexedBy ){ | 128554 | if( pSrc->a[0].fg.isIndexedBy ){ |
| 127875 | assert( pSrc->a[0].fg.isCte==0 ); | 128555 | assert( pSrc->a[0].fg.isCte==0 ); |
| 127876 | pSrc->a[0].u2.pIBIndex = 0; | 128556 | pSrc->a[0].u2.pIBIndex = 0; |
| @@ -130697,7 +131377,11 @@ static void minMaxFinalize(sqlite3_context *context){ | |||
| 130697 | ** group_concat(EXPR, ?SEPARATOR?) | 131377 | ** group_concat(EXPR, ?SEPARATOR?) |
| 130698 | ** string_agg(EXPR, SEPARATOR) | 131378 | ** string_agg(EXPR, SEPARATOR) |
| 130699 | ** | 131379 | ** |
| 130700 | ** The SEPARATOR goes before the EXPR string. This is tragic. The | 131380 | ** Content is accumulated in GroupConcatCtx.str with the SEPARATOR |
| 131381 | ** coming before the EXPR value, except for the first entry which | ||
| 131382 | ** omits the SEPARATOR. | ||
| 131383 | ** | ||
| 131384 | ** It is tragic that the SEPARATOR goes before the EXPR string. The | ||
| 130701 | ** groupConcatInverse() implementation would have been easier if the | 131385 | ** groupConcatInverse() implementation would have been easier if the |
| 130702 | ** SEPARATOR were appended after EXPR. And the order is undocumented, | 131386 | ** SEPARATOR were appended after EXPR. And the order is undocumented, |
| 130703 | ** so we could change it, in theory. But the old behavior has been | 131387 | ** so we could change it, in theory. But the old behavior has been |
| @@ -130801,7 +131485,7 @@ static void groupConcatInverse( | |||
| 130801 | /* pGCC is always non-NULL since groupConcatStep() will have always | 131485 | /* pGCC is always non-NULL since groupConcatStep() will have always |
| 130802 | ** run first to initialize it */ | 131486 | ** run first to initialize it */ |
| 130803 | if( ALWAYS(pGCC) ){ | 131487 | if( ALWAYS(pGCC) ){ |
| 130804 | int nVS; | 131488 | int nVS; /* Number of characters to remove */ |
| 130805 | /* Must call sqlite3_value_text() to convert the argument into text prior | 131489 | /* Must call sqlite3_value_text() to convert the argument into text prior |
| 130806 | ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ | 131490 | ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ |
| 130807 | (void)sqlite3_value_text(argv[0]); | 131491 | (void)sqlite3_value_text(argv[0]); |
| @@ -131179,7 +131863,13 @@ static void signFunc( | |||
| 131179 | ** Implementation of fpdecode(x,y,z) function. | 131863 | ** Implementation of fpdecode(x,y,z) function. |
| 131180 | ** | 131864 | ** |
| 131181 | ** x is a real number that is to be decoded. y is the precision. | 131865 | ** x is a real number that is to be decoded. y is the precision. |
| 131182 | ** z is the maximum real precision. | 131866 | ** z is the maximum real precision. Return a string that shows the |
| 131867 | ** results of the sqlite3FpDecode() function. | ||
| 131868 | ** | ||
| 131869 | ** Used for testing and debugging only, specifically testing and debugging | ||
| 131870 | ** of the sqlite3FpDecode() function. This SQL function does not appear | ||
| 131871 | ** in production builds. This function is not an API and is subject to | ||
| 131872 | ** modification or removal in future versions of SQLite. | ||
| 131183 | */ | 131873 | */ |
| 131184 | static void fpdecodeFunc( | 131874 | static void fpdecodeFunc( |
| 131185 | sqlite3_context *context, | 131875 | sqlite3_context *context, |
| @@ -131195,6 +131885,7 @@ static void fpdecodeFunc( | |||
| 131195 | x = sqlite3_value_double(argv[0]); | 131885 | x = sqlite3_value_double(argv[0]); |
| 131196 | y = sqlite3_value_int(argv[1]); | 131886 | y = sqlite3_value_int(argv[1]); |
| 131197 | z = sqlite3_value_int(argv[2]); | 131887 | z = sqlite3_value_int(argv[2]); |
| 131888 | if( z<=0 ) z = 1; | ||
| 131198 | sqlite3FpDecode(&s, x, y, z); | 131889 | sqlite3FpDecode(&s, x, y, z); |
| 131199 | if( s.isSpecial==2 ){ | 131890 | if( s.isSpecial==2 ){ |
| 131200 | sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); | 131891 | sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); |
| @@ -131205,6 +131896,82 @@ static void fpdecodeFunc( | |||
| 131205 | } | 131896 | } |
| 131206 | #endif /* SQLITE_DEBUG */ | 131897 | #endif /* SQLITE_DEBUG */ |
| 131207 | 131898 | ||
| 131899 | #ifdef SQLITE_DEBUG | ||
| 131900 | /* | ||
| 131901 | ** Implementation of parseuri(uri,flags) function. | ||
| 131902 | ** | ||
| 131903 | ** Required Arguments: | ||
| 131904 | ** "uri" The URI to parse. | ||
| 131905 | ** "flags" Bitmask of flags, as if to sqlite3_open_v2(). | ||
| 131906 | ** | ||
| 131907 | ** Additional arguments beyond the first two make calls to | ||
| 131908 | ** sqlite3_uri_key() for integers and sqlite3_uri_parameter for | ||
| 131909 | ** anything else. | ||
| 131910 | ** | ||
| 131911 | ** The result is a string showing the results of calling sqlite3ParseUri(). | ||
| 131912 | ** | ||
| 131913 | ** Used for testing and debugging only, specifically testing and debugging | ||
| 131914 | ** of the sqlite3ParseUri() function. This SQL function does not appear | ||
| 131915 | ** in production builds. This function is not an API and is subject to | ||
| 131916 | ** modification or removal in future versions of SQLite. | ||
| 131917 | */ | ||
| 131918 | static void parseuriFunc( | ||
| 131919 | sqlite3_context *ctx, | ||
| 131920 | int argc, | ||
| 131921 | sqlite3_value **argv | ||
| 131922 | ){ | ||
| 131923 | sqlite3_str *pResult; | ||
| 131924 | const char *zVfs; | ||
| 131925 | const char *zUri; | ||
| 131926 | unsigned int flgs; | ||
| 131927 | int rc; | ||
| 131928 | sqlite3_vfs *pVfs = 0; | ||
| 131929 | char *zFile = 0; | ||
| 131930 | char *zErr = 0; | ||
| 131931 | |||
| 131932 | if( argc<2 ) return; | ||
| 131933 | pVfs = sqlite3_vfs_find(0); | ||
| 131934 | assert( pVfs ); | ||
| 131935 | zVfs = pVfs->zName; | ||
| 131936 | zUri = (const char*)sqlite3_value_text(argv[0]); | ||
| 131937 | if( zUri==0 ) return; | ||
| 131938 | flgs = (unsigned int)sqlite3_value_int(argv[1]); | ||
| 131939 | rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); | ||
| 131940 | pResult = sqlite3_str_new(0); | ||
| 131941 | if( pResult ){ | ||
| 131942 | int i; | ||
| 131943 | sqlite3_str_appendf(pResult, "rc=%d", rc); | ||
| 131944 | sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); | ||
| 131945 | sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0); | ||
| 131946 | sqlite3_str_appendf(pResult, ", err=%Q", zErr); | ||
| 131947 | sqlite3_str_appendf(pResult, ", file=%Q", zFile); | ||
| 131948 | if( zFile ){ | ||
| 131949 | const char *z = zFile; | ||
| 131950 | z += sqlite3Strlen30(z)+1; | ||
| 131951 | while( z[0] ){ | ||
| 131952 | sqlite3_str_appendf(pResult, ", %Q", z); | ||
| 131953 | z += sqlite3Strlen30(z)+1; | ||
| 131954 | } | ||
| 131955 | for(i=2; i<argc; i++){ | ||
| 131956 | const char *zArg; | ||
| 131957 | if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ | ||
| 131958 | int k = sqlite3_value_int(argv[i]); | ||
| 131959 | sqlite3_str_appendf(pResult, ", '%d:%q'",k,sqlite3_uri_key(zFile, k)); | ||
| 131960 | }else if( (zArg = (const char*)sqlite3_value_text(argv[i]))!=0 ){ | ||
| 131961 | sqlite3_str_appendf(pResult, ", '%q:%q'", | ||
| 131962 | zArg, sqlite3_uri_parameter(zFile,zArg)); | ||
| 131963 | }else{ | ||
| 131964 | sqlite3_str_appendf(pResult, ", NULL"); | ||
| 131965 | } | ||
| 131966 | } | ||
| 131967 | } | ||
| 131968 | sqlite3_result_text(ctx, sqlite3_str_finish(pResult), -1, sqlite3_free); | ||
| 131969 | } | ||
| 131970 | sqlite3_free_filename(zFile); | ||
| 131971 | sqlite3_free(zErr); | ||
| 131972 | } | ||
| 131973 | #endif /* SQLITE_DEBUG */ | ||
| 131974 | |||
| 131208 | /* | 131975 | /* |
| 131209 | ** All of the FuncDef structures in the aBuiltinFunc[] array above | 131976 | ** All of the FuncDef structures in the aBuiltinFunc[] array above |
| 131210 | ** to the global function hash table. This occurs at start-time (as | 131977 | ** to the global function hash table. This occurs at start-time (as |
| @@ -131267,7 +132034,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ | |||
| 131267 | WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, | 132034 | WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, |
| 131268 | SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), | 132035 | SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), |
| 131269 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), | 132036 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), |
| 131270 | FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), | 132037 | FUNCTION2(subtype, 1, 0, 0, subtypeFunc, |
| 132038 | SQLITE_FUNC_TYPEOF|SQLITE_SUBTYPE), | ||
| 131271 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), | 132039 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), |
| 131272 | FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), | 132040 | FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), |
| 131273 | FUNCTION(instr, 2, 0, 0, instrFunc ), | 132041 | FUNCTION(instr, 2, 0, 0, instrFunc ), |
| @@ -131278,6 +132046,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ | |||
| 131278 | FUNCTION(abs, 1, 0, 0, absFunc ), | 132046 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 131279 | #ifdef SQLITE_DEBUG | 132047 | #ifdef SQLITE_DEBUG |
| 131280 | FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), | 132048 | FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), |
| 132049 | FUNCTION(parseuri, -1, 0, 0, parseuriFunc ), | ||
| 131281 | #endif | 132050 | #endif |
| 131282 | #ifndef SQLITE_OMIT_FLOATING_POINT | 132051 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 131283 | FUNCTION(round, 1, 0, 0, roundFunc ), | 132052 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| @@ -131372,7 +132141,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ | |||
| 131372 | MFUNCTION(sqrt, 1, sqrt, math1Func ), | 132141 | MFUNCTION(sqrt, 1, sqrt, math1Func ), |
| 131373 | MFUNCTION(radians, 1, degToRad, math1Func ), | 132142 | MFUNCTION(radians, 1, degToRad, math1Func ), |
| 131374 | MFUNCTION(degrees, 1, radToDeg, math1Func ), | 132143 | MFUNCTION(degrees, 1, radToDeg, math1Func ), |
| 131375 | FUNCTION(pi, 0, 0, 0, piFunc ), | 132144 | MFUNCTION(pi, 0, 0, piFunc ), |
| 131376 | #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ | 132145 | #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ |
| 131377 | FUNCTION(sign, 1, 0, 0, signFunc ), | 132146 | FUNCTION(sign, 1, 0, 0, signFunc ), |
| 131378 | INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), | 132147 | INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), |
| @@ -132451,9 +133220,9 @@ SQLITE_PRIVATE void sqlite3FkCheck( | |||
| 132451 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); | 133220 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); |
| 132452 | if( pSrc ){ | 133221 | if( pSrc ){ |
| 132453 | SrcItem *pItem = pSrc->a; | 133222 | SrcItem *pItem = pSrc->a; |
| 132454 | pItem->pTab = pFKey->pFrom; | 133223 | pItem->pSTab = pFKey->pFrom; |
| 132455 | pItem->zName = pFKey->pFrom->zName; | 133224 | pItem->zName = pFKey->pFrom->zName; |
| 132456 | pItem->pTab->nTabRef++; | 133225 | pItem->pSTab->nTabRef++; |
| 132457 | pItem->iCursor = pParse->nTab++; | 133226 | pItem->iCursor = pParse->nTab++; |
| 132458 | 133227 | ||
| 132459 | if( regNew!=0 ){ | 133228 | if( regNew!=0 ){ |
| @@ -132736,7 +133505,8 @@ static Trigger *fkActionTrigger( | |||
| 132736 | SrcList *pSrc; | 133505 | SrcList *pSrc; |
| 132737 | Expr *pRaise; | 133506 | Expr *pRaise; |
| 132738 | 133507 | ||
| 132739 | pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); | 133508 | pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), |
| 133509 | pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); | ||
| 132740 | if( pRaise ){ | 133510 | if( pRaise ){ |
| 132741 | pRaise->affExpr = OE_Abort; | 133511 | pRaise->affExpr = OE_Abort; |
| 132742 | } | 133512 | } |
| @@ -132744,7 +133514,8 @@ static Trigger *fkActionTrigger( | |||
| 132744 | if( pSrc ){ | 133514 | if( pSrc ){ |
| 132745 | assert( pSrc->nSrc==1 ); | 133515 | assert( pSrc->nSrc==1 ); |
| 132746 | pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); | 133516 | pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); |
| 132747 | pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); | 133517 | assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); |
| 133518 | pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); | ||
| 132748 | } | 133519 | } |
| 132749 | pSelect = sqlite3SelectNew(pParse, | 133520 | pSelect = sqlite3SelectNew(pParse, |
| 132750 | sqlite3ExprListAppend(pParse, 0, pRaise), | 133521 | sqlite3ExprListAppend(pParse, 0, pRaise), |
| @@ -133478,8 +134249,11 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ | |||
| 133478 | SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ | 134249 | SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ |
| 133479 | if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ | 134250 | if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ |
| 133480 | SrcItem *pItem = &pVal->pSrc->a[0]; | 134251 | SrcItem *pItem = &pVal->pSrc->a[0]; |
| 133481 | sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn); | 134252 | assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); |
| 133482 | sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1); | 134253 | if( pItem->fg.isSubquery ){ |
| 134254 | sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); | ||
| 134255 | sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); | ||
| 134256 | } | ||
| 133483 | } | 134257 | } |
| 133484 | } | 134258 | } |
| 133485 | 134259 | ||
| @@ -133607,6 +134381,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList | |||
| 133607 | 134381 | ||
| 133608 | if( pRet ){ | 134382 | if( pRet ){ |
| 133609 | SelectDest dest; | 134383 | SelectDest dest; |
| 134384 | Subquery *pSubq; | ||
| 133610 | pRet->pSrc->nSrc = 1; | 134385 | pRet->pSrc->nSrc = 1; |
| 133611 | pRet->pPrior = pLeft->pPrior; | 134386 | pRet->pPrior = pLeft->pPrior; |
| 133612 | pRet->op = pLeft->op; | 134387 | pRet->op = pLeft->op; |
| @@ -133616,28 +134391,32 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList | |||
| 133616 | assert( pLeft->pNext==0 ); | 134391 | assert( pLeft->pNext==0 ); |
| 133617 | assert( pRet->pNext==0 ); | 134392 | assert( pRet->pNext==0 ); |
| 133618 | p = &pRet->pSrc->a[0]; | 134393 | p = &pRet->pSrc->a[0]; |
| 133619 | p->pSelect = pLeft; | ||
| 133620 | p->fg.viaCoroutine = 1; | 134394 | p->fg.viaCoroutine = 1; |
| 133621 | p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; | ||
| 133622 | p->regReturn = ++pParse->nMem; | ||
| 133623 | p->iCursor = -1; | 134395 | p->iCursor = -1; |
| 134396 | assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); | ||
| 133624 | p->u1.nRow = 2; | 134397 | p->u1.nRow = 2; |
| 133625 | sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub); | 134398 | if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ |
| 133626 | sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn); | 134399 | pSubq = p->u4.pSubq; |
| 133627 | 134400 | pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; | |
| 133628 | /* Allocate registers for the output of the co-routine. Do so so | 134401 | pSubq->regReturn = ++pParse->nMem; |
| 133629 | ** that there are two unused registers immediately before those | 134402 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, |
| 133630 | ** used by the co-routine. This allows the code in sqlite3Insert() | 134403 | pSubq->regReturn, 0, pSubq->addrFillSub); |
| 133631 | ** to use these registers directly, instead of copying the output | 134404 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); |
| 133632 | ** of the co-routine to a separate array for processing. */ | 134405 | |
| 133633 | dest.iSdst = pParse->nMem + 3; | 134406 | /* Allocate registers for the output of the co-routine. Do so so |
| 133634 | dest.nSdst = pLeft->pEList->nExpr; | 134407 | ** that there are two unused registers immediately before those |
| 133635 | pParse->nMem += 2 + dest.nSdst; | 134408 | ** used by the co-routine. This allows the code in sqlite3Insert() |
| 133636 | 134409 | ** to use these registers directly, instead of copying the output | |
| 133637 | pLeft->selFlags |= SF_MultiValue; | 134410 | ** of the co-routine to a separate array for processing. */ |
| 133638 | sqlite3Select(pParse, pLeft, &dest); | 134411 | dest.iSdst = pParse->nMem + 3; |
| 133639 | p->regResult = dest.iSdst; | 134412 | dest.nSdst = pLeft->pEList->nExpr; |
| 133640 | assert( pParse->nErr || dest.iSdst>0 ); | 134413 | pParse->nMem += 2 + dest.nSdst; |
| 134414 | |||
| 134415 | pLeft->selFlags |= SF_MultiValue; | ||
| 134416 | sqlite3Select(pParse, pLeft, &dest); | ||
| 134417 | pSubq->regResult = dest.iSdst; | ||
| 134418 | assert( pParse->nErr || dest.iSdst>0 ); | ||
| 134419 | } | ||
| 133641 | pLeft = pRet; | 134420 | pLeft = pRet; |
| 133642 | } | 134421 | } |
| 133643 | }else{ | 134422 | }else{ |
| @@ -133647,12 +134426,18 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList | |||
| 133647 | } | 134426 | } |
| 133648 | 134427 | ||
| 133649 | if( pParse->nErr==0 ){ | 134428 | if( pParse->nErr==0 ){ |
| 134429 | Subquery *pSubq; | ||
| 133650 | assert( p!=0 ); | 134430 | assert( p!=0 ); |
| 133651 | if( p->pSelect->pEList->nExpr!=pRow->nExpr ){ | 134431 | assert( p->fg.isSubquery ); |
| 133652 | sqlite3SelectWrongNumTermsError(pParse, p->pSelect); | 134432 | pSubq = p->u4.pSubq; |
| 134433 | assert( pSubq!=0 ); | ||
| 134434 | assert( pSubq->pSelect!=0 ); | ||
| 134435 | assert( pSubq->pSelect->pEList!=0 ); | ||
| 134436 | if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ | ||
| 134437 | sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); | ||
| 133653 | }else{ | 134438 | }else{ |
| 133654 | sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0); | 134439 | sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); |
| 133655 | sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn); | 134440 | sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); |
| 133656 | } | 134441 | } |
| 133657 | } | 134442 | } |
| 133658 | sqlite3ExprListDelete(pParse->db, pRow); | 134443 | sqlite3ExprListDelete(pParse->db, pRow); |
| @@ -134003,9 +134788,14 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 134003 | && pSelect->pPrior==0 | 134788 | && pSelect->pPrior==0 |
| 134004 | ){ | 134789 | ){ |
| 134005 | SrcItem *pItem = &pSelect->pSrc->a[0]; | 134790 | SrcItem *pItem = &pSelect->pSrc->a[0]; |
| 134006 | dest.iSDParm = pItem->regReturn; | 134791 | Subquery *pSubq; |
| 134007 | regFromSelect = pItem->regResult; | 134792 | assert( pItem->fg.isSubquery ); |
| 134008 | nColumn = pItem->pSelect->pEList->nExpr; | 134793 | pSubq = pItem->u4.pSubq; |
| 134794 | dest.iSDParm = pSubq->regReturn; | ||
| 134795 | regFromSelect = pSubq->regResult; | ||
| 134796 | assert( pSubq->pSelect!=0 ); | ||
| 134797 | assert( pSubq->pSelect->pEList!=0 ); | ||
| 134798 | nColumn = pSubq->pSelect->pEList->nExpr; | ||
| 134009 | ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); | 134799 | ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); |
| 134010 | if( bIdListInOrder && nColumn==pTab->nCol ){ | 134800 | if( bIdListInOrder && nColumn==pTab->nCol ){ |
| 134011 | regData = regFromSelect; | 134801 | regData = regFromSelect; |
| @@ -135925,7 +136715,7 @@ static int xferOptimization( | |||
| 135925 | if( pSelect->pSrc->nSrc!=1 ){ | 136715 | if( pSelect->pSrc->nSrc!=1 ){ |
| 135926 | return 0; /* FROM clause must have exactly one term */ | 136716 | return 0; /* FROM clause must have exactly one term */ |
| 135927 | } | 136717 | } |
| 135928 | if( pSelect->pSrc->a[0].pSelect ){ | 136718 | if( pSelect->pSrc->a[0].fg.isSubquery ){ |
| 135929 | return 0; /* FROM clause cannot contain a subquery */ | 136719 | return 0; /* FROM clause cannot contain a subquery */ |
| 135930 | } | 136720 | } |
| 135931 | if( pSelect->pWhere ){ | 136721 | if( pSelect->pWhere ){ |
| @@ -140485,6 +141275,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 140485 | 141275 | ||
| 140486 | /* Make sure sufficient number of registers have been allocated */ | 141276 | /* Make sure sufficient number of registers have been allocated */ |
| 140487 | sqlite3TouchRegister(pParse, 8+cnt); | 141277 | sqlite3TouchRegister(pParse, 8+cnt); |
| 141278 | sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt); | ||
| 140488 | sqlite3ClearTempRegCache(pParse); | 141279 | sqlite3ClearTempRegCache(pParse); |
| 140489 | 141280 | ||
| 140490 | /* Do the b-tree integrity checks */ | 141281 | /* Do the b-tree integrity checks */ |
| @@ -142810,12 +143601,24 @@ static int sqlite3Prepare16( | |||
| 142810 | if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ | 143601 | if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ |
| 142811 | return SQLITE_MISUSE_BKPT; | 143602 | return SQLITE_MISUSE_BKPT; |
| 142812 | } | 143603 | } |
| 143604 | |||
| 143605 | /* Make sure nBytes is non-negative and correct. It should be the | ||
| 143606 | ** number of bytes until the end of the input buffer or until the first | ||
| 143607 | ** U+0000 character. If the input nBytes is odd, convert it into | ||
| 143608 | ** an even number. If the input nBytes is negative, then the input | ||
| 143609 | ** must be terminated by at least one U+0000 character */ | ||
| 142813 | if( nBytes>=0 ){ | 143610 | if( nBytes>=0 ){ |
| 142814 | int sz; | 143611 | int sz; |
| 142815 | const char *z = (const char*)zSql; | 143612 | const char *z = (const char*)zSql; |
| 142816 | for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){} | 143613 | for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){} |
| 142817 | nBytes = sz; | 143614 | nBytes = sz; |
| 143615 | }else{ | ||
| 143616 | int sz; | ||
| 143617 | const char *z = (const char*)zSql; | ||
| 143618 | for(sz=0; z[sz]!=0 || z[sz+1]!=0; sz += 2){} | ||
| 143619 | nBytes = sz; | ||
| 142818 | } | 143620 | } |
| 143621 | |||
| 142819 | sqlite3_mutex_enter(db->mutex); | 143622 | sqlite3_mutex_enter(db->mutex); |
| 142820 | zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); | 143623 | zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); |
| 142821 | if( zSql8 ){ | 143624 | if( zSql8 ){ |
| @@ -142829,7 +143632,7 @@ static int sqlite3Prepare16( | |||
| 142829 | ** the same number of characters into the UTF-16 string. | 143632 | ** the same number of characters into the UTF-16 string. |
| 142830 | */ | 143633 | */ |
| 142831 | int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); | 143634 | int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); |
| 142832 | *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); | 143635 | *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); |
| 142833 | } | 143636 | } |
| 142834 | sqlite3DbFree(db, zSql8); | 143637 | sqlite3DbFree(db, zSql8); |
| 142835 | rc = sqlite3ApiExit(db, rc); | 143638 | rc = sqlite3ApiExit(db, rc); |
| @@ -143223,11 +144026,13 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ | |||
| 143223 | */ | 144026 | */ |
| 143224 | SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ | 144027 | SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ |
| 143225 | assert( pItem!=0 ); | 144028 | assert( pItem!=0 ); |
| 143226 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); | 144029 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); |
| 143227 | if( pItem->fg.isNestedFrom ){ | 144030 | if( pItem->fg.isNestedFrom ){ |
| 143228 | ExprList *pResults; | 144031 | ExprList *pResults; |
| 143229 | assert( pItem->pSelect!=0 ); | 144032 | assert( pItem->fg.isSubquery ); |
| 143230 | pResults = pItem->pSelect->pEList; | 144033 | assert( pItem->u4.pSubq!=0 ); |
| 144034 | assert( pItem->u4.pSubq->pSelect!=0 ); | ||
| 144035 | pResults = pItem->u4.pSubq->pSelect->pEList; | ||
| 143231 | assert( pResults!=0 ); | 144036 | assert( pResults!=0 ); |
| 143232 | assert( iCol>=0 && iCol<pResults->nExpr ); | 144037 | assert( iCol>=0 && iCol<pResults->nExpr ); |
| 143233 | pResults->a[iCol].fg.bUsed = 1; | 144038 | pResults->a[iCol].fg.bUsed = 1; |
| @@ -143261,9 +144066,9 @@ static int tableAndColumnIndex( | |||
| 143261 | assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ | 144066 | assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ |
| 143262 | 144067 | ||
| 143263 | for(i=iStart; i<=iEnd; i++){ | 144068 | for(i=iStart; i<=iEnd; i++){ |
| 143264 | iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); | 144069 | iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); |
| 143265 | if( iCol>=0 | 144070 | if( iCol>=0 |
| 143266 | && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) | 144071 | && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) |
| 143267 | ){ | 144072 | ){ |
| 143268 | if( piTab ){ | 144073 | if( piTab ){ |
| 143269 | sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); | 144074 | sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); |
| @@ -143392,10 +144197,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ | |||
| 143392 | pLeft = &pSrc->a[0]; | 144197 | pLeft = &pSrc->a[0]; |
| 143393 | pRight = &pLeft[1]; | 144198 | pRight = &pLeft[1]; |
| 143394 | for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ | 144199 | for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ |
| 143395 | Table *pRightTab = pRight->pTab; | 144200 | Table *pRightTab = pRight->pSTab; |
| 143396 | u32 joinType; | 144201 | u32 joinType; |
| 143397 | 144202 | ||
| 143398 | if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; | 144203 | if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; |
| 143399 | joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; | 144204 | joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; |
| 143400 | 144205 | ||
| 143401 | /* If this is a NATURAL join, synthesize an appropriate USING clause | 144206 | /* If this is a NATURAL join, synthesize an appropriate USING clause |
| @@ -144268,12 +145073,18 @@ static void selectInnerLoop( | |||
| 144268 | ** case the order does matter */ | 145073 | ** case the order does matter */ |
| 144269 | pushOntoSorter( | 145074 | pushOntoSorter( |
| 144270 | pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); | 145075 | pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); |
| 145076 | pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ | ||
| 144271 | }else{ | 145077 | }else{ |
| 144272 | int r1 = sqlite3GetTempReg(pParse); | 145078 | int r1 = sqlite3GetTempReg(pParse); |
| 144273 | assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); | 145079 | assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); |
| 144274 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, | 145080 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, |
| 144275 | r1, pDest->zAffSdst, nResultCol); | 145081 | r1, pDest->zAffSdst, nResultCol); |
| 144276 | sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); | 145082 | sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); |
| 145083 | if( pDest->iSDParm2 ){ | ||
| 145084 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, | ||
| 145085 | regResult, nResultCol); | ||
| 145086 | ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); | ||
| 145087 | } | ||
| 144277 | sqlite3ReleaseTempReg(pParse, r1); | 145088 | sqlite3ReleaseTempReg(pParse, r1); |
| 144278 | } | 145089 | } |
| 144279 | break; | 145090 | break; |
| @@ -144815,8 +145626,12 @@ static const char *columnTypeImpl( | |||
| 144815 | SrcList *pTabList = pNC->pSrcList; | 145626 | SrcList *pTabList = pNC->pSrcList; |
| 144816 | for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); | 145627 | for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); |
| 144817 | if( j<pTabList->nSrc ){ | 145628 | if( j<pTabList->nSrc ){ |
| 144818 | pTab = pTabList->a[j].pTab; | 145629 | pTab = pTabList->a[j].pSTab; |
| 144819 | pS = pTabList->a[j].pSelect; | 145630 | if( pTabList->a[j].fg.isSubquery ){ |
| 145631 | pS = pTabList->a[j].u4.pSubq->pSelect; | ||
| 145632 | }else{ | ||
| 145633 | pS = 0; | ||
| 145634 | } | ||
| 144820 | }else{ | 145635 | }else{ |
| 144821 | pNC = pNC->pNext; | 145636 | pNC = pNC->pNext; |
| 144822 | } | 145637 | } |
| @@ -145383,7 +146198,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ | |||
| 145383 | p->iLimit = iLimit = ++pParse->nMem; | 146198 | p->iLimit = iLimit = ++pParse->nMem; |
| 145384 | v = sqlite3GetVdbe(pParse); | 146199 | v = sqlite3GetVdbe(pParse); |
| 145385 | assert( v!=0 ); | 146200 | assert( v!=0 ); |
| 145386 | if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ | 146201 | if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ |
| 145387 | sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); | 146202 | sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); |
| 145388 | VdbeComment((v, "LIMIT counter")); | 146203 | VdbeComment((v, "LIMIT counter")); |
| 145389 | if( n==0 ){ | 146204 | if( n==0 ){ |
| @@ -145863,7 +146678,7 @@ static int multiSelect( | |||
| 145863 | p->pPrior = pPrior; | 146678 | p->pPrior = pPrior; |
| 145864 | p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); | 146679 | p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); |
| 145865 | if( p->pLimit | 146680 | if( p->pLimit |
| 145866 | && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) | 146681 | && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) |
| 145867 | && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) | 146682 | && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) |
| 145868 | ){ | 146683 | ){ |
| 145869 | p->nSelectRow = sqlite3LogEst((u64)nLimit); | 146684 | p->nSelectRow = sqlite3LogEst((u64)nLimit); |
| @@ -146207,6 +147022,11 @@ static int generateOutputSubroutine( | |||
| 146207 | r1, pDest->zAffSdst, pIn->nSdst); | 147022 | r1, pDest->zAffSdst, pIn->nSdst); |
| 146208 | sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, | 147023 | sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, |
| 146209 | pIn->iSdst, pIn->nSdst); | 147024 | pIn->iSdst, pIn->nSdst); |
| 147025 | if( pDest->iSDParm2>0 ){ | ||
| 147026 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, | ||
| 147027 | pIn->iSdst, pIn->nSdst); | ||
| 147028 | ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); | ||
| 147029 | } | ||
| 146210 | sqlite3ReleaseTempReg(pParse, r1); | 147030 | sqlite3ReleaseTempReg(pParse, r1); |
| 146211 | break; | 147031 | break; |
| 146212 | } | 147032 | } |
| @@ -146863,7 +147683,9 @@ static void substSelect( | |||
| 146863 | pSrc = p->pSrc; | 147683 | pSrc = p->pSrc; |
| 146864 | assert( pSrc!=0 ); | 147684 | assert( pSrc!=0 ); |
| 146865 | for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ | 147685 | for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ |
| 146866 | substSelect(pSubst, pItem->pSelect, 1); | 147686 | if( pItem->fg.isSubquery ){ |
| 147687 | substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); | ||
| 147688 | } | ||
| 146867 | if( pItem->fg.isTabFunc ){ | 147689 | if( pItem->fg.isTabFunc ){ |
| 146868 | substExprList(pSubst, pItem->u1.pFuncArg); | 147690 | substExprList(pSubst, pItem->u1.pFuncArg); |
| 146869 | } | 147691 | } |
| @@ -146894,7 +147716,7 @@ static void recomputeColumnsUsed( | |||
| 146894 | SrcItem *pSrcItem /* Which FROM clause item to recompute */ | 147716 | SrcItem *pSrcItem /* Which FROM clause item to recompute */ |
| 146895 | ){ | 147717 | ){ |
| 146896 | Walker w; | 147718 | Walker w; |
| 146897 | if( NEVER(pSrcItem->pTab==0) ) return; | 147719 | if( NEVER(pSrcItem->pSTab==0) ) return; |
| 146898 | memset(&w, 0, sizeof(w)); | 147720 | memset(&w, 0, sizeof(w)); |
| 146899 | w.xExprCallback = recomputeColumnsUsedExpr; | 147721 | w.xExprCallback = recomputeColumnsUsedExpr; |
| 146900 | w.xSelectCallback = sqlite3SelectWalkNoop; | 147722 | w.xSelectCallback = sqlite3SelectWalkNoop; |
| @@ -146934,8 +147756,10 @@ static void srclistRenumberCursors( | |||
| 146934 | aCsrMap[pItem->iCursor+1] = pParse->nTab++; | 147756 | aCsrMap[pItem->iCursor+1] = pParse->nTab++; |
| 146935 | } | 147757 | } |
| 146936 | pItem->iCursor = aCsrMap[pItem->iCursor+1]; | 147758 | pItem->iCursor = aCsrMap[pItem->iCursor+1]; |
| 146937 | for(p=pItem->pSelect; p; p=p->pPrior){ | 147759 | if( pItem->fg.isSubquery ){ |
| 146938 | srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); | 147760 | for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ |
| 147761 | srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); | ||
| 147762 | } | ||
| 146939 | } | 147763 | } |
| 146940 | } | 147764 | } |
| 146941 | } | 147765 | } |
| @@ -147246,7 +148070,8 @@ static int flattenSubquery( | |||
| 147246 | assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); | 148070 | assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); |
| 147247 | pSubitem = &pSrc->a[iFrom]; | 148071 | pSubitem = &pSrc->a[iFrom]; |
| 147248 | iParent = pSubitem->iCursor; | 148072 | iParent = pSubitem->iCursor; |
| 147249 | pSub = pSubitem->pSelect; | 148073 | assert( pSubitem->fg.isSubquery ); |
| 148074 | pSub = pSubitem->u4.pSubq->pSelect; | ||
| 147250 | assert( pSub!=0 ); | 148075 | assert( pSub!=0 ); |
| 147251 | 148076 | ||
| 147252 | #ifndef SQLITE_OMIT_WINDOWFUNC | 148077 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| @@ -147299,7 +148124,7 @@ static int flattenSubquery( | |||
| 147299 | */ | 148124 | */ |
| 147300 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ | 148125 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 147301 | if( pSubSrc->nSrc>1 /* (3a) */ | 148126 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 147302 | || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ | 148127 | || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ |
| 147303 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ | 148128 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 147304 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ | 148129 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 147305 | ){ | 148130 | ){ |
| @@ -147385,14 +148210,18 @@ static int flattenSubquery( | |||
| 147385 | pParse->zAuthContext = zSavedAuthContext; | 148210 | pParse->zAuthContext = zSavedAuthContext; |
| 147386 | 148211 | ||
| 147387 | /* Delete the transient structures associated with the subquery */ | 148212 | /* Delete the transient structures associated with the subquery */ |
| 147388 | pSub1 = pSubitem->pSelect; | 148213 | |
| 147389 | sqlite3DbFree(db, pSubitem->zDatabase); | 148214 | if( ALWAYS(pSubitem->fg.isSubquery) ){ |
| 148215 | pSub1 = sqlite3SubqueryDetach(db, pSubitem); | ||
| 148216 | }else{ | ||
| 148217 | pSub1 = 0; | ||
| 148218 | } | ||
| 148219 | assert( pSubitem->fg.isSubquery==0 ); | ||
| 148220 | assert( pSubitem->fg.fixedSchema==0 ); | ||
| 147390 | sqlite3DbFree(db, pSubitem->zName); | 148221 | sqlite3DbFree(db, pSubitem->zName); |
| 147391 | sqlite3DbFree(db, pSubitem->zAlias); | 148222 | sqlite3DbFree(db, pSubitem->zAlias); |
| 147392 | pSubitem->zDatabase = 0; | ||
| 147393 | pSubitem->zName = 0; | 148223 | pSubitem->zName = 0; |
| 147394 | pSubitem->zAlias = 0; | 148224 | pSubitem->zAlias = 0; |
| 147395 | pSubitem->pSelect = 0; | ||
| 147396 | assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); | 148225 | assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); |
| 147397 | 148226 | ||
| 147398 | /* If the sub-query is a compound SELECT statement, then (by restrictions | 148227 | /* If the sub-query is a compound SELECT statement, then (by restrictions |
| @@ -147433,8 +148262,8 @@ static int flattenSubquery( | |||
| 147433 | ExprList *pOrderBy = p->pOrderBy; | 148262 | ExprList *pOrderBy = p->pOrderBy; |
| 147434 | Expr *pLimit = p->pLimit; | 148263 | Expr *pLimit = p->pLimit; |
| 147435 | Select *pPrior = p->pPrior; | 148264 | Select *pPrior = p->pPrior; |
| 147436 | Table *pItemTab = pSubitem->pTab; | 148265 | Table *pItemTab = pSubitem->pSTab; |
| 147437 | pSubitem->pTab = 0; | 148266 | pSubitem->pSTab = 0; |
| 147438 | p->pOrderBy = 0; | 148267 | p->pOrderBy = 0; |
| 147439 | p->pPrior = 0; | 148268 | p->pPrior = 0; |
| 147440 | p->pLimit = 0; | 148269 | p->pLimit = 0; |
| @@ -147442,7 +148271,7 @@ static int flattenSubquery( | |||
| 147442 | p->pLimit = pLimit; | 148271 | p->pLimit = pLimit; |
| 147443 | p->pOrderBy = pOrderBy; | 148272 | p->pOrderBy = pOrderBy; |
| 147444 | p->op = TK_ALL; | 148273 | p->op = TK_ALL; |
| 147445 | pSubitem->pTab = pItemTab; | 148274 | pSubitem->pSTab = pItemTab; |
| 147446 | if( pNew==0 ){ | 148275 | if( pNew==0 ){ |
| 147447 | p->pPrior = pPrior; | 148276 | p->pPrior = pPrior; |
| 147448 | }else{ | 148277 | }else{ |
| @@ -147457,11 +148286,14 @@ static int flattenSubquery( | |||
| 147457 | TREETRACE(0x4,pParse,p,("compound-subquery flattener" | 148286 | TREETRACE(0x4,pParse,p,("compound-subquery flattener" |
| 147458 | " creates %u as peer\n",pNew->selId)); | 148287 | " creates %u as peer\n",pNew->selId)); |
| 147459 | } | 148288 | } |
| 147460 | assert( pSubitem->pSelect==0 ); | 148289 | assert( pSubitem->fg.isSubquery==0 ); |
| 147461 | } | 148290 | } |
| 147462 | sqlite3DbFree(db, aCsrMap); | 148291 | sqlite3DbFree(db, aCsrMap); |
| 147463 | if( db->mallocFailed ){ | 148292 | if( db->mallocFailed ){ |
| 147464 | pSubitem->pSelect = pSub1; | 148293 | assert( pSubitem->fg.fixedSchema==0 ); |
| 148294 | assert( pSubitem->fg.isSubquery==0 ); | ||
| 148295 | assert( pSubitem->u4.zDatabase==0 ); | ||
| 148296 | sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); | ||
| 147465 | return 1; | 148297 | return 1; |
| 147466 | } | 148298 | } |
| 147467 | 148299 | ||
| @@ -147472,8 +148304,8 @@ static int flattenSubquery( | |||
| 147472 | ** | 148304 | ** |
| 147473 | ** pSubitem->pTab is always non-NULL by test restrictions and tests above. | 148305 | ** pSubitem->pTab is always non-NULL by test restrictions and tests above. |
| 147474 | */ | 148306 | */ |
| 147475 | if( ALWAYS(pSubitem->pTab!=0) ){ | 148307 | if( ALWAYS(pSubitem->pSTab!=0) ){ |
| 147476 | Table *pTabToDel = pSubitem->pTab; | 148308 | Table *pTabToDel = pSubitem->pSTab; |
| 147477 | if( pTabToDel->nTabRef==1 ){ | 148309 | if( pTabToDel->nTabRef==1 ){ |
| 147478 | Parse *pToplevel = sqlite3ParseToplevel(pParse); | 148310 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 147479 | sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); | 148311 | sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); |
| @@ -147481,7 +148313,7 @@ static int flattenSubquery( | |||
| 147481 | }else{ | 148313 | }else{ |
| 147482 | pTabToDel->nTabRef--; | 148314 | pTabToDel->nTabRef--; |
| 147483 | } | 148315 | } |
| 147484 | pSubitem->pTab = 0; | 148316 | pSubitem->pSTab = 0; |
| 147485 | } | 148317 | } |
| 147486 | 148318 | ||
| 147487 | /* The following loop runs once for each term in a compound-subquery | 148319 | /* The following loop runs once for each term in a compound-subquery |
| @@ -147537,8 +148369,11 @@ static int flattenSubquery( | |||
| 147537 | */ | 148369 | */ |
| 147538 | for(i=0; i<nSubSrc; i++){ | 148370 | for(i=0; i<nSubSrc; i++){ |
| 147539 | SrcItem *pItem = &pSrc->a[i+iFrom]; | 148371 | SrcItem *pItem = &pSrc->a[i+iFrom]; |
| 147540 | if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); | ||
| 147541 | assert( pItem->fg.isTabFunc==0 ); | 148372 | assert( pItem->fg.isTabFunc==0 ); |
| 148373 | assert( pItem->fg.isSubquery | ||
| 148374 | || pItem->fg.fixedSchema | ||
| 148375 | || pItem->u4.zDatabase==0 ); | ||
| 148376 | if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); | ||
| 147542 | *pItem = pSubSrc->a[i]; | 148377 | *pItem = pSubSrc->a[i]; |
| 147543 | pItem->fg.jointype |= ltorj; | 148378 | pItem->fg.jointype |= ltorj; |
| 147544 | iNewParent = pSubSrc->a[i].iCursor; | 148379 | iNewParent = pSubSrc->a[i].iCursor; |
| @@ -147957,7 +148792,8 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ | |||
| 147957 | ** | 148792 | ** |
| 147958 | ** NAME AMBIGUITY | 148793 | ** NAME AMBIGUITY |
| 147959 | ** | 148794 | ** |
| 147960 | ** This optimization is called the "WHERE-clause push-down optimization". | 148795 | ** This optimization is called the "WHERE-clause push-down optimization" |
| 148796 | ** or sometimes the "predicate push-down optimization". | ||
| 147961 | ** | 148797 | ** |
| 147962 | ** Do not confuse this optimization with another unrelated optimization | 148798 | ** Do not confuse this optimization with another unrelated optimization |
| 147963 | ** with a similar name: The "MySQL push-down optimization" causes WHERE | 148799 | ** with a similar name: The "MySQL push-down optimization" causes WHERE |
| @@ -148221,10 +149057,10 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ | |||
| 148221 | if( pItem->fg.isCorrelated || pItem->fg.isCte ){ | 149057 | if( pItem->fg.isCorrelated || pItem->fg.isCte ){ |
| 148222 | return 0; | 149058 | return 0; |
| 148223 | } | 149059 | } |
| 148224 | assert( pItem->pTab!=0 ); | 149060 | assert( pItem->pSTab!=0 ); |
| 148225 | pTab = pItem->pTab; | 149061 | pTab = pItem->pSTab; |
| 148226 | assert( pItem->pSelect!=0 ); | 149062 | assert( pItem->fg.isSubquery ); |
| 148227 | pSub = pItem->pSelect; | 149063 | pSub = pItem->u4.pSubq->pSelect; |
| 148228 | assert( pSub->pEList->nExpr==pTab->nCol ); | 149064 | assert( pSub->pEList->nExpr==pTab->nCol ); |
| 148229 | for(pX=pSub; pX; pX=pX->pPrior){ | 149065 | for(pX=pSub; pX; pX=pX->pPrior){ |
| 148230 | if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ | 149066 | if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ |
| @@ -148353,13 +149189,13 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ | |||
| 148353 | if( p->pWhere | 149189 | if( p->pWhere |
| 148354 | || p->pEList->nExpr!=1 | 149190 | || p->pEList->nExpr!=1 |
| 148355 | || p->pSrc->nSrc!=1 | 149191 | || p->pSrc->nSrc!=1 |
| 148356 | || p->pSrc->a[0].pSelect | 149192 | || p->pSrc->a[0].fg.isSubquery |
| 148357 | || pAggInfo->nFunc!=1 | 149193 | || pAggInfo->nFunc!=1 |
| 148358 | || p->pHaving | 149194 | || p->pHaving |
| 148359 | ){ | 149195 | ){ |
| 148360 | return 0; | 149196 | return 0; |
| 148361 | } | 149197 | } |
| 148362 | pTab = p->pSrc->a[0].pTab; | 149198 | pTab = p->pSrc->a[0].pSTab; |
| 148363 | assert( pTab!=0 ); | 149199 | assert( pTab!=0 ); |
| 148364 | assert( !IsView(pTab) ); | 149200 | assert( !IsView(pTab) ); |
| 148365 | if( !IsOrdinaryTable(pTab) ) return 0; | 149201 | if( !IsOrdinaryTable(pTab) ) return 0; |
| @@ -148384,7 +149220,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ | |||
| 148384 | ** pFrom->pIndex and return SQLITE_OK. | 149220 | ** pFrom->pIndex and return SQLITE_OK. |
| 148385 | */ | 149221 | */ |
| 148386 | SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ | 149222 | SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ |
| 148387 | Table *pTab = pFrom->pTab; | 149223 | Table *pTab = pFrom->pSTab; |
| 148388 | char *zIndexedBy = pFrom->u1.zIndexedBy; | 149224 | char *zIndexedBy = pFrom->u1.zIndexedBy; |
| 148389 | Index *pIdx; | 149225 | Index *pIdx; |
| 148390 | assert( pTab!=0 ); | 149226 | assert( pTab!=0 ); |
| @@ -148461,7 +149297,11 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ | |||
| 148461 | if( pNew==0 ) return WRC_Abort; | 149297 | if( pNew==0 ) return WRC_Abort; |
| 148462 | memset(&dummy, 0, sizeof(dummy)); | 149298 | memset(&dummy, 0, sizeof(dummy)); |
| 148463 | pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); | 149299 | pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); |
| 148464 | if( pNewSrc==0 ) return WRC_Abort; | 149300 | assert( pNewSrc!=0 || pParse->nErr ); |
| 149301 | if( pParse->nErr ){ | ||
| 149302 | sqlite3SrcListDelete(db, pNewSrc); | ||
| 149303 | return WRC_Abort; | ||
| 149304 | } | ||
| 148465 | *pNew = *p; | 149305 | *pNew = *p; |
| 148466 | p->pSrc = pNewSrc; | 149306 | p->pSrc = pNewSrc; |
| 148467 | p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); | 149307 | p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); |
| @@ -148516,7 +149356,7 @@ static struct Cte *searchWith( | |||
| 148516 | ){ | 149356 | ){ |
| 148517 | const char *zName = pItem->zName; | 149357 | const char *zName = pItem->zName; |
| 148518 | With *p; | 149358 | With *p; |
| 148519 | assert( pItem->zDatabase==0 ); | 149359 | assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); |
| 148520 | assert( zName!=0 ); | 149360 | assert( zName!=0 ); |
| 148521 | for(p=pWith; p; p=p->pOuter){ | 149361 | for(p=pWith; p; p=p->pOuter){ |
| 148522 | int i; | 149362 | int i; |
| @@ -148586,7 +149426,7 @@ static int resolveFromTermToCte( | |||
| 148586 | Cte *pCte; /* Matched CTE (or NULL if no match) */ | 149426 | Cte *pCte; /* Matched CTE (or NULL if no match) */ |
| 148587 | With *pWith; /* The matching WITH */ | 149427 | With *pWith; /* The matching WITH */ |
| 148588 | 149428 | ||
| 148589 | assert( pFrom->pTab==0 ); | 149429 | assert( pFrom->pSTab==0 ); |
| 148590 | if( pParse->pWith==0 ){ | 149430 | if( pParse->pWith==0 ){ |
| 148591 | /* There are no WITH clauses in the stack. No match is possible */ | 149431 | /* There are no WITH clauses in the stack. No match is possible */ |
| 148592 | return 0; | 149432 | return 0; |
| @@ -148596,7 +149436,8 @@ static int resolveFromTermToCte( | |||
| 148596 | ** go no further. */ | 149436 | ** go no further. */ |
| 148597 | return 0; | 149437 | return 0; |
| 148598 | } | 149438 | } |
| 148599 | if( pFrom->zDatabase!=0 ){ | 149439 | assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); |
| 149440 | if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ | ||
| 148600 | /* The FROM term contains a schema qualifier (ex: main.t1) and so | 149441 | /* The FROM term contains a schema qualifier (ex: main.t1) and so |
| 148601 | ** it cannot possibly be a CTE reference. */ | 149442 | ** it cannot possibly be a CTE reference. */ |
| 148602 | return 0; | 149443 | return 0; |
| @@ -148632,7 +149473,7 @@ static int resolveFromTermToCte( | |||
| 148632 | } | 149473 | } |
| 148633 | if( cannotBeFunction(pParse, pFrom) ) return 2; | 149474 | if( cannotBeFunction(pParse, pFrom) ) return 2; |
| 148634 | 149475 | ||
| 148635 | assert( pFrom->pTab==0 ); | 149476 | assert( pFrom->pSTab==0 ); |
| 148636 | pTab = sqlite3DbMallocZero(db, sizeof(Table)); | 149477 | pTab = sqlite3DbMallocZero(db, sizeof(Table)); |
| 148637 | if( pTab==0 ) return 2; | 149478 | if( pTab==0 ) return 2; |
| 148638 | pCteUse = pCte->pUse; | 149479 | pCteUse = pCte->pUse; |
| @@ -148646,26 +149487,29 @@ static int resolveFromTermToCte( | |||
| 148646 | } | 149487 | } |
| 148647 | pCteUse->eM10d = pCte->eM10d; | 149488 | pCteUse->eM10d = pCte->eM10d; |
| 148648 | } | 149489 | } |
| 148649 | pFrom->pTab = pTab; | 149490 | pFrom->pSTab = pTab; |
| 148650 | pTab->nTabRef = 1; | 149491 | pTab->nTabRef = 1; |
| 148651 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); | 149492 | pTab->zName = sqlite3DbStrDup(db, pCte->zName); |
| 148652 | pTab->iPKey = -1; | 149493 | pTab->iPKey = -1; |
| 148653 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | 149494 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 148654 | pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; | 149495 | pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; |
| 148655 | pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); | 149496 | sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); |
| 148656 | if( db->mallocFailed ) return 2; | 149497 | if( db->mallocFailed ) return 2; |
| 148657 | pFrom->pSelect->selFlags |= SF_CopyCte; | 149498 | assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); |
| 148658 | assert( pFrom->pSelect ); | 149499 | pSel = pFrom->u4.pSubq->pSelect; |
| 149500 | assert( pSel!=0 ); | ||
| 149501 | pSel->selFlags |= SF_CopyCte; | ||
| 148659 | if( pFrom->fg.isIndexedBy ){ | 149502 | if( pFrom->fg.isIndexedBy ){ |
| 148660 | sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); | 149503 | sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); |
| 148661 | return 2; | 149504 | return 2; |
| 148662 | } | 149505 | } |
| 149506 | assert( !pFrom->fg.isIndexedBy ); | ||
| 148663 | pFrom->fg.isCte = 1; | 149507 | pFrom->fg.isCte = 1; |
| 148664 | pFrom->u2.pCteUse = pCteUse; | 149508 | pFrom->u2.pCteUse = pCteUse; |
| 148665 | pCteUse->nUse++; | 149509 | pCteUse->nUse++; |
| 148666 | 149510 | ||
| 148667 | /* Check if this is a recursive CTE. */ | 149511 | /* Check if this is a recursive CTE. */ |
| 148668 | pRecTerm = pSel = pFrom->pSelect; | 149512 | pRecTerm = pSel; |
| 148669 | bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); | 149513 | bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); |
| 148670 | while( bMayRecursive && pRecTerm->op==pSel->op ){ | 149514 | while( bMayRecursive && pRecTerm->op==pSel->op ){ |
| 148671 | int i; | 149515 | int i; |
| @@ -148673,11 +149517,13 @@ static int resolveFromTermToCte( | |||
| 148673 | assert( pRecTerm->pPrior!=0 ); | 149517 | assert( pRecTerm->pPrior!=0 ); |
| 148674 | for(i=0; i<pSrc->nSrc; i++){ | 149518 | for(i=0; i<pSrc->nSrc; i++){ |
| 148675 | SrcItem *pItem = &pSrc->a[i]; | 149519 | SrcItem *pItem = &pSrc->a[i]; |
| 148676 | if( pItem->zDatabase==0 | 149520 | if( pItem->zName!=0 |
| 148677 | && pItem->zName!=0 | 149521 | && !pItem->fg.hadSchema |
| 149522 | && ALWAYS( !pItem->fg.isSubquery ) | ||
| 149523 | && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) | ||
| 148678 | && 0==sqlite3StrICmp(pItem->zName, pCte->zName) | 149524 | && 0==sqlite3StrICmp(pItem->zName, pCte->zName) |
| 148679 | ){ | 149525 | ){ |
| 148680 | pItem->pTab = pTab; | 149526 | pItem->pSTab = pTab; |
| 148681 | pTab->nTabRef++; | 149527 | pTab->nTabRef++; |
| 148682 | pItem->fg.isRecursive = 1; | 149528 | pItem->fg.isRecursive = 1; |
| 148683 | if( pRecTerm->selFlags & SF_Recursive ){ | 149529 | if( pRecTerm->selFlags & SF_Recursive ){ |
| @@ -148779,11 +149625,14 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ | |||
| 148779 | ** SQLITE_NOMEM. | 149625 | ** SQLITE_NOMEM. |
| 148780 | */ | 149626 | */ |
| 148781 | SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ | 149627 | SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ |
| 148782 | Select *pSel = pFrom->pSelect; | 149628 | Select *pSel; |
| 148783 | Table *pTab; | 149629 | Table *pTab; |
| 148784 | 149630 | ||
| 149631 | assert( pFrom->fg.isSubquery ); | ||
| 149632 | assert( pFrom->u4.pSubq!=0 ); | ||
| 149633 | pSel = pFrom->u4.pSubq->pSelect; | ||
| 148785 | assert( pSel ); | 149634 | assert( pSel ); |
| 148786 | pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); | 149635 | pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); |
| 148787 | if( pTab==0 ) return SQLITE_NOMEM; | 149636 | if( pTab==0 ) return SQLITE_NOMEM; |
| 148788 | pTab->nTabRef = 1; | 149637 | pTab->nTabRef = 1; |
| 148789 | if( pFrom->zAlias ){ | 149638 | if( pFrom->zAlias ){ |
| @@ -148903,33 +149752,35 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 148903 | */ | 149752 | */ |
| 148904 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | 149753 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ |
| 148905 | Table *pTab; | 149754 | Table *pTab; |
| 148906 | assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); | 149755 | assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); |
| 148907 | if( pFrom->pTab ) continue; | 149756 | if( pFrom->pSTab ) continue; |
| 148908 | assert( pFrom->fg.isRecursive==0 ); | 149757 | assert( pFrom->fg.isRecursive==0 ); |
| 148909 | if( pFrom->zName==0 ){ | 149758 | if( pFrom->zName==0 ){ |
| 148910 | #ifndef SQLITE_OMIT_SUBQUERY | 149759 | #ifndef SQLITE_OMIT_SUBQUERY |
| 148911 | Select *pSel = pFrom->pSelect; | 149760 | Select *pSel; |
| 149761 | assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); | ||
| 149762 | pSel = pFrom->u4.pSubq->pSelect; | ||
| 148912 | /* A sub-query in the FROM clause of a SELECT */ | 149763 | /* A sub-query in the FROM clause of a SELECT */ |
| 148913 | assert( pSel!=0 ); | 149764 | assert( pSel!=0 ); |
| 148914 | assert( pFrom->pTab==0 ); | 149765 | assert( pFrom->pSTab==0 ); |
| 148915 | if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; | 149766 | if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; |
| 148916 | if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; | 149767 | if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; |
| 148917 | #endif | 149768 | #endif |
| 148918 | #ifndef SQLITE_OMIT_CTE | 149769 | #ifndef SQLITE_OMIT_CTE |
| 148919 | }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ | 149770 | }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ |
| 148920 | if( rc>1 ) return WRC_Abort; | 149771 | if( rc>1 ) return WRC_Abort; |
| 148921 | pTab = pFrom->pTab; | 149772 | pTab = pFrom->pSTab; |
| 148922 | assert( pTab!=0 ); | 149773 | assert( pTab!=0 ); |
| 148923 | #endif | 149774 | #endif |
| 148924 | }else{ | 149775 | }else{ |
| 148925 | /* An ordinary table or view name in the FROM clause */ | 149776 | /* An ordinary table or view name in the FROM clause */ |
| 148926 | assert( pFrom->pTab==0 ); | 149777 | assert( pFrom->pSTab==0 ); |
| 148927 | pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); | 149778 | pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); |
| 148928 | if( pTab==0 ) return WRC_Abort; | 149779 | if( pTab==0 ) return WRC_Abort; |
| 148929 | if( pTab->nTabRef>=0xffff ){ | 149780 | if( pTab->nTabRef>=0xffff ){ |
| 148930 | sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", | 149781 | sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", |
| 148931 | pTab->zName); | 149782 | pTab->zName); |
| 148932 | pFrom->pTab = 0; | 149783 | pFrom->pSTab = 0; |
| 148933 | return WRC_Abort; | 149784 | return WRC_Abort; |
| 148934 | } | 149785 | } |
| 148935 | pTab->nTabRef++; | 149786 | pTab->nTabRef++; |
| @@ -148941,7 +149792,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 148941 | i16 nCol; | 149792 | i16 nCol; |
| 148942 | u8 eCodeOrig = pWalker->eCode; | 149793 | u8 eCodeOrig = pWalker->eCode; |
| 148943 | if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; | 149794 | if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; |
| 148944 | assert( pFrom->pSelect==0 ); | 149795 | assert( pFrom->fg.isSubquery==0 ); |
| 148945 | if( IsView(pTab) ){ | 149796 | if( IsView(pTab) ){ |
| 148946 | if( (db->flags & SQLITE_EnableView)==0 | 149797 | if( (db->flags & SQLITE_EnableView)==0 |
| 148947 | && pTab->pSchema!=db->aDb[1].pSchema | 149798 | && pTab->pSchema!=db->aDb[1].pSchema |
| @@ -148949,7 +149800,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 148949 | sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", | 149800 | sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", |
| 148950 | pTab->zName); | 149801 | pTab->zName); |
| 148951 | } | 149802 | } |
| 148952 | pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); | 149803 | sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); |
| 148953 | } | 149804 | } |
| 148954 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 149805 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 148955 | else if( ALWAYS(IsVirtual(pTab)) | 149806 | else if( ALWAYS(IsVirtual(pTab)) |
| @@ -148965,7 +149816,9 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 148965 | nCol = pTab->nCol; | 149816 | nCol = pTab->nCol; |
| 148966 | pTab->nCol = -1; | 149817 | pTab->nCol = -1; |
| 148967 | pWalker->eCode = 1; /* Turn on Select.selId renumbering */ | 149818 | pWalker->eCode = 1; /* Turn on Select.selId renumbering */ |
| 148968 | sqlite3WalkSelect(pWalker, pFrom->pSelect); | 149819 | if( pFrom->fg.isSubquery ){ |
| 149820 | sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); | ||
| 149821 | } | ||
| 148969 | pWalker->eCode = eCodeOrig; | 149822 | pWalker->eCode = eCodeOrig; |
| 148970 | pTab->nCol = nCol; | 149823 | pTab->nCol = nCol; |
| 148971 | } | 149824 | } |
| @@ -149052,7 +149905,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 149052 | } | 149905 | } |
| 149053 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | 149906 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ |
| 149054 | int nAdd; /* Number of cols including rowid */ | 149907 | int nAdd; /* Number of cols including rowid */ |
| 149055 | Table *pTab = pFrom->pTab; /* Table for this data source */ | 149908 | Table *pTab = pFrom->pSTab; /* Table for this data source */ |
| 149056 | ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ | 149909 | ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ |
| 149057 | char *zTabName; /* AS name for this data source */ | 149910 | char *zTabName; /* AS name for this data source */ |
| 149058 | const char *zSchemaName = 0; /* Schema name for this data source */ | 149911 | const char *zSchemaName = 0; /* Schema name for this data source */ |
| @@ -149063,10 +149916,11 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 149063 | zTabName = pTab->zName; | 149916 | zTabName = pTab->zName; |
| 149064 | } | 149917 | } |
| 149065 | if( db->mallocFailed ) break; | 149918 | if( db->mallocFailed ) break; |
| 149066 | assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); | 149919 | assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); |
| 149067 | if( pFrom->fg.isNestedFrom ){ | 149920 | if( pFrom->fg.isNestedFrom ){ |
| 149068 | assert( pFrom->pSelect!=0 ); | 149921 | assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); |
| 149069 | pNestedFrom = pFrom->pSelect->pEList; | 149922 | assert( pFrom->u4.pSubq->pSelect!=0 ); |
| 149923 | pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; | ||
| 149070 | assert( pNestedFrom!=0 ); | 149924 | assert( pNestedFrom!=0 ); |
| 149071 | assert( pNestedFrom->nExpr==pTab->nCol ); | 149925 | assert( pNestedFrom->nExpr==pTab->nCol ); |
| 149072 | assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); | 149926 | assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); |
| @@ -149305,14 +150159,12 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ | |||
| 149305 | assert( (p->selFlags & SF_Resolved) ); | 150159 | assert( (p->selFlags & SF_Resolved) ); |
| 149306 | pTabList = p->pSrc; | 150160 | pTabList = p->pSrc; |
| 149307 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | 150161 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ |
| 149308 | Table *pTab = pFrom->pTab; | 150162 | Table *pTab = pFrom->pSTab; |
| 149309 | assert( pTab!=0 ); | 150163 | assert( pTab!=0 ); |
| 149310 | if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ | 150164 | if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ |
| 149311 | /* A sub-query in the FROM clause of a SELECT */ | 150165 | /* A sub-query in the FROM clause of a SELECT */ |
| 149312 | Select *pSel = pFrom->pSelect; | 150166 | Select *pSel = pFrom->u4.pSubq->pSelect; |
| 149313 | if( pSel ){ | 150167 | sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); |
| 149314 | sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); | ||
| 149315 | } | ||
| 149316 | } | 150168 | } |
| 149317 | } | 150169 | } |
| 149318 | } | 150170 | } |
| @@ -149626,6 +150478,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ | |||
| 149626 | for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ | 150478 | for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ |
| 149627 | ExprList *pList; | 150479 | ExprList *pList; |
| 149628 | assert( ExprUseXList(pF->pFExpr) ); | 150480 | assert( ExprUseXList(pF->pFExpr) ); |
| 150481 | if( pParse->nErr ) return; | ||
| 149629 | pList = pF->pFExpr->x.pList; | 150482 | pList = pF->pFExpr->x.pList; |
| 149630 | if( pF->iOBTab>=0 ){ | 150483 | if( pF->iOBTab>=0 ){ |
| 149631 | /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs | 150484 | /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs |
| @@ -149835,6 +150688,7 @@ static void updateAccumulator( | |||
| 149835 | if( addrNext ){ | 150688 | if( addrNext ){ |
| 149836 | sqlite3VdbeResolveLabel(v, addrNext); | 150689 | sqlite3VdbeResolveLabel(v, addrNext); |
| 149837 | } | 150690 | } |
| 150691 | if( pParse->nErr ) return; | ||
| 149838 | } | 150692 | } |
| 149839 | if( regHit==0 && pAggInfo->nAccumulator ){ | 150693 | if( regHit==0 && pAggInfo->nAccumulator ){ |
| 149840 | regHit = regAcc; | 150694 | regHit = regAcc; |
| @@ -149844,6 +150698,7 @@ static void updateAccumulator( | |||
| 149844 | } | 150698 | } |
| 149845 | for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ | 150699 | for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ |
| 149846 | sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); | 150700 | sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); |
| 150701 | if( pParse->nErr ) return; | ||
| 149847 | } | 150702 | } |
| 149848 | 150703 | ||
| 149849 | pAggInfo->directMode = 0; | 150704 | pAggInfo->directMode = 0; |
| @@ -149959,25 +150814,28 @@ static SrcItem *isSelfJoinView( | |||
| 149959 | int iFirst, int iEnd /* Range of FROM-clause entries to search. */ | 150814 | int iFirst, int iEnd /* Range of FROM-clause entries to search. */ |
| 149960 | ){ | 150815 | ){ |
| 149961 | SrcItem *pItem; | 150816 | SrcItem *pItem; |
| 149962 | assert( pThis->pSelect!=0 ); | 150817 | Select *pSel; |
| 149963 | if( pThis->pSelect->selFlags & SF_PushDown ) return 0; | 150818 | assert( pThis->fg.isSubquery ); |
| 150819 | pSel = pThis->u4.pSubq->pSelect; | ||
| 150820 | assert( pSel!=0 ); | ||
| 150821 | if( pSel->selFlags & SF_PushDown ) return 0; | ||
| 149964 | while( iFirst<iEnd ){ | 150822 | while( iFirst<iEnd ){ |
| 149965 | Select *pS1; | 150823 | Select *pS1; |
| 149966 | pItem = &pTabList->a[iFirst++]; | 150824 | pItem = &pTabList->a[iFirst++]; |
| 149967 | if( pItem->pSelect==0 ) continue; | 150825 | if( !pItem->fg.isSubquery ) continue; |
| 149968 | if( pItem->fg.viaCoroutine ) continue; | 150826 | if( pItem->fg.viaCoroutine ) continue; |
| 149969 | if( pItem->zName==0 ) continue; | 150827 | if( pItem->zName==0 ) continue; |
| 149970 | assert( pItem->pTab!=0 ); | 150828 | assert( pItem->pSTab!=0 ); |
| 149971 | assert( pThis->pTab!=0 ); | 150829 | assert( pThis->pSTab!=0 ); |
| 149972 | if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; | 150830 | if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; |
| 149973 | if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; | 150831 | if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; |
| 149974 | pS1 = pItem->pSelect; | 150832 | pS1 = pItem->u4.pSubq->pSelect; |
| 149975 | if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ | 150833 | if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ |
| 149976 | /* The query flattener left two different CTE tables with identical | 150834 | /* The query flattener left two different CTE tables with identical |
| 149977 | ** names in the same FROM clause. */ | 150835 | ** names in the same FROM clause. */ |
| 149978 | continue; | 150836 | continue; |
| 149979 | } | 150837 | } |
| 149980 | if( pItem->pSelect->selFlags & SF_PushDown ){ | 150838 | if( pS1->selFlags & SF_PushDown ){ |
| 149981 | /* The view was modified by some other optimization such as | 150839 | /* The view was modified by some other optimization such as |
| 149982 | ** pushDownWhereTerms() */ | 150840 | ** pushDownWhereTerms() */ |
| 149983 | continue; | 150841 | continue; |
| @@ -150021,6 +150879,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 150021 | Expr *pExpr; | 150879 | Expr *pExpr; |
| 150022 | Expr *pCount; | 150880 | Expr *pCount; |
| 150023 | sqlite3 *db; | 150881 | sqlite3 *db; |
| 150882 | SrcItem *pFrom; | ||
| 150024 | if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ | 150883 | if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ |
| 150025 | if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ | 150884 | if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ |
| 150026 | if( p->pWhere ) return 0; | 150885 | if( p->pWhere ) return 0; |
| @@ -150035,8 +150894,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 150035 | if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ | 150894 | if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ |
| 150036 | if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ | 150895 | if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ |
| 150037 | if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ | 150896 | if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ |
| 150038 | pSub = p->pSrc->a[0].pSelect; | 150897 | pFrom = p->pSrc->a; |
| 150039 | if( pSub==0 ) return 0; /* The FROM is a subquery */ | 150898 | if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ |
| 150899 | pSub = pFrom->u4.pSubq->pSelect; | ||
| 150040 | if( pSub->pPrior==0 ) return 0; /* Must be a compound */ | 150900 | if( pSub->pPrior==0 ) return 0; /* Must be a compound */ |
| 150041 | if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ | 150901 | if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ |
| 150042 | do{ | 150902 | do{ |
| @@ -150045,7 +150905,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 150045 | if( pSub->pLimit ) return 0; /* No LIMIT clause */ | 150905 | if( pSub->pLimit ) return 0; /* No LIMIT clause */ |
| 150046 | if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ | 150906 | if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ |
| 150047 | assert( pSub->pHaving==0 ); /* Due to the previous */ | 150907 | assert( pSub->pHaving==0 ); /* Due to the previous */ |
| 150048 | pSub = pSub->pPrior; /* Repeat over compound */ | 150908 | pSub = pSub->pPrior; /* Repeat over compound */ |
| 150049 | }while( pSub ); | 150909 | }while( pSub ); |
| 150050 | 150910 | ||
| 150051 | /* If we reach this point then it is OK to perform the transformation */ | 150911 | /* If we reach this point then it is OK to perform the transformation */ |
| @@ -150053,8 +150913,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 150053 | db = pParse->db; | 150913 | db = pParse->db; |
| 150054 | pCount = pExpr; | 150914 | pCount = pExpr; |
| 150055 | pExpr = 0; | 150915 | pExpr = 0; |
| 150056 | pSub = p->pSrc->a[0].pSelect; | 150916 | pSub = sqlite3SubqueryDetach(db, pFrom); |
| 150057 | p->pSrc->a[0].pSelect = 0; | ||
| 150058 | sqlite3SrcListDelete(db, p->pSrc); | 150917 | sqlite3SrcListDelete(db, p->pSrc); |
| 150059 | p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); | 150918 | p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); |
| 150060 | while( pSub ){ | 150919 | while( pSub ){ |
| @@ -150099,12 +150958,12 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ | |||
| 150099 | for(i=0; i<pSrc->nSrc; i++){ | 150958 | for(i=0; i<pSrc->nSrc; i++){ |
| 150100 | SrcItem *p1 = &pSrc->a[i]; | 150959 | SrcItem *p1 = &pSrc->a[i]; |
| 150101 | if( p1==p0 ) continue; | 150960 | if( p1==p0 ) continue; |
| 150102 | if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ | 150961 | if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ |
| 150103 | return 1; | 150962 | return 1; |
| 150104 | } | 150963 | } |
| 150105 | if( p1->pSelect | 150964 | if( p1->fg.isSubquery |
| 150106 | && (p1->pSelect->selFlags & SF_NestedFrom)!=0 | 150965 | && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 |
| 150107 | && sameSrcAlias(p0, p1->pSelect->pSrc) | 150966 | && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) |
| 150108 | ){ | 150967 | ){ |
| 150109 | return 1; | 150968 | return 1; |
| 150110 | } | 150969 | } |
| @@ -150169,13 +151028,13 @@ static int fromClauseTermCanBeCoroutine( | |||
| 150169 | if( i==0 ) break; | 151028 | if( i==0 ) break; |
| 150170 | i--; | 151029 | i--; |
| 150171 | pItem--; | 151030 | pItem--; |
| 150172 | if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ | 151031 | if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ |
| 150173 | } | 151032 | } |
| 150174 | return 1; | 151033 | return 1; |
| 150175 | } | 151034 | } |
| 150176 | 151035 | ||
| 150177 | /* | 151036 | /* |
| 150178 | ** Generate code for the SELECT statement given in the p argument. | 151037 | ** Generate byte-code for the SELECT statement given in the p argument. |
| 150179 | ** | 151038 | ** |
| 150180 | ** The results are returned according to the SelectDest structure. | 151039 | ** The results are returned according to the SelectDest structure. |
| 150181 | ** See comments in sqliteInt.h for further information. | 151040 | ** See comments in sqliteInt.h for further information. |
| @@ -150186,6 +151045,40 @@ static int fromClauseTermCanBeCoroutine( | |||
| 150186 | ** | 151045 | ** |
| 150187 | ** This routine does NOT free the Select structure passed in. The | 151046 | ** This routine does NOT free the Select structure passed in. The |
| 150188 | ** calling function needs to do that. | 151047 | ** calling function needs to do that. |
| 151048 | ** | ||
| 151049 | ** This is a long function. The following is an outline of the processing | ||
| 151050 | ** steps, with tags referencing various milestones: | ||
| 151051 | ** | ||
| 151052 | ** * Resolve names and similar preparation tag-select-0100 | ||
| 151053 | ** * Scan of the FROM clause tag-select-0200 | ||
| 151054 | ** + OUTER JOIN strength reduction tag-select-0220 | ||
| 151055 | ** + Sub-query ORDER BY removal tag-select-0230 | ||
| 151056 | ** + Query flattening tag-select-0240 | ||
| 151057 | ** * Separate subroutine for compound-SELECT tag-select-0300 | ||
| 151058 | ** * WHERE-clause constant propagation tag-select-0330 | ||
| 151059 | ** * Count()-of-VIEW optimization tag-select-0350 | ||
| 151060 | ** * Scan of the FROM clause again tag-select-0400 | ||
| 151061 | ** + Authorize unreferenced tables tag-select-0410 | ||
| 151062 | ** + Predicate push-down optimization tag-select-0420 | ||
| 151063 | ** + Omit unused subquery columns optimization tag-select-0440 | ||
| 151064 | ** + Generate code to implement subqueries tag-select-0480 | ||
| 151065 | ** - Co-routines tag-select-0482 | ||
| 151066 | ** - Reuse previously computed CTE tag-select-0484 | ||
| 151067 | ** - REuse previously computed VIEW tag-select-0486 | ||
| 151068 | ** - Materialize a VIEW or CTE tag-select-0488 | ||
| 151069 | ** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 | ||
| 151070 | ** * Set up for ORDER BY tag-select-0600 | ||
| 151071 | ** * Create output table tag-select-0630 | ||
| 151072 | ** * Prepare registers for LIMIT tag-select-0650 | ||
| 151073 | ** * Setup for DISTINCT tag-select-0680 | ||
| 151074 | ** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 | ||
| 151075 | ** * Generate code for aggregate and/or GROUP BY tag-select-0800 | ||
| 151076 | ** + GROUP BY queries tag-select-0810 | ||
| 151077 | ** + non-GROUP BY queries tag-select-0820 | ||
| 151078 | ** - Special case of count() w/o GROUP BY tag-select-0821 | ||
| 151079 | ** - General case of non-GROUP BY aggregates tag-select-0822 | ||
| 151080 | ** * Sort results, as needed tag-select-0900 | ||
| 151081 | ** * Internal self-checks tag-select-1000 | ||
| 150189 | */ | 151082 | */ |
| 150190 | SQLITE_PRIVATE int sqlite3Select( | 151083 | SQLITE_PRIVATE int sqlite3Select( |
| 150191 | Parse *pParse, /* The parser context */ | 151084 | Parse *pParse, /* The parser context */ |
| @@ -150229,6 +151122,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150229 | } | 151122 | } |
| 150230 | #endif | 151123 | #endif |
| 150231 | 151124 | ||
| 151125 | /* tag-select-0100 */ | ||
| 150232 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); | 151126 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); |
| 150233 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); | 151127 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); |
| 150234 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); | 151128 | assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); |
| @@ -150280,7 +151174,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150280 | if( sameSrcAlias(p0, p->pSrc) ){ | 151174 | if( sameSrcAlias(p0, p->pSrc) ){ |
| 150281 | sqlite3ErrorMsg(pParse, | 151175 | sqlite3ErrorMsg(pParse, |
| 150282 | "target object/alias may not appear in FROM clause: %s", | 151176 | "target object/alias may not appear in FROM clause: %s", |
| 150283 | p0->zAlias ? p0->zAlias : p0->pTab->zName | 151177 | p0->zAlias ? p0->zAlias : p0->pSTab->zName |
| 150284 | ); | 151178 | ); |
| 150285 | goto select_end; | 151179 | goto select_end; |
| 150286 | } | 151180 | } |
| @@ -150315,12 +151209,13 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150315 | 151209 | ||
| 150316 | /* Try to do various optimizations (flattening subqueries, and strength | 151210 | /* Try to do various optimizations (flattening subqueries, and strength |
| 150317 | ** reduction of join operators) in the FROM clause up into the main query | 151211 | ** reduction of join operators) in the FROM clause up into the main query |
| 151212 | ** tag-select-0200 | ||
| 150318 | */ | 151213 | */ |
| 150319 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 151214 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) |
| 150320 | for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ | 151215 | for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ |
| 150321 | SrcItem *pItem = &pTabList->a[i]; | 151216 | SrcItem *pItem = &pTabList->a[i]; |
| 150322 | Select *pSub = pItem->pSelect; | 151217 | Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; |
| 150323 | Table *pTab = pItem->pTab; | 151218 | Table *pTab = pItem->pSTab; |
| 150324 | 151219 | ||
| 150325 | /* The expander should have already created transient Table objects | 151220 | /* The expander should have already created transient Table objects |
| 150326 | ** even for FROM clause elements such as subqueries that do not correspond | 151221 | ** even for FROM clause elements such as subqueries that do not correspond |
| @@ -150337,6 +151232,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150337 | ** way that the i-th table cannot be the NULL row of a join, then | 151232 | ** way that the i-th table cannot be the NULL row of a join, then |
| 150338 | ** perform the appropriate simplification. This is called | 151233 | ** perform the appropriate simplification. This is called |
| 150339 | ** "OUTER JOIN strength reduction" in the SQLite documentation. | 151234 | ** "OUTER JOIN strength reduction" in the SQLite documentation. |
| 151235 | ** tag-select-0220 | ||
| 150340 | */ | 151236 | */ |
| 150341 | if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 | 151237 | if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 |
| 150342 | && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, | 151238 | && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, |
| @@ -150407,7 +151303,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150407 | if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; | 151303 | if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; |
| 150408 | assert( pSub->pGroupBy==0 ); | 151304 | assert( pSub->pGroupBy==0 ); |
| 150409 | 151305 | ||
| 150410 | /* If a FROM-clause subquery has an ORDER BY clause that is not | 151306 | /* tag-select-0230: |
| 151307 | ** If a FROM-clause subquery has an ORDER BY clause that is not | ||
| 150411 | ** really doing anything, then delete it now so that it does not | 151308 | ** really doing anything, then delete it now so that it does not |
| 150412 | ** interfere with query flattening. See the discussion at | 151309 | ** interfere with query flattening. See the discussion at |
| 150413 | ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a | 151310 | ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a |
| @@ -150426,13 +151323,16 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150426 | ** (a) The outer query has a different ORDER BY clause | 151323 | ** (a) The outer query has a different ORDER BY clause |
| 150427 | ** (b) The subquery is part of a join | 151324 | ** (b) The subquery is part of a join |
| 150428 | ** See forum post 062d576715d277c8 | 151325 | ** See forum post 062d576715d277c8 |
| 151326 | ** (6) The subquery is not a recursive CTE. ORDER BY has a different | ||
| 151327 | ** meaning for recursive CTEs and this optimization does not | ||
| 151328 | ** apply. | ||
| 150429 | ** | 151329 | ** |
| 150430 | ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. | 151330 | ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. |
| 150431 | */ | 151331 | */ |
| 150432 | if( pSub->pOrderBy!=0 | 151332 | if( pSub->pOrderBy!=0 |
| 150433 | && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ | 151333 | && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ |
| 150434 | && pSub->pLimit==0 /* Condition (1) */ | 151334 | && pSub->pLimit==0 /* Condition (1) */ |
| 150435 | && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ | 151335 | && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ |
| 150436 | && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ | 151336 | && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ |
| 150437 | && OptimizationEnabled(db, SQLITE_OmitOrderBy) | 151337 | && OptimizationEnabled(db, SQLITE_OmitOrderBy) |
| 150438 | ){ | 151338 | ){ |
| @@ -150470,6 +151370,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150470 | continue; | 151370 | continue; |
| 150471 | } | 151371 | } |
| 150472 | 151372 | ||
| 151373 | /* tag-select-0240 */ | ||
| 150473 | if( flattenSubquery(pParse, p, i, isAgg) ){ | 151374 | if( flattenSubquery(pParse, p, i, isAgg) ){ |
| 150474 | if( pParse->nErr ) goto select_end; | 151375 | if( pParse->nErr ) goto select_end; |
| 150475 | /* This subquery can be absorbed into its parent. */ | 151376 | /* This subquery can be absorbed into its parent. */ |
| @@ -150485,7 +151386,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150485 | 151386 | ||
| 150486 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 151387 | #ifndef SQLITE_OMIT_COMPOUND_SELECT |
| 150487 | /* Handle compound SELECT statements using the separate multiSelect() | 151388 | /* Handle compound SELECT statements using the separate multiSelect() |
| 150488 | ** procedure. | 151389 | ** procedure. tag-select-0300 |
| 150489 | */ | 151390 | */ |
| 150490 | if( p->pPrior ){ | 151391 | if( p->pPrior ){ |
| 150491 | rc = multiSelect(pParse, p, pDest); | 151392 | rc = multiSelect(pParse, p, pDest); |
| @@ -150501,9 +151402,9 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150501 | #endif | 151402 | #endif |
| 150502 | 151403 | ||
| 150503 | /* Do the WHERE-clause constant propagation optimization if this is | 151404 | /* Do the WHERE-clause constant propagation optimization if this is |
| 150504 | ** a join. No need to speed time on this operation for non-join queries | 151405 | ** a join. No need to spend time on this operation for non-join queries |
| 150505 | ** as the equivalent optimization will be handled by query planner in | 151406 | ** as the equivalent optimization will be handled by query planner in |
| 150506 | ** sqlite3WhereBegin(). | 151407 | ** sqlite3WhereBegin(). tag-select-0330 |
| 150507 | */ | 151408 | */ |
| 150508 | if( p->pWhere!=0 | 151409 | if( p->pWhere!=0 |
| 150509 | && p->pWhere->op==TK_AND | 151410 | && p->pWhere->op==TK_AND |
| @@ -150520,6 +151421,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150520 | TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); | 151421 | TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); |
| 150521 | } | 151422 | } |
| 150522 | 151423 | ||
| 151424 | /* tag-select-0350 */ | ||
| 150523 | if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) | 151425 | if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) |
| 150524 | && countOfViewOptimization(pParse, p) | 151426 | && countOfViewOptimization(pParse, p) |
| 150525 | ){ | 151427 | ){ |
| @@ -150527,20 +151429,26 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150527 | pTabList = p->pSrc; | 151429 | pTabList = p->pSrc; |
| 150528 | } | 151430 | } |
| 150529 | 151431 | ||
| 150530 | /* For each term in the FROM clause, do two things: | 151432 | /* Loop over all terms in the FROM clause and do two things for each term: |
| 150531 | ** (1) Authorized unreferenced tables | 151433 | ** |
| 150532 | ** (2) Generate code for all sub-queries | 151434 | ** (1) Authorize unreferenced tables |
| 151435 | ** (2) Generate code for all sub-queries | ||
| 151436 | ** | ||
| 151437 | ** tag-select-0400 | ||
| 150533 | */ | 151438 | */ |
| 150534 | for(i=0; i<pTabList->nSrc; i++){ | 151439 | for(i=0; i<pTabList->nSrc; i++){ |
| 150535 | SrcItem *pItem = &pTabList->a[i]; | 151440 | SrcItem *pItem = &pTabList->a[i]; |
| 150536 | SrcItem *pPrior; | 151441 | SrcItem *pPrior; |
| 150537 | SelectDest dest; | 151442 | SelectDest dest; |
| 151443 | Subquery *pSubq; | ||
| 150538 | Select *pSub; | 151444 | Select *pSub; |
| 150539 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 151445 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) |
| 150540 | const char *zSavedAuthContext; | 151446 | const char *zSavedAuthContext; |
| 150541 | #endif | 151447 | #endif |
| 150542 | 151448 | ||
| 150543 | /* Issue SQLITE_READ authorizations with a fake column name for any | 151449 | /* Authorized unreferenced tables. tag-select-0410 |
| 151450 | ** | ||
| 151451 | ** Issue SQLITE_READ authorizations with a fake column name for any | ||
| 150544 | ** tables that are referenced but from which no values are extracted. | 151452 | ** tables that are referenced but from which no values are extracted. |
| 150545 | ** Examples of where these kinds of null SQLITE_READ authorizations | 151453 | ** Examples of where these kinds of null SQLITE_READ authorizations |
| 150546 | ** would occur: | 151454 | ** would occur: |
| @@ -150557,17 +151465,28 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150557 | ** string for the fake column name seems safer. | 151465 | ** string for the fake column name seems safer. |
| 150558 | */ | 151466 | */ |
| 150559 | if( pItem->colUsed==0 && pItem->zName!=0 ){ | 151467 | if( pItem->colUsed==0 && pItem->zName!=0 ){ |
| 150560 | sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); | 151468 | const char *zDb; |
| 151469 | if( pItem->fg.fixedSchema ){ | ||
| 151470 | int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); | ||
| 151471 | zDb = db->aDb[iDb].zDbSName; | ||
| 151472 | }else if( pItem->fg.isSubquery ){ | ||
| 151473 | zDb = 0; | ||
| 151474 | }else{ | ||
| 151475 | zDb = pItem->u4.zDatabase; | ||
| 151476 | } | ||
| 151477 | sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); | ||
| 150561 | } | 151478 | } |
| 150562 | 151479 | ||
| 150563 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 151480 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) |
| 150564 | /* Generate code for all sub-queries in the FROM clause | 151481 | /* Generate code for all sub-queries in the FROM clause |
| 150565 | */ | 151482 | */ |
| 150566 | pSub = pItem->pSelect; | 151483 | if( pItem->fg.isSubquery==0 ) continue; |
| 150567 | if( pSub==0 || pItem->addrFillSub!=0 ) continue; | 151484 | pSubq = pItem->u4.pSubq; |
| 151485 | assert( pSubq!=0 ); | ||
| 151486 | pSub = pSubq->pSelect; | ||
| 150568 | 151487 | ||
| 150569 | /* The code for a subquery should only be generated once. */ | 151488 | /* The code for a subquery should only be generated once. */ |
| 150570 | assert( pItem->addrFillSub==0 ); | 151489 | if( pSubq->addrFillSub!=0 ) continue; |
| 150571 | 151490 | ||
| 150572 | /* Increment Parse.nHeight by the height of the largest expression | 151491 | /* Increment Parse.nHeight by the height of the largest expression |
| 150573 | ** tree referred to by this, the parent select. The child select | 151492 | ** tree referred to by this, the parent select. The child select |
| @@ -150580,6 +151499,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150580 | 151499 | ||
| 150581 | /* Make copies of constant WHERE-clause terms in the outer query down | 151500 | /* Make copies of constant WHERE-clause terms in the outer query down |
| 150582 | ** inside the subquery. This can help the subquery to run more efficiently. | 151501 | ** inside the subquery. This can help the subquery to run more efficiently. |
| 151502 | ** This is the "predicate push-down optimization". tag-select-0420 | ||
| 150583 | */ | 151503 | */ |
| 150584 | if( OptimizationEnabled(db, SQLITE_PushDown) | 151504 | if( OptimizationEnabled(db, SQLITE_PushDown) |
| 150585 | && (pItem->fg.isCte==0 | 151505 | && (pItem->fg.isCte==0 |
| @@ -150593,13 +151513,14 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150593 | sqlite3TreeViewSelect(0, p, 0); | 151513 | sqlite3TreeViewSelect(0, p, 0); |
| 150594 | } | 151514 | } |
| 150595 | #endif | 151515 | #endif |
| 150596 | assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); | 151516 | assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); |
| 150597 | }else{ | 151517 | }else{ |
| 150598 | TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); | 151518 | TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); |
| 150599 | } | 151519 | } |
| 150600 | 151520 | ||
| 150601 | /* Convert unused result columns of the subquery into simple NULL | 151521 | /* Convert unused result columns of the subquery into simple NULL |
| 150602 | ** expressions, to avoid unneeded searching and computation. | 151522 | ** expressions, to avoid unneeded searching and computation. |
| 151523 | ** tag-select-0440 | ||
| 150603 | */ | 151524 | */ |
| 150604 | if( OptimizationEnabled(db, SQLITE_NullUnusedCols) | 151525 | if( OptimizationEnabled(db, SQLITE_NullUnusedCols) |
| 150605 | && disableUnusedSubqueryResultColumns(pItem) | 151526 | && disableUnusedSubqueryResultColumns(pItem) |
| @@ -150617,32 +151538,33 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150617 | zSavedAuthContext = pParse->zAuthContext; | 151538 | zSavedAuthContext = pParse->zAuthContext; |
| 150618 | pParse->zAuthContext = pItem->zName; | 151539 | pParse->zAuthContext = pItem->zName; |
| 150619 | 151540 | ||
| 150620 | /* Generate code to implement the subquery | 151541 | /* Generate byte-code to implement the subquery tag-select-0480 |
| 150621 | */ | 151542 | */ |
| 150622 | if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ | 151543 | if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ |
| 150623 | /* Implement a co-routine that will return a single row of the result | 151544 | /* Implement a co-routine that will return a single row of the result |
| 150624 | ** set on each invocation. | 151545 | ** set on each invocation. tag-select-0482 |
| 150625 | */ | 151546 | */ |
| 150626 | int addrTop = sqlite3VdbeCurrentAddr(v)+1; | 151547 | int addrTop = sqlite3VdbeCurrentAddr(v)+1; |
| 150627 | 151548 | ||
| 150628 | pItem->regReturn = ++pParse->nMem; | 151549 | pSubq->regReturn = ++pParse->nMem; |
| 150629 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); | 151550 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); |
| 150630 | VdbeComment((v, "%!S", pItem)); | 151551 | VdbeComment((v, "%!S", pItem)); |
| 150631 | pItem->addrFillSub = addrTop; | 151552 | pSubq->addrFillSub = addrTop; |
| 150632 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); | 151553 | sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); |
| 150633 | ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); | 151554 | ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); |
| 150634 | sqlite3Select(pParse, pSub, &dest); | 151555 | sqlite3Select(pParse, pSub, &dest); |
| 150635 | pItem->pTab->nRowLogEst = pSub->nSelectRow; | 151556 | pItem->pSTab->nRowLogEst = pSub->nSelectRow; |
| 150636 | pItem->fg.viaCoroutine = 1; | 151557 | pItem->fg.viaCoroutine = 1; |
| 150637 | pItem->regResult = dest.iSdst; | 151558 | pSubq->regResult = dest.iSdst; |
| 150638 | sqlite3VdbeEndCoroutine(v, pItem->regReturn); | 151559 | sqlite3VdbeEndCoroutine(v, pSubq->regReturn); |
| 151560 | VdbeComment((v, "end %!S", pItem)); | ||
| 150639 | sqlite3VdbeJumpHere(v, addrTop-1); | 151561 | sqlite3VdbeJumpHere(v, addrTop-1); |
| 150640 | sqlite3ClearTempRegCache(pParse); | 151562 | sqlite3ClearTempRegCache(pParse); |
| 150641 | }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ | 151563 | }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ |
| 150642 | /* This is a CTE for which materialization code has already been | 151564 | /* This is a CTE for which materialization code has already been |
| 150643 | ** generated. Invoke the subroutine to compute the materialization, | 151565 | ** generated. Invoke the subroutine to compute the materialization, |
| 150644 | ** the make the pItem->iCursor be a copy of the ephemeral table that | 151566 | ** then make the pItem->iCursor be a copy of the ephemeral table that |
| 150645 | ** holds the result of the materialization. */ | 151567 | ** holds the result of the materialization. tag-select-0484 */ |
| 150646 | CteUse *pCteUse = pItem->u2.pCteUse; | 151568 | CteUse *pCteUse = pItem->u2.pCteUse; |
| 150647 | sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); | 151569 | sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); |
| 150648 | if( pItem->iCursor!=pCteUse->iCur ){ | 151570 | if( pItem->iCursor!=pCteUse->iCur ){ |
| @@ -150652,25 +151574,30 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150652 | pSub->nSelectRow = pCteUse->nRowEst; | 151574 | pSub->nSelectRow = pCteUse->nRowEst; |
| 150653 | }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ | 151575 | }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ |
| 150654 | /* This view has already been materialized by a prior entry in | 151576 | /* This view has already been materialized by a prior entry in |
| 150655 | ** this same FROM clause. Reuse it. */ | 151577 | ** this same FROM clause. Reuse it. tag-select-0486 */ |
| 150656 | if( pPrior->addrFillSub ){ | 151578 | Subquery *pPriorSubq; |
| 150657 | sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); | 151579 | assert( pPrior->fg.isSubquery ); |
| 151580 | pPriorSubq = pPrior->u4.pSubq; | ||
| 151581 | assert( pPriorSubq!=0 ); | ||
| 151582 | if( pPriorSubq->addrFillSub ){ | ||
| 151583 | sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, | ||
| 151584 | pPriorSubq->addrFillSub); | ||
| 150658 | } | 151585 | } |
| 150659 | sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); | 151586 | sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); |
| 150660 | pSub->nSelectRow = pPrior->pSelect->nSelectRow; | 151587 | pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; |
| 150661 | }else{ | 151588 | }else{ |
| 150662 | /* Materialize the view. If the view is not correlated, generate a | 151589 | /* Materialize the view. If the view is not correlated, generate a |
| 150663 | ** subroutine to do the materialization so that subsequent uses of | 151590 | ** subroutine to do the materialization so that subsequent uses of |
| 150664 | ** the same view can reuse the materialization. */ | 151591 | ** the same view can reuse the materialization. tag-select-0488 */ |
| 150665 | int topAddr; | 151592 | int topAddr; |
| 150666 | int onceAddr = 0; | 151593 | int onceAddr = 0; |
| 150667 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | 151594 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 150668 | int addrExplain; | 151595 | int addrExplain; |
| 150669 | #endif | 151596 | #endif |
| 150670 | 151597 | ||
| 150671 | pItem->regReturn = ++pParse->nMem; | 151598 | pSubq->regReturn = ++pParse->nMem; |
| 150672 | topAddr = sqlite3VdbeAddOp0(v, OP_Goto); | 151599 | topAddr = sqlite3VdbeAddOp0(v, OP_Goto); |
| 150673 | pItem->addrFillSub = topAddr+1; | 151600 | pSubq->addrFillSub = topAddr+1; |
| 150674 | pItem->fg.isMaterialized = 1; | 151601 | pItem->fg.isMaterialized = 1; |
| 150675 | if( pItem->fg.isCorrelated==0 ){ | 151602 | if( pItem->fg.isCorrelated==0 ){ |
| 150676 | /* If the subquery is not correlated and if we are not inside of | 151603 | /* If the subquery is not correlated and if we are not inside of |
| @@ -150685,17 +151612,17 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150685 | 151612 | ||
| 150686 | ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); | 151613 | ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); |
| 150687 | sqlite3Select(pParse, pSub, &dest); | 151614 | sqlite3Select(pParse, pSub, &dest); |
| 150688 | pItem->pTab->nRowLogEst = pSub->nSelectRow; | 151615 | pItem->pSTab->nRowLogEst = pSub->nSelectRow; |
| 150689 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); | 151616 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 150690 | sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); | 151617 | sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); |
| 150691 | VdbeComment((v, "end %!S", pItem)); | 151618 | VdbeComment((v, "end %!S", pItem)); |
| 150692 | sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); | 151619 | sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); |
| 150693 | sqlite3VdbeJumpHere(v, topAddr); | 151620 | sqlite3VdbeJumpHere(v, topAddr); |
| 150694 | sqlite3ClearTempRegCache(pParse); | 151621 | sqlite3ClearTempRegCache(pParse); |
| 150695 | if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ | 151622 | if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ |
| 150696 | CteUse *pCteUse = pItem->u2.pCteUse; | 151623 | CteUse *pCteUse = pItem->u2.pCteUse; |
| 150697 | pCteUse->addrM9e = pItem->addrFillSub; | 151624 | pCteUse->addrM9e = pSubq->addrFillSub; |
| 150698 | pCteUse->regRtn = pItem->regReturn; | 151625 | pCteUse->regRtn = pSubq->regReturn; |
| 150699 | pCteUse->iCur = pItem->iCursor; | 151626 | pCteUse->iCur = pItem->iCursor; |
| 150700 | pCteUse->nRowEst = pSub->nSelectRow; | 151627 | pCteUse->nRowEst = pSub->nSelectRow; |
| 150701 | } | 151628 | } |
| @@ -150721,7 +151648,9 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150721 | } | 151648 | } |
| 150722 | #endif | 151649 | #endif |
| 150723 | 151650 | ||
| 150724 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and | 151651 | /* tag-select-0500 |
| 151652 | ** | ||
| 151653 | ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and | ||
| 150725 | ** if the select-list is the same as the ORDER BY list, then this query | 151654 | ** if the select-list is the same as the ORDER BY list, then this query |
| 150726 | ** can be rewritten as a GROUP BY. In other words, this: | 151655 | ** can be rewritten as a GROUP BY. In other words, this: |
| 150727 | ** | 151656 | ** |
| @@ -150738,12 +151667,18 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150738 | */ | 151667 | */ |
| 150739 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct | 151668 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct |
| 150740 | && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 | 151669 | && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 |
| 151670 | && OptimizationEnabled(db, SQLITE_GroupByOrder) | ||
| 150741 | #ifndef SQLITE_OMIT_WINDOWFUNC | 151671 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 150742 | && p->pWin==0 | 151672 | && p->pWin==0 |
| 150743 | #endif | 151673 | #endif |
| 150744 | ){ | 151674 | ){ |
| 150745 | p->selFlags &= ~SF_Distinct; | 151675 | p->selFlags &= ~SF_Distinct; |
| 150746 | pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); | 151676 | pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); |
| 151677 | if( pGroupBy ){ | ||
| 151678 | for(i=0; i<pGroupBy->nExpr; i++){ | ||
| 151679 | pGroupBy->a[i].u.x.iOrderByCol = i+1; | ||
| 151680 | } | ||
| 151681 | } | ||
| 150747 | p->selFlags |= SF_Aggregate; | 151682 | p->selFlags |= SF_Aggregate; |
| 150748 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, | 151683 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 150749 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the | 151684 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| @@ -150765,7 +151700,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150765 | ** If that is the case, then the OP_OpenEphemeral instruction will be | 151700 | ** If that is the case, then the OP_OpenEphemeral instruction will be |
| 150766 | ** changed to an OP_Noop once we figure out that the sorting index is | 151701 | ** changed to an OP_Noop once we figure out that the sorting index is |
| 150767 | ** not needed. The sSort.addrSortIndex variable is used to facilitate | 151702 | ** not needed. The sSort.addrSortIndex variable is used to facilitate |
| 150768 | ** that change. | 151703 | ** that change. tag-select-0600 |
| 150769 | */ | 151704 | */ |
| 150770 | if( sSort.pOrderBy ){ | 151705 | if( sSort.pOrderBy ){ |
| 150771 | KeyInfo *pKeyInfo; | 151706 | KeyInfo *pKeyInfo; |
| @@ -150782,6 +151717,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150782 | } | 151717 | } |
| 150783 | 151718 | ||
| 150784 | /* If the output is destined for a temporary table, open that table. | 151719 | /* If the output is destined for a temporary table, open that table. |
| 151720 | ** tag-select-0630 | ||
| 150785 | */ | 151721 | */ |
| 150786 | if( pDest->eDest==SRT_EphemTab ){ | 151722 | if( pDest->eDest==SRT_EphemTab ){ |
| 150787 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); | 151723 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); |
| @@ -150799,7 +151735,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150799 | } | 151735 | } |
| 150800 | } | 151736 | } |
| 150801 | 151737 | ||
| 150802 | /* Set the limiter. | 151738 | /* Set the limiter. tag-select-0650 |
| 150803 | */ | 151739 | */ |
| 150804 | iEnd = sqlite3VdbeMakeLabel(pParse); | 151740 | iEnd = sqlite3VdbeMakeLabel(pParse); |
| 150805 | if( (p->selFlags & SF_FixedLimit)==0 ){ | 151741 | if( (p->selFlags & SF_FixedLimit)==0 ){ |
| @@ -150811,7 +151747,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150811 | sSort.sortFlags |= SORTFLAG_UseSorter; | 151747 | sSort.sortFlags |= SORTFLAG_UseSorter; |
| 150812 | } | 151748 | } |
| 150813 | 151749 | ||
| 150814 | /* Open an ephemeral index to use for the distinct set. | 151750 | /* Open an ephemeral index to use for the distinct set. tag-select-0680 |
| 150815 | */ | 151751 | */ |
| 150816 | if( p->selFlags & SF_Distinct ){ | 151752 | if( p->selFlags & SF_Distinct ){ |
| 150817 | sDistinct.tabTnct = pParse->nTab++; | 151753 | sDistinct.tabTnct = pParse->nTab++; |
| @@ -150826,7 +151762,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150826 | } | 151762 | } |
| 150827 | 151763 | ||
| 150828 | if( !isAgg && pGroupBy==0 ){ | 151764 | if( !isAgg && pGroupBy==0 ){ |
| 150829 | /* No aggregate functions and no GROUP BY clause */ | 151765 | /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ |
| 150830 | u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) | 151766 | u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) |
| 150831 | | (p->selFlags & SF_FixedLimit); | 151767 | | (p->selFlags & SF_FixedLimit); |
| 150832 | #ifndef SQLITE_OMIT_WINDOWFUNC | 151768 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| @@ -150899,8 +151835,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 150899 | sqlite3WhereEnd(pWInfo); | 151835 | sqlite3WhereEnd(pWInfo); |
| 150900 | } | 151836 | } |
| 150901 | }else{ | 151837 | }else{ |
| 150902 | /* This case when there exist aggregate functions or a GROUP BY clause | 151838 | /* This case is for when there exist aggregate functions or a GROUP BY |
| 150903 | ** or both */ | 151839 | ** clause or both. tag-select-0800 */ |
| 150904 | NameContext sNC; /* Name context for processing aggregate information */ | 151840 | NameContext sNC; /* Name context for processing aggregate information */ |
| 150905 | int iAMem; /* First Mem address for storing current GROUP BY */ | 151841 | int iAMem; /* First Mem address for storing current GROUP BY */ |
| 150906 | int iBMem; /* First Mem address for previous GROUP BY */ | 151842 | int iBMem; /* First Mem address for previous GROUP BY */ |
| @@ -151019,7 +151955,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151019 | 151955 | ||
| 151020 | 151956 | ||
| 151021 | /* Processing for aggregates with GROUP BY is very different and | 151957 | /* Processing for aggregates with GROUP BY is very different and |
| 151022 | ** much more complex than aggregates without a GROUP BY. | 151958 | ** much more complex than aggregates without a GROUP BY. tag-select-0810 |
| 151023 | */ | 151959 | */ |
| 151024 | if( pGroupBy ){ | 151960 | if( pGroupBy ){ |
| 151025 | KeyInfo *pKeyInfo; /* Keying information for the group by clause */ | 151961 | KeyInfo *pKeyInfo; /* Keying information for the group by clause */ |
| @@ -151206,12 +152142,25 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151206 | sortOut, sortPTab); | 152142 | sortOut, sortPTab); |
| 151207 | } | 152143 | } |
| 151208 | for(j=0; j<pGroupBy->nExpr; j++){ | 152144 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 152145 | int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; | ||
| 152146 | |||
| 151209 | if( groupBySort ){ | 152147 | if( groupBySort ){ |
| 151210 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); | 152148 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 151211 | }else{ | 152149 | }else{ |
| 151212 | pAggInfo->directMode = 1; | 152150 | pAggInfo->directMode = 1; |
| 151213 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); | 152151 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 151214 | } | 152152 | } |
| 152153 | |||
| 152154 | if( iOrderByCol ){ | ||
| 152155 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; | ||
| 152156 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); | ||
| 152157 | if( ALWAYS(pBase!=0) | ||
| 152158 | && pBase->op!=TK_AGG_COLUMN | ||
| 152159 | && pBase->op!=TK_REGISTER | ||
| 152160 | ){ | ||
| 152161 | sqlite3ExprToRegister(pX, iAMem+j); | ||
| 152162 | } | ||
| 152163 | } | ||
| 151215 | } | 152164 | } |
| 151216 | sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, | 152165 | sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, |
| 151217 | (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); | 152166 | (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); |
| @@ -151227,9 +152176,9 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151227 | ** and resets the aggregate accumulator registers in preparation | 152176 | ** and resets the aggregate accumulator registers in preparation |
| 151228 | ** for the next GROUP BY batch. | 152177 | ** for the next GROUP BY batch. |
| 151229 | */ | 152178 | */ |
| 151230 | sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); | ||
| 151231 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); | 152179 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); |
| 151232 | VdbeComment((v, "output one row")); | 152180 | VdbeComment((v, "output one row")); |
| 152181 | sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); | ||
| 151233 | sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); | 152182 | sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); |
| 151234 | VdbeComment((v, "check abort flag")); | 152183 | VdbeComment((v, "check abort flag")); |
| 151235 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); | 152184 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| @@ -151303,9 +152252,12 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151303 | } | 152252 | } |
| 151304 | } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ | 152253 | } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ |
| 151305 | else { | 152254 | else { |
| 152255 | /* Aggregate functions without GROUP BY. tag-select-0820 */ | ||
| 151306 | Table *pTab; | 152256 | Table *pTab; |
| 151307 | if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ | 152257 | if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ |
| 151308 | /* If isSimpleCount() returns a pointer to a Table structure, then | 152258 | /* tag-select-0821 |
| 152259 | ** | ||
| 152260 | ** If isSimpleCount() returns a pointer to a Table structure, then | ||
| 151309 | ** the SQL statement is of the form: | 152261 | ** the SQL statement is of the form: |
| 151310 | ** | 152262 | ** |
| 151311 | ** SELECT count(*) FROM <tbl> | 152263 | ** SELECT count(*) FROM <tbl> |
| @@ -151364,6 +152316,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151364 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); | 152316 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); |
| 151365 | explainSimpleCount(pParse, pTab, pBest); | 152317 | explainSimpleCount(pParse, pTab, pBest); |
| 151366 | }else{ | 152318 | }else{ |
| 152319 | /* The general case of an aggregate query without GROUP BY | ||
| 152320 | ** tag-select-0822 */ | ||
| 151367 | int regAcc = 0; /* "populate accumulators" flag */ | 152321 | int regAcc = 0; /* "populate accumulators" flag */ |
| 151368 | ExprList *pDistinct = 0; | 152322 | ExprList *pDistinct = 0; |
| 151369 | u16 distFlag = 0; | 152323 | u16 distFlag = 0; |
| @@ -151452,7 +152406,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 151452 | } | 152406 | } |
| 151453 | 152407 | ||
| 151454 | /* If there is an ORDER BY clause, then we need to sort the results | 152408 | /* If there is an ORDER BY clause, then we need to sort the results |
| 151455 | ** and send them to the callback one by one. | 152409 | ** and send them to the callback one by one. tag-select-0900 |
| 151456 | */ | 152410 | */ |
| 151457 | if( sSort.pOrderBy ){ | 152411 | if( sSort.pOrderBy ){ |
| 151458 | assert( p->pEList==pEList ); | 152412 | assert( p->pEList==pEList ); |
| @@ -151475,6 +152429,7 @@ select_end: | |||
| 151475 | assert( db->mallocFailed==0 || pParse->nErr!=0 ); | 152429 | assert( db->mallocFailed==0 || pParse->nErr!=0 ); |
| 151476 | sqlite3ExprListDelete(db, pMinMaxOrderBy); | 152430 | sqlite3ExprListDelete(db, pMinMaxOrderBy); |
| 151477 | #ifdef SQLITE_DEBUG | 152431 | #ifdef SQLITE_DEBUG |
| 152432 | /* Internal self-checks. tag-select-1000 */ | ||
| 151478 | if( pAggInfo && !db->mallocFailed ){ | 152433 | if( pAggInfo && !db->mallocFailed ){ |
| 151479 | #if TREETRACE_ENABLED | 152434 | #if TREETRACE_ENABLED |
| 151480 | if( sqlite3TreeTrace & 0x20 ){ | 152435 | if( sqlite3TreeTrace & 0x20 ){ |
| @@ -151864,8 +152819,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( | |||
| 151864 | ** name on pTableName if we are reparsing out of the schema table | 152819 | ** name on pTableName if we are reparsing out of the schema table |
| 151865 | */ | 152820 | */ |
| 151866 | if( db->init.busy && iDb!=1 ){ | 152821 | if( db->init.busy && iDb!=1 ){ |
| 151867 | sqlite3DbFree(db, pTableName->a[0].zDatabase); | 152822 | assert( pTableName->a[0].fg.fixedSchema==0 ); |
| 151868 | pTableName->a[0].zDatabase = 0; | 152823 | assert( pTableName->a[0].fg.isSubquery==0 ); |
| 152824 | sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); | ||
| 152825 | pTableName->a[0].u4.zDatabase = 0; | ||
| 151869 | } | 152826 | } |
| 151870 | 152827 | ||
| 151871 | /* If the trigger name was unqualified, and the table is a temp table, | 152828 | /* If the trigger name was unqualified, and the table is a temp table, |
| @@ -152343,7 +153300,8 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) | |||
| 152343 | } | 153300 | } |
| 152344 | 153301 | ||
| 152345 | assert( pName->nSrc==1 ); | 153302 | assert( pName->nSrc==1 ); |
| 152346 | zDb = pName->a[0].zDatabase; | 153303 | assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); |
| 153304 | zDb = pName->a[0].u4.zDatabase; | ||
| 152347 | zName = pName->a[0].zName; | 153305 | zName = pName->a[0].zName; |
| 152348 | assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); | 153306 | assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); |
| 152349 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ | 153307 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| @@ -152580,7 +153538,9 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( | |||
| 152580 | Schema *pSchema = pStep->pTrig->pSchema; | 153538 | Schema *pSchema = pStep->pTrig->pSchema; |
| 152581 | pSrc->a[0].zName = zName; | 153539 | pSrc->a[0].zName = zName; |
| 152582 | if( pSchema!=db->aDb[1].pSchema ){ | 153540 | if( pSchema!=db->aDb[1].pSchema ){ |
| 152583 | pSrc->a[0].pSchema = pSchema; | 153541 | assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); |
| 153542 | pSrc->a[0].u4.pSchema = pSchema; | ||
| 153543 | pSrc->a[0].fg.fixedSchema = 1; | ||
| 152584 | } | 153544 | } |
| 152585 | if( pStep->pFrom ){ | 153545 | if( pStep->pFrom ){ |
| 152586 | SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); | 153546 | SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); |
| @@ -152693,7 +153653,7 @@ static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ | |||
| 152693 | pSrc = pSelect->pSrc; | 153653 | pSrc = pSelect->pSrc; |
| 152694 | assert( pSrc!=0 ); | 153654 | assert( pSrc!=0 ); |
| 152695 | for(i=0; i<pSrc->nSrc; i++){ | 153655 | for(i=0; i<pSrc->nSrc; i++){ |
| 152696 | if( pSrc->a[i].pTab==pWalker->u.pTab ){ | 153656 | if( pSrc->a[i].pSTab==pWalker->u.pTab ){ |
| 152697 | testcase( pSelect->selFlags & SF_Correlated ); | 153657 | testcase( pSelect->selFlags & SF_Correlated ); |
| 152698 | pSelect->selFlags |= SF_Correlated; | 153658 | pSelect->selFlags |= SF_Correlated; |
| 152699 | pWalker->eCode = 1; | 153659 | pWalker->eCode = 1; |
| @@ -152764,7 +153724,7 @@ static void codeReturningTrigger( | |||
| 152764 | sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); | 153724 | sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); |
| 152765 | sSelect.pSrc = &sFrom; | 153725 | sSelect.pSrc = &sFrom; |
| 152766 | sFrom.nSrc = 1; | 153726 | sFrom.nSrc = 1; |
| 152767 | sFrom.a[0].pTab = pTab; | 153727 | sFrom.a[0].pSTab = pTab; |
| 152768 | sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ | 153728 | sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ |
| 152769 | sFrom.a[0].iCursor = -1; | 153729 | sFrom.a[0].iCursor = -1; |
| 152770 | sqlite3SelectPrep(pParse, &sSelect, 0); | 153730 | sqlite3SelectPrep(pParse, &sSelect, 0); |
| @@ -153475,7 +154435,7 @@ static void updateFromSelect( | |||
| 153475 | Expr *pLimit2 = 0; | 154435 | Expr *pLimit2 = 0; |
| 153476 | ExprList *pOrderBy2 = 0; | 154436 | ExprList *pOrderBy2 = 0; |
| 153477 | sqlite3 *db = pParse->db; | 154437 | sqlite3 *db = pParse->db; |
| 153478 | Table *pTab = pTabList->a[0].pTab; | 154438 | Table *pTab = pTabList->a[0].pSTab; |
| 153479 | SrcList *pSrc; | 154439 | SrcList *pSrc; |
| 153480 | Expr *pWhere2; | 154440 | Expr *pWhere2; |
| 153481 | int eDest; | 154441 | int eDest; |
| @@ -153499,8 +154459,8 @@ static void updateFromSelect( | |||
| 153499 | if( pSrc ){ | 154459 | if( pSrc ){ |
| 153500 | assert( pSrc->a[0].fg.notCte ); | 154460 | assert( pSrc->a[0].fg.notCte ); |
| 153501 | pSrc->a[0].iCursor = -1; | 154461 | pSrc->a[0].iCursor = -1; |
| 153502 | pSrc->a[0].pTab->nTabRef--; | 154462 | pSrc->a[0].pSTab->nTabRef--; |
| 153503 | pSrc->a[0].pTab = 0; | 154463 | pSrc->a[0].pSTab = 0; |
| 153504 | } | 154464 | } |
| 153505 | if( pPk ){ | 154465 | if( pPk ){ |
| 153506 | for(i=0; i<pPk->nKeyCol; i++){ | 154466 | for(i=0; i<pPk->nKeyCol; i++){ |
| @@ -154748,7 +155708,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | |||
| 154748 | int nClause = 0; /* Counter of ON CONFLICT clauses */ | 155708 | int nClause = 0; /* Counter of ON CONFLICT clauses */ |
| 154749 | 155709 | ||
| 154750 | assert( pTabList->nSrc==1 ); | 155710 | assert( pTabList->nSrc==1 ); |
| 154751 | assert( pTabList->a[0].pTab!=0 ); | 155711 | assert( pTabList->a[0].pSTab!=0 ); |
| 154752 | assert( pUpsert!=0 ); | 155712 | assert( pUpsert!=0 ); |
| 154753 | assert( pUpsert->pUpsertTarget!=0 ); | 155713 | assert( pUpsert->pUpsertTarget!=0 ); |
| 154754 | 155714 | ||
| @@ -154767,7 +155727,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | |||
| 154767 | if( rc ) return rc; | 155727 | if( rc ) return rc; |
| 154768 | 155728 | ||
| 154769 | /* Check to see if the conflict target matches the rowid. */ | 155729 | /* Check to see if the conflict target matches the rowid. */ |
| 154770 | pTab = pTabList->a[0].pTab; | 155730 | pTab = pTabList->a[0].pSTab; |
| 154771 | pTarget = pUpsert->pUpsertTarget; | 155731 | pTarget = pUpsert->pUpsertTarget; |
| 154772 | iCursor = pTabList->a[0].iCursor; | 155732 | iCursor = pTabList->a[0].iCursor; |
| 154773 | if( HasRowid(pTab) | 155733 | if( HasRowid(pTab) |
| @@ -155138,6 +156098,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 155138 | const char *zDbMain; /* Schema name of database to vacuum */ | 156098 | const char *zDbMain; /* Schema name of database to vacuum */ |
| 155139 | const char *zOut; /* Name of output file */ | 156099 | const char *zOut; /* Name of output file */ |
| 155140 | u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ | 156100 | u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ |
| 156101 | u64 iRandom; /* Random value used for zDbVacuum[] */ | ||
| 156102 | char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ | ||
| 156103 | |||
| 155141 | 156104 | ||
| 155142 | if( !db->autoCommit ){ | 156105 | if( !db->autoCommit ){ |
| 155143 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); | 156106 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); |
| @@ -155178,27 +156141,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 155178 | pMain = db->aDb[iDb].pBt; | 156141 | pMain = db->aDb[iDb].pBt; |
| 155179 | isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); | 156142 | isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); |
| 155180 | 156143 | ||
| 155181 | /* Attach the temporary database as 'vacuum_db'. The synchronous pragma | 156144 | /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma |
| 155182 | ** can be set to 'off' for this file, as it is not recovered if a crash | 156145 | ** can be set to 'off' for this file, as it is not recovered if a crash |
| 155183 | ** occurs anyway. The integrity of the database is maintained by a | 156146 | ** occurs anyway. The integrity of the database is maintained by a |
| 155184 | ** (possibly synchronous) transaction opened on the main database before | 156147 | ** (possibly synchronous) transaction opened on the main database before |
| 155185 | ** sqlite3BtreeCopyFile() is called. | 156148 | ** sqlite3BtreeCopyFile() is called. |
| 155186 | ** | 156149 | ** |
| 155187 | ** An optimization would be to use a non-journaled pager. | 156150 | ** An optimization would be to use a non-journaled pager. |
| 155188 | ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but | 156151 | ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but |
| 155189 | ** that actually made the VACUUM run slower. Very little journalling | 156152 | ** that actually made the VACUUM run slower. Very little journalling |
| 155190 | ** actually occurs when doing a vacuum since the vacuum_db is initially | 156153 | ** actually occurs when doing a vacuum since the vacuum_db is initially |
| 155191 | ** empty. Only the journal header is written. Apparently it takes more | 156154 | ** empty. Only the journal header is written. Apparently it takes more |
| 155192 | ** time to parse and run the PRAGMA to turn journalling off than it does | 156155 | ** time to parse and run the PRAGMA to turn journalling off than it does |
| 155193 | ** to write the journal header file. | 156156 | ** to write the journal header file. |
| 155194 | */ | 156157 | */ |
| 156158 | sqlite3_randomness(sizeof(iRandom),&iRandom); | ||
| 156159 | sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); | ||
| 155195 | nDb = db->nDb; | 156160 | nDb = db->nDb; |
| 155196 | rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); | 156161 | rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); |
| 155197 | db->openFlags = saved_openFlags; | 156162 | db->openFlags = saved_openFlags; |
| 155198 | if( rc!=SQLITE_OK ) goto end_of_vacuum; | 156163 | if( rc!=SQLITE_OK ) goto end_of_vacuum; |
| 155199 | assert( (db->nDb-1)==nDb ); | 156164 | assert( (db->nDb-1)==nDb ); |
| 155200 | pDb = &db->aDb[nDb]; | 156165 | pDb = &db->aDb[nDb]; |
| 155201 | assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); | 156166 | assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); |
| 155202 | pTemp = pDb->pBt; | 156167 | pTemp = pDb->pBt; |
| 155203 | if( pOut ){ | 156168 | if( pOut ){ |
| 155204 | sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); | 156169 | sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); |
| @@ -155275,11 +156240,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 155275 | ** the contents to the temporary database. | 156240 | ** the contents to the temporary database. |
| 155276 | */ | 156241 | */ |
| 155277 | rc = execSqlF(db, pzErrMsg, | 156242 | rc = execSqlF(db, pzErrMsg, |
| 155278 | "SELECT'INSERT INTO vacuum_db.'||quote(name)" | 156243 | "SELECT'INSERT INTO %s.'||quote(name)" |
| 155279 | "||' SELECT*FROM\"%w\".'||quote(name)" | 156244 | "||' SELECT*FROM\"%w\".'||quote(name)" |
| 155280 | "FROM vacuum_db.sqlite_schema " | 156245 | "FROM %s.sqlite_schema " |
| 155281 | "WHERE type='table'AND coalesce(rootpage,1)>0", | 156246 | "WHERE type='table'AND coalesce(rootpage,1)>0", |
| 155282 | zDbMain | 156247 | zDbVacuum, zDbMain, zDbVacuum |
| 155283 | ); | 156248 | ); |
| 155284 | assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); | 156249 | assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); |
| 155285 | db->mDbFlags &= ~DBFLAG_Vacuum; | 156250 | db->mDbFlags &= ~DBFLAG_Vacuum; |
| @@ -155291,11 +156256,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 155291 | ** from the schema table. | 156256 | ** from the schema table. |
| 155292 | */ | 156257 | */ |
| 155293 | rc = execSqlF(db, pzErrMsg, | 156258 | rc = execSqlF(db, pzErrMsg, |
| 155294 | "INSERT INTO vacuum_db.sqlite_schema" | 156259 | "INSERT INTO %s.sqlite_schema" |
| 155295 | " SELECT*FROM \"%w\".sqlite_schema" | 156260 | " SELECT*FROM \"%w\".sqlite_schema" |
| 155296 | " WHERE type IN('view','trigger')" | 156261 | " WHERE type IN('view','trigger')" |
| 155297 | " OR(type='table'AND rootpage=0)", | 156262 | " OR(type='table'AND rootpage=0)", |
| 155298 | zDbMain | 156263 | zDbVacuum, zDbMain |
| 155299 | ); | 156264 | ); |
| 155300 | if( rc ) goto end_of_vacuum; | 156265 | if( rc ) goto end_of_vacuum; |
| 155301 | 156266 | ||
| @@ -156259,6 +157224,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ | |||
| 156259 | Table *pNew = sParse.pNewTable; | 157224 | Table *pNew = sParse.pNewTable; |
| 156260 | Index *pIdx; | 157225 | Index *pIdx; |
| 156261 | pTab->aCol = pNew->aCol; | 157226 | pTab->aCol = pNew->aCol; |
| 157227 | assert( IsOrdinaryTable(pNew) ); | ||
| 156262 | sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); | 157228 | sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); |
| 156263 | pTab->nNVCol = pTab->nCol = pNew->nCol; | 157229 | pTab->nNVCol = pTab->nCol = pNew->nCol; |
| 156264 | pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); | 157230 | pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); |
| @@ -156933,11 +157899,13 @@ struct WhereLoop { | |||
| 156933 | u16 nTop; /* Size of TOP vector */ | 157899 | u16 nTop; /* Size of TOP vector */ |
| 156934 | u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ | 157900 | u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ |
| 156935 | Index *pIndex; /* Index used, or NULL */ | 157901 | Index *pIndex; /* Index used, or NULL */ |
| 157902 | ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ | ||
| 156936 | } btree; | 157903 | } btree; |
| 156937 | struct { /* Information for virtual tables */ | 157904 | struct { /* Information for virtual tables */ |
| 156938 | int idxNum; /* Index number */ | 157905 | int idxNum; /* Index number */ |
| 156939 | u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ | 157906 | u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ |
| 156940 | u32 bOmitOffset : 1; /* True to let virtual table handle offset */ | 157907 | u32 bOmitOffset : 1; /* True to let virtual table handle offset */ |
| 157908 | u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ | ||
| 156941 | i8 isOrdered; /* True if satisfies ORDER BY */ | 157909 | i8 isOrdered; /* True if satisfies ORDER BY */ |
| 156942 | u16 omitMask; /* Terms that may be omitted */ | 157910 | u16 omitMask; /* Terms that may be omitted */ |
| 156943 | char *idxStr; /* Index identifier string */ | 157911 | char *idxStr; /* Index identifier string */ |
| @@ -156950,6 +157918,8 @@ struct WhereLoop { | |||
| 156950 | /**** whereLoopXfer() copies fields above ***********************/ | 157918 | /**** whereLoopXfer() copies fields above ***********************/ |
| 156951 | # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) | 157919 | # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) |
| 156952 | u16 nLSlot; /* Number of slots allocated for aLTerm[] */ | 157920 | u16 nLSlot; /* Number of slots allocated for aLTerm[] */ |
| 157921 | LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not | ||
| 157922 | ** initialized unless pWInfo->nOutStarDelta>0 */ | ||
| 156953 | WhereTerm **aLTerm; /* WhereTerms used */ | 157923 | WhereTerm **aLTerm; /* WhereTerms used */ |
| 156954 | WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ | 157924 | WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ |
| 156955 | WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ | 157925 | WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ |
| @@ -157272,6 +158242,7 @@ struct WhereInfo { | |||
| 157272 | unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ | 158242 | unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ |
| 157273 | unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ | 158243 | unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ |
| 157274 | unsigned sorted :1; /* True if really sorted (not just grouped) */ | 158244 | unsigned sorted :1; /* True if really sorted (not just grouped) */ |
| 158245 | LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */ | ||
| 157275 | LogEst nRowOut; /* Estimated number of output rows */ | 158246 | LogEst nRowOut; /* Estimated number of output rows */ |
| 157276 | int iTop; /* The very beginning of the WHERE loop */ | 158247 | int iTop; /* The very beginning of the WHERE loop */ |
| 157277 | int iEndWhere; /* End of the WHERE clause itself */ | 158248 | int iEndWhere; /* End of the WHERE clause itself */ |
| @@ -157423,7 +158394,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); | |||
| 157423 | #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ | 158394 | #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ |
| 157424 | #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ | 158395 | #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ |
| 157425 | #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ | 158396 | #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ |
| 157426 | /* 0x02000000 -- available for reuse */ | 158397 | #define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. |
| 158398 | ** NB: False-negatives are possible */ | ||
| 157427 | #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ | 158399 | #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ |
| 157428 | 158400 | ||
| 157429 | #endif /* !defined(SQLITE_WHEREINT_H) */ | 158401 | #endif /* !defined(SQLITE_WHEREINT_H) */ |
| @@ -157568,7 +158540,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( | |||
| 157568 | assert( pLoop->u.btree.pIndex!=0 ); | 158540 | assert( pLoop->u.btree.pIndex!=0 ); |
| 157569 | pIdx = pLoop->u.btree.pIndex; | 158541 | pIdx = pLoop->u.btree.pIndex; |
| 157570 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); | 158542 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 157571 | if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ | 158543 | if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 157572 | if( isSearch ){ | 158544 | if( isSearch ){ |
| 157573 | zFmt = "PRIMARY KEY"; | 158545 | zFmt = "PRIMARY KEY"; |
| 157574 | } | 158546 | } |
| @@ -157611,7 +158583,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( | |||
| 157611 | } | 158583 | } |
| 157612 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 158584 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 157613 | else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ | 158585 | else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ |
| 157614 | sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", | 158586 | sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); |
| 158587 | sqlite3_str_appendf(&str, | ||
| 158588 | pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", | ||
| 157615 | pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); | 158589 | pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); |
| 157616 | } | 158590 | } |
| 157617 | #endif | 158591 | #endif |
| @@ -157629,7 +158603,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( | |||
| 157629 | zMsg = sqlite3StrAccumFinish(&str); | 158603 | zMsg = sqlite3StrAccumFinish(&str); |
| 157630 | sqlite3ExplainBreakpoint("",zMsg); | 158604 | sqlite3ExplainBreakpoint("",zMsg); |
| 157631 | ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), | 158605 | ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), |
| 157632 | pParse->addrExplain, 0, zMsg,P4_DYNAMIC); | 158606 | pParse->addrExplain, pLoop->rRun, |
| 158607 | zMsg, P4_DYNAMIC); | ||
| 157633 | } | 158608 | } |
| 157634 | return ret; | 158609 | return ret; |
| 157635 | } | 158610 | } |
| @@ -157664,7 +158639,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( | |||
| 157664 | sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); | 158639 | sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); |
| 157665 | pLoop = pLevel->pWLoop; | 158640 | pLoop = pLevel->pWLoop; |
| 157666 | if( pLoop->wsFlags & WHERE_IPK ){ | 158641 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 157667 | const Table *pTab = pItem->pTab; | 158642 | const Table *pTab = pItem->pSTab; |
| 157668 | if( pTab->iPKey>=0 ){ | 158643 | if( pTab->iPKey>=0 ){ |
| 157669 | sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); | 158644 | sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); |
| 157670 | }else{ | 158645 | }else{ |
| @@ -157727,7 +158702,9 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( | |||
| 157727 | sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); | 158702 | sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); |
| 157728 | } | 158703 | } |
| 157729 | }else{ | 158704 | }else{ |
| 157730 | int addr = pSrclist->a[pLvl->iFrom].addrFillSub; | 158705 | int addr; |
| 158706 | assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); | ||
| 158707 | addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; | ||
| 157731 | VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); | 158708 | VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); |
| 157732 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); | 158709 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); |
| 157733 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); | 158710 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); |
| @@ -157871,6 +158848,39 @@ static void updateRangeAffinityStr( | |||
| 157871 | } | 158848 | } |
| 157872 | } | 158849 | } |
| 157873 | 158850 | ||
| 158851 | /* | ||
| 158852 | ** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because | ||
| 158853 | ** columns might have been rearranged in the result set. This routine | ||
| 158854 | ** fixes them up. | ||
| 158855 | ** | ||
| 158856 | ** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values | ||
| 158857 | ** contain the *old* locations of each expression. This is a temporary | ||
| 158858 | ** use of u.x.iOrderByCol, not its intended use. The caller must reset | ||
| 158859 | ** u.x.iOrderByCol back to zero for all entries in pEList before the | ||
| 158860 | ** caller returns. | ||
| 158861 | ** | ||
| 158862 | ** This routine changes pOrderBy->a[].u.x.iOrderByCol values from | ||
| 158863 | ** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based | ||
| 158864 | ** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. | ||
| 158865 | */ | ||
| 158866 | static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ | ||
| 158867 | int i, j; | ||
| 158868 | if( pOrderBy==0 ) return; | ||
| 158869 | for(i=0; i<pOrderBy->nExpr; i++){ | ||
| 158870 | int t = pOrderBy->a[i].u.x.iOrderByCol; | ||
| 158871 | if( t==0 ) continue; | ||
| 158872 | for(j=0; j<pEList->nExpr; j++){ | ||
| 158873 | if( pEList->a[j].u.x.iOrderByCol==t ){ | ||
| 158874 | pOrderBy->a[i].u.x.iOrderByCol = j+1; | ||
| 158875 | break; | ||
| 158876 | } | ||
| 158877 | } | ||
| 158878 | if( j>=pEList->nExpr ){ | ||
| 158879 | pOrderBy->a[i].u.x.iOrderByCol = 0; | ||
| 158880 | } | ||
| 158881 | } | ||
| 158882 | } | ||
| 158883 | |||
| 157874 | 158884 | ||
| 157875 | /* | 158885 | /* |
| 157876 | ** pX is an expression of the form: (vector) IN (SELECT ...) | 158886 | ** pX is an expression of the form: (vector) IN (SELECT ...) |
| @@ -157934,6 +158944,7 @@ static Expr *removeUnindexableInClauseTerms( | |||
| 157934 | if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ | 158944 | if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ |
| 157935 | pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); | 158945 | pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); |
| 157936 | pOrigRhs->a[iField].pExpr = 0; | 158946 | pOrigRhs->a[iField].pExpr = 0; |
| 158947 | if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; | ||
| 157937 | if( pOrigLhs ){ | 158948 | if( pOrigLhs ){ |
| 157938 | assert( pOrigLhs->a[iField].pExpr!=0 ); | 158949 | assert( pOrigLhs->a[iField].pExpr!=0 ); |
| 157939 | pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); | 158950 | pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); |
| @@ -157947,6 +158958,7 @@ static Expr *removeUnindexableInClauseTerms( | |||
| 157947 | pNew->pLeft->x.pList = pLhs; | 158958 | pNew->pLeft->x.pList = pLhs; |
| 157948 | } | 158959 | } |
| 157949 | pSelect->pEList = pRhs; | 158960 | pSelect->pEList = pRhs; |
| 158961 | pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ | ||
| 157950 | if( pLhs && pLhs->nExpr==1 ){ | 158962 | if( pLhs && pLhs->nExpr==1 ){ |
| 157951 | /* Take care here not to generate a TK_VECTOR containing only a | 158963 | /* Take care here not to generate a TK_VECTOR containing only a |
| 157952 | ** single value. Since the parser never creates such a vector, some | 158964 | ** single value. Since the parser never creates such a vector, some |
| @@ -157956,18 +158968,16 @@ static Expr *removeUnindexableInClauseTerms( | |||
| 157956 | sqlite3ExprDelete(db, pNew->pLeft); | 158968 | sqlite3ExprDelete(db, pNew->pLeft); |
| 157957 | pNew->pLeft = p; | 158969 | pNew->pLeft = p; |
| 157958 | } | 158970 | } |
| 157959 | if( pSelect->pOrderBy ){ | 158971 | |
| 157960 | /* If the SELECT statement has an ORDER BY clause, zero the | 158972 | /* If either the ORDER BY clause or the GROUP BY clause contains |
| 157961 | ** iOrderByCol variables. These are set to non-zero when an | 158973 | ** references to result-set columns, those references might now be |
| 157962 | ** ORDER BY term exactly matches one of the terms of the | 158974 | ** obsolete. So fix them up. |
| 157963 | ** result-set. Since the result-set of the SELECT statement may | 158975 | */ |
| 157964 | ** have been modified or reordered, these variables are no longer | 158976 | assert( pRhs!=0 || db->mallocFailed ); |
| 157965 | ** set correctly. Since setting them is just an optimization, | 158977 | if( pRhs ){ |
| 157966 | ** it's easiest just to zero them here. */ | 158978 | adjustOrderByCol(pSelect->pOrderBy, pRhs); |
| 157967 | ExprList *pOrderBy = pSelect->pOrderBy; | 158979 | adjustOrderByCol(pSelect->pGroupBy, pRhs); |
| 157968 | for(i=0; i<pOrderBy->nExpr; i++){ | 158980 | for(i=0; i<pRhs->nExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; |
| 157969 | pOrderBy->a[i].u.x.iOrderByCol = 0; | ||
| 157970 | } | ||
| 157971 | } | 158981 | } |
| 157972 | 158982 | ||
| 157973 | #if 0 | 158983 | #if 0 |
| @@ -157982,6 +158992,147 @@ static Expr *removeUnindexableInClauseTerms( | |||
| 157982 | } | 158992 | } |
| 157983 | 158993 | ||
| 157984 | 158994 | ||
| 158995 | #ifndef SQLITE_OMIT_SUBQUERY | ||
| 158996 | /* | ||
| 158997 | ** Generate code for a single X IN (....) term of the WHERE clause. | ||
| 158998 | ** | ||
| 158999 | ** This is a special-case of codeEqualityTerm() that works for IN operators | ||
| 159000 | ** only. It is broken out into a subroutine because this case is | ||
| 159001 | ** uncommon and by splitting it off into a subroutine, the common case | ||
| 159002 | ** runs faster. | ||
| 159003 | ** | ||
| 159004 | ** The current value for the constraint is left in register iTarget. | ||
| 159005 | ** This routine sets up a loop that will iterate over all values of X. | ||
| 159006 | */ | ||
| 159007 | static SQLITE_NOINLINE void codeINTerm( | ||
| 159008 | Parse *pParse, /* The parsing context */ | ||
| 159009 | WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ | ||
| 159010 | WhereLevel *pLevel, /* The level of the FROM clause we are working on */ | ||
| 159011 | int iEq, /* Index of the equality term within this level */ | ||
| 159012 | int bRev, /* True for reverse-order IN operations */ | ||
| 159013 | int iTarget /* Attempt to leave results in this register */ | ||
| 159014 | ){ | ||
| 159015 | Expr *pX = pTerm->pExpr; | ||
| 159016 | int eType = IN_INDEX_NOOP; | ||
| 159017 | int iTab; | ||
| 159018 | struct InLoop *pIn; | ||
| 159019 | WhereLoop *pLoop = pLevel->pWLoop; | ||
| 159020 | Vdbe *v = pParse->pVdbe; | ||
| 159021 | int i; | ||
| 159022 | int nEq = 0; | ||
| 159023 | int *aiMap = 0; | ||
| 159024 | |||
| 159025 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 | ||
| 159026 | && pLoop->u.btree.pIndex!=0 | ||
| 159027 | && pLoop->u.btree.pIndex->aSortOrder[iEq] | ||
| 159028 | ){ | ||
| 159029 | testcase( iEq==0 ); | ||
| 159030 | testcase( bRev ); | ||
| 159031 | bRev = !bRev; | ||
| 159032 | } | ||
| 159033 | assert( pX->op==TK_IN ); | ||
| 159034 | |||
| 159035 | for(i=0; i<iEq; i++){ | ||
| 159036 | if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ | ||
| 159037 | disableTerm(pLevel, pTerm); | ||
| 159038 | return; | ||
| 159039 | } | ||
| 159040 | } | ||
| 159041 | for(i=iEq;i<pLoop->nLTerm; i++){ | ||
| 159042 | assert( pLoop->aLTerm[i]!=0 ); | ||
| 159043 | if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; | ||
| 159044 | } | ||
| 159045 | |||
| 159046 | iTab = 0; | ||
| 159047 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ | ||
| 159048 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); | ||
| 159049 | }else{ | ||
| 159050 | Expr *pExpr = pTerm->pExpr; | ||
| 159051 | if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ | ||
| 159052 | sqlite3 *db = pParse->db; | ||
| 159053 | pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); | ||
| 159054 | if( !db->mallocFailed ){ | ||
| 159055 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); | ||
| 159056 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); | ||
| 159057 | pExpr->iTable = iTab; | ||
| 159058 | } | ||
| 159059 | sqlite3ExprDelete(db, pX); | ||
| 159060 | }else{ | ||
| 159061 | int n = sqlite3ExprVectorSize(pX->pLeft); | ||
| 159062 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); | ||
| 159063 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); | ||
| 159064 | } | ||
| 159065 | pX = pExpr; | ||
| 159066 | } | ||
| 159067 | |||
| 159068 | if( eType==IN_INDEX_INDEX_DESC ){ | ||
| 159069 | testcase( bRev ); | ||
| 159070 | bRev = !bRev; | ||
| 159071 | } | ||
| 159072 | sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); | ||
| 159073 | VdbeCoverageIf(v, bRev); | ||
| 159074 | VdbeCoverageIf(v, !bRev); | ||
| 159075 | |||
| 159076 | assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); | ||
| 159077 | pLoop->wsFlags |= WHERE_IN_ABLE; | ||
| 159078 | if( pLevel->u.in.nIn==0 ){ | ||
| 159079 | pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); | ||
| 159080 | } | ||
| 159081 | if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ | ||
| 159082 | pLoop->wsFlags |= WHERE_IN_EARLYOUT; | ||
| 159083 | } | ||
| 159084 | |||
| 159085 | i = pLevel->u.in.nIn; | ||
| 159086 | pLevel->u.in.nIn += nEq; | ||
| 159087 | pLevel->u.in.aInLoop = | ||
| 159088 | sqlite3WhereRealloc(pTerm->pWC->pWInfo, | ||
| 159089 | pLevel->u.in.aInLoop, | ||
| 159090 | sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); | ||
| 159091 | pIn = pLevel->u.in.aInLoop; | ||
| 159092 | if( pIn ){ | ||
| 159093 | int iMap = 0; /* Index in aiMap[] */ | ||
| 159094 | pIn += i; | ||
| 159095 | for(i=iEq;i<pLoop->nLTerm; i++){ | ||
| 159096 | if( pLoop->aLTerm[i]->pExpr==pX ){ | ||
| 159097 | int iOut = iTarget + i - iEq; | ||
| 159098 | if( eType==IN_INDEX_ROWID ){ | ||
| 159099 | pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); | ||
| 159100 | }else{ | ||
| 159101 | int iCol = aiMap ? aiMap[iMap++] : 0; | ||
| 159102 | pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); | ||
| 159103 | } | ||
| 159104 | sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); | ||
| 159105 | if( i==iEq ){ | ||
| 159106 | pIn->iCur = iTab; | ||
| 159107 | pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; | ||
| 159108 | if( iEq>0 ){ | ||
| 159109 | pIn->iBase = iTarget - i; | ||
| 159110 | pIn->nPrefix = i; | ||
| 159111 | }else{ | ||
| 159112 | pIn->nPrefix = 0; | ||
| 159113 | } | ||
| 159114 | }else{ | ||
| 159115 | pIn->eEndLoopOp = OP_Noop; | ||
| 159116 | } | ||
| 159117 | pIn++; | ||
| 159118 | } | ||
| 159119 | } | ||
| 159120 | testcase( iEq>0 | ||
| 159121 | && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 | ||
| 159122 | && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); | ||
| 159123 | if( iEq>0 | ||
| 159124 | && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 | ||
| 159125 | ){ | ||
| 159126 | sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); | ||
| 159127 | } | ||
| 159128 | }else{ | ||
| 159129 | pLevel->u.in.nIn = 0; | ||
| 159130 | } | ||
| 159131 | sqlite3DbFree(pParse->db, aiMap); | ||
| 159132 | } | ||
| 159133 | #endif | ||
| 159134 | |||
| 159135 | |||
| 157985 | /* | 159136 | /* |
| 157986 | ** Generate code for a single equality term of the WHERE clause. An equality | 159137 | ** Generate code for a single equality term of the WHERE clause. An equality |
| 157987 | ** term can be either X=expr or X IN (...). pTerm is the term to be | 159138 | ** term can be either X=expr or X IN (...). pTerm is the term to be |
| @@ -158006,7 +159157,6 @@ static int codeEqualityTerm( | |||
| 158006 | int iTarget /* Attempt to leave results in this register */ | 159157 | int iTarget /* Attempt to leave results in this register */ |
| 158007 | ){ | 159158 | ){ |
| 158008 | Expr *pX = pTerm->pExpr; | 159159 | Expr *pX = pTerm->pExpr; |
| 158009 | Vdbe *v = pParse->pVdbe; | ||
| 158010 | int iReg; /* Register holding results */ | 159160 | int iReg; /* Register holding results */ |
| 158011 | 159161 | ||
| 158012 | assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); | 159162 | assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); |
| @@ -158015,125 +159165,12 @@ static int codeEqualityTerm( | |||
| 158015 | iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); | 159165 | iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); |
| 158016 | }else if( pX->op==TK_ISNULL ){ | 159166 | }else if( pX->op==TK_ISNULL ){ |
| 158017 | iReg = iTarget; | 159167 | iReg = iTarget; |
| 158018 | sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); | 159168 | sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); |
| 158019 | #ifndef SQLITE_OMIT_SUBQUERY | 159169 | #ifndef SQLITE_OMIT_SUBQUERY |
| 158020 | }else{ | 159170 | }else{ |
| 158021 | int eType = IN_INDEX_NOOP; | ||
| 158022 | int iTab; | ||
| 158023 | struct InLoop *pIn; | ||
| 158024 | WhereLoop *pLoop = pLevel->pWLoop; | ||
| 158025 | int i; | ||
| 158026 | int nEq = 0; | ||
| 158027 | int *aiMap = 0; | ||
| 158028 | |||
| 158029 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 | ||
| 158030 | && pLoop->u.btree.pIndex!=0 | ||
| 158031 | && pLoop->u.btree.pIndex->aSortOrder[iEq] | ||
| 158032 | ){ | ||
| 158033 | testcase( iEq==0 ); | ||
| 158034 | testcase( bRev ); | ||
| 158035 | bRev = !bRev; | ||
| 158036 | } | ||
| 158037 | assert( pX->op==TK_IN ); | 159171 | assert( pX->op==TK_IN ); |
| 158038 | iReg = iTarget; | 159172 | iReg = iTarget; |
| 158039 | 159173 | codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); | |
| 158040 | for(i=0; i<iEq; i++){ | ||
| 158041 | if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ | ||
| 158042 | disableTerm(pLevel, pTerm); | ||
| 158043 | return iTarget; | ||
| 158044 | } | ||
| 158045 | } | ||
| 158046 | for(i=iEq;i<pLoop->nLTerm; i++){ | ||
| 158047 | assert( pLoop->aLTerm[i]!=0 ); | ||
| 158048 | if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; | ||
| 158049 | } | ||
| 158050 | |||
| 158051 | iTab = 0; | ||
| 158052 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ | ||
| 158053 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); | ||
| 158054 | }else{ | ||
| 158055 | Expr *pExpr = pTerm->pExpr; | ||
| 158056 | if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ | ||
| 158057 | sqlite3 *db = pParse->db; | ||
| 158058 | pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); | ||
| 158059 | if( !db->mallocFailed ){ | ||
| 158060 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); | ||
| 158061 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); | ||
| 158062 | pExpr->iTable = iTab; | ||
| 158063 | } | ||
| 158064 | sqlite3ExprDelete(db, pX); | ||
| 158065 | }else{ | ||
| 158066 | int n = sqlite3ExprVectorSize(pX->pLeft); | ||
| 158067 | aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); | ||
| 158068 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); | ||
| 158069 | } | ||
| 158070 | pX = pExpr; | ||
| 158071 | } | ||
| 158072 | |||
| 158073 | if( eType==IN_INDEX_INDEX_DESC ){ | ||
| 158074 | testcase( bRev ); | ||
| 158075 | bRev = !bRev; | ||
| 158076 | } | ||
| 158077 | sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); | ||
| 158078 | VdbeCoverageIf(v, bRev); | ||
| 158079 | VdbeCoverageIf(v, !bRev); | ||
| 158080 | |||
| 158081 | assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); | ||
| 158082 | pLoop->wsFlags |= WHERE_IN_ABLE; | ||
| 158083 | if( pLevel->u.in.nIn==0 ){ | ||
| 158084 | pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); | ||
| 158085 | } | ||
| 158086 | if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ | ||
| 158087 | pLoop->wsFlags |= WHERE_IN_EARLYOUT; | ||
| 158088 | } | ||
| 158089 | |||
| 158090 | i = pLevel->u.in.nIn; | ||
| 158091 | pLevel->u.in.nIn += nEq; | ||
| 158092 | pLevel->u.in.aInLoop = | ||
| 158093 | sqlite3WhereRealloc(pTerm->pWC->pWInfo, | ||
| 158094 | pLevel->u.in.aInLoop, | ||
| 158095 | sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); | ||
| 158096 | pIn = pLevel->u.in.aInLoop; | ||
| 158097 | if( pIn ){ | ||
| 158098 | int iMap = 0; /* Index in aiMap[] */ | ||
| 158099 | pIn += i; | ||
| 158100 | for(i=iEq;i<pLoop->nLTerm; i++){ | ||
| 158101 | if( pLoop->aLTerm[i]->pExpr==pX ){ | ||
| 158102 | int iOut = iReg + i - iEq; | ||
| 158103 | if( eType==IN_INDEX_ROWID ){ | ||
| 158104 | pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); | ||
| 158105 | }else{ | ||
| 158106 | int iCol = aiMap ? aiMap[iMap++] : 0; | ||
| 158107 | pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); | ||
| 158108 | } | ||
| 158109 | sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); | ||
| 158110 | if( i==iEq ){ | ||
| 158111 | pIn->iCur = iTab; | ||
| 158112 | pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; | ||
| 158113 | if( iEq>0 ){ | ||
| 158114 | pIn->iBase = iReg - i; | ||
| 158115 | pIn->nPrefix = i; | ||
| 158116 | }else{ | ||
| 158117 | pIn->nPrefix = 0; | ||
| 158118 | } | ||
| 158119 | }else{ | ||
| 158120 | pIn->eEndLoopOp = OP_Noop; | ||
| 158121 | } | ||
| 158122 | pIn++; | ||
| 158123 | } | ||
| 158124 | } | ||
| 158125 | testcase( iEq>0 | ||
| 158126 | && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 | ||
| 158127 | && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); | ||
| 158128 | if( iEq>0 | ||
| 158129 | && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 | ||
| 158130 | ){ | ||
| 158131 | sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); | ||
| 158132 | } | ||
| 158133 | }else{ | ||
| 158134 | pLevel->u.in.nIn = 0; | ||
| 158135 | } | ||
| 158136 | sqlite3DbFree(pParse->db, aiMap); | ||
| 158137 | #endif | 159174 | #endif |
| 158138 | } | 159175 | } |
| 158139 | 159176 | ||
| @@ -158805,7 +159842,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 158805 | iCur = pTabItem->iCursor; | 159842 | iCur = pTabItem->iCursor; |
| 158806 | pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); | 159843 | pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); |
| 158807 | bRev = (pWInfo->revMask>>iLevel)&1; | 159844 | bRev = (pWInfo->revMask>>iLevel)&1; |
| 158808 | VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); | 159845 | VdbeModuleComment((v, "Begin WHERE-loop%d: %s", |
| 159846 | iLevel, pTabItem->pSTab->zName)); | ||
| 158809 | #if WHERETRACE_ENABLED /* 0x4001 */ | 159847 | #if WHERETRACE_ENABLED /* 0x4001 */ |
| 158810 | if( sqlite3WhereTrace & 0x1 ){ | 159848 | if( sqlite3WhereTrace & 0x1 ){ |
| 158811 | sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", | 159849 | sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", |
| @@ -158860,11 +159898,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 158860 | 159898 | ||
| 158861 | /* Special case of a FROM clause subquery implemented as a co-routine */ | 159899 | /* Special case of a FROM clause subquery implemented as a co-routine */ |
| 158862 | if( pTabItem->fg.viaCoroutine ){ | 159900 | if( pTabItem->fg.viaCoroutine ){ |
| 158863 | int regYield = pTabItem->regReturn; | 159901 | int regYield; |
| 158864 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); | 159902 | Subquery *pSubq; |
| 159903 | assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); | ||
| 159904 | pSubq = pTabItem->u4.pSubq; | ||
| 159905 | regYield = pSubq->regReturn; | ||
| 159906 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); | ||
| 158865 | pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); | 159907 | pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); |
| 158866 | VdbeCoverage(v); | 159908 | VdbeCoverage(v); |
| 158867 | VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); | 159909 | VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); |
| 158868 | pLevel->op = OP_Goto; | 159910 | pLevel->op = OP_Goto; |
| 158869 | }else | 159911 | }else |
| 158870 | 159912 | ||
| @@ -159593,7 +160635,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 159593 | int untestedTerms = 0; /* Some terms not completely tested */ | 160635 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 159594 | int ii; /* Loop counter */ | 160636 | int ii; /* Loop counter */ |
| 159595 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ | 160637 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 159596 | Table *pTab = pTabItem->pTab; | 160638 | Table *pTab = pTabItem->pSTab; |
| 159597 | 160639 | ||
| 159598 | pTerm = pLoop->aLTerm[0]; | 160640 | pTerm = pLoop->aLTerm[0]; |
| 159599 | assert( pTerm!=0 ); | 160641 | assert( pTerm!=0 ); |
| @@ -160052,7 +161094,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 160052 | ** least once. This is accomplished by storing the PK for the row in | 161094 | ** least once. This is accomplished by storing the PK for the row in |
| 160053 | ** both the iMatch index and the regBloom Bloom filter. | 161095 | ** both the iMatch index and the regBloom Bloom filter. |
| 160054 | */ | 161096 | */ |
| 160055 | pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; | 161097 | pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; |
| 160056 | if( HasRowid(pTab) ){ | 161098 | if( HasRowid(pTab) ){ |
| 160057 | r = sqlite3GetTempRange(pParse, 2); | 161099 | r = sqlite3GetTempRange(pParse, 2); |
| 160058 | sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); | 161100 | sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); |
| @@ -160159,7 +161201,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( | |||
| 160159 | Bitmask mAll = 0; | 161201 | Bitmask mAll = 0; |
| 160160 | int k; | 161202 | int k; |
| 160161 | 161203 | ||
| 160162 | ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); | 161204 | ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); |
| 160163 | sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, | 161205 | sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, |
| 160164 | pRJ->regReturn); | 161206 | pRJ->regReturn); |
| 160165 | for(k=0; k<iLevel; k++){ | 161207 | for(k=0; k<iLevel; k++){ |
| @@ -160169,9 +161211,13 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( | |||
| 160169 | pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; | 161211 | pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; |
| 160170 | mAll |= pWInfo->a[k].pWLoop->maskSelf; | 161212 | mAll |= pWInfo->a[k].pWLoop->maskSelf; |
| 160171 | if( pRight->fg.viaCoroutine ){ | 161213 | if( pRight->fg.viaCoroutine ){ |
| 161214 | Subquery *pSubq; | ||
| 161215 | assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); | ||
| 161216 | pSubq = pRight->u4.pSubq; | ||
| 161217 | assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); | ||
| 160172 | sqlite3VdbeAddOp3( | 161218 | sqlite3VdbeAddOp3( |
| 160173 | v, OP_Null, 0, pRight->regResult, | 161219 | v, OP_Null, 0, pSubq->regResult, |
| 160174 | pRight->regResult + pRight->pSelect->pEList->nExpr-1 | 161220 | pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 |
| 160175 | ); | 161221 | ); |
| 160176 | } | 161222 | } |
| 160177 | sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); | 161223 | sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); |
| @@ -160209,7 +161255,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( | |||
| 160209 | int nPk; | 161255 | int nPk; |
| 160210 | int jmp; | 161256 | int jmp; |
| 160211 | int addrCont = sqlite3WhereContinueLabel(pSubWInfo); | 161257 | int addrCont = sqlite3WhereContinueLabel(pSubWInfo); |
| 160212 | Table *pTab = pTabItem->pTab; | 161258 | Table *pTab = pTabItem->pSTab; |
| 160213 | if( HasRowid(pTab) ){ | 161259 | if( HasRowid(pTab) ){ |
| 160214 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); | 161260 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); |
| 160215 | nPk = 1; | 161261 | nPk = 1; |
| @@ -160342,7 +161388,12 @@ static int allowedOp(int op){ | |||
| 160342 | assert( TK_LT>TK_EQ && TK_LT<TK_GE ); | 161388 | assert( TK_LT>TK_EQ && TK_LT<TK_GE ); |
| 160343 | assert( TK_LE>TK_EQ && TK_LE<TK_GE ); | 161389 | assert( TK_LE>TK_EQ && TK_LE<TK_GE ); |
| 160344 | assert( TK_GE==TK_EQ+4 ); | 161390 | assert( TK_GE==TK_EQ+4 ); |
| 160345 | return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; | 161391 | assert( TK_IN<TK_EQ ); |
| 161392 | assert( TK_IS<TK_EQ ); | ||
| 161393 | assert( TK_ISNULL<TK_EQ ); | ||
| 161394 | if( op>TK_GE ) return 0; | ||
| 161395 | if( op>=TK_EQ ) return 1; | ||
| 161396 | return op==TK_IN || op==TK_ISNULL || op==TK_IS; | ||
| 160346 | } | 161397 | } |
| 160347 | 161398 | ||
| 160348 | /* | 161399 | /* |
| @@ -160375,15 +161426,16 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ | |||
| 160375 | static u16 operatorMask(int op){ | 161426 | static u16 operatorMask(int op){ |
| 160376 | u16 c; | 161427 | u16 c; |
| 160377 | assert( allowedOp(op) ); | 161428 | assert( allowedOp(op) ); |
| 160378 | if( op==TK_IN ){ | 161429 | if( op>=TK_EQ ){ |
| 161430 | assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); | ||
| 161431 | c = (u16)(WO_EQ<<(op-TK_EQ)); | ||
| 161432 | }else if( op==TK_IN ){ | ||
| 160379 | c = WO_IN; | 161433 | c = WO_IN; |
| 160380 | }else if( op==TK_ISNULL ){ | 161434 | }else if( op==TK_ISNULL ){ |
| 160381 | c = WO_ISNULL; | 161435 | c = WO_ISNULL; |
| 160382 | }else if( op==TK_IS ){ | ||
| 160383 | c = WO_IS; | ||
| 160384 | }else{ | 161436 | }else{ |
| 160385 | assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); | 161437 | assert( op==TK_IS ); |
| 160386 | c = (u16)(WO_EQ<<(op-TK_EQ)); | 161438 | c = WO_IS; |
| 160387 | } | 161439 | } |
| 160388 | assert( op!=TK_ISNULL || c==WO_ISNULL ); | 161440 | assert( op!=TK_ISNULL || c==WO_ISNULL ); |
| 160389 | assert( op!=TK_IN || c==WO_IN ); | 161441 | assert( op!=TK_IN || c==WO_IN ); |
| @@ -160454,12 +161506,26 @@ static int isLikeOrGlob( | |||
| 160454 | z = (u8*)pRight->u.zToken; | 161506 | z = (u8*)pRight->u.zToken; |
| 160455 | } | 161507 | } |
| 160456 | if( z ){ | 161508 | if( z ){ |
| 160457 | 161509 | /* Count the number of prefix bytes prior to the first wildcard. | |
| 160458 | /* Count the number of prefix characters prior to the first wildcard */ | 161510 | ** or U+fffd character. If the underlying database has a UTF16LE |
| 161511 | ** encoding, then only consider ASCII characters. Note that the | ||
| 161512 | ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in | ||
| 161513 | ** this code, but the database engine itself might be processing | ||
| 161514 | ** content using a different encoding. */ | ||
| 160459 | cnt = 0; | 161515 | cnt = 0; |
| 160460 | while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ | 161516 | while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ |
| 160461 | cnt++; | 161517 | cnt++; |
| 160462 | if( c==wc[3] && z[cnt]!=0 ) cnt++; | 161518 | if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ |
| 161519 | cnt++; | ||
| 161520 | }else if( c>=0x80 ){ | ||
| 161521 | const u8 *z2 = z+cnt-1; | ||
| 161522 | if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){ | ||
| 161523 | cnt--; | ||
| 161524 | break; | ||
| 161525 | }else{ | ||
| 161526 | cnt = (int)(z2-z); | ||
| 161527 | } | ||
| 161528 | } | ||
| 160463 | } | 161529 | } |
| 160464 | 161530 | ||
| 160465 | /* The optimization is possible only if (1) the pattern does not begin | 161531 | /* The optimization is possible only if (1) the pattern does not begin |
| @@ -160470,11 +161536,11 @@ static int isLikeOrGlob( | |||
| 160470 | ** range search. The third is because the caller assumes that the pattern | 161536 | ** range search. The third is because the caller assumes that the pattern |
| 160471 | ** consists of at least one character after all escapes have been | 161537 | ** consists of at least one character after all escapes have been |
| 160472 | ** removed. */ | 161538 | ** removed. */ |
| 160473 | if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ | 161539 | if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){ |
| 160474 | Expr *pPrefix; | 161540 | Expr *pPrefix; |
| 160475 | 161541 | ||
| 160476 | /* A "complete" match if the pattern ends with "*" or "%" */ | 161542 | /* A "complete" match if the pattern ends with "*" or "%" */ |
| 160477 | *pisComplete = c==wc[0] && z[cnt+1]==0; | 161543 | *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; |
| 160478 | 161544 | ||
| 160479 | /* Get the pattern prefix. Remove all escapes from the prefix. */ | 161545 | /* Get the pattern prefix. Remove all escapes from the prefix. */ |
| 160480 | pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); | 161546 | pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); |
| @@ -160670,6 +161736,13 @@ static int isAuxiliaryVtabOperator( | |||
| 160670 | } | 161736 | } |
| 160671 | } | 161737 | } |
| 160672 | } | 161738 | } |
| 161739 | }else if( pExpr->op>=TK_EQ ){ | ||
| 161740 | /* Comparison operators are a common case. Save a few comparisons for | ||
| 161741 | ** that common case by terminating early. */ | ||
| 161742 | assert( TK_NE < TK_EQ ); | ||
| 161743 | assert( TK_ISNOT < TK_EQ ); | ||
| 161744 | assert( TK_NOTNULL < TK_EQ ); | ||
| 161745 | return 0; | ||
| 160673 | }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ | 161746 | }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ |
| 160674 | int res = 0; | 161747 | int res = 0; |
| 160675 | Expr *pLeft = pExpr->pLeft; | 161748 | Expr *pLeft = pExpr->pLeft; |
| @@ -161186,7 +162259,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ | |||
| 161186 | if( ALWAYS(pSrc!=0) ){ | 162259 | if( ALWAYS(pSrc!=0) ){ |
| 161187 | int i; | 162260 | int i; |
| 161188 | for(i=0; i<pSrc->nSrc; i++){ | 162261 | for(i=0; i<pSrc->nSrc; i++){ |
| 161189 | mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); | 162262 | if( pSrc->a[i].fg.isSubquery ){ |
| 162263 | mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); | ||
| 162264 | } | ||
| 161190 | if( pSrc->a[i].fg.isUsing==0 ){ | 162265 | if( pSrc->a[i].fg.isUsing==0 ){ |
| 161191 | mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); | 162266 | mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); |
| 161192 | } | 162267 | } |
| @@ -161224,7 +162299,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( | |||
| 161224 | int iCur; | 162299 | int iCur; |
| 161225 | do{ | 162300 | do{ |
| 161226 | iCur = pFrom->a[j].iCursor; | 162301 | iCur = pFrom->a[j].iCursor; |
| 161227 | for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 162302 | for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 161228 | if( pIdx->aColExpr==0 ) continue; | 162303 | if( pIdx->aColExpr==0 ) continue; |
| 161229 | for(i=0; i<pIdx->nKeyCol; i++){ | 162304 | for(i=0; i<pIdx->nKeyCol; i++){ |
| 161230 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; | 162305 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; |
| @@ -161268,7 +162343,7 @@ static int exprMightBeIndexed( | |||
| 161268 | 162343 | ||
| 161269 | for(i=0; i<pFrom->nSrc; i++){ | 162344 | for(i=0; i<pFrom->nSrc; i++){ |
| 161270 | Index *pIdx; | 162345 | Index *pIdx; |
| 161271 | for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 162346 | for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 161272 | if( pIdx->aColExpr ){ | 162347 | if( pIdx->aColExpr ){ |
| 161273 | return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); | 162348 | return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); |
| 161274 | } | 162349 | } |
| @@ -161811,7 +162886,7 @@ static void whereAddLimitExpr( | |||
| 161811 | Expr *pNew; | 162886 | Expr *pNew; |
| 161812 | int iVal = 0; | 162887 | int iVal = 0; |
| 161813 | 162888 | ||
| 161814 | if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ | 162889 | if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ |
| 161815 | Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); | 162890 | Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); |
| 161816 | if( pVal==0 ) return; | 162891 | if( pVal==0 ) return; |
| 161817 | ExprSetProperty(pVal, EP_IntValue); | 162892 | ExprSetProperty(pVal, EP_IntValue); |
| @@ -161856,7 +162931,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec | |||
| 161856 | assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ | 162931 | assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ |
| 161857 | if( p->pGroupBy==0 | 162932 | if( p->pGroupBy==0 |
| 161858 | && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ | 162933 | && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ |
| 161859 | && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ | 162934 | && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ |
| 161860 | ){ | 162935 | ){ |
| 161861 | ExprList *pOrderBy = p->pOrderBy; | 162936 | ExprList *pOrderBy = p->pOrderBy; |
| 161862 | int iCsr = p->pSrc->a[0].iCursor; | 162937 | int iCsr = p->pSrc->a[0].iCursor; |
| @@ -162077,7 +163152,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( | |||
| 162077 | Expr *pColRef; | 163152 | Expr *pColRef; |
| 162078 | Expr *pTerm; | 163153 | Expr *pTerm; |
| 162079 | if( pItem->fg.isTabFunc==0 ) return; | 163154 | if( pItem->fg.isTabFunc==0 ) return; |
| 162080 | pTab = pItem->pTab; | 163155 | pTab = pItem->pSTab; |
| 162081 | assert( pTab!=0 ); | 163156 | assert( pTab!=0 ); |
| 162082 | pArgs = pItem->u1.pFuncArg; | 163157 | pArgs = pItem->u1.pFuncArg; |
| 162083 | if( pArgs==0 ) return; | 163158 | if( pArgs==0 ) return; |
| @@ -162761,7 +163836,7 @@ static int isDistinctRedundant( | |||
| 162761 | ** clause is redundant. */ | 163836 | ** clause is redundant. */ |
| 162762 | if( pTabList->nSrc!=1 ) return 0; | 163837 | if( pTabList->nSrc!=1 ) return 0; |
| 162763 | iBase = pTabList->a[0].iCursor; | 163838 | iBase = pTabList->a[0].iCursor; |
| 162764 | pTab = pTabList->a[0].pTab; | 163839 | pTab = pTabList->a[0].pSTab; |
| 162765 | 163840 | ||
| 162766 | /* If any of the expressions is an IPK column on table iBase, then return | 163841 | /* If any of the expressions is an IPK column on table iBase, then return |
| 162767 | ** true. Note: The (p->iTable==iBase) part of this test may be false if the | 163842 | ** true. Note: The (p->iTable==iBase) part of this test may be false if the |
| @@ -162836,6 +163911,12 @@ static void translateColumnToCopy( | |||
| 162836 | VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); | 163911 | VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); |
| 162837 | int iEnd = sqlite3VdbeCurrentAddr(v); | 163912 | int iEnd = sqlite3VdbeCurrentAddr(v); |
| 162838 | if( pParse->db->mallocFailed ) return; | 163913 | if( pParse->db->mallocFailed ) return; |
| 163914 | #ifdef SQLITE_DEBUG | ||
| 163915 | if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ | ||
| 163916 | printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", | ||
| 163917 | iTabCur, iStart, iEnd); | ||
| 163918 | } | ||
| 163919 | #endif | ||
| 162839 | for(; iStart<iEnd; iStart++, pOp++){ | 163920 | for(; iStart<iEnd; iStart++, pOp++){ |
| 162840 | if( pOp->p1!=iTabCur ) continue; | 163921 | if( pOp->p1!=iTabCur ) continue; |
| 162841 | if( pOp->opcode==OP_Column ){ | 163922 | if( pOp->opcode==OP_Column ){ |
| @@ -162957,6 +164038,40 @@ static int constraintCompatibleWithOuterJoin( | |||
| 162957 | return 1; | 164038 | return 1; |
| 162958 | } | 164039 | } |
| 162959 | 164040 | ||
| 164041 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | ||
| 164042 | /* | ||
| 164043 | ** Return true if column iCol of table pTab seem like it might be a | ||
| 164044 | ** good column to use as part of a query-time index. | ||
| 164045 | ** | ||
| 164046 | ** Current algorithm (subject to improvement!): | ||
| 164047 | ** | ||
| 164048 | ** 1. If iCol is already the left-most column of some other index, | ||
| 164049 | ** then return false. | ||
| 164050 | ** | ||
| 164051 | ** 2. If iCol is part of an existing index that has an aiRowLogEst of | ||
| 164052 | ** more than 20, then return false. | ||
| 164053 | ** | ||
| 164054 | ** 3. If no disqualifying conditions above are found, return true. | ||
| 164055 | */ | ||
| 164056 | static SQLITE_NOINLINE int columnIsGoodIndexCandidate( | ||
| 164057 | const Table *pTab, | ||
| 164058 | int iCol | ||
| 164059 | ){ | ||
| 164060 | const Index *pIdx; | ||
| 164061 | for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ | ||
| 164062 | int j; | ||
| 164063 | for(j=0; j<pIdx->nKeyCol; j++){ | ||
| 164064 | if( pIdx->aiColumn[j]==iCol ){ | ||
| 164065 | if( j==0 ) return 0; | ||
| 164066 | if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; | ||
| 164067 | break; | ||
| 164068 | } | ||
| 164069 | } | ||
| 164070 | } | ||
| 164071 | return 1; | ||
| 164072 | } | ||
| 164073 | #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ | ||
| 164074 | |||
| 162960 | 164075 | ||
| 162961 | 164076 | ||
| 162962 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | 164077 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| @@ -162971,6 +164086,8 @@ static int termCanDriveIndex( | |||
| 162971 | const Bitmask notReady /* Tables in outer loops of the join */ | 164086 | const Bitmask notReady /* Tables in outer loops of the join */ |
| 162972 | ){ | 164087 | ){ |
| 162973 | char aff; | 164088 | char aff; |
| 164089 | int leftCol; | ||
| 164090 | |||
| 162974 | if( pTerm->leftCursor!=pSrc->iCursor ) return 0; | 164091 | if( pTerm->leftCursor!=pSrc->iCursor ) return 0; |
| 162975 | if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; | 164092 | if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; |
| 162976 | assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); | 164093 | assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); |
| @@ -162981,11 +164098,12 @@ static int termCanDriveIndex( | |||
| 162981 | } | 164098 | } |
| 162982 | if( (pTerm->prereqRight & notReady)!=0 ) return 0; | 164099 | if( (pTerm->prereqRight & notReady)!=0 ) return 0; |
| 162983 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | 164100 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| 162984 | if( pTerm->u.x.leftColumn<0 ) return 0; | 164101 | leftCol = pTerm->u.x.leftColumn; |
| 162985 | aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; | 164102 | if( leftCol<0 ) return 0; |
| 164103 | aff = pSrc->pSTab->aCol[leftCol].affinity; | ||
| 162986 | if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; | 164104 | if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; |
| 162987 | testcase( pTerm->pExpr->op==TK_IS ); | 164105 | testcase( pTerm->pExpr->op==TK_IS ); |
| 162988 | return 1; | 164106 | return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); |
| 162989 | } | 164107 | } |
| 162990 | #endif | 164108 | #endif |
| 162991 | 164109 | ||
| @@ -163093,7 +164211,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 163093 | nKeyCol = 0; | 164211 | nKeyCol = 0; |
| 163094 | pTabList = pWC->pWInfo->pTabList; | 164212 | pTabList = pWC->pWInfo->pTabList; |
| 163095 | pSrc = &pTabList->a[pLevel->iFrom]; | 164213 | pSrc = &pTabList->a[pLevel->iFrom]; |
| 163096 | pTable = pSrc->pTab; | 164214 | pTable = pSrc->pSTab; |
| 163097 | pWCEnd = &pWC->a[pWC->nTerm]; | 164215 | pWCEnd = &pWC->a[pWC->nTerm]; |
| 163098 | pLoop = pLevel->pWLoop; | 164216 | pLoop = pLevel->pWLoop; |
| 163099 | idxCols = 0; | 164217 | idxCols = 0; |
| @@ -163235,12 +164353,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 163235 | /* Fill the automatic index with content */ | 164353 | /* Fill the automatic index with content */ |
| 163236 | assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); | 164354 | assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); |
| 163237 | if( pSrc->fg.viaCoroutine ){ | 164355 | if( pSrc->fg.viaCoroutine ){ |
| 163238 | int regYield = pSrc->regReturn; | 164356 | int regYield; |
| 164357 | Subquery *pSubq; | ||
| 164358 | assert( pSrc->fg.isSubquery ); | ||
| 164359 | pSubq = pSrc->u4.pSubq; | ||
| 164360 | assert( pSubq!=0 ); | ||
| 164361 | regYield = pSubq->regReturn; | ||
| 163239 | addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); | 164362 | addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); |
| 163240 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); | 164363 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); |
| 163241 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); | 164364 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); |
| 163242 | VdbeCoverage(v); | 164365 | VdbeCoverage(v); |
| 163243 | VdbeComment((v, "next row of %s", pSrc->pTab->zName)); | 164366 | VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); |
| 163244 | }else{ | 164367 | }else{ |
| 163245 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); | 164368 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); |
| 163246 | } | 164369 | } |
| @@ -163262,11 +164385,12 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 163262 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); | 164385 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 163263 | if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); | 164386 | if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); |
| 163264 | if( pSrc->fg.viaCoroutine ){ | 164387 | if( pSrc->fg.viaCoroutine ){ |
| 164388 | assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); | ||
| 163265 | sqlite3VdbeChangeP2(v, addrCounter, regBase+n); | 164389 | sqlite3VdbeChangeP2(v, addrCounter, regBase+n); |
| 163266 | testcase( pParse->db->mallocFailed ); | 164390 | testcase( pParse->db->mallocFailed ); |
| 163267 | assert( pLevel->iIdxCur>0 ); | 164391 | assert( pLevel->iIdxCur>0 ); |
| 163268 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, | 164392 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, |
| 163269 | pSrc->regResult, pLevel->iIdxCur); | 164393 | pSrc->u4.pSubq->regResult, pLevel->iIdxCur); |
| 163270 | sqlite3VdbeGoto(v, addrTop); | 164394 | sqlite3VdbeGoto(v, addrTop); |
| 163271 | pSrc->fg.viaCoroutine = 0; | 164395 | pSrc->fg.viaCoroutine = 0; |
| 163272 | }else{ | 164396 | }else{ |
| @@ -163357,7 +164481,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 163357 | iSrc = pLevel->iFrom; | 164481 | iSrc = pLevel->iFrom; |
| 163358 | pItem = &pTabList->a[iSrc]; | 164482 | pItem = &pTabList->a[iSrc]; |
| 163359 | assert( pItem!=0 ); | 164483 | assert( pItem!=0 ); |
| 163360 | pTab = pItem->pTab; | 164484 | pTab = pItem->pSTab; |
| 163361 | assert( pTab!=0 ); | 164485 | assert( pTab!=0 ); |
| 163362 | sz = sqlite3LogEstToInt(pTab->nRowLogEst); | 164486 | sz = sqlite3LogEstToInt(pTab->nRowLogEst); |
| 163363 | if( sz<10000 ){ | 164487 | if( sz<10000 ){ |
| @@ -163388,7 +164512,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 163388 | int r1 = sqlite3GetTempRange(pParse, n); | 164512 | int r1 = sqlite3GetTempRange(pParse, n); |
| 163389 | int jj; | 164513 | int jj; |
| 163390 | for(jj=0; jj<n; jj++){ | 164514 | for(jj=0; jj<n; jj++){ |
| 163391 | assert( pIdx->pTable==pItem->pTab ); | 164515 | assert( pIdx->pTable==pItem->pSTab ); |
| 163392 | sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); | 164516 | sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); |
| 163393 | } | 164517 | } |
| 163394 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); | 164518 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); |
| @@ -163427,6 +164551,20 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 163427 | 164551 | ||
| 163428 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 164552 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 163429 | /* | 164553 | /* |
| 164554 | ** Return term iTerm of the WhereClause passed as the first argument. Terms | ||
| 164555 | ** are numbered from 0 upwards, starting with the terms in pWC->a[], then | ||
| 164556 | ** those in pWC->pOuter->a[] (if any), and so on. | ||
| 164557 | */ | ||
| 164558 | static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ | ||
| 164559 | WhereClause *p; | ||
| 164560 | for(p=pWC; p; p=p->pOuter){ | ||
| 164561 | if( iTerm<p->nTerm ) return &p->a[iTerm]; | ||
| 164562 | iTerm -= p->nTerm; | ||
| 164563 | } | ||
| 164564 | return 0; | ||
| 164565 | } | ||
| 164566 | |||
| 164567 | /* | ||
| 163430 | ** Allocate and populate an sqlite3_index_info structure. It is the | 164568 | ** Allocate and populate an sqlite3_index_info structure. It is the |
| 163431 | ** responsibility of the caller to eventually release the structure | 164569 | ** responsibility of the caller to eventually release the structure |
| 163432 | ** by passing the pointer returned by this function to freeIndexInfo(). | 164570 | ** by passing the pointer returned by this function to freeIndexInfo(). |
| @@ -163452,9 +164590,10 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 163452 | const Table *pTab; | 164590 | const Table *pTab; |
| 163453 | int eDistinct = 0; | 164591 | int eDistinct = 0; |
| 163454 | ExprList *pOrderBy = pWInfo->pOrderBy; | 164592 | ExprList *pOrderBy = pWInfo->pOrderBy; |
| 164593 | WhereClause *p; | ||
| 163455 | 164594 | ||
| 163456 | assert( pSrc!=0 ); | 164595 | assert( pSrc!=0 ); |
| 163457 | pTab = pSrc->pTab; | 164596 | pTab = pSrc->pSTab; |
| 163458 | assert( pTab!=0 ); | 164597 | assert( pTab!=0 ); |
| 163459 | assert( IsVirtual(pTab) ); | 164598 | assert( IsVirtual(pTab) ); |
| 163460 | 164599 | ||
| @@ -163462,28 +164601,30 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 163462 | ** Mark each term with the TERM_OK flag. Set nTerm to the number of | 164601 | ** Mark each term with the TERM_OK flag. Set nTerm to the number of |
| 163463 | ** terms found. | 164602 | ** terms found. |
| 163464 | */ | 164603 | */ |
| 163465 | for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ | 164604 | for(p=pWC, nTerm=0; p; p=p->pOuter){ |
| 163466 | pTerm->wtFlags &= ~TERM_OK; | 164605 | for(i=0, pTerm=p->a; i<p->nTerm; i++, pTerm++){ |
| 163467 | if( pTerm->leftCursor != pSrc->iCursor ) continue; | 164606 | pTerm->wtFlags &= ~TERM_OK; |
| 163468 | if( pTerm->prereqRight & mUnusable ) continue; | 164607 | if( pTerm->leftCursor != pSrc->iCursor ) continue; |
| 163469 | assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); | 164608 | if( pTerm->prereqRight & mUnusable ) continue; |
| 163470 | testcase( pTerm->eOperator & WO_IN ); | 164609 | assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); |
| 163471 | testcase( pTerm->eOperator & WO_ISNULL ); | 164610 | testcase( pTerm->eOperator & WO_IN ); |
| 163472 | testcase( pTerm->eOperator & WO_IS ); | 164611 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 163473 | testcase( pTerm->eOperator & WO_ALL ); | 164612 | testcase( pTerm->eOperator & WO_IS ); |
| 163474 | if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; | 164613 | testcase( pTerm->eOperator & WO_ALL ); |
| 163475 | if( pTerm->wtFlags & TERM_VNULL ) continue; | 164614 | if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; |
| 164615 | if( pTerm->wtFlags & TERM_VNULL ) continue; | ||
| 163476 | 164616 | ||
| 163477 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | 164617 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| 163478 | assert( pTerm->u.x.leftColumn>=XN_ROWID ); | 164618 | assert( pTerm->u.x.leftColumn>=XN_ROWID ); |
| 163479 | assert( pTerm->u.x.leftColumn<pTab->nCol ); | 164619 | assert( pTerm->u.x.leftColumn<pTab->nCol ); |
| 163480 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 | 164620 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 |
| 163481 | && !constraintCompatibleWithOuterJoin(pTerm,pSrc) | 164621 | && !constraintCompatibleWithOuterJoin(pTerm,pSrc) |
| 163482 | ){ | 164622 | ){ |
| 163483 | continue; | 164623 | continue; |
| 164624 | } | ||
| 164625 | nTerm++; | ||
| 164626 | pTerm->wtFlags |= TERM_OK; | ||
| 163484 | } | 164627 | } |
| 163485 | nTerm++; | ||
| 163486 | pTerm->wtFlags |= TERM_OK; | ||
| 163487 | } | 164628 | } |
| 163488 | 164629 | ||
| 163489 | /* If the ORDER BY clause contains only columns in the current | 164630 | /* If the ORDER BY clause contains only columns in the current |
| @@ -163558,53 +164699,69 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 163558 | pIdxInfo->aConstraint = pIdxCons; | 164699 | pIdxInfo->aConstraint = pIdxCons; |
| 163559 | pIdxInfo->aOrderBy = pIdxOrderBy; | 164700 | pIdxInfo->aOrderBy = pIdxOrderBy; |
| 163560 | pIdxInfo->aConstraintUsage = pUsage; | 164701 | pIdxInfo->aConstraintUsage = pUsage; |
| 164702 | pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; | ||
| 164703 | if( HasRowid(pTab)==0 ){ | ||
| 164704 | /* Ensure that all bits associated with PK columns are set. This is to | ||
| 164705 | ** ensure they are available for cases like RIGHT joins or OR loops. */ | ||
| 164706 | Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); | ||
| 164707 | assert( pPk!=0 ); | ||
| 164708 | for(i=0; i<pPk->nKeyCol; i++){ | ||
| 164709 | int iCol = pPk->aiColumn[i]; | ||
| 164710 | assert( iCol>=0 ); | ||
| 164711 | if( iCol>=BMS-1 ) iCol = BMS-1; | ||
| 164712 | pIdxInfo->colUsed |= MASKBIT(iCol); | ||
| 164713 | } | ||
| 164714 | } | ||
| 163561 | pHidden->pWC = pWC; | 164715 | pHidden->pWC = pWC; |
| 163562 | pHidden->pParse = pParse; | 164716 | pHidden->pParse = pParse; |
| 163563 | pHidden->eDistinct = eDistinct; | 164717 | pHidden->eDistinct = eDistinct; |
| 163564 | pHidden->mIn = 0; | 164718 | pHidden->mIn = 0; |
| 163565 | for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ | 164719 | for(p=pWC, i=j=0; p; p=p->pOuter){ |
| 163566 | u16 op; | 164720 | int nLast = i+p->nTerm;; |
| 163567 | if( (pTerm->wtFlags & TERM_OK)==0 ) continue; | 164721 | for(pTerm=p->a; i<nLast; i++, pTerm++){ |
| 163568 | pIdxCons[j].iColumn = pTerm->u.x.leftColumn; | 164722 | u16 op; |
| 163569 | pIdxCons[j].iTermOffset = i; | 164723 | if( (pTerm->wtFlags & TERM_OK)==0 ) continue; |
| 163570 | op = pTerm->eOperator & WO_ALL; | 164724 | pIdxCons[j].iColumn = pTerm->u.x.leftColumn; |
| 163571 | if( op==WO_IN ){ | 164725 | pIdxCons[j].iTermOffset = i; |
| 163572 | if( (pTerm->wtFlags & TERM_SLICE)==0 ){ | 164726 | op = pTerm->eOperator & WO_ALL; |
| 163573 | pHidden->mIn |= SMASKBIT32(j); | 164727 | if( op==WO_IN ){ |
| 163574 | } | 164728 | if( (pTerm->wtFlags & TERM_SLICE)==0 ){ |
| 163575 | op = WO_EQ; | 164729 | pHidden->mIn |= SMASKBIT32(j); |
| 163576 | } | 164730 | } |
| 163577 | if( op==WO_AUX ){ | 164731 | op = WO_EQ; |
| 163578 | pIdxCons[j].op = pTerm->eMatchOp; | 164732 | } |
| 163579 | }else if( op & (WO_ISNULL|WO_IS) ){ | 164733 | if( op==WO_AUX ){ |
| 163580 | if( op==WO_ISNULL ){ | 164734 | pIdxCons[j].op = pTerm->eMatchOp; |
| 163581 | pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; | 164735 | }else if( op & (WO_ISNULL|WO_IS) ){ |
| 163582 | }else{ | 164736 | if( op==WO_ISNULL ){ |
| 163583 | pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; | 164737 | pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; |
| 163584 | } | 164738 | }else{ |
| 163585 | }else{ | 164739 | pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; |
| 163586 | pIdxCons[j].op = (u8)op; | 164740 | } |
| 163587 | /* The direct assignment in the previous line is possible only because | 164741 | }else{ |
| 163588 | ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The | 164742 | pIdxCons[j].op = (u8)op; |
| 163589 | ** following asserts verify this fact. */ | 164743 | /* The direct assignment in the previous line is possible only because |
| 163590 | assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); | 164744 | ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The |
| 163591 | assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); | 164745 | ** following asserts verify this fact. */ |
| 163592 | assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); | 164746 | assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); |
| 163593 | assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); | 164747 | assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); |
| 163594 | assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); | 164748 | assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); |
| 163595 | assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); | 164749 | assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); |
| 163596 | 164750 | assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); | |
| 163597 | if( op & (WO_LT|WO_LE|WO_GT|WO_GE) | 164751 | assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); |
| 163598 | && sqlite3ExprIsVector(pTerm->pExpr->pRight) | 164752 | |
| 163599 | ){ | 164753 | if( op & (WO_LT|WO_LE|WO_GT|WO_GE) |
| 163600 | testcase( j!=i ); | 164754 | && sqlite3ExprIsVector(pTerm->pExpr->pRight) |
| 163601 | if( j<16 ) mNoOmit |= (1 << j); | 164755 | ){ |
| 163602 | if( op==WO_LT ) pIdxCons[j].op = WO_LE; | 164756 | testcase( j!=i ); |
| 163603 | if( op==WO_GT ) pIdxCons[j].op = WO_GE; | 164757 | if( j<16 ) mNoOmit |= (1 << j); |
| 164758 | if( op==WO_LT ) pIdxCons[j].op = WO_LE; | ||
| 164759 | if( op==WO_GT ) pIdxCons[j].op = WO_GE; | ||
| 164760 | } | ||
| 163604 | } | 164761 | } |
| 163605 | } | ||
| 163606 | 164762 | ||
| 163607 | j++; | 164763 | j++; |
| 164764 | } | ||
| 163608 | } | 164765 | } |
| 163609 | assert( j==nTerm ); | 164766 | assert( j==nTerm ); |
| 163610 | pIdxInfo->nConstraint = j; | 164767 | pIdxInfo->nConstraint = j; |
| @@ -163625,6 +164782,17 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 163625 | } | 164782 | } |
| 163626 | 164783 | ||
| 163627 | /* | 164784 | /* |
| 164785 | ** Free and zero the sqlite3_index_info.idxStr value if needed. | ||
| 164786 | */ | ||
| 164787 | static void freeIdxStr(sqlite3_index_info *pIdxInfo){ | ||
| 164788 | if( pIdxInfo->needToFreeIdxStr ){ | ||
| 164789 | sqlite3_free(pIdxInfo->idxStr); | ||
| 164790 | pIdxInfo->idxStr = 0; | ||
| 164791 | pIdxInfo->needToFreeIdxStr = 0; | ||
| 164792 | } | ||
| 164793 | } | ||
| 164794 | |||
| 164795 | /* | ||
| 163628 | ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() | 164796 | ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() |
| 163629 | ** and possibly modified by xBestIndex methods. | 164797 | ** and possibly modified by xBestIndex methods. |
| 163630 | */ | 164798 | */ |
| @@ -163639,6 +164807,7 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ | |||
| 163639 | sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ | 164807 | sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ |
| 163640 | pHidden->aRhs[i] = 0; | 164808 | pHidden->aRhs[i] = 0; |
| 163641 | } | 164809 | } |
| 164810 | freeIdxStr(pIdxInfo); | ||
| 163642 | sqlite3DbFree(db, pIdxInfo); | 164811 | sqlite3DbFree(db, pIdxInfo); |
| 163643 | } | 164812 | } |
| 163644 | 164813 | ||
| @@ -163659,9 +164828,11 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ | |||
| 163659 | ** that this is required. | 164828 | ** that this is required. |
| 163660 | */ | 164829 | */ |
| 163661 | static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ | 164830 | static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ |
| 163662 | sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; | ||
| 163663 | int rc; | 164831 | int rc; |
| 164832 | sqlite3_vtab *pVtab; | ||
| 163664 | 164833 | ||
| 164834 | assert( IsVirtual(pTab) ); | ||
| 164835 | pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; | ||
| 163665 | whereTraceIndexInfoInputs(p, pTab); | 164836 | whereTraceIndexInfoInputs(p, pTab); |
| 163666 | pParse->db->nSchemaLock++; | 164837 | pParse->db->nSchemaLock++; |
| 163667 | rc = pVtab->pModule->xBestIndex(pVtab, p); | 164838 | rc = pVtab->pModule->xBestIndex(pVtab, p); |
| @@ -164432,7 +165603,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause | |||
| 164432 | WhereInfo *pWInfo = pWC->pWInfo; | 165603 | WhereInfo *pWInfo = pWC->pWInfo; |
| 164433 | int nb = 1+(pWInfo->pTabList->nSrc+3)/4; | 165604 | int nb = 1+(pWInfo->pTabList->nSrc+3)/4; |
| 164434 | SrcItem *pItem = pWInfo->pTabList->a + p->iTab; | 165605 | SrcItem *pItem = pWInfo->pTabList->a + p->iTab; |
| 164435 | Table *pTab = pItem->pTab; | 165606 | Table *pTab = pItem->pSTab; |
| 164436 | Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; | 165607 | Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; |
| 164437 | sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, | 165608 | sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, |
| 164438 | p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); | 165609 | p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); |
| @@ -164604,7 +165775,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ | |||
| 164604 | ** and Y has additional constraints that might speed the search that X lacks | 165775 | ** and Y has additional constraints that might speed the search that X lacks |
| 164605 | ** but the cost of running X is not more than the cost of running Y. | 165776 | ** but the cost of running X is not more than the cost of running Y. |
| 164606 | ** | 165777 | ** |
| 164607 | ** In other words, return true if the cost relationwship between X and Y | 165778 | ** In other words, return true if the cost relationship between X and Y |
| 164608 | ** is inverted and needs to be adjusted. | 165779 | ** is inverted and needs to be adjusted. |
| 164609 | ** | 165780 | ** |
| 164610 | ** Case 1: | 165781 | ** Case 1: |
| @@ -164990,7 +166161,7 @@ static void whereLoopOutputAdjust( | |||
| 164990 | Expr *pRight = pTerm->pExpr->pRight; | 166161 | Expr *pRight = pTerm->pExpr->pRight; |
| 164991 | int k = 0; | 166162 | int k = 0; |
| 164992 | testcase( pTerm->pExpr->op==TK_IS ); | 166163 | testcase( pTerm->pExpr->op==TK_IS ); |
| 164993 | if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ | 166164 | if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ |
| 164994 | k = 10; | 166165 | k = 10; |
| 164995 | }else{ | 166166 | }else{ |
| 164996 | k = 20; | 166167 | k = 20; |
| @@ -165287,7 +166458,7 @@ static int whereLoopAddBtreeIndex( | |||
| 165287 | || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) | 166458 | || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) |
| 165288 | ){ | 166459 | ){ |
| 165289 | if( iCol==XN_ROWID || pProbe->uniqNotNull | 166460 | if( iCol==XN_ROWID || pProbe->uniqNotNull |
| 165290 | || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) | 166461 | || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) |
| 165291 | ){ | 166462 | ){ |
| 165292 | pNew->wsFlags |= WHERE_ONEROW; | 166463 | pNew->wsFlags |= WHERE_ONEROW; |
| 165293 | }else{ | 166464 | }else{ |
| @@ -165420,7 +166591,7 @@ static int whereLoopAddBtreeIndex( | |||
| 165420 | ** 2. Stepping forward in the index pNew->nOut times to find all | 166591 | ** 2. Stepping forward in the index pNew->nOut times to find all |
| 165421 | ** additional matching entries. | 166592 | ** additional matching entries. |
| 165422 | */ | 166593 | */ |
| 165423 | assert( pSrc->pTab->szTabRow>0 ); | 166594 | assert( pSrc->pSTab->szTabRow>0 ); |
| 165424 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ | 166595 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ |
| 165425 | /* The pProbe->szIdxRow is low for an IPK table since the interior | 166596 | /* The pProbe->szIdxRow is low for an IPK table since the interior |
| 165426 | ** pages are small. Thus szIdxRow gives a good estimate of seek cost. | 166597 | ** pages are small. Thus szIdxRow gives a good estimate of seek cost. |
| @@ -165428,7 +166599,7 @@ static int whereLoopAddBtreeIndex( | |||
| 165428 | ** under-estimate the scanning cost. */ | 166599 | ** under-estimate the scanning cost. */ |
| 165429 | rCostIdx = pNew->nOut + 16; | 166600 | rCostIdx = pNew->nOut + 16; |
| 165430 | }else{ | 166601 | }else{ |
| 165431 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; | 166602 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; |
| 165432 | } | 166603 | } |
| 165433 | rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); | 166604 | rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 165434 | 166605 | ||
| @@ -165893,9 +167064,9 @@ static int whereLoopAddBtree( | |||
| 165893 | pWInfo = pBuilder->pWInfo; | 167064 | pWInfo = pBuilder->pWInfo; |
| 165894 | pTabList = pWInfo->pTabList; | 167065 | pTabList = pWInfo->pTabList; |
| 165895 | pSrc = pTabList->a + pNew->iTab; | 167066 | pSrc = pTabList->a + pNew->iTab; |
| 165896 | pTab = pSrc->pTab; | 167067 | pTab = pSrc->pSTab; |
| 165897 | pWC = pBuilder->pWC; | 167068 | pWC = pBuilder->pWC; |
| 165898 | assert( !IsVirtual(pSrc->pTab) ); | 167069 | assert( !IsVirtual(pSrc->pSTab) ); |
| 165899 | 167070 | ||
| 165900 | if( pSrc->fg.isIndexedBy ){ | 167071 | if( pSrc->fg.isIndexedBy ){ |
| 165901 | assert( pSrc->fg.isCte==0 ); | 167072 | assert( pSrc->fg.isCte==0 ); |
| @@ -165920,7 +167091,7 @@ static int whereLoopAddBtree( | |||
| 165920 | sPk.idxType = SQLITE_IDXTYPE_IPK; | 167091 | sPk.idxType = SQLITE_IDXTYPE_IPK; |
| 165921 | aiRowEstPk[0] = pTab->nRowLogEst; | 167092 | aiRowEstPk[0] = pTab->nRowLogEst; |
| 165922 | aiRowEstPk[1] = 0; | 167093 | aiRowEstPk[1] = 0; |
| 165923 | pFirst = pSrc->pTab->pIndex; | 167094 | pFirst = pSrc->pSTab->pIndex; |
| 165924 | if( pSrc->fg.notIndexed==0 ){ | 167095 | if( pSrc->fg.notIndexed==0 ){ |
| 165925 | /* The real indices of the table are only considered if the | 167096 | /* The real indices of the table are only considered if the |
| 165926 | ** NOT INDEXED qualifier is omitted from the FROM clause */ | 167097 | ** NOT INDEXED qualifier is omitted from the FROM clause */ |
| @@ -166010,6 +167181,7 @@ static int whereLoopAddBtree( | |||
| 166010 | pNew->prereq = mPrereq; | 167181 | pNew->prereq = mPrereq; |
| 166011 | pNew->nOut = rSize; | 167182 | pNew->nOut = rSize; |
| 166012 | pNew->u.btree.pIndex = pProbe; | 167183 | pNew->u.btree.pIndex = pProbe; |
| 167184 | pNew->u.btree.pOrderBy = 0; | ||
| 166013 | b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); | 167185 | b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); |
| 166014 | 167186 | ||
| 166015 | /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ | 167187 | /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ |
| @@ -166039,6 +167211,10 @@ static int whereLoopAddBtree( | |||
| 166039 | #endif | 167211 | #endif |
| 166040 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); | 167212 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 166041 | whereLoopOutputAdjust(pWC, pNew, rSize); | 167213 | whereLoopOutputAdjust(pWC, pNew, rSize); |
| 167214 | if( pSrc->fg.isSubquery ){ | ||
| 167215 | if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; | ||
| 167216 | pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; | ||
| 167217 | } | ||
| 166042 | rc = whereLoopInsert(pBuilder, pNew); | 167218 | rc = whereLoopInsert(pBuilder, pNew); |
| 166043 | pNew->nOut = rSize; | 167219 | pNew->nOut = rSize; |
| 166044 | if( rc ) break; | 167220 | if( rc ) break; |
| @@ -166241,7 +167417,7 @@ static int whereLoopAddVirtualOne( | |||
| 166241 | ** arguments mUsable and mExclude. */ | 167417 | ** arguments mUsable and mExclude. */ |
| 166242 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; | 167418 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 166243 | for(i=0; i<nConstraint; i++, pIdxCons++){ | 167419 | for(i=0; i<nConstraint; i++, pIdxCons++){ |
| 166244 | WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset]; | 167420 | WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset); |
| 166245 | pIdxCons->usable = 0; | 167421 | pIdxCons->usable = 0; |
| 166246 | if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight | 167422 | if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight |
| 166247 | && (pTerm->eOperator & mExclude)==0 | 167423 | && (pTerm->eOperator & mExclude)==0 |
| @@ -166260,11 +167436,10 @@ static int whereLoopAddVirtualOne( | |||
| 166260 | pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; | 167436 | pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; |
| 166261 | pIdxInfo->estimatedRows = 25; | 167437 | pIdxInfo->estimatedRows = 25; |
| 166262 | pIdxInfo->idxFlags = 0; | 167438 | pIdxInfo->idxFlags = 0; |
| 166263 | pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; | ||
| 166264 | pHidden->mHandleIn = 0; | 167439 | pHidden->mHandleIn = 0; |
| 166265 | 167440 | ||
| 166266 | /* Invoke the virtual table xBestIndex() method */ | 167441 | /* Invoke the virtual table xBestIndex() method */ |
| 166267 | rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); | 167442 | rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); |
| 166268 | if( rc ){ | 167443 | if( rc ){ |
| 166269 | if( rc==SQLITE_CONSTRAINT ){ | 167444 | if( rc==SQLITE_CONSTRAINT ){ |
| 166270 | /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means | 167445 | /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means |
| @@ -166272,6 +167447,7 @@ static int whereLoopAddVirtualOne( | |||
| 166272 | ** Make no entries in the loop table. | 167447 | ** Make no entries in the loop table. |
| 166273 | */ | 167448 | */ |
| 166274 | WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); | 167449 | WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); |
| 167450 | freeIdxStr(pIdxInfo); | ||
| 166275 | return SQLITE_OK; | 167451 | return SQLITE_OK; |
| 166276 | } | 167452 | } |
| 166277 | return rc; | 167453 | return rc; |
| @@ -166289,18 +167465,17 @@ static int whereLoopAddVirtualOne( | |||
| 166289 | int j = pIdxCons->iTermOffset; | 167465 | int j = pIdxCons->iTermOffset; |
| 166290 | if( iTerm>=nConstraint | 167466 | if( iTerm>=nConstraint |
| 166291 | || j<0 | 167467 | || j<0 |
| 166292 | || j>=pWC->nTerm | 167468 | || (pTerm = termFromWhereClause(pWC, j))==0 |
| 166293 | || pNew->aLTerm[iTerm]!=0 | 167469 | || pNew->aLTerm[iTerm]!=0 |
| 166294 | || pIdxCons->usable==0 | 167470 | || pIdxCons->usable==0 |
| 166295 | ){ | 167471 | ){ |
| 166296 | sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); | 167472 | sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); |
| 166297 | testcase( pIdxInfo->needToFreeIdxStr ); | 167473 | freeIdxStr(pIdxInfo); |
| 166298 | return SQLITE_ERROR; | 167474 | return SQLITE_ERROR; |
| 166299 | } | 167475 | } |
| 166300 | testcase( iTerm==nConstraint-1 ); | 167476 | testcase( iTerm==nConstraint-1 ); |
| 166301 | testcase( j==0 ); | 167477 | testcase( j==0 ); |
| 166302 | testcase( j==pWC->nTerm-1 ); | 167478 | testcase( j==pWC->nTerm-1 ); |
| 166303 | pTerm = &pWC->a[j]; | ||
| 166304 | pNew->prereq |= pTerm->prereqRight; | 167479 | pNew->prereq |= pTerm->prereqRight; |
| 166305 | assert( iTerm<pNew->nLSlot ); | 167480 | assert( iTerm<pNew->nLSlot ); |
| 166306 | pNew->aLTerm[iTerm] = pTerm; | 167481 | pNew->aLTerm[iTerm] = pTerm; |
| @@ -166345,11 +167520,7 @@ static int whereLoopAddVirtualOne( | |||
| 166345 | ** the plan cannot be used. In these cases set variable *pbRetryLimit | 167520 | ** the plan cannot be used. In these cases set variable *pbRetryLimit |
| 166346 | ** to true to tell the caller to retry with LIMIT and OFFSET | 167521 | ** to true to tell the caller to retry with LIMIT and OFFSET |
| 166347 | ** disabled. */ | 167522 | ** disabled. */ |
| 166348 | if( pIdxInfo->needToFreeIdxStr ){ | 167523 | freeIdxStr(pIdxInfo); |
| 166349 | sqlite3_free(pIdxInfo->idxStr); | ||
| 166350 | pIdxInfo->idxStr = 0; | ||
| 166351 | pIdxInfo->needToFreeIdxStr = 0; | ||
| 166352 | } | ||
| 166353 | *pbRetryLimit = 1; | 167524 | *pbRetryLimit = 1; |
| 166354 | return SQLITE_OK; | 167525 | return SQLITE_OK; |
| 166355 | } | 167526 | } |
| @@ -166361,8 +167532,8 @@ static int whereLoopAddVirtualOne( | |||
| 166361 | if( pNew->aLTerm[i]==0 ){ | 167532 | if( pNew->aLTerm[i]==0 ){ |
| 166362 | /* The non-zero argvIdx values must be contiguous. Raise an | 167533 | /* The non-zero argvIdx values must be contiguous. Raise an |
| 166363 | ** error if they are not */ | 167534 | ** error if they are not */ |
| 166364 | sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); | 167535 | sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); |
| 166365 | testcase( pIdxInfo->needToFreeIdxStr ); | 167536 | freeIdxStr(pIdxInfo); |
| 166366 | return SQLITE_ERROR; | 167537 | return SQLITE_ERROR; |
| 166367 | } | 167538 | } |
| 166368 | } | 167539 | } |
| @@ -166373,6 +167544,7 @@ static int whereLoopAddVirtualOne( | |||
| 166373 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; | 167544 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; |
| 166374 | pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? | 167545 | pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? |
| 166375 | pIdxInfo->nOrderBy : 0); | 167546 | pIdxInfo->nOrderBy : 0); |
| 167547 | pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; | ||
| 166376 | pNew->rSetup = 0; | 167548 | pNew->rSetup = 0; |
| 166377 | pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); | 167549 | pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); |
| 166378 | pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); | 167550 | pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); |
| @@ -166417,7 +167589,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int | |||
| 166417 | if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ | 167589 | if( iCons>=0 && iCons<pIdxInfo->nConstraint ){ |
| 166418 | CollSeq *pC = 0; | 167590 | CollSeq *pC = 0; |
| 166419 | int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; | 167591 | int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; |
| 166420 | Expr *pX = pHidden->pWC->a[iTerm].pExpr; | 167592 | Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; |
| 166421 | if( pX->pLeft ){ | 167593 | if( pX->pLeft ){ |
| 166422 | pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); | 167594 | pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); |
| 166423 | } | 167595 | } |
| @@ -166463,7 +167635,9 @@ SQLITE_API int sqlite3_vtab_rhs_value( | |||
| 166463 | rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ | 167635 | rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ |
| 166464 | }else{ | 167636 | }else{ |
| 166465 | if( pH->aRhs[iCons]==0 ){ | 167637 | if( pH->aRhs[iCons]==0 ){ |
| 166466 | WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; | 167638 | WhereTerm *pTerm = termFromWhereClause( |
| 167639 | pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset | ||
| 167640 | ); | ||
| 166467 | rc = sqlite3ValueFromExpr( | 167641 | rc = sqlite3ValueFromExpr( |
| 166468 | pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), | 167642 | pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), |
| 166469 | SQLITE_AFF_BLOB, &pH->aRhs[iCons] | 167643 | SQLITE_AFF_BLOB, &pH->aRhs[iCons] |
| @@ -166561,7 +167735,7 @@ static int whereLoopAddVirtual( | |||
| 166561 | pWC = pBuilder->pWC; | 167735 | pWC = pBuilder->pWC; |
| 166562 | pNew = pBuilder->pNew; | 167736 | pNew = pBuilder->pNew; |
| 166563 | pSrc = &pWInfo->pTabList->a[pNew->iTab]; | 167737 | pSrc = &pWInfo->pTabList->a[pNew->iTab]; |
| 166564 | assert( IsVirtual(pSrc->pTab) ); | 167738 | assert( IsVirtual(pSrc->pSTab) ); |
| 166565 | p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); | 167739 | p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); |
| 166566 | if( p==0 ) return SQLITE_NOMEM_BKPT; | 167740 | if( p==0 ) return SQLITE_NOMEM_BKPT; |
| 166567 | pNew->rSetup = 0; | 167741 | pNew->rSetup = 0; |
| @@ -166575,7 +167749,7 @@ static int whereLoopAddVirtual( | |||
| 166575 | } | 167749 | } |
| 166576 | 167750 | ||
| 166577 | /* First call xBestIndex() with all constraints usable. */ | 167751 | /* First call xBestIndex() with all constraints usable. */ |
| 166578 | WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); | 167752 | WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); |
| 166579 | WHERETRACE(0x800, (" VirtualOne: all usable\n")); | 167753 | WHERETRACE(0x800, (" VirtualOne: all usable\n")); |
| 166580 | rc = whereLoopAddVirtualOne( | 167754 | rc = whereLoopAddVirtualOne( |
| 166581 | pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry | 167755 | pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry |
| @@ -166619,9 +167793,8 @@ static int whereLoopAddVirtual( | |||
| 166619 | Bitmask mNext = ALLBITS; | 167793 | Bitmask mNext = ALLBITS; |
| 166620 | assert( mNext>0 ); | 167794 | assert( mNext>0 ); |
| 166621 | for(i=0; i<nConstraint; i++){ | 167795 | for(i=0; i<nConstraint; i++){ |
| 166622 | Bitmask mThis = ( | 167796 | int iTerm = p->aConstraint[i].iTermOffset; |
| 166623 | pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq | 167797 | Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; |
| 166624 | ); | ||
| 166625 | if( mThis>mPrev && mThis<mNext ) mNext = mThis; | 167798 | if( mThis>mPrev && mThis<mNext ) mNext = mThis; |
| 166626 | } | 167799 | } |
| 166627 | mPrev = mNext; | 167800 | mPrev = mNext; |
| @@ -166657,9 +167830,8 @@ static int whereLoopAddVirtual( | |||
| 166657 | } | 167830 | } |
| 166658 | } | 167831 | } |
| 166659 | 167832 | ||
| 166660 | if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); | ||
| 166661 | freeIndexInfo(pParse->db, p); | 167833 | freeIndexInfo(pParse->db, p); |
| 166662 | WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); | 167834 | WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); |
| 166663 | return rc; | 167835 | return rc; |
| 166664 | } | 167836 | } |
| 166665 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ | 167837 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -166731,7 +167903,7 @@ static int whereLoopAddOr( | |||
| 166731 | } | 167903 | } |
| 166732 | #endif | 167904 | #endif |
| 166733 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 167905 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 166734 | if( IsVirtual(pItem->pTab) ){ | 167906 | if( IsVirtual(pItem->pSTab) ){ |
| 166735 | rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); | 167907 | rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); |
| 166736 | }else | 167908 | }else |
| 166737 | #endif | 167909 | #endif |
| @@ -166845,7 +168017,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ | |||
| 166845 | mPrereq = 0; | 168017 | mPrereq = 0; |
| 166846 | } | 168018 | } |
| 166847 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 168019 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 166848 | if( IsVirtual(pItem->pTab) ){ | 168020 | if( IsVirtual(pItem->pSTab) ){ |
| 166849 | SrcItem *p; | 168021 | SrcItem *p; |
| 166850 | for(p=&pItem[1]; p<pEnd; p++){ | 168022 | for(p=&pItem[1]; p<pEnd; p++){ |
| 166851 | if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ | 168023 | if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ |
| @@ -166877,6 +168049,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ | |||
| 166877 | return rc; | 168049 | return rc; |
| 166878 | } | 168050 | } |
| 166879 | 168051 | ||
| 168052 | /* Implementation of the order-by-subquery optimization: | ||
| 168053 | ** | ||
| 168054 | ** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really | ||
| 168055 | ** a subquery or CTE that has an ORDER BY clause. See if any of the terms | ||
| 168056 | ** in the subquery ORDER BY clause will satisfy pOrderBy from the outer | ||
| 168057 | ** query. Mark off all satisfied terms (by setting bits in *pOBSat) and | ||
| 168058 | ** return TRUE if they do. If not, return false. | ||
| 168059 | ** | ||
| 168060 | ** Example: | ||
| 168061 | ** | ||
| 168062 | ** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); | ||
| 168063 | ** CREATE TABLE t2(x,y); | ||
| 168064 | ** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) | ||
| 168065 | ** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; | ||
| 168066 | ** | ||
| 168067 | ** The CTE named "t3" comes out in the natural order of "p", so the first | ||
| 168068 | ** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" | ||
| 168069 | ** and sorting only needs to occur on the second term "b". | ||
| 168070 | ** | ||
| 168071 | ** Limitations: | ||
| 168072 | ** | ||
| 168073 | ** (1) The optimization is not applied if the outer ORDER BY contains | ||
| 168074 | ** a COLLATE clause. The optimization might be applied if the | ||
| 168075 | ** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as | ||
| 168076 | ** long as the subquery ORDER BY does the same. But if the | ||
| 168077 | ** outer ORDER BY uses COLLATE, even a redundant COLLATE, the | ||
| 168078 | ** optimization is bypassed. | ||
| 168079 | ** | ||
| 168080 | ** (2) The subquery ORDER BY terms must exactly match subquery result | ||
| 168081 | ** columns, including any COLLATE annotations. This routine relies | ||
| 168082 | ** on iOrderByCol to do matching between order by terms and result | ||
| 168083 | ** columns, and iOrderByCol will not be set if the result column | ||
| 168084 | ** and ORDER BY collations differ. | ||
| 168085 | ** | ||
| 168086 | ** (3) The subquery and outer ORDER BY can be in opposite directions as | ||
| 168087 | ** long as the subquery is materialized. If the subquery is | ||
| 168088 | ** implemented as a co-routine, the sort orders must be in the same | ||
| 168089 | ** direction because there is no way to run a co-routine backwards. | ||
| 168090 | */ | ||
| 168091 | static SQLITE_NOINLINE int wherePathMatchSubqueryOB( | ||
| 168092 | WhereInfo *pWInfo, /* The WHERE clause */ | ||
| 168093 | WhereLoop *pLoop, /* The nested loop term that is a subquery */ | ||
| 168094 | int iLoop, /* Which level of the nested loop. 0==outermost */ | ||
| 168095 | int iCur, /* Cursor used by the this loop */ | ||
| 168096 | ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ | ||
| 168097 | Bitmask *pRevMask, /* When loops need to go in reverse order */ | ||
| 168098 | Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ | ||
| 168099 | ){ | ||
| 168100 | int iOB; /* Index into pOrderBy->a[] */ | ||
| 168101 | int jSub; /* Index into pSubOB->a[] */ | ||
| 168102 | u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ | ||
| 168103 | u8 revIdx = 0; /* Sort direction for jSub */ | ||
| 168104 | Expr *pOBExpr; /* Current term of outer ORDER BY */ | ||
| 168105 | ExprList *pSubOB; /* Complete ORDER BY on the subquery */ | ||
| 168106 | |||
| 168107 | pSubOB = pLoop->u.btree.pOrderBy; | ||
| 168108 | assert( pSubOB!=0 ); | ||
| 168109 | for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} | ||
| 168110 | for(jSub=0; jSub<pSubOB->nExpr && iOB<pOrderBy->nExpr; jSub++, iOB++){ | ||
| 168111 | if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; | ||
| 168112 | pOBExpr = pOrderBy->a[iOB].pExpr; | ||
| 168113 | if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; | ||
| 168114 | if( pOBExpr->iTable!=iCur ) break; | ||
| 168115 | if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; | ||
| 168116 | if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ | ||
| 168117 | u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ | ||
| 168118 | u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ | ||
| 168119 | if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ | ||
| 168120 | break; | ||
| 168121 | } | ||
| 168122 | revIdx = sfSub & KEYINFO_ORDER_DESC; | ||
| 168123 | if( jSub>0 ){ | ||
| 168124 | if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ | ||
| 168125 | break; | ||
| 168126 | } | ||
| 168127 | }else{ | ||
| 168128 | rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); | ||
| 168129 | if( rev ){ | ||
| 168130 | if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ | ||
| 168131 | /* Cannot run a co-routine in reverse order */ | ||
| 168132 | break; | ||
| 168133 | } | ||
| 168134 | *pRevMask |= MASKBIT(iLoop); | ||
| 168135 | } | ||
| 168136 | } | ||
| 168137 | } | ||
| 168138 | *pOBSat |= MASKBIT(iOB); | ||
| 168139 | } | ||
| 168140 | return jSub>0; | ||
| 168141 | } | ||
| 168142 | |||
| 166880 | /* | 168143 | /* |
| 166881 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th | 168144 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th |
| 166882 | ** parameters) to see if it outputs rows in the requested ORDER BY | 168145 | ** parameters) to see if it outputs rows in the requested ORDER BY |
| @@ -167022,9 +168285,18 @@ static i8 wherePathSatisfiesOrderBy( | |||
| 167022 | 168285 | ||
| 167023 | if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ | 168286 | if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ |
| 167024 | if( pLoop->wsFlags & WHERE_IPK ){ | 168287 | if( pLoop->wsFlags & WHERE_IPK ){ |
| 168288 | if( pLoop->u.btree.pOrderBy | ||
| 168289 | && OptimizationEnabled(db, SQLITE_OrderBySubq) | ||
| 168290 | && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, | ||
| 168291 | pOrderBy,pRevMask, &obSat) | ||
| 168292 | ){ | ||
| 168293 | nColumn = 0; | ||
| 168294 | isOrderDistinct = 0; | ||
| 168295 | }else{ | ||
| 168296 | nColumn = 1; | ||
| 168297 | } | ||
| 167025 | pIndex = 0; | 168298 | pIndex = 0; |
| 167026 | nKeyCol = 0; | 168299 | nKeyCol = 0; |
| 167027 | nColumn = 1; | ||
| 167028 | }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ | 168300 | }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ |
| 167029 | return 0; | 168301 | return 0; |
| 167030 | }else{ | 168302 | }else{ |
| @@ -167034,7 +168306,7 @@ static i8 wherePathSatisfiesOrderBy( | |||
| 167034 | assert( pIndex->aiColumn[nColumn-1]==XN_ROWID | 168306 | assert( pIndex->aiColumn[nColumn-1]==XN_ROWID |
| 167035 | || !HasRowid(pIndex->pTable)); | 168307 | || !HasRowid(pIndex->pTable)); |
| 167036 | /* All relevant terms of the index must also be non-NULL in order | 168308 | /* All relevant terms of the index must also be non-NULL in order |
| 167037 | ** for isOrderDistinct to be true. So the isOrderDistint value | 168309 | ** for isOrderDistinct to be true. So the isOrderDistinct value |
| 167038 | ** computed here might be a false positive. Corrections will be | 168310 | ** computed here might be a false positive. Corrections will be |
| 167039 | ** made at tag-20210426-1 below */ | 168311 | ** made at tag-20210426-1 below */ |
| 167040 | isOrderDistinct = IsUniqueIndex(pIndex) | 168312 | isOrderDistinct = IsUniqueIndex(pIndex) |
| @@ -167119,7 +168391,7 @@ static i8 wherePathSatisfiesOrderBy( | |||
| 167119 | } | 168391 | } |
| 167120 | 168392 | ||
| 167121 | /* Find the ORDER BY term that corresponds to the j-th column | 168393 | /* Find the ORDER BY term that corresponds to the j-th column |
| 167122 | ** of the index and mark that ORDER BY term off | 168394 | ** of the index and mark that ORDER BY term having been satisfied. |
| 167123 | */ | 168395 | */ |
| 167124 | isMatch = 0; | 168396 | isMatch = 0; |
| 167125 | for(i=0; bOnce && i<nOrderBy; i++){ | 168397 | for(i=0; bOnce && i<nOrderBy; i++){ |
| @@ -167327,6 +168599,83 @@ static LogEst whereSortingCost( | |||
| 167327 | } | 168599 | } |
| 167328 | 168600 | ||
| 167329 | /* | 168601 | /* |
| 168602 | ** Compute the maximum number of paths in the solver algorithm, for | ||
| 168603 | ** queries that have three or more terms in the FROM clause. Queries with | ||
| 168604 | ** two or fewer FROM clause terms are handled by the caller. | ||
| 168605 | ** | ||
| 168606 | ** Query planning is NP-hard. We must limit the number of paths at | ||
| 168607 | ** each step of the solver search algorithm to avoid exponential behavior. | ||
| 168608 | ** | ||
| 168609 | ** The value returned is a tuning parameter. Currently the value is: | ||
| 168610 | ** | ||
| 168611 | ** 18 for star queries | ||
| 168612 | ** 12 otherwise | ||
| 168613 | ** | ||
| 168614 | ** For the purposes of SQLite, a star-query is defined as a query | ||
| 168615 | ** with a large central table that is joined against four or more | ||
| 168616 | ** smaller tables. The central table is called the "fact" table. | ||
| 168617 | ** The smaller tables that get joined are "dimension tables". | ||
| 168618 | ** | ||
| 168619 | ** SIDE EFFECT: (and really the whole point of this subroutine) | ||
| 168620 | ** | ||
| 168621 | ** If pWInfo describes a star-query, then the cost on WhereLoops for the | ||
| 168622 | ** fact table is reduced. This heuristic helps keep fact tables in | ||
| 168623 | ** outer loops. Without this heuristic, paths with fact tables in outer | ||
| 168624 | ** loops tend to get pruned by the mxChoice limit on the number of paths, | ||
| 168625 | ** resulting in poor query plans. The total amount of heuristic cost | ||
| 168626 | ** adjustment is stored in pWInfo->nOutStarDelta and the cost adjustment | ||
| 168627 | ** for each WhereLoop is stored in its rStarDelta field. | ||
| 168628 | */ | ||
| 168629 | static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){ | ||
| 168630 | int nLoop = pWInfo->nLevel; /* Number of terms in the join */ | ||
| 168631 | if( nRowEst==0 && nLoop>=5 ){ | ||
| 168632 | /* Check to see if we are dealing with a star schema and if so, reduce | ||
| 168633 | ** the cost of fact tables relative to dimension tables, as a heuristic | ||
| 168634 | ** to help keep the fact tables in outer loops. | ||
| 168635 | */ | ||
| 168636 | int iLoop; /* Counter over join terms */ | ||
| 168637 | Bitmask m; /* Bitmask for current loop */ | ||
| 168638 | assert( pWInfo->nOutStarDelta==0 ); | ||
| 168639 | for(iLoop=0, m=1; iLoop<nLoop; iLoop++, m<<=1){ | ||
| 168640 | WhereLoop *pWLoop; /* For looping over WhereLoops */ | ||
| 168641 | int nDep = 0; /* Number of dimension tables */ | ||
| 168642 | LogEst rDelta; /* Heuristic cost adjustment */ | ||
| 168643 | Bitmask mSeen = 0; /* Mask of dimension tables */ | ||
| 168644 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ | ||
| 168645 | if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){ | ||
| 168646 | nDep++; | ||
| 168647 | mSeen |= pWLoop->maskSelf; | ||
| 168648 | } | ||
| 168649 | } | ||
| 168650 | if( nDep<=3 ) continue; | ||
| 168651 | rDelta = 15*(nDep-3); | ||
| 168652 | #ifdef WHERETRACE_ENABLED /* 0x4 */ | ||
| 168653 | if( sqlite3WhereTrace&0x4 ){ | ||
| 168654 | SrcItem *pItem = pWInfo->pTabList->a + iLoop; | ||
| 168655 | sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n", | ||
| 168656 | pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName, | ||
| 168657 | nDep, rDelta); | ||
| 168658 | } | ||
| 168659 | #endif | ||
| 168660 | if( pWInfo->nOutStarDelta==0 ){ | ||
| 168661 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ | ||
| 168662 | pWLoop->rStarDelta = 0; | ||
| 168663 | } | ||
| 168664 | } | ||
| 168665 | pWInfo->nOutStarDelta += rDelta; | ||
| 168666 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ | ||
| 168667 | if( pWLoop->maskSelf==m ){ | ||
| 168668 | pWLoop->rRun -= rDelta; | ||
| 168669 | pWLoop->nOut -= rDelta; | ||
| 168670 | pWLoop->rStarDelta = rDelta; | ||
| 168671 | } | ||
| 168672 | } | ||
| 168673 | } | ||
| 168674 | } | ||
| 168675 | return pWInfo->nOutStarDelta>0 ? 18 : 12; | ||
| 168676 | } | ||
| 168677 | |||
| 168678 | /* | ||
| 167330 | ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine | 168679 | ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine |
| 167331 | ** attempts to find the lowest cost path that visits each WhereLoop | 168680 | ** attempts to find the lowest cost path that visits each WhereLoop |
| 167332 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. | 168681 | ** once. This path is then loaded into the pWInfo->a[].pWLoop fields. |
| @@ -167361,13 +168710,25 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 167361 | 168710 | ||
| 167362 | pParse = pWInfo->pParse; | 168711 | pParse = pWInfo->pParse; |
| 167363 | nLoop = pWInfo->nLevel; | 168712 | nLoop = pWInfo->nLevel; |
| 167364 | /* TUNING: For simple queries, only the best path is tracked. | ||
| 167365 | ** For 2-way joins, the 5 best paths are followed. | ||
| 167366 | ** For joins of 3 or more tables, track the 10 best paths */ | ||
| 167367 | mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); | ||
| 167368 | assert( nLoop<=pWInfo->pTabList->nSrc ); | ||
| 167369 | WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", | 168713 | WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", |
| 167370 | nRowEst, pParse->nQueryLoop)); | 168714 | nRowEst, pParse->nQueryLoop)); |
| 168715 | /* TUNING: mxChoice is the maximum number of possible paths to preserve | ||
| 168716 | ** at each step. Based on the number of loops in the FROM clause: | ||
| 168717 | ** | ||
| 168718 | ** nLoop mxChoice | ||
| 168719 | ** ----- -------- | ||
| 168720 | ** 1 1 // the most common case | ||
| 168721 | ** 2 5 | ||
| 168722 | ** 3+ 12 or 18 // see computeMxChoice() | ||
| 168723 | */ | ||
| 168724 | if( nLoop<=1 ){ | ||
| 168725 | mxChoice = 1; | ||
| 168726 | }else if( nLoop==2 ){ | ||
| 168727 | mxChoice = 5; | ||
| 168728 | }else{ | ||
| 168729 | mxChoice = computeMxChoice(pWInfo, nRowEst); | ||
| 168730 | } | ||
| 168731 | assert( nLoop<=pWInfo->pTabList->nSrc ); | ||
| 167371 | 168732 | ||
| 167372 | /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this | 168733 | /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this |
| 167373 | ** case the purpose of this call is to estimate the number of rows returned | 168734 | ** case the purpose of this call is to estimate the number of rows returned |
| @@ -167450,7 +168811,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 167450 | 168811 | ||
| 167451 | /* At this point, pWLoop is a candidate to be the next loop. | 168812 | /* At this point, pWLoop is a candidate to be the next loop. |
| 167452 | ** Compute its cost */ | 168813 | ** Compute its cost */ |
| 167453 | rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); | 168814 | rUnsorted = pWLoop->rRun + pFrom->nRow; |
| 168815 | if( pWLoop->rSetup ){ | ||
| 168816 | rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted); | ||
| 168817 | } | ||
| 167454 | rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); | 168818 | rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); |
| 167455 | nOut = pFrom->nRow + pWLoop->nOut; | 168819 | nOut = pFrom->nRow + pWLoop->nOut; |
| 167456 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; | 168820 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| @@ -167495,6 +168859,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 167495 | ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range | 168859 | ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range |
| 167496 | ** of legal values for isOrdered, -1..64. | 168860 | ** of legal values for isOrdered, -1..64. |
| 167497 | */ | 168861 | */ |
| 168862 | testcase( nTo==0 ); | ||
| 167498 | for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ | 168863 | for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ |
| 167499 | if( pTo->maskLoop==maskNew | 168864 | if( pTo->maskLoop==maskNew |
| 167500 | && ((pTo->isOrdered^isOrdered)&0x80)==0 | 168865 | && ((pTo->isOrdered^isOrdered)&0x80)==0 |
| @@ -167611,16 +168976,28 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 167611 | 168976 | ||
| 167612 | #ifdef WHERETRACE_ENABLED /* >=2 */ | 168977 | #ifdef WHERETRACE_ENABLED /* >=2 */ |
| 167613 | if( sqlite3WhereTrace & 0x02 ){ | 168978 | if( sqlite3WhereTrace & 0x02 ){ |
| 168979 | LogEst rMin, rFloor = 0; | ||
| 168980 | int nDone = 0; | ||
| 167614 | sqlite3DebugPrintf("---- after round %d ----\n", iLoop); | 168981 | sqlite3DebugPrintf("---- after round %d ----\n", iLoop); |
| 167615 | for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ | 168982 | while( nDone<nTo ){ |
| 167616 | sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", | 168983 | rMin = 0x7fff; |
| 167617 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, | 168984 | for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ |
| 167618 | pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); | 168985 | if( pTo->rCost>rFloor && pTo->rCost<rMin ) rMin = pTo->rCost; |
| 167619 | if( pTo->isOrdered>0 ){ | 168986 | } |
| 167620 | sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); | 168987 | for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ |
| 167621 | }else{ | 168988 | if( pTo->rCost==rMin ){ |
| 167622 | sqlite3DebugPrintf("\n"); | 168989 | sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", |
| 168990 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, | ||
| 168991 | pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); | ||
| 168992 | if( pTo->isOrdered>0 ){ | ||
| 168993 | sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); | ||
| 168994 | }else{ | ||
| 168995 | sqlite3DebugPrintf("\n"); | ||
| 168996 | } | ||
| 168997 | nDone++; | ||
| 168998 | } | ||
| 167623 | } | 168999 | } |
| 169000 | rFloor = rMin; | ||
| 167624 | } | 169001 | } |
| 167625 | } | 169002 | } |
| 167626 | #endif | 169003 | #endif |
| @@ -167715,7 +169092,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 167715 | } | 169092 | } |
| 167716 | } | 169093 | } |
| 167717 | 169094 | ||
| 167718 | pWInfo->nRowOut = pFrom->nRow; | 169095 | pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta; |
| 167719 | 169096 | ||
| 167720 | /* Free temporary memory and return success */ | 169097 | /* Free temporary memory and return success */ |
| 167721 | sqlite3StackFreeNN(pParse->db, pSpace); | 169098 | sqlite3StackFreeNN(pParse->db, pSpace); |
| @@ -167826,7 +169203,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ | |||
| 167826 | if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; | 169203 | if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; |
| 167827 | assert( pWInfo->pTabList->nSrc>=1 ); | 169204 | assert( pWInfo->pTabList->nSrc>=1 ); |
| 167828 | pItem = pWInfo->pTabList->a; | 169205 | pItem = pWInfo->pTabList->a; |
| 167829 | pTab = pItem->pTab; | 169206 | pTab = pItem->pSTab; |
| 167830 | if( IsVirtual(pTab) ) return 0; | 169207 | if( IsVirtual(pTab) ) return 0; |
| 167831 | if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ | 169208 | if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ |
| 167832 | testcase( pItem->fg.isIndexedBy ); | 169209 | testcase( pItem->fg.isIndexedBy ); |
| @@ -168016,6 +169393,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( | |||
| 168016 | WhereTerm *pTerm, *pEnd; | 169393 | WhereTerm *pTerm, *pEnd; |
| 168017 | SrcItem *pItem; | 169394 | SrcItem *pItem; |
| 168018 | WhereLoop *pLoop; | 169395 | WhereLoop *pLoop; |
| 169396 | Bitmask m1; | ||
| 168019 | pLoop = pWInfo->a[i].pWLoop; | 169397 | pLoop = pWInfo->a[i].pWLoop; |
| 168020 | pItem = &pWInfo->pTabList->a[pLoop->iTab]; | 169398 | pItem = &pWInfo->pTabList->a[pLoop->iTab]; |
| 168021 | if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; | 169399 | if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; |
| @@ -168042,7 +169420,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( | |||
| 168042 | } | 169420 | } |
| 168043 | } | 169421 | } |
| 168044 | if( pTerm<pEnd ) continue; | 169422 | if( pTerm<pEnd ) continue; |
| 168045 | WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId)); | 169423 | WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId)); |
| 169424 | m1 = MASKBIT(i)-1; | ||
| 169425 | testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); | ||
| 169426 | pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); | ||
| 168046 | notReady &= ~pLoop->maskSelf; | 169427 | notReady &= ~pLoop->maskSelf; |
| 168047 | for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ | 169428 | for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ |
| 168048 | if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ | 169429 | if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ |
| @@ -168089,7 +169470,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 168089 | WhereLoop *pLoop = pWInfo->a[i].pWLoop; | 169470 | WhereLoop *pLoop = pWInfo->a[i].pWLoop; |
| 168090 | const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); | 169471 | const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); |
| 168091 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; | 169472 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; |
| 168092 | Table *pTab = pItem->pTab; | 169473 | Table *pTab = pItem->pSTab; |
| 168093 | if( (pTab->tabFlags & TF_HasStat1)==0 ) break; | 169474 | if( (pTab->tabFlags & TF_HasStat1)==0 ) break; |
| 168094 | pTab->tabFlags |= TF_MaybeReanalyze; | 169475 | pTab->tabFlags |= TF_MaybeReanalyze; |
| 168095 | if( i>=1 | 169476 | if( i>=1 |
| @@ -168109,62 +169490,11 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 168109 | } | 169490 | } |
| 168110 | } | 169491 | } |
| 168111 | nSearch += pLoop->nOut; | 169492 | nSearch += pLoop->nOut; |
| 169493 | if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta; | ||
| 168112 | } | 169494 | } |
| 168113 | } | 169495 | } |
| 168114 | 169496 | ||
| 168115 | /* | 169497 | /* |
| 168116 | ** Expression Node callback for sqlite3ExprCanReturnSubtype(). | ||
| 168117 | ** | ||
| 168118 | ** Only a function call is able to return a subtype. So if the node | ||
| 168119 | ** is not a function call, return WRC_Prune immediately. | ||
| 168120 | ** | ||
| 168121 | ** A function call is able to return a subtype if it has the | ||
| 168122 | ** SQLITE_RESULT_SUBTYPE property. | ||
| 168123 | ** | ||
| 168124 | ** Assume that every function is able to pass-through a subtype from | ||
| 168125 | ** one of its argument (using sqlite3_result_value()). Most functions | ||
| 168126 | ** are not this way, but we don't have a mechanism to distinguish those | ||
| 168127 | ** that are from those that are not, so assume they all work this way. | ||
| 168128 | ** That means that if one of its arguments is another function and that | ||
| 168129 | ** other function is able to return a subtype, then this function is | ||
| 168130 | ** able to return a subtype. | ||
| 168131 | */ | ||
| 168132 | static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ | ||
| 168133 | int n; | ||
| 168134 | FuncDef *pDef; | ||
| 168135 | sqlite3 *db; | ||
| 168136 | if( pExpr->op!=TK_FUNCTION ){ | ||
| 168137 | return WRC_Prune; | ||
| 168138 | } | ||
| 168139 | assert( ExprUseXList(pExpr) ); | ||
| 168140 | db = pWalker->pParse->db; | ||
| 168141 | n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; | ||
| 168142 | pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); | ||
| 168143 | if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ | ||
| 168144 | pWalker->eCode = 1; | ||
| 168145 | return WRC_Prune; | ||
| 168146 | } | ||
| 168147 | return WRC_Continue; | ||
| 168148 | } | ||
| 168149 | |||
| 168150 | /* | ||
| 168151 | ** Return TRUE if expression pExpr is able to return a subtype. | ||
| 168152 | ** | ||
| 168153 | ** A TRUE return does not guarantee that a subtype will be returned. | ||
| 168154 | ** It only indicates that a subtype return is possible. False positives | ||
| 168155 | ** are acceptable as they only disable an optimization. False negatives, | ||
| 168156 | ** on the other hand, can lead to incorrect answers. | ||
| 168157 | */ | ||
| 168158 | static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ | ||
| 168159 | Walker w; | ||
| 168160 | memset(&w, 0, sizeof(w)); | ||
| 168161 | w.pParse = pParse; | ||
| 168162 | w.xExprCallback = exprNodeCanReturnSubtype; | ||
| 168163 | sqlite3WalkExpr(&w, pExpr); | ||
| 168164 | return w.eCode; | ||
| 168165 | } | ||
| 168166 | |||
| 168167 | /* | ||
| 168168 | ** The index pIdx is used by a query and contains one or more expressions. | 169498 | ** The index pIdx is used by a query and contains one or more expressions. |
| 168169 | ** In other words pIdx is an index on an expression. iIdxCur is the cursor | 169499 | ** In other words pIdx is an index on an expression. iIdxCur is the cursor |
| 168170 | ** number for the index and iDataCur is the cursor number for the corresponding | 169500 | ** number for the index and iDataCur is the cursor number for the corresponding |
| @@ -168197,12 +169527,6 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( | |||
| 168197 | continue; | 169527 | continue; |
| 168198 | } | 169528 | } |
| 168199 | if( sqlite3ExprIsConstant(0,pExpr) ) continue; | 169529 | if( sqlite3ExprIsConstant(0,pExpr) ) continue; |
| 168200 | if( pExpr->op==TK_FUNCTION && sqlite3ExprCanReturnSubtype(pParse,pExpr) ){ | ||
| 168201 | /* Functions that might set a subtype should not be replaced by the | ||
| 168202 | ** value taken from an expression index since the index omits the | ||
| 168203 | ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ | ||
| 168204 | continue; | ||
| 168205 | } | ||
| 168206 | p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); | 169530 | p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); |
| 168207 | if( p==0 ) break; | 169531 | if( p==0 ) break; |
| 168208 | p->pIENext = pParse->pIdxEpr; | 169532 | p->pIENext = pParse->pIdxEpr; |
| @@ -168245,8 +169569,8 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ | |||
| 168245 | SrcItem *pItem = &pWInfo->pTabList->a[ii]; | 169569 | SrcItem *pItem = &pWInfo->pTabList->a[ii]; |
| 168246 | if( !pItem->fg.isCte | 169570 | if( !pItem->fg.isCte |
| 168247 | || pItem->u2.pCteUse->eM10d!=M10d_Yes | 169571 | || pItem->u2.pCteUse->eM10d!=M10d_Yes |
| 168248 | || NEVER(pItem->pSelect==0) | 169572 | || NEVER(pItem->fg.isSubquery==0) |
| 168249 | || pItem->pSelect->pOrderBy==0 | 169573 | || pItem->u4.pSubq->pSelect->pOrderBy==0 |
| 168250 | ){ | 169574 | ){ |
| 168251 | pWInfo->revMask |= MASKBIT(ii); | 169575 | pWInfo->revMask |= MASKBIT(ii); |
| 168252 | } | 169576 | } |
| @@ -168625,7 +169949,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168625 | if( db->mallocFailed ) goto whereBeginError; | 169949 | if( db->mallocFailed ) goto whereBeginError; |
| 168626 | if( pWInfo->pOrderBy ){ | 169950 | if( pWInfo->pOrderBy ){ |
| 168627 | whereInterstageHeuristic(pWInfo); | 169951 | whereInterstageHeuristic(pWInfo); |
| 168628 | wherePathSolver(pWInfo, pWInfo->nRowOut+1); | 169952 | wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); |
| 168629 | if( db->mallocFailed ) goto whereBeginError; | 169953 | if( db->mallocFailed ) goto whereBeginError; |
| 168630 | } | 169954 | } |
| 168631 | 169955 | ||
| @@ -168736,15 +170060,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168736 | if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ | 170060 | if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ |
| 168737 | int wsFlags = pWInfo->a[0].pWLoop->wsFlags; | 170061 | int wsFlags = pWInfo->a[0].pWLoop->wsFlags; |
| 168738 | int bOnerow = (wsFlags & WHERE_ONEROW)!=0; | 170062 | int bOnerow = (wsFlags & WHERE_ONEROW)!=0; |
| 168739 | assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); | 170063 | assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); |
| 168740 | if( bOnerow || ( | 170064 | if( bOnerow || ( |
| 168741 | 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) | 170065 | 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) |
| 168742 | && !IsVirtual(pTabList->a[0].pTab) | 170066 | && !IsVirtual(pTabList->a[0].pSTab) |
| 168743 | && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) | 170067 | && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) |
| 168744 | && OptimizationEnabled(db, SQLITE_OnePass) | 170068 | && OptimizationEnabled(db, SQLITE_OnePass) |
| 168745 | )){ | 170069 | )){ |
| 168746 | pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; | 170070 | pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; |
| 168747 | if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ | 170071 | if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ |
| 168748 | if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ | 170072 | if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ |
| 168749 | bFordelete = OPFLAG_FORDELETE; | 170073 | bFordelete = OPFLAG_FORDELETE; |
| 168750 | } | 170074 | } |
| @@ -168762,7 +170086,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168762 | SrcItem *pTabItem; | 170086 | SrcItem *pTabItem; |
| 168763 | 170087 | ||
| 168764 | pTabItem = &pTabList->a[pLevel->iFrom]; | 170088 | pTabItem = &pTabList->a[pLevel->iFrom]; |
| 168765 | pTab = pTabItem->pTab; | 170089 | pTab = pTabItem->pSTab; |
| 168766 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 170090 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 168767 | pLoop = pLevel->pWLoop; | 170091 | pLoop = pLevel->pWLoop; |
| 168768 | if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ | 170092 | if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ |
| @@ -168833,7 +170157,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168833 | iIndexCur = pLevel->iTabCur; | 170157 | iIndexCur = pLevel->iTabCur; |
| 168834 | op = 0; | 170158 | op = 0; |
| 168835 | }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ | 170159 | }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ |
| 168836 | Index *pJ = pTabItem->pTab->pIndex; | 170160 | Index *pJ = pTabItem->pSTab->pIndex; |
| 168837 | iIndexCur = iAuxArg; | 170161 | iIndexCur = iAuxArg; |
| 168838 | assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); | 170162 | assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); |
| 168839 | while( ALWAYS(pJ) && pJ!=pIx ){ | 170163 | while( ALWAYS(pJ) && pJ!=pIx ){ |
| @@ -168900,7 +170224,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168900 | sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); | 170224 | sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); |
| 168901 | pRJ->regReturn = ++pParse->nMem; | 170225 | pRJ->regReturn = ++pParse->nMem; |
| 168902 | sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); | 170226 | sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); |
| 168903 | assert( pTab==pTabItem->pTab ); | 170227 | assert( pTab==pTabItem->pSTab ); |
| 168904 | if( HasRowid(pTab) ){ | 170228 | if( HasRowid(pTab) ){ |
| 168905 | KeyInfo *pInfo; | 170229 | KeyInfo *pInfo; |
| 168906 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); | 170230 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); |
| @@ -168939,13 +170263,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 168939 | wsFlags = pLevel->pWLoop->wsFlags; | 170263 | wsFlags = pLevel->pWLoop->wsFlags; |
| 168940 | pSrc = &pTabList->a[pLevel->iFrom]; | 170264 | pSrc = &pTabList->a[pLevel->iFrom]; |
| 168941 | if( pSrc->fg.isMaterialized ){ | 170265 | if( pSrc->fg.isMaterialized ){ |
| 168942 | if( pSrc->fg.isCorrelated ){ | 170266 | Subquery *pSubq; |
| 168943 | sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); | 170267 | int iOnce = 0; |
| 170268 | assert( pSrc->fg.isSubquery ); | ||
| 170269 | pSubq = pSrc->u4.pSubq; | ||
| 170270 | if( pSrc->fg.isCorrelated==0 ){ | ||
| 170271 | iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | ||
| 168944 | }else{ | 170272 | }else{ |
| 168945 | int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | 170273 | iOnce = 0; |
| 168946 | sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); | ||
| 168947 | sqlite3VdbeJumpHere(v, iOnce); | ||
| 168948 | } | 170274 | } |
| 170275 | sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); | ||
| 170276 | VdbeComment((v, "materialize %!S", pSrc)); | ||
| 170277 | if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); | ||
| 168949 | } | 170278 | } |
| 168950 | assert( pTabList == pWInfo->pTabList ); | 170279 | assert( pTabList == pWInfo->pTabList ); |
| 168951 | if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ | 170280 | if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ |
| @@ -169158,9 +170487,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 169158 | assert( pLevel->iTabCur==pSrc->iCursor ); | 170487 | assert( pLevel->iTabCur==pSrc->iCursor ); |
| 169159 | if( pSrc->fg.viaCoroutine ){ | 170488 | if( pSrc->fg.viaCoroutine ){ |
| 169160 | int m, n; | 170489 | int m, n; |
| 169161 | n = pSrc->regResult; | 170490 | assert( pSrc->fg.isSubquery ); |
| 169162 | assert( pSrc->pTab!=0 ); | 170491 | n = pSrc->u4.pSubq->regResult; |
| 169163 | m = pSrc->pTab->nCol; | 170492 | assert( pSrc->pSTab!=0 ); |
| 170493 | m = pSrc->pSTab->nCol; | ||
| 169164 | sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); | 170494 | sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); |
| 169165 | } | 170495 | } |
| 169166 | sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); | 170496 | sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); |
| @@ -169184,7 +170514,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 169184 | sqlite3VdbeJumpHere(v, addr); | 170514 | sqlite3VdbeJumpHere(v, addr); |
| 169185 | } | 170515 | } |
| 169186 | VdbeModuleComment((v, "End WHERE-loop%d: %s", i, | 170516 | VdbeModuleComment((v, "End WHERE-loop%d: %s", i, |
| 169187 | pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); | 170517 | pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); |
| 169188 | } | 170518 | } |
| 169189 | 170519 | ||
| 169190 | assert( pWInfo->nLevel<=pTabList->nSrc ); | 170520 | assert( pWInfo->nLevel<=pTabList->nSrc ); |
| @@ -169193,7 +170523,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 169193 | VdbeOp *pOp, *pLastOp; | 170523 | VdbeOp *pOp, *pLastOp; |
| 169194 | Index *pIdx = 0; | 170524 | Index *pIdx = 0; |
| 169195 | SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; | 170525 | SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; |
| 169196 | Table *pTab = pTabItem->pTab; | 170526 | Table *pTab = pTabItem->pSTab; |
| 169197 | assert( pTab!=0 ); | 170527 | assert( pTab!=0 ); |
| 169198 | pLoop = pLevel->pWLoop; | 170528 | pLoop = pLevel->pWLoop; |
| 169199 | 170529 | ||
| @@ -169212,9 +170542,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 169212 | */ | 170542 | */ |
| 169213 | if( pTabItem->fg.viaCoroutine ){ | 170543 | if( pTabItem->fg.viaCoroutine ){ |
| 169214 | testcase( pParse->db->mallocFailed ); | 170544 | testcase( pParse->db->mallocFailed ); |
| 169215 | assert( pTabItem->regResult>=0 ); | 170545 | assert( pTabItem->fg.isSubquery ); |
| 170546 | assert( pTabItem->u4.pSubq->regResult>=0 ); | ||
| 169216 | translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, | 170547 | translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, |
| 169217 | pTabItem->regResult, 0); | 170548 | pTabItem->u4.pSubq->regResult, 0); |
| 169218 | continue; | 170549 | continue; |
| 169219 | } | 170550 | } |
| 169220 | 170551 | ||
| @@ -170256,7 +171587,7 @@ static ExprList *exprListAppendList( | |||
| 170256 | int iDummy; | 171587 | int iDummy; |
| 170257 | Expr *pSub; | 171588 | Expr *pSub; |
| 170258 | pSub = sqlite3ExprSkipCollateAndLikely(pDup); | 171589 | pSub = sqlite3ExprSkipCollateAndLikely(pDup); |
| 170259 | if( sqlite3ExprIsInteger(pSub, &iDummy) ){ | 171590 | if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ |
| 170260 | pSub->op = TK_NULL; | 171591 | pSub->op = TK_NULL; |
| 170261 | pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); | 171592 | pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); |
| 170262 | pSub->u.zToken = 0; | 171593 | pSub->u.zToken = 0; |
| @@ -170424,9 +171755,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 170424 | assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside | 171755 | assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside |
| 170425 | ** of sqlite3DbMallocRawNN() called from | 171756 | ** of sqlite3DbMallocRawNN() called from |
| 170426 | ** sqlite3SrcListAppend() */ | 171757 | ** sqlite3SrcListAppend() */ |
| 170427 | if( p->pSrc ){ | 171758 | if( p->pSrc==0 ){ |
| 171759 | sqlite3SelectDelete(db, pSub); | ||
| 171760 | }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ | ||
| 170428 | Table *pTab2; | 171761 | Table *pTab2; |
| 170429 | p->pSrc->a[0].pSelect = pSub; | ||
| 170430 | p->pSrc->a[0].fg.isCorrelated = 1; | 171762 | p->pSrc->a[0].fg.isCorrelated = 1; |
| 170431 | sqlite3SrcListAssignCursors(pParse, p->pSrc); | 171763 | sqlite3SrcListAssignCursors(pParse, p->pSrc); |
| 170432 | pSub->selFlags |= SF_Expanded|SF_OrderByReqd; | 171764 | pSub->selFlags |= SF_Expanded|SF_OrderByReqd; |
| @@ -170440,7 +171772,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 170440 | }else{ | 171772 | }else{ |
| 170441 | memcpy(pTab, pTab2, sizeof(Table)); | 171773 | memcpy(pTab, pTab2, sizeof(Table)); |
| 170442 | pTab->tabFlags |= TF_Ephemeral; | 171774 | pTab->tabFlags |= TF_Ephemeral; |
| 170443 | p->pSrc->a[0].pTab = pTab; | 171775 | p->pSrc->a[0].pSTab = pTab; |
| 170444 | pTab = pTab2; | 171776 | pTab = pTab2; |
| 170445 | memset(&w, 0, sizeof(w)); | 171777 | memset(&w, 0, sizeof(w)); |
| 170446 | w.xExprCallback = sqlite3WindowExtraAggFuncDepth; | 171778 | w.xExprCallback = sqlite3WindowExtraAggFuncDepth; |
| @@ -170448,8 +171780,6 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 170448 | w.xSelectCallback2 = sqlite3WalkerDepthDecrease; | 171780 | w.xSelectCallback2 = sqlite3WalkerDepthDecrease; |
| 170449 | sqlite3WalkSelect(&w, pSub); | 171781 | sqlite3WalkSelect(&w, pSub); |
| 170450 | } | 171782 | } |
| 170451 | }else{ | ||
| 170452 | sqlite3SelectDelete(db, pSub); | ||
| 170453 | } | 171783 | } |
| 170454 | if( db->mallocFailed ) rc = SQLITE_NOMEM; | 171784 | if( db->mallocFailed ) rc = SQLITE_NOMEM; |
| 170455 | 171785 | ||
| @@ -170736,10 +172066,15 @@ SQLITE_PRIVATE int sqlite3WindowCompare( | |||
| 170736 | ** and initialize registers and cursors used by sqlite3WindowCodeStep(). | 172066 | ** and initialize registers and cursors used by sqlite3WindowCodeStep(). |
| 170737 | */ | 172067 | */ |
| 170738 | SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ | 172068 | SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ |
| 170739 | int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; | ||
| 170740 | Window *pMWin = pSelect->pWin; | ||
| 170741 | Window *pWin; | 172069 | Window *pWin; |
| 170742 | Vdbe *v = sqlite3GetVdbe(pParse); | 172070 | int nEphExpr; |
| 172071 | Window *pMWin; | ||
| 172072 | Vdbe *v; | ||
| 172073 | |||
| 172074 | assert( pSelect->pSrc->a[0].fg.isSubquery ); | ||
| 172075 | nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; | ||
| 172076 | pMWin = pSelect->pWin; | ||
| 172077 | v = sqlite3GetVdbe(pParse); | ||
| 170743 | 172078 | ||
| 170744 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); | 172079 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); |
| 170745 | sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); | 172080 | sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); |
| @@ -172136,7 +173471,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 172136 | Vdbe *v = sqlite3GetVdbe(pParse); | 173471 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 172137 | int csrWrite; /* Cursor used to write to eph. table */ | 173472 | int csrWrite; /* Cursor used to write to eph. table */ |
| 172138 | int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ | 173473 | int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ |
| 172139 | int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ | 173474 | int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ |
| 172140 | int iInput; /* To iterate through sub cols */ | 173475 | int iInput; /* To iterate through sub cols */ |
| 172141 | int addrNe; /* Address of OP_Ne */ | 173476 | int addrNe; /* Address of OP_Ne */ |
| 172142 | int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ | 173477 | int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ |
| @@ -172733,132 +174068,132 @@ static void updateDeleteLimitError( | |||
| 172733 | #define TK_OR 43 | 174068 | #define TK_OR 43 |
| 172734 | #define TK_AND 44 | 174069 | #define TK_AND 44 |
| 172735 | #define TK_IS 45 | 174070 | #define TK_IS 45 |
| 172736 | #define TK_MATCH 46 | 174071 | #define TK_ISNOT 46 |
| 172737 | #define TK_LIKE_KW 47 | 174072 | #define TK_MATCH 47 |
| 172738 | #define TK_BETWEEN 48 | 174073 | #define TK_LIKE_KW 48 |
| 172739 | #define TK_IN 49 | 174074 | #define TK_BETWEEN 49 |
| 172740 | #define TK_ISNULL 50 | 174075 | #define TK_IN 50 |
| 172741 | #define TK_NOTNULL 51 | 174076 | #define TK_ISNULL 51 |
| 172742 | #define TK_NE 52 | 174077 | #define TK_NOTNULL 52 |
| 172743 | #define TK_EQ 53 | 174078 | #define TK_NE 53 |
| 172744 | #define TK_GT 54 | 174079 | #define TK_EQ 54 |
| 172745 | #define TK_LE 55 | 174080 | #define TK_GT 55 |
| 172746 | #define TK_LT 56 | 174081 | #define TK_LE 56 |
| 172747 | #define TK_GE 57 | 174082 | #define TK_LT 57 |
| 172748 | #define TK_ESCAPE 58 | 174083 | #define TK_GE 58 |
| 172749 | #define TK_ID 59 | 174084 | #define TK_ESCAPE 59 |
| 172750 | #define TK_COLUMNKW 60 | 174085 | #define TK_ID 60 |
| 172751 | #define TK_DO 61 | 174086 | #define TK_COLUMNKW 61 |
| 172752 | #define TK_FOR 62 | 174087 | #define TK_DO 62 |
| 172753 | #define TK_IGNORE 63 | 174088 | #define TK_FOR 63 |
| 172754 | #define TK_INITIALLY 64 | 174089 | #define TK_IGNORE 64 |
| 172755 | #define TK_INSTEAD 65 | 174090 | #define TK_INITIALLY 65 |
| 172756 | #define TK_NO 66 | 174091 | #define TK_INSTEAD 66 |
| 172757 | #define TK_KEY 67 | 174092 | #define TK_NO 67 |
| 172758 | #define TK_OF 68 | 174093 | #define TK_KEY 68 |
| 172759 | #define TK_OFFSET 69 | 174094 | #define TK_OF 69 |
| 172760 | #define TK_PRAGMA 70 | 174095 | #define TK_OFFSET 70 |
| 172761 | #define TK_RAISE 71 | 174096 | #define TK_PRAGMA 71 |
| 172762 | #define TK_RECURSIVE 72 | 174097 | #define TK_RAISE 72 |
| 172763 | #define TK_REPLACE 73 | 174098 | #define TK_RECURSIVE 73 |
| 172764 | #define TK_RESTRICT 74 | 174099 | #define TK_REPLACE 74 |
| 172765 | #define TK_ROW 75 | 174100 | #define TK_RESTRICT 75 |
| 172766 | #define TK_ROWS 76 | 174101 | #define TK_ROW 76 |
| 172767 | #define TK_TRIGGER 77 | 174102 | #define TK_ROWS 77 |
| 172768 | #define TK_VACUUM 78 | 174103 | #define TK_TRIGGER 78 |
| 172769 | #define TK_VIEW 79 | 174104 | #define TK_VACUUM 79 |
| 172770 | #define TK_VIRTUAL 80 | 174105 | #define TK_VIEW 80 |
| 172771 | #define TK_WITH 81 | 174106 | #define TK_VIRTUAL 81 |
| 172772 | #define TK_NULLS 82 | 174107 | #define TK_WITH 82 |
| 172773 | #define TK_FIRST 83 | 174108 | #define TK_NULLS 83 |
| 172774 | #define TK_LAST 84 | 174109 | #define TK_FIRST 84 |
| 172775 | #define TK_CURRENT 85 | 174110 | #define TK_LAST 85 |
| 172776 | #define TK_FOLLOWING 86 | 174111 | #define TK_CURRENT 86 |
| 172777 | #define TK_PARTITION 87 | 174112 | #define TK_FOLLOWING 87 |
| 172778 | #define TK_PRECEDING 88 | 174113 | #define TK_PARTITION 88 |
| 172779 | #define TK_RANGE 89 | 174114 | #define TK_PRECEDING 89 |
| 172780 | #define TK_UNBOUNDED 90 | 174115 | #define TK_RANGE 90 |
| 172781 | #define TK_EXCLUDE 91 | 174116 | #define TK_UNBOUNDED 91 |
| 172782 | #define TK_GROUPS 92 | 174117 | #define TK_EXCLUDE 92 |
| 172783 | #define TK_OTHERS 93 | 174118 | #define TK_GROUPS 93 |
| 172784 | #define TK_TIES 94 | 174119 | #define TK_OTHERS 94 |
| 172785 | #define TK_GENERATED 95 | 174120 | #define TK_TIES 95 |
| 172786 | #define TK_ALWAYS 96 | 174121 | #define TK_GENERATED 96 |
| 172787 | #define TK_MATERIALIZED 97 | 174122 | #define TK_ALWAYS 97 |
| 172788 | #define TK_REINDEX 98 | 174123 | #define TK_MATERIALIZED 98 |
| 172789 | #define TK_RENAME 99 | 174124 | #define TK_REINDEX 99 |
| 172790 | #define TK_CTIME_KW 100 | 174125 | #define TK_RENAME 100 |
| 172791 | #define TK_ANY 101 | 174126 | #define TK_CTIME_KW 101 |
| 172792 | #define TK_BITAND 102 | 174127 | #define TK_ANY 102 |
| 172793 | #define TK_BITOR 103 | 174128 | #define TK_BITAND 103 |
| 172794 | #define TK_LSHIFT 104 | 174129 | #define TK_BITOR 104 |
| 172795 | #define TK_RSHIFT 105 | 174130 | #define TK_LSHIFT 105 |
| 172796 | #define TK_PLUS 106 | 174131 | #define TK_RSHIFT 106 |
| 172797 | #define TK_MINUS 107 | 174132 | #define TK_PLUS 107 |
| 172798 | #define TK_STAR 108 | 174133 | #define TK_MINUS 108 |
| 172799 | #define TK_SLASH 109 | 174134 | #define TK_STAR 109 |
| 172800 | #define TK_REM 110 | 174135 | #define TK_SLASH 110 |
| 172801 | #define TK_CONCAT 111 | 174136 | #define TK_REM 111 |
| 172802 | #define TK_PTR 112 | 174137 | #define TK_CONCAT 112 |
| 172803 | #define TK_COLLATE 113 | 174138 | #define TK_PTR 113 |
| 172804 | #define TK_BITNOT 114 | 174139 | #define TK_COLLATE 114 |
| 172805 | #define TK_ON 115 | 174140 | #define TK_BITNOT 115 |
| 172806 | #define TK_INDEXED 116 | 174141 | #define TK_ON 116 |
| 172807 | #define TK_STRING 117 | 174142 | #define TK_INDEXED 117 |
| 172808 | #define TK_JOIN_KW 118 | 174143 | #define TK_STRING 118 |
| 172809 | #define TK_CONSTRAINT 119 | 174144 | #define TK_JOIN_KW 119 |
| 172810 | #define TK_DEFAULT 120 | 174145 | #define TK_CONSTRAINT 120 |
| 172811 | #define TK_NULL 121 | 174146 | #define TK_DEFAULT 121 |
| 172812 | #define TK_PRIMARY 122 | 174147 | #define TK_NULL 122 |
| 172813 | #define TK_UNIQUE 123 | 174148 | #define TK_PRIMARY 123 |
| 172814 | #define TK_CHECK 124 | 174149 | #define TK_UNIQUE 124 |
| 172815 | #define TK_REFERENCES 125 | 174150 | #define TK_CHECK 125 |
| 172816 | #define TK_AUTOINCR 126 | 174151 | #define TK_REFERENCES 126 |
| 172817 | #define TK_INSERT 127 | 174152 | #define TK_AUTOINCR 127 |
| 172818 | #define TK_DELETE 128 | 174153 | #define TK_INSERT 128 |
| 172819 | #define TK_UPDATE 129 | 174154 | #define TK_DELETE 129 |
| 172820 | #define TK_SET 130 | 174155 | #define TK_UPDATE 130 |
| 172821 | #define TK_DEFERRABLE 131 | 174156 | #define TK_SET 131 |
| 172822 | #define TK_FOREIGN 132 | 174157 | #define TK_DEFERRABLE 132 |
| 172823 | #define TK_DROP 133 | 174158 | #define TK_FOREIGN 133 |
| 172824 | #define TK_UNION 134 | 174159 | #define TK_DROP 134 |
| 172825 | #define TK_ALL 135 | 174160 | #define TK_UNION 135 |
| 172826 | #define TK_EXCEPT 136 | 174161 | #define TK_ALL 136 |
| 172827 | #define TK_INTERSECT 137 | 174162 | #define TK_EXCEPT 137 |
| 172828 | #define TK_SELECT 138 | 174163 | #define TK_INTERSECT 138 |
| 172829 | #define TK_VALUES 139 | 174164 | #define TK_SELECT 139 |
| 172830 | #define TK_DISTINCT 140 | 174165 | #define TK_VALUES 140 |
| 172831 | #define TK_DOT 141 | 174166 | #define TK_DISTINCT 141 |
| 172832 | #define TK_FROM 142 | 174167 | #define TK_DOT 142 |
| 172833 | #define TK_JOIN 143 | 174168 | #define TK_FROM 143 |
| 172834 | #define TK_USING 144 | 174169 | #define TK_JOIN 144 |
| 172835 | #define TK_ORDER 145 | 174170 | #define TK_USING 145 |
| 172836 | #define TK_GROUP 146 | 174171 | #define TK_ORDER 146 |
| 172837 | #define TK_HAVING 147 | 174172 | #define TK_GROUP 147 |
| 172838 | #define TK_LIMIT 148 | 174173 | #define TK_HAVING 148 |
| 172839 | #define TK_WHERE 149 | 174174 | #define TK_LIMIT 149 |
| 172840 | #define TK_RETURNING 150 | 174175 | #define TK_WHERE 150 |
| 172841 | #define TK_INTO 151 | 174176 | #define TK_RETURNING 151 |
| 172842 | #define TK_NOTHING 152 | 174177 | #define TK_INTO 152 |
| 172843 | #define TK_FLOAT 153 | 174178 | #define TK_NOTHING 153 |
| 172844 | #define TK_BLOB 154 | 174179 | #define TK_FLOAT 154 |
| 172845 | #define TK_INTEGER 155 | 174180 | #define TK_BLOB 155 |
| 172846 | #define TK_VARIABLE 156 | 174181 | #define TK_INTEGER 156 |
| 172847 | #define TK_CASE 157 | 174182 | #define TK_VARIABLE 157 |
| 172848 | #define TK_WHEN 158 | 174183 | #define TK_CASE 158 |
| 172849 | #define TK_THEN 159 | 174184 | #define TK_WHEN 159 |
| 172850 | #define TK_ELSE 160 | 174185 | #define TK_THEN 160 |
| 172851 | #define TK_INDEX 161 | 174186 | #define TK_ELSE 161 |
| 172852 | #define TK_ALTER 162 | 174187 | #define TK_INDEX 162 |
| 172853 | #define TK_ADD 163 | 174188 | #define TK_ALTER 163 |
| 172854 | #define TK_WINDOW 164 | 174189 | #define TK_ADD 164 |
| 172855 | #define TK_OVER 165 | 174190 | #define TK_WINDOW 165 |
| 172856 | #define TK_FILTER 166 | 174191 | #define TK_OVER 166 |
| 172857 | #define TK_COLUMN 167 | 174192 | #define TK_FILTER 167 |
| 172858 | #define TK_AGG_FUNCTION 168 | 174193 | #define TK_COLUMN 168 |
| 172859 | #define TK_AGG_COLUMN 169 | 174194 | #define TK_AGG_FUNCTION 169 |
| 172860 | #define TK_TRUEFALSE 170 | 174195 | #define TK_AGG_COLUMN 170 |
| 172861 | #define TK_ISNOT 171 | 174196 | #define TK_TRUEFALSE 171 |
| 172862 | #define TK_FUNCTION 172 | 174197 | #define TK_FUNCTION 172 |
| 172863 | #define TK_UPLUS 173 | 174198 | #define TK_UPLUS 173 |
| 172864 | #define TK_UMINUS 174 | 174199 | #define TK_UMINUS 174 |
| @@ -172939,7 +174274,7 @@ static void updateDeleteLimitError( | |||
| 172939 | #define YYCODETYPE unsigned short int | 174274 | #define YYCODETYPE unsigned short int |
| 172940 | #define YYNOCODE 322 | 174275 | #define YYNOCODE 322 |
| 172941 | #define YYACTIONTYPE unsigned short int | 174276 | #define YYACTIONTYPE unsigned short int |
| 172942 | #define YYWILDCARD 101 | 174277 | #define YYWILDCARD 102 |
| 172943 | #define sqlite3ParserTOKENTYPE Token | 174278 | #define sqlite3ParserTOKENTYPE Token |
| 172944 | typedef union { | 174279 | typedef union { |
| 172945 | int yyinit; | 174280 | int yyinit; |
| @@ -173076,446 +174411,452 @@ typedef union { | |||
| 173076 | ** yy_default[] Default action for each state. | 174411 | ** yy_default[] Default action for each state. |
| 173077 | ** | 174412 | ** |
| 173078 | *********** Begin parsing tables **********************************************/ | 174413 | *********** Begin parsing tables **********************************************/ |
| 173079 | #define YY_ACTTAB_COUNT (2142) | 174414 | #define YY_ACTTAB_COUNT (2207) |
| 173080 | static const YYACTIONTYPE yy_action[] = { | 174415 | static const YYACTIONTYPE yy_action[] = { |
| 173081 | /* 0 */ 576, 128, 125, 232, 1622, 549, 576, 1290, 1281, 576, | 174416 | /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, |
| 173082 | /* 10 */ 328, 576, 1300, 212, 576, 128, 125, 232, 578, 412, | 174417 | /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, |
| 173083 | /* 20 */ 578, 391, 1542, 51, 51, 523, 405, 1293, 529, 51, | 174418 | /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, |
| 173084 | /* 30 */ 51, 983, 51, 51, 81, 81, 1107, 61, 61, 984, | 174419 | /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, |
| 173085 | /* 40 */ 1107, 1292, 380, 135, 136, 90, 1228, 1228, 1063, 1066, | 174420 | /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, |
| 173086 | /* 50 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 1577, 412, | 174421 | /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, |
| 173087 | /* 60 */ 287, 287, 7, 287, 287, 422, 1050, 1050, 1064, 1067, | 174422 | /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, |
| 173088 | /* 70 */ 289, 556, 492, 573, 524, 561, 573, 497, 561, 482, | 174423 | /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, |
| 173089 | /* 80 */ 530, 262, 229, 135, 136, 90, 1228, 1228, 1063, 1066, | 174424 | /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, |
| 173090 | /* 90 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 128, 125, | 174425 | /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, |
| 173091 | /* 100 */ 232, 1506, 132, 132, 132, 132, 131, 131, 130, 130, | 174426 | /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, |
| 173092 | /* 110 */ 130, 129, 126, 450, 1204, 1255, 1, 1, 582, 2, | 174427 | /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067, |
| 173093 | /* 120 */ 1259, 1571, 420, 1582, 379, 320, 1174, 153, 1174, 1584, | 174428 | /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, |
| 173094 | /* 130 */ 412, 378, 1582, 543, 1341, 330, 111, 570, 570, 570, | 174429 | /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341, |
| 173095 | /* 140 */ 293, 1054, 132, 132, 132, 132, 131, 131, 130, 130, | 174430 | /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, |
| 173096 | /* 150 */ 130, 129, 126, 450, 135, 136, 90, 1228, 1228, 1063, | 174431 | /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228, |
| 173097 | /* 160 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 287, | 174432 | /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, |
| 173098 | /* 170 */ 287, 1204, 1205, 1204, 255, 287, 287, 510, 507, 506, | 174433 | /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523, |
| 173099 | /* 180 */ 137, 455, 573, 212, 561, 447, 446, 505, 573, 1616, | 174434 | /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562, |
| 173100 | /* 190 */ 561, 134, 134, 134, 134, 127, 400, 243, 132, 132, | 174435 | /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547, |
| 173101 | /* 200 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, | 174436 | /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132, |
| 173102 | /* 210 */ 282, 471, 345, 132, 132, 132, 132, 131, 131, 130, | 174437 | /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133, |
| 173103 | /* 220 */ 130, 130, 129, 126, 450, 574, 155, 936, 936, 454, | 174438 | /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205, |
| 173104 | /* 230 */ 227, 521, 1236, 412, 1236, 134, 134, 134, 134, 132, | 174439 | /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127, |
| 173105 | /* 240 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, | 174440 | /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, |
| 173106 | /* 250 */ 450, 130, 130, 130, 129, 126, 450, 135, 136, 90, | 174441 | /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137, |
| 173107 | /* 260 */ 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, | 174442 | /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135, |
| 173108 | /* 270 */ 134, 134, 128, 125, 232, 450, 576, 412, 397, 1249, | 174443 | /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472, |
| 173109 | /* 280 */ 180, 92, 93, 132, 132, 132, 132, 131, 131, 130, | 174444 | /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134, |
| 173110 | /* 290 */ 130, 130, 129, 126, 450, 381, 387, 1204, 383, 81, | 174445 | /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363, |
| 173111 | /* 300 */ 81, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, | 174446 | /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132, |
| 173112 | /* 310 */ 133, 133, 134, 134, 134, 134, 132, 132, 132, 132, | 174447 | /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134, |
| 173113 | /* 320 */ 131, 131, 130, 130, 130, 129, 126, 450, 131, 131, | 174448 | /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, |
| 173114 | /* 330 */ 130, 130, 130, 129, 126, 450, 556, 1204, 302, 319, | 174449 | /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413, |
| 173115 | /* 340 */ 567, 121, 568, 480, 4, 555, 1149, 1657, 1628, 1657, | 174450 | /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128, |
| 173116 | /* 350 */ 45, 128, 125, 232, 1204, 1205, 1204, 1250, 571, 1169, | 174451 | /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413, |
| 173117 | /* 360 */ 132, 132, 132, 132, 131, 131, 130, 130, 130, 129, | 174452 | /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063, |
| 173118 | /* 370 */ 126, 450, 1169, 287, 287, 1169, 1019, 576, 422, 1019, | 174453 | /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51, |
| 173119 | /* 380 */ 412, 451, 1602, 582, 2, 1259, 573, 44, 561, 95, | 174454 | /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063, |
| 173120 | /* 390 */ 320, 110, 153, 565, 1204, 1205, 1204, 522, 522, 1341, | 174455 | /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320, |
| 173121 | /* 400 */ 81, 81, 7, 44, 135, 136, 90, 1228, 1228, 1063, | 174456 | /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204, |
| 173122 | /* 410 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 295, | 174457 | /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264, |
| 173123 | /* 420 */ 1149, 1658, 1040, 1658, 1204, 1147, 319, 567, 119, 119, | 174458 | /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132, |
| 173124 | /* 430 */ 343, 466, 331, 343, 287, 287, 120, 556, 451, 577, | 174459 | /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333, |
| 173125 | /* 440 */ 451, 1169, 1169, 1028, 319, 567, 438, 573, 210, 561, | 174460 | /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132, |
| 173126 | /* 450 */ 1339, 1451, 546, 531, 1169, 1169, 1598, 1169, 1169, 416, | 174461 | /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511, |
| 173127 | /* 460 */ 319, 567, 243, 132, 132, 132, 132, 131, 131, 130, | 174462 | /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506, |
| 173128 | /* 470 */ 130, 130, 129, 126, 450, 1028, 1028, 1030, 1031, 35, | 174463 | /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582, |
| 173129 | /* 480 */ 44, 1204, 1205, 1204, 472, 287, 287, 1328, 412, 1307, | 174464 | /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138, |
| 173130 | /* 490 */ 372, 1595, 359, 225, 454, 1204, 195, 1328, 573, 1147, | 174465 | /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, |
| 173131 | /* 500 */ 561, 1333, 1333, 274, 576, 1188, 576, 340, 46, 196, | 174466 | /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553, |
| 173132 | /* 510 */ 537, 217, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, | 174467 | /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344, |
| 173133 | /* 520 */ 1053, 133, 133, 134, 134, 134, 134, 19, 19, 19, | 174468 | /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882, |
| 173134 | /* 530 */ 19, 412, 581, 1204, 1259, 511, 1204, 319, 567, 320, | 174469 | /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066, |
| 173135 | /* 540 */ 944, 153, 425, 491, 430, 943, 1204, 488, 1341, 1450, | 174470 | /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, |
| 173136 | /* 550 */ 532, 1277, 1204, 1205, 1204, 135, 136, 90, 1228, 1228, | 174471 | /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, |
| 173137 | /* 560 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, | 174472 | /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403, |
| 173138 | /* 570 */ 575, 132, 132, 132, 132, 131, 131, 130, 130, 130, | 174473 | /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205, |
| 173139 | /* 580 */ 129, 126, 450, 287, 287, 528, 287, 287, 372, 1595, | 174474 | /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331, |
| 173140 | /* 590 */ 1204, 1205, 1204, 1204, 1205, 1204, 573, 486, 561, 573, | 174475 | /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132, |
| 173141 | /* 600 */ 889, 561, 412, 1204, 1205, 1204, 886, 40, 22, 22, | 174476 | /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423, |
| 173142 | /* 610 */ 220, 243, 525, 1449, 132, 132, 132, 132, 131, 131, | 174477 | /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562, |
| 173143 | /* 620 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, | 174478 | /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234, |
| 173144 | /* 630 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174479 | /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462, |
| 173145 | /* 640 */ 134, 412, 180, 454, 1204, 879, 255, 287, 287, 510, | 174480 | /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, |
| 173146 | /* 650 */ 507, 506, 372, 1595, 1568, 1331, 1331, 576, 889, 505, | 174481 | /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50, |
| 173147 | /* 660 */ 573, 44, 561, 559, 1207, 135, 136, 90, 1228, 1228, | 174482 | /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122, |
| 173148 | /* 670 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, | 174483 | /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212, |
| 173149 | /* 680 */ 81, 81, 422, 576, 377, 132, 132, 132, 132, 131, | 174484 | /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053, |
| 173150 | /* 690 */ 131, 130, 130, 130, 129, 126, 450, 297, 287, 287, | 174485 | /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, |
| 173151 | /* 700 */ 460, 1204, 1205, 1204, 1204, 534, 19, 19, 448, 448, | 174486 | /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, |
| 173152 | /* 710 */ 448, 573, 412, 561, 230, 436, 1187, 535, 319, 567, | 174487 | /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339, |
| 173153 | /* 720 */ 363, 432, 1207, 1435, 132, 132, 132, 132, 131, 131, | 174488 | /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353, |
| 173154 | /* 730 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, | 174489 | /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028, |
| 173155 | /* 740 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174490 | /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, |
| 173156 | /* 750 */ 134, 412, 211, 949, 1169, 1041, 1110, 1110, 494, 547, | 174491 | /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971, |
| 173157 | /* 760 */ 547, 1204, 1205, 1204, 7, 539, 1570, 1169, 376, 576, | 174492 | /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562, |
| 173158 | /* 770 */ 1169, 5, 1204, 486, 3, 135, 136, 90, 1228, 1228, | 174493 | /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411, |
| 173159 | /* 780 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, | 174494 | /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228, |
| 173160 | /* 790 */ 576, 513, 19, 19, 427, 132, 132, 132, 132, 131, | 174495 | /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, |
| 173161 | /* 800 */ 131, 130, 130, 130, 129, 126, 450, 305, 1204, 433, | 174496 | /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121, |
| 173162 | /* 810 */ 225, 1204, 385, 19, 19, 273, 290, 371, 516, 366, | 174497 | /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452, |
| 173163 | /* 820 */ 515, 260, 412, 538, 1568, 549, 1024, 362, 437, 1204, | 174498 | /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138, |
| 173164 | /* 830 */ 1205, 1204, 902, 1552, 132, 132, 132, 132, 131, 131, | 174499 | /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, |
| 173165 | /* 840 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, | 174500 | /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, |
| 173166 | /* 850 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174501 | /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, |
| 173167 | /* 860 */ 134, 412, 1435, 514, 1281, 1204, 1205, 1204, 1204, 1205, | 174502 | /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205, |
| 173168 | /* 870 */ 1204, 903, 48, 342, 1568, 1568, 1279, 1627, 1568, 911, | 174503 | /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573, |
| 173169 | /* 880 */ 576, 129, 126, 450, 110, 135, 136, 90, 1228, 1228, | 174504 | /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134, |
| 173170 | /* 890 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, | 174505 | /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, |
| 173171 | /* 900 */ 265, 576, 459, 19, 19, 132, 132, 132, 132, 131, | 174506 | /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392, |
| 173172 | /* 910 */ 131, 130, 130, 130, 129, 126, 450, 1345, 204, 576, | 174507 | /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205, |
| 173173 | /* 920 */ 459, 458, 50, 47, 19, 19, 49, 434, 1105, 573, | 174508 | /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658, |
| 173174 | /* 930 */ 497, 561, 412, 428, 108, 1224, 1569, 1554, 376, 205, | 174509 | /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066, |
| 173175 | /* 940 */ 550, 550, 81, 81, 132, 132, 132, 132, 131, 131, | 174510 | /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311, |
| 173176 | /* 950 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, | 174511 | /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066, |
| 173177 | /* 960 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174512 | /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131, |
| 173178 | /* 970 */ 134, 480, 576, 1204, 576, 1541, 412, 1435, 969, 315, | 174513 | /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516, |
| 173179 | /* 980 */ 1659, 398, 284, 497, 969, 893, 1569, 1569, 376, 376, | 174514 | /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435, |
| 173180 | /* 990 */ 1569, 461, 376, 1224, 459, 80, 80, 81, 81, 497, | 174515 | /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132, |
| 173181 | /* 1000 */ 374, 114, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, | 174516 | /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205, |
| 173182 | /* 1010 */ 133, 134, 134, 134, 134, 132, 132, 132, 132, 131, | 174517 | /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132, |
| 173183 | /* 1020 */ 131, 130, 130, 130, 129, 126, 450, 1204, 1505, 576, | 174518 | /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19, |
| 173184 | /* 1030 */ 1204, 1205, 1204, 1366, 316, 486, 281, 281, 497, 431, | 174519 | /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936, |
| 173185 | /* 1040 */ 557, 288, 288, 402, 1340, 471, 345, 298, 429, 573, | 174520 | /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19, |
| 173186 | /* 1050 */ 576, 561, 81, 81, 573, 374, 561, 971, 386, 132, | 174521 | /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315, |
| 173187 | /* 1060 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, | 174522 | /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115, |
| 173188 | /* 1070 */ 450, 231, 117, 81, 81, 287, 287, 231, 287, 287, | 174523 | /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, |
| 173189 | /* 1080 */ 576, 1511, 576, 1336, 1204, 1205, 1204, 139, 573, 556, | 174524 | /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529, |
| 173190 | /* 1090 */ 561, 573, 412, 561, 441, 456, 969, 213, 558, 1511, | 174525 | /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, |
| 173191 | /* 1100 */ 1513, 1550, 969, 143, 143, 145, 145, 1368, 314, 478, | 174526 | /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169, |
| 173192 | /* 1110 */ 444, 970, 412, 850, 851, 852, 135, 136, 90, 1228, | 174527 | /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576, |
| 173193 | /* 1120 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174528 | /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134, |
| 173194 | /* 1130 */ 134, 357, 412, 397, 1148, 304, 135, 136, 90, 1228, | 174529 | /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, |
| 173195 | /* 1140 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174530 | /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134, |
| 173196 | /* 1150 */ 134, 1575, 323, 6, 862, 7, 135, 124, 90, 1228, | 174531 | /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336, |
| 173197 | /* 1160 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, | 174532 | /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19, |
| 173198 | /* 1170 */ 134, 409, 408, 1511, 212, 132, 132, 132, 132, 131, | 174533 | /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207, |
| 173199 | /* 1180 */ 131, 130, 130, 130, 129, 126, 450, 411, 118, 1204, | 174534 | /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411, |
| 173200 | /* 1190 */ 116, 10, 352, 265, 355, 132, 132, 132, 132, 131, | 174535 | /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334, |
| 173201 | /* 1200 */ 131, 130, 130, 130, 129, 126, 450, 576, 324, 306, | 174536 | /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, |
| 173202 | /* 1210 */ 576, 306, 1250, 469, 158, 132, 132, 132, 132, 131, | 174537 | /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969, |
| 173203 | /* 1220 */ 131, 130, 130, 130, 129, 126, 450, 207, 1224, 1126, | 174538 | /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053, |
| 173204 | /* 1230 */ 65, 65, 470, 66, 66, 412, 447, 446, 882, 531, | 174539 | /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267, |
| 173205 | /* 1240 */ 335, 258, 257, 256, 1127, 1233, 1204, 1205, 1204, 327, | 174540 | /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053, |
| 173206 | /* 1250 */ 1235, 874, 159, 576, 16, 480, 1085, 1040, 1234, 1128, | 174541 | /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409, |
| 173207 | /* 1260 */ 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, | 174542 | /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, |
| 173208 | /* 1270 */ 134, 134, 134, 134, 1029, 576, 81, 81, 1028, 1040, | 174543 | /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554, |
| 173209 | /* 1280 */ 922, 576, 463, 1236, 576, 1236, 1224, 502, 107, 1435, | 174544 | /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, |
| 173210 | /* 1290 */ 923, 6, 576, 410, 1498, 882, 1029, 480, 21, 21, | 174545 | /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111, |
| 173211 | /* 1300 */ 1028, 332, 1380, 334, 53, 53, 497, 81, 81, 874, | 174546 | /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, |
| 173212 | /* 1310 */ 1028, 1028, 1030, 445, 259, 19, 19, 533, 132, 132, | 174547 | /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7, |
| 173213 | /* 1320 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, | 174548 | /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569, |
| 173214 | /* 1330 */ 551, 301, 1028, 1028, 1030, 107, 532, 545, 121, 568, | 174549 | /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984, |
| 173215 | /* 1340 */ 1188, 4, 1126, 1576, 449, 576, 462, 7, 1282, 418, | 174550 | /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228, |
| 173216 | /* 1350 */ 462, 350, 1435, 576, 518, 571, 544, 1127, 121, 568, | 174551 | /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, |
| 173217 | /* 1360 */ 442, 4, 1188, 464, 533, 1180, 1223, 9, 67, 67, | 174552 | /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228, |
| 173218 | /* 1370 */ 487, 576, 1128, 303, 410, 571, 54, 54, 451, 576, | 174553 | /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, |
| 173219 | /* 1380 */ 123, 944, 576, 417, 576, 333, 943, 1379, 576, 236, | 174554 | /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108, |
| 173220 | /* 1390 */ 565, 576, 1574, 564, 68, 68, 7, 576, 451, 362, | 174555 | /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123, |
| 173221 | /* 1400 */ 419, 182, 69, 69, 541, 70, 70, 71, 71, 540, | 174556 | /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133, |
| 173222 | /* 1410 */ 565, 72, 72, 484, 55, 55, 473, 1180, 296, 1040, | 174557 | /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576, |
| 173223 | /* 1420 */ 56, 56, 296, 493, 541, 119, 119, 410, 1573, 542, | 174558 | /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133, |
| 173224 | /* 1430 */ 569, 418, 7, 120, 1244, 451, 577, 451, 465, 1040, | 174559 | /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223, |
| 173225 | /* 1440 */ 1028, 576, 1557, 552, 476, 119, 119, 527, 259, 121, | 174560 | /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576, |
| 173226 | /* 1450 */ 568, 240, 4, 120, 576, 451, 577, 451, 576, 477, | 174561 | /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70, |
| 173227 | /* 1460 */ 1028, 576, 156, 576, 57, 57, 571, 576, 286, 229, | 174562 | /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576, |
| 173228 | /* 1470 */ 410, 336, 1028, 1028, 1030, 1031, 35, 59, 59, 219, | 174563 | /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56, |
| 173229 | /* 1480 */ 983, 60, 60, 220, 73, 73, 74, 74, 984, 451, | 174564 | /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59, |
| 173230 | /* 1490 */ 75, 75, 1028, 1028, 1030, 1031, 35, 96, 216, 291, | 174565 | /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452, |
| 173231 | /* 1500 */ 552, 565, 1188, 318, 395, 395, 394, 276, 392, 576, | 174566 | /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20, |
| 173232 | /* 1510 */ 485, 859, 474, 1311, 410, 541, 576, 417, 1530, 1144, | 174567 | /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320, |
| 173233 | /* 1520 */ 540, 399, 1188, 292, 237, 1153, 326, 38, 23, 576, | 174568 | /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576, |
| 173234 | /* 1530 */ 1040, 576, 20, 20, 325, 299, 119, 119, 164, 76, | 174569 | /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293, |
| 173235 | /* 1540 */ 76, 1529, 121, 568, 120, 4, 451, 577, 451, 203, | 174570 | /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111, |
| 173236 | /* 1550 */ 576, 1028, 141, 141, 142, 142, 576, 322, 39, 571, | 174571 | /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889, |
| 173237 | /* 1560 */ 341, 1021, 110, 264, 239, 901, 900, 423, 242, 908, | 174572 | /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62, |
| 173238 | /* 1570 */ 909, 370, 173, 77, 77, 43, 479, 1310, 264, 62, | 174573 | /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908, |
| 173239 | /* 1580 */ 62, 369, 451, 1028, 1028, 1030, 1031, 35, 1601, 1192, | 174574 | /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568, |
| 173240 | /* 1590 */ 453, 1092, 238, 291, 565, 163, 1309, 110, 395, 395, | 174575 | /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64, |
| 173241 | /* 1600 */ 394, 276, 392, 986, 987, 859, 481, 346, 264, 110, | 174576 | /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170, |
| 173242 | /* 1610 */ 1032, 489, 576, 1188, 503, 1088, 261, 261, 237, 576, | 174577 | /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576, |
| 173243 | /* 1620 */ 326, 121, 568, 1040, 4, 347, 1376, 413, 325, 119, | 174578 | /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452, |
| 173244 | /* 1630 */ 119, 948, 319, 567, 351, 78, 78, 120, 571, 451, | 174579 | /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84, |
| 173245 | /* 1640 */ 577, 451, 79, 79, 1028, 354, 356, 576, 360, 1092, | 174580 | /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111, |
| 173246 | /* 1650 */ 110, 576, 974, 942, 264, 123, 457, 358, 239, 576, | 174581 | /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576, |
| 173247 | /* 1660 */ 519, 451, 939, 1104, 123, 1104, 173, 576, 1032, 43, | 174582 | /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111, |
| 173248 | /* 1670 */ 63, 63, 1324, 565, 168, 168, 1028, 1028, 1030, 1031, | 174583 | /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188, |
| 173249 | /* 1680 */ 35, 576, 169, 169, 1308, 872, 238, 157, 1589, 576, | 174584 | /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162, |
| 173250 | /* 1690 */ 86, 86, 365, 89, 568, 375, 4, 1103, 941, 1103, | 174585 | /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348, |
| 173251 | /* 1700 */ 123, 576, 1040, 1389, 64, 64, 1188, 1434, 119, 119, | 174586 | /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149, |
| 173252 | /* 1710 */ 571, 576, 82, 82, 563, 576, 120, 165, 451, 577, | 174587 | /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872, |
| 173253 | /* 1720 */ 451, 413, 1362, 1028, 144, 144, 319, 567, 576, 1374, | 174588 | /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941, |
| 173254 | /* 1730 */ 562, 498, 279, 451, 83, 83, 1439, 576, 166, 166, | 174589 | /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359, |
| 173255 | /* 1740 */ 576, 1289, 554, 576, 1280, 565, 576, 12, 576, 1268, | 174590 | /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121, |
| 173256 | /* 1750 */ 457, 146, 146, 1267, 576, 1028, 1028, 1030, 1031, 35, | 174591 | /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452, |
| 173257 | /* 1760 */ 140, 140, 1269, 167, 167, 1609, 160, 160, 1359, 150, | 174592 | /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269, |
| 173258 | /* 1770 */ 150, 149, 149, 311, 1040, 576, 312, 147, 147, 313, | 174593 | /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416, |
| 173259 | /* 1780 */ 119, 119, 222, 235, 576, 1188, 396, 576, 120, 576, | 174594 | /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228, |
| 173260 | /* 1790 */ 451, 577, 451, 1192, 453, 1028, 508, 291, 148, 148, | 174595 | /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031, |
| 173261 | /* 1800 */ 1421, 1612, 395, 395, 394, 276, 392, 85, 85, 859, | 174596 | /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501, |
| 173262 | /* 1810 */ 87, 87, 84, 84, 553, 576, 294, 576, 1426, 338, | 174597 | /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612, |
| 173263 | /* 1820 */ 339, 1425, 237, 300, 326, 1416, 1409, 1028, 1028, 1030, | 174598 | /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547, |
| 173264 | /* 1830 */ 1031, 35, 325, 344, 403, 483, 226, 1307, 52, 52, | 174599 | /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235, |
| 173265 | /* 1840 */ 58, 58, 368, 1371, 1502, 566, 1501, 121, 568, 221, | 174600 | /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193, |
| 173266 | /* 1850 */ 4, 208, 268, 209, 390, 1244, 1549, 1188, 1372, 1370, | 174601 | /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402, |
| 173267 | /* 1860 */ 1369, 1547, 239, 184, 571, 233, 421, 1241, 95, 218, | 174602 | /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102, |
| 173268 | /* 1870 */ 173, 1507, 193, 43, 91, 94, 178, 186, 467, 188, | 174603 | /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254, |
| 173269 | /* 1880 */ 468, 1422, 13, 189, 190, 191, 501, 451, 245, 108, | 174604 | /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326, |
| 173270 | /* 1890 */ 238, 401, 1428, 1427, 1430, 475, 404, 1496, 197, 565, | 174605 | /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441, |
| 173271 | /* 1900 */ 14, 490, 249, 101, 1518, 496, 349, 280, 251, 201, | 174606 | /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121, |
| 173272 | /* 1910 */ 353, 499, 252, 406, 1270, 253, 517, 1327, 1326, 435, | 174607 | /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452, |
| 173273 | /* 1920 */ 1325, 1318, 103, 893, 1296, 413, 227, 407, 1040, 1626, | 174608 | /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90, |
| 173274 | /* 1930 */ 319, 567, 1625, 1297, 119, 119, 439, 367, 1317, 1295, | 174609 | /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216, |
| 173275 | /* 1940 */ 1624, 526, 120, 440, 451, 577, 451, 1594, 309, 1028, | 174610 | /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389, |
| 173276 | /* 1950 */ 310, 373, 266, 267, 457, 1580, 1579, 443, 138, 1394, | 174611 | /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031, |
| 173277 | /* 1960 */ 552, 1393, 11, 1483, 384, 115, 317, 1350, 109, 536, | 174612 | /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172, |
| 173278 | /* 1970 */ 42, 579, 382, 214, 1349, 388, 1198, 389, 275, 277, | 174613 | /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217, |
| 173279 | /* 1980 */ 278, 1028, 1028, 1030, 1031, 35, 580, 1265, 414, 1260, | 174614 | /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154, |
| 173280 | /* 1990 */ 170, 415, 183, 1534, 1535, 1533, 171, 154, 307, 1532, | 174615 | /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116, |
| 173281 | /* 2000 */ 846, 223, 224, 88, 452, 215, 172, 321, 234, 1102, | 174616 | /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100, |
| 173282 | /* 2010 */ 152, 1188, 1100, 329, 185, 174, 1223, 925, 187, 241, | 174617 | /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24, |
| 173283 | /* 2020 */ 337, 244, 1116, 192, 175, 176, 424, 426, 97, 194, | 174618 | /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452, |
| 173284 | /* 2030 */ 98, 99, 100, 177, 1119, 1115, 246, 247, 161, 24, | 174619 | /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396, |
| 173285 | /* 2040 */ 248, 348, 1238, 264, 1108, 250, 495, 199, 198, 15, | 174620 | /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, |
| 173286 | /* 2050 */ 861, 500, 369, 254, 504, 509, 512, 200, 102, 25, | 174621 | /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, |
| 173287 | /* 2060 */ 179, 361, 26, 364, 104, 891, 308, 162, 105, 904, | 174622 | /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, |
| 173288 | /* 2070 */ 520, 106, 1185, 1069, 1155, 17, 228, 27, 1154, 283, | 174623 | /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, |
| 173289 | /* 2080 */ 285, 263, 978, 202, 972, 123, 28, 1175, 29, 30, | 174624 | /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, |
| 173290 | /* 2090 */ 1179, 1171, 31, 1173, 1160, 41, 32, 206, 548, 33, | 174625 | /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171, |
| 173291 | /* 2100 */ 110, 1178, 1083, 8, 112, 1070, 113, 1068, 1072, 34, | 174626 | /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173, |
| 173292 | /* 2110 */ 1073, 560, 1125, 269, 1124, 270, 36, 18, 1194, 1033, | 174627 | /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33, |
| 173293 | /* 2120 */ 873, 151, 122, 37, 393, 271, 272, 572, 181, 1193, | 174628 | /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114, |
| 173294 | /* 2130 */ 1256, 1256, 1256, 935, 1256, 1256, 1256, 1256, 1256, 1256, | 174629 | /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194, |
| 173295 | /* 2140 */ 1256, 1617, | 174630 | /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572, |
| 174631 | /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256, | ||
| 174632 | /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, | ||
| 174633 | /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, | ||
| 174634 | /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, | ||
| 174635 | /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, | ||
| 174636 | /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, | ||
| 173296 | }; | 174637 | }; |
| 173297 | static const YYCODETYPE yy_lookahead[] = { | 174638 | static const YYCODETYPE yy_lookahead[] = { |
| 173298 | /* 0 */ 194, 276, 277, 278, 216, 194, 194, 217, 194, 194, | 174639 | /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240, |
| 173299 | /* 10 */ 194, 194, 224, 194, 194, 276, 277, 278, 204, 19, | 174640 | /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19, |
| 173300 | /* 20 */ 206, 202, 297, 217, 218, 205, 207, 217, 205, 217, | 174641 | /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217, |
| 173301 | /* 30 */ 218, 31, 217, 218, 217, 218, 29, 217, 218, 39, | 174642 | /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39, |
| 173302 | /* 40 */ 33, 217, 220, 43, 44, 45, 46, 47, 48, 49, | 174643 | /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49, |
| 173303 | /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 312, 19, | 174644 | /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, |
| 173304 | /* 60 */ 240, 241, 316, 240, 241, 194, 46, 47, 48, 49, | 174645 | /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276, |
| 173305 | /* 70 */ 22, 254, 65, 253, 254, 255, 253, 194, 255, 194, | 174646 | /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217, |
| 173306 | /* 80 */ 263, 258, 259, 43, 44, 45, 46, 47, 48, 49, | 174647 | /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49, |
| 173307 | /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 276, 277, | 174648 | /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270, |
| 173308 | /* 100 */ 278, 285, 102, 103, 104, 105, 106, 107, 108, 109, | 174649 | /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109, |
| 173309 | /* 110 */ 110, 111, 112, 113, 59, 186, 187, 188, 189, 190, | 174650 | /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50, |
| 173310 | /* 120 */ 191, 310, 239, 317, 318, 196, 86, 198, 88, 317, | 174651 | /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89, |
| 173311 | /* 130 */ 19, 319, 317, 318, 205, 264, 25, 211, 212, 213, | 174652 | /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205, |
| 173312 | /* 140 */ 205, 121, 102, 103, 104, 105, 106, 107, 108, 109, | 174653 | /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109, |
| 173313 | /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, | 174654 | /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47, |
| 173314 | /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 240, | 174655 | /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 173315 | /* 170 */ 241, 116, 117, 118, 119, 240, 241, 122, 123, 124, | 174656 | /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311, |
| 173316 | /* 180 */ 69, 298, 253, 194, 255, 106, 107, 132, 253, 141, | 174657 | /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255, |
| 173317 | /* 190 */ 255, 54, 55, 56, 57, 58, 207, 268, 102, 103, | 174658 | /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88, |
| 173318 | /* 200 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, | 174659 | /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110, |
| 173319 | /* 210 */ 214, 128, 129, 102, 103, 104, 105, 106, 107, 108, | 174660 | /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107, |
| 173320 | /* 220 */ 109, 110, 111, 112, 113, 134, 25, 136, 137, 300, | 174661 | /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118, |
| 173321 | /* 230 */ 165, 166, 153, 19, 155, 54, 55, 56, 57, 102, | 174662 | /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277, |
| 173322 | /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, | 174663 | /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111, |
| 173323 | /* 250 */ 113, 108, 109, 110, 111, 112, 113, 43, 44, 45, | 174664 | /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43, |
| 173324 | /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, | 174665 | /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53, |
| 173325 | /* 270 */ 56, 57, 276, 277, 278, 113, 194, 19, 22, 23, | 174666 | /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129, |
| 173326 | /* 280 */ 194, 67, 24, 102, 103, 104, 105, 106, 107, 108, | 174667 | /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106, |
| 173327 | /* 290 */ 109, 110, 111, 112, 113, 220, 250, 59, 252, 217, | 174668 | /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132, |
| 173328 | /* 300 */ 218, 43, 44, 45, 46, 47, 48, 49, 50, 51, | 174669 | /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111, |
| 173329 | /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, | 174670 | /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103, |
| 173330 | /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 106, 107, | 174671 | /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, |
| 173331 | /* 330 */ 108, 109, 110, 111, 112, 113, 254, 59, 205, 138, | 174672 | /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19, |
| 173332 | /* 340 */ 139, 19, 20, 194, 22, 263, 22, 23, 231, 25, | 174673 | /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113, |
| 173333 | /* 350 */ 72, 276, 277, 278, 116, 117, 118, 101, 36, 76, | 174674 | /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19, |
| 173334 | /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, | 174675 | /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49, |
| 173335 | /* 370 */ 112, 113, 89, 240, 241, 92, 73, 194, 194, 73, | 174676 | /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217, |
| 173336 | /* 380 */ 19, 59, 188, 189, 190, 191, 253, 81, 255, 151, | 174677 | /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49, |
| 173337 | /* 390 */ 196, 25, 198, 71, 116, 117, 118, 311, 312, 205, | 174678 | /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139, |
| 173338 | /* 400 */ 217, 218, 316, 81, 43, 44, 45, 46, 47, 48, | 174679 | /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117, |
| 173339 | /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 270, | 174680 | /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258, |
| 173340 | /* 420 */ 22, 23, 100, 25, 59, 101, 138, 139, 106, 107, | 174681 | /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109, |
| 173341 | /* 430 */ 127, 128, 129, 127, 240, 241, 114, 254, 116, 117, | 174682 | /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237, |
| 173342 | /* 440 */ 118, 76, 76, 121, 138, 139, 263, 253, 264, 255, | 174683 | /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109, |
| 173343 | /* 450 */ 205, 275, 87, 19, 89, 89, 194, 92, 92, 199, | 174684 | /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123, |
| 173344 | /* 460 */ 138, 139, 268, 102, 103, 104, 105, 106, 107, 108, | 174685 | /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133, |
| 173345 | /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, | 174686 | /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317, |
| 173346 | /* 480 */ 81, 116, 117, 118, 129, 240, 241, 224, 19, 226, | 174687 | /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44, |
| 173347 | /* 490 */ 314, 315, 23, 25, 300, 59, 22, 234, 253, 101, | 174688 | /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, |
| 173348 | /* 500 */ 255, 236, 237, 26, 194, 183, 194, 152, 72, 22, | 174689 | /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146, |
| 173349 | /* 510 */ 145, 150, 43, 44, 45, 46, 47, 48, 49, 50, | 174690 | /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128, |
| 173350 | /* 520 */ 51, 52, 53, 54, 55, 56, 57, 217, 218, 217, | 174691 | /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60, |
| 173351 | /* 530 */ 218, 19, 189, 59, 191, 23, 59, 138, 139, 196, | 174692 | /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50, |
| 173352 | /* 540 */ 135, 198, 232, 283, 232, 140, 59, 287, 205, 275, | 174693 | /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, |
| 173353 | /* 550 */ 116, 205, 116, 117, 118, 43, 44, 45, 46, 47, | 174694 | /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, |
| 173354 | /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 174695 | /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205, |
| 173355 | /* 570 */ 194, 102, 103, 104, 105, 106, 107, 108, 109, 110, | 174696 | /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118, |
| 173356 | /* 580 */ 111, 112, 113, 240, 241, 194, 240, 241, 314, 315, | 174697 | /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237, |
| 173357 | /* 590 */ 116, 117, 118, 116, 117, 118, 253, 194, 255, 253, | 174698 | /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110, |
| 173358 | /* 600 */ 59, 255, 19, 116, 117, 118, 23, 22, 217, 218, | 174699 | /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194, |
| 173359 | /* 610 */ 142, 268, 205, 275, 102, 103, 104, 105, 106, 107, | 174700 | /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255, |
| 173360 | /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 174701 | /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278, |
| 173361 | /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174702 | /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271, |
| 173362 | /* 640 */ 57, 19, 194, 300, 59, 23, 119, 240, 241, 122, | 174703 | /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 173363 | /* 650 */ 123, 124, 314, 315, 194, 236, 237, 194, 117, 132, | 174704 | /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242, |
| 173364 | /* 660 */ 253, 81, 255, 205, 59, 43, 44, 45, 46, 47, | 174705 | /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115, |
| 173365 | /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 174706 | /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264, |
| 173366 | /* 680 */ 217, 218, 194, 194, 194, 102, 103, 104, 105, 106, | 174707 | /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52, |
| 173367 | /* 690 */ 107, 108, 109, 110, 111, 112, 113, 294, 240, 241, | 174708 | /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, |
| 173368 | /* 700 */ 120, 116, 117, 118, 59, 194, 217, 218, 211, 212, | 174709 | /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, |
| 173369 | /* 710 */ 213, 253, 19, 255, 194, 19, 23, 254, 138, 139, | 174710 | /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205, |
| 173370 | /* 720 */ 24, 232, 117, 194, 102, 103, 104, 105, 106, 107, | 174711 | /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78, |
| 173371 | /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 174712 | /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122, |
| 173372 | /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174713 | /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 173373 | /* 750 */ 57, 19, 264, 108, 76, 23, 127, 128, 129, 311, | 174714 | /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144, |
| 173374 | /* 760 */ 312, 116, 117, 118, 316, 87, 306, 89, 308, 194, | 174715 | /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255, |
| 173375 | /* 770 */ 92, 22, 59, 194, 22, 43, 44, 45, 46, 47, | 174716 | /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256, |
| 173376 | /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 174717 | /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48, |
| 173377 | /* 790 */ 194, 95, 217, 218, 265, 102, 103, 104, 105, 106, | 174718 | /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, |
| 173378 | /* 800 */ 107, 108, 109, 110, 111, 112, 113, 232, 59, 113, | 174719 | /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107, |
| 173379 | /* 810 */ 25, 59, 194, 217, 218, 119, 120, 121, 122, 123, | 174720 | /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117, |
| 173380 | /* 820 */ 124, 125, 19, 145, 194, 194, 23, 131, 232, 116, | 174721 | /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44, |
| 173381 | /* 830 */ 117, 118, 35, 194, 102, 103, 104, 105, 106, 107, | 174722 | /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54, |
| 173382 | /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 174723 | /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, |
| 173383 | /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174724 | /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, |
| 173384 | /* 860 */ 57, 19, 194, 66, 194, 116, 117, 118, 116, 117, | 174725 | /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118, |
| 173385 | /* 870 */ 118, 74, 242, 294, 194, 194, 206, 23, 194, 25, | 174726 | /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253, |
| 173386 | /* 880 */ 194, 111, 112, 113, 25, 43, 44, 45, 46, 47, | 174727 | /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104, |
| 173387 | /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 174728 | /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, |
| 173388 | /* 900 */ 24, 194, 194, 217, 218, 102, 103, 104, 105, 106, | 174729 | /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202, |
| 173389 | /* 910 */ 107, 108, 109, 110, 111, 112, 113, 241, 232, 194, | 174730 | /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118, |
| 173390 | /* 920 */ 212, 213, 242, 242, 217, 218, 242, 130, 11, 253, | 174731 | /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25, |
| 173391 | /* 930 */ 194, 255, 19, 265, 149, 59, 306, 194, 308, 232, | 174732 | /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50, |
| 173392 | /* 940 */ 309, 310, 217, 218, 102, 103, 104, 105, 106, 107, | 174733 | /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227, |
| 173393 | /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 174734 | /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50, |
| 173394 | /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174735 | /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112, |
| 173395 | /* 970 */ 57, 194, 194, 59, 194, 239, 19, 194, 25, 254, | 174736 | /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125, |
| 173396 | /* 980 */ 303, 304, 23, 194, 25, 126, 306, 306, 308, 308, | 174737 | /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194, |
| 173397 | /* 990 */ 306, 271, 308, 117, 286, 217, 218, 217, 218, 194, | 174738 | /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110, |
| 173398 | /* 1000 */ 194, 159, 45, 46, 47, 48, 49, 50, 51, 52, | 174739 | /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118, |
| 173399 | /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, | 174740 | /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110, |
| 173400 | /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 59, 239, 194, | 174741 | /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218, |
| 173401 | /* 1030 */ 116, 117, 118, 260, 254, 194, 240, 241, 194, 233, | 174742 | /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137, |
| 173402 | /* 1040 */ 205, 240, 241, 205, 239, 128, 129, 270, 265, 253, | 174743 | /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218, |
| 173403 | /* 1050 */ 194, 255, 217, 218, 253, 194, 255, 143, 280, 102, | 174744 | /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262, |
| 173404 | /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, | 174745 | /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160, |
| 173405 | /* 1070 */ 113, 118, 159, 217, 218, 240, 241, 118, 240, 241, | 174746 | /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 173406 | /* 1080 */ 194, 194, 194, 239, 116, 117, 118, 22, 253, 254, | 174747 | /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194, |
| 173407 | /* 1090 */ 255, 253, 19, 255, 233, 194, 143, 24, 263, 212, | 174748 | /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 173408 | /* 1100 */ 213, 194, 143, 217, 218, 217, 218, 261, 262, 271, | 174749 | /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77, |
| 173409 | /* 1110 */ 254, 143, 19, 7, 8, 9, 43, 44, 45, 46, | 174750 | /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194, |
| 173410 | /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174751 | /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106, |
| 173411 | /* 1130 */ 57, 16, 19, 22, 23, 294, 43, 44, 45, 46, | 174752 | /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194, |
| 173412 | /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174753 | /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106, |
| 173413 | /* 1150 */ 57, 312, 194, 214, 21, 316, 43, 44, 45, 46, | 174754 | /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239, |
| 173414 | /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 174755 | /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218, |
| 173415 | /* 1170 */ 57, 106, 107, 286, 194, 102, 103, 104, 105, 106, | 174756 | /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232, |
| 173416 | /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 207, 158, 59, | 174757 | /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256, |
| 173417 | /* 1190 */ 160, 22, 77, 24, 79, 102, 103, 104, 105, 106, | 174758 | /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162, |
| 173418 | /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 194, 194, 229, | 174759 | /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, |
| 173419 | /* 1210 */ 194, 231, 101, 80, 22, 102, 103, 104, 105, 106, | 174760 | /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25, |
| 173420 | /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 288, 59, 12, | 174761 | /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52, |
| 173421 | /* 1230 */ 217, 218, 293, 217, 218, 19, 106, 107, 59, 19, | 174762 | /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24, |
| 173422 | /* 1240 */ 16, 127, 128, 129, 27, 115, 116, 117, 118, 194, | 174763 | /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52, |
| 173423 | /* 1250 */ 120, 59, 22, 194, 24, 194, 123, 100, 128, 42, | 174764 | /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108, |
| 173424 | /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, | 174765 | /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 173425 | /* 1270 */ 54, 55, 56, 57, 117, 194, 217, 218, 121, 100, | 174766 | /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194, |
| 173426 | /* 1280 */ 63, 194, 245, 153, 194, 155, 117, 19, 115, 194, | 174767 | /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 173427 | /* 1290 */ 73, 214, 194, 256, 161, 116, 117, 194, 217, 218, | 174768 | /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25, |
| 173428 | /* 1300 */ 121, 77, 194, 79, 217, 218, 194, 217, 218, 117, | 174769 | /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 173429 | /* 1310 */ 153, 154, 155, 254, 46, 217, 218, 144, 102, 103, | 174770 | /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316, |
| 173430 | /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, | 174771 | /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209, |
| 173431 | /* 1330 */ 232, 270, 153, 154, 155, 115, 116, 66, 19, 20, | 174772 | /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39, |
| 173432 | /* 1340 */ 183, 22, 12, 312, 254, 194, 262, 316, 209, 210, | 174773 | /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48, |
| 173433 | /* 1350 */ 266, 239, 194, 194, 108, 36, 85, 27, 19, 20, | 174774 | /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, |
| 173434 | /* 1360 */ 265, 22, 183, 245, 144, 94, 25, 48, 217, 218, | 174775 | /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48, |
| 173435 | /* 1370 */ 293, 194, 42, 270, 256, 36, 217, 218, 59, 194, | 174776 | /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, |
| 173436 | /* 1380 */ 25, 135, 194, 115, 194, 161, 140, 194, 194, 15, | 174777 | /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116, |
| 173437 | /* 1390 */ 71, 194, 312, 63, 217, 218, 316, 194, 59, 131, | 174778 | /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19, |
| 173438 | /* 1400 */ 301, 302, 217, 218, 85, 217, 218, 217, 218, 90, | 174779 | /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108, |
| 173439 | /* 1410 */ 71, 217, 218, 19, 217, 218, 245, 146, 262, 100, | 174780 | /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194, |
| 173440 | /* 1420 */ 217, 218, 266, 265, 85, 106, 107, 256, 312, 90, | 174781 | /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108, |
| 173441 | /* 1430 */ 209, 210, 316, 114, 60, 116, 117, 118, 194, 100, | 174782 | /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25, |
| 173442 | /* 1440 */ 121, 194, 194, 145, 115, 106, 107, 19, 46, 19, | 174783 | /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194, |
| 173443 | /* 1450 */ 20, 24, 22, 114, 194, 116, 117, 118, 194, 245, | 174784 | /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217, |
| 173444 | /* 1460 */ 121, 194, 164, 194, 217, 218, 36, 194, 258, 259, | 174785 | /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194, |
| 173445 | /* 1470 */ 256, 194, 153, 154, 155, 156, 157, 217, 218, 150, | 174786 | /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218, |
| 173446 | /* 1480 */ 31, 217, 218, 142, 217, 218, 217, 218, 39, 59, | 174787 | /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217, |
| 173447 | /* 1490 */ 217, 218, 153, 154, 155, 156, 157, 149, 150, 5, | 174788 | /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119, |
| 173448 | /* 1500 */ 145, 71, 183, 245, 10, 11, 12, 13, 14, 194, | 174789 | /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217, |
| 173449 | /* 1510 */ 116, 17, 129, 227, 256, 85, 194, 115, 194, 23, | 174790 | /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139, |
| 173450 | /* 1520 */ 90, 25, 183, 99, 30, 97, 32, 22, 22, 194, | 174791 | /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194, |
| 173451 | /* 1530 */ 100, 194, 217, 218, 40, 152, 106, 107, 23, 217, | 174792 | /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100, |
| 173452 | /* 1540 */ 218, 194, 19, 20, 114, 22, 116, 117, 118, 257, | 174793 | /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25, |
| 173453 | /* 1550 */ 194, 121, 217, 218, 217, 218, 194, 133, 53, 36, | 174794 | /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60, |
| 173454 | /* 1560 */ 23, 23, 25, 25, 70, 120, 121, 61, 141, 7, | 174795 | /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217, |
| 173455 | /* 1570 */ 8, 121, 78, 217, 218, 81, 23, 227, 25, 217, | 174796 | /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7, |
| 173456 | /* 1580 */ 218, 131, 59, 153, 154, 155, 156, 157, 0, 1, | 174797 | /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20, |
| 173457 | /* 1590 */ 2, 59, 98, 5, 71, 23, 227, 25, 10, 11, | 174798 | /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218, |
| 173458 | /* 1600 */ 12, 13, 14, 83, 84, 17, 23, 23, 25, 25, | 174799 | /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218, |
| 173459 | /* 1610 */ 59, 194, 194, 183, 23, 23, 25, 25, 30, 194, | 174800 | /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194, |
| 173460 | /* 1620 */ 32, 19, 20, 100, 22, 194, 194, 133, 40, 106, | 174801 | /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60, |
| 173461 | /* 1630 */ 107, 108, 138, 139, 194, 217, 218, 114, 36, 116, | 174802 | /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217, |
| 173462 | /* 1640 */ 117, 118, 217, 218, 121, 194, 194, 194, 23, 117, | 174803 | /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25, |
| 173463 | /* 1650 */ 25, 194, 23, 23, 25, 25, 162, 194, 70, 194, | 174804 | /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194, |
| 173464 | /* 1660 */ 145, 59, 23, 153, 25, 155, 78, 194, 117, 81, | 174805 | /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25, |
| 173465 | /* 1670 */ 217, 218, 194, 71, 217, 218, 153, 154, 155, 156, | 174806 | /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183, |
| 173466 | /* 1680 */ 157, 194, 217, 218, 194, 23, 98, 25, 321, 194, | 174807 | /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217, |
| 173467 | /* 1690 */ 217, 218, 194, 19, 20, 194, 22, 153, 23, 155, | 174808 | /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194, |
| 173468 | /* 1700 */ 25, 194, 100, 194, 217, 218, 183, 194, 106, 107, | 174809 | /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218, |
| 173469 | /* 1710 */ 36, 194, 217, 218, 237, 194, 114, 243, 116, 117, | 174810 | /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23, |
| 173470 | /* 1720 */ 118, 133, 194, 121, 217, 218, 138, 139, 194, 194, | 174811 | /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23, |
| 173471 | /* 1730 */ 194, 290, 289, 59, 217, 218, 194, 194, 217, 218, | 174812 | /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194, |
| 173472 | /* 1740 */ 194, 194, 140, 194, 194, 71, 194, 244, 194, 194, | 174813 | /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107, |
| 173473 | /* 1750 */ 162, 217, 218, 194, 194, 153, 154, 155, 156, 157, | 174814 | /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117, |
| 173474 | /* 1760 */ 217, 218, 194, 217, 218, 194, 217, 218, 257, 217, | 174815 | /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194, |
| 173475 | /* 1770 */ 218, 217, 218, 257, 100, 194, 257, 217, 218, 257, | 174816 | /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269, |
| 173476 | /* 1780 */ 106, 107, 215, 299, 194, 183, 192, 194, 114, 194, | 174817 | /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230, |
| 173477 | /* 1790 */ 116, 117, 118, 1, 2, 121, 221, 5, 217, 218, | 174818 | /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157, |
| 173478 | /* 1800 */ 273, 197, 10, 11, 12, 13, 14, 217, 218, 17, | 174819 | /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220, |
| 173479 | /* 1810 */ 217, 218, 217, 218, 140, 194, 246, 194, 273, 295, | 174820 | /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197, |
| 173480 | /* 1820 */ 247, 273, 30, 247, 32, 269, 269, 153, 154, 155, | 174821 | /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201, |
| 173481 | /* 1830 */ 156, 157, 40, 246, 273, 295, 230, 226, 217, 218, | 174822 | /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299, |
| 173482 | /* 1840 */ 217, 218, 220, 261, 220, 282, 220, 19, 20, 244, | 174823 | /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238, |
| 173483 | /* 1850 */ 22, 250, 141, 250, 246, 60, 201, 183, 261, 261, | 174824 | /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247, |
| 173484 | /* 1860 */ 261, 201, 70, 299, 36, 299, 201, 38, 151, 150, | 174825 | /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159, |
| 173485 | /* 1870 */ 78, 285, 22, 81, 296, 296, 43, 235, 18, 238, | 174826 | /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200, |
| 173486 | /* 1880 */ 201, 274, 272, 238, 238, 238, 18, 59, 200, 149, | 174827 | /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219, |
| 173487 | /* 1890 */ 98, 247, 274, 274, 235, 247, 247, 247, 235, 71, | 174828 | /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114, |
| 173488 | /* 1900 */ 272, 201, 200, 158, 292, 62, 291, 201, 200, 22, | 174829 | /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107, |
| 173489 | /* 1910 */ 201, 222, 200, 222, 201, 200, 115, 219, 219, 64, | 174830 | /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117, |
| 173490 | /* 1920 */ 219, 228, 22, 126, 221, 133, 165, 222, 100, 225, | 174831 | /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19, |
| 173491 | /* 1930 */ 138, 139, 225, 219, 106, 107, 24, 219, 228, 219, | 174832 | /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249, |
| 173492 | /* 1940 */ 219, 307, 114, 113, 116, 117, 118, 315, 284, 121, | 174833 | /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248, |
| 173493 | /* 1950 */ 284, 222, 201, 91, 162, 320, 320, 82, 148, 267, | 174834 | /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157, |
| 173494 | /* 1960 */ 145, 267, 22, 279, 201, 158, 281, 251, 147, 146, | 174835 | /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208, |
| 173495 | /* 1970 */ 25, 203, 250, 249, 251, 248, 13, 247, 195, 195, | 174836 | /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22, |
| 173496 | /* 1980 */ 6, 153, 154, 155, 156, 157, 193, 193, 305, 193, | 174837 | /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16, |
| 173497 | /* 1990 */ 208, 305, 302, 214, 214, 214, 208, 223, 223, 214, | 174838 | /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1, |
| 173498 | /* 2000 */ 4, 215, 215, 214, 3, 22, 208, 163, 15, 23, | 174839 | /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54, |
| 173499 | /* 2010 */ 16, 183, 23, 139, 151, 130, 25, 20, 142, 24, | 174840 | /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22, |
| 173500 | /* 2020 */ 16, 144, 1, 142, 130, 130, 61, 37, 53, 151, | 174841 | /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119, |
| 173501 | /* 2030 */ 53, 53, 53, 130, 116, 1, 34, 141, 5, 22, | 174842 | /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10, |
| 173502 | /* 2040 */ 115, 161, 75, 25, 68, 141, 41, 115, 68, 24, | 174843 | /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, |
| 173503 | /* 2050 */ 20, 19, 131, 125, 67, 67, 96, 22, 22, 22, | 174844 | /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, |
| 173504 | /* 2060 */ 37, 23, 22, 24, 22, 59, 67, 23, 149, 28, | 174845 | /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, |
| 173505 | /* 2070 */ 22, 25, 23, 23, 23, 22, 141, 34, 97, 23, | 174846 | /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, |
| 173506 | /* 2080 */ 23, 34, 116, 22, 143, 25, 34, 75, 34, 34, | 174847 | /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, |
| 173507 | /* 2090 */ 75, 88, 34, 86, 23, 22, 34, 25, 24, 34, | 174848 | /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89, |
| 173508 | /* 2100 */ 25, 93, 23, 44, 142, 23, 142, 23, 23, 22, | 174849 | /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87, |
| 173509 | /* 2110 */ 11, 25, 23, 25, 23, 22, 22, 22, 1, 23, | 174850 | /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34, |
| 173510 | /* 2120 */ 23, 23, 22, 22, 15, 141, 141, 25, 25, 1, | 174851 | /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143, |
| 173511 | /* 2130 */ 322, 322, 322, 135, 322, 322, 322, 322, 322, 322, | 174852 | /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1, |
| 173512 | /* 2140 */ 322, 141, 322, 322, 322, 322, 322, 322, 322, 322, | 174853 | /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25, |
| 173513 | /* 2150 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174854 | /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322, |
| 173514 | /* 2160 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174855 | /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140, |
| 173515 | /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174856 | /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322, |
| 173516 | /* 2180 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174857 | /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322, |
| 173517 | /* 2190 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174858 | /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322, |
| 173518 | /* 2200 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174859 | /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322, |
| 173519 | /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174860 | /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173520 | /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174861 | /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173521 | /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174862 | /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| @@ -173527,118 +174868,125 @@ static const YYCODETYPE yy_lookahead[] = { | |||
| 173527 | /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174868 | /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173528 | /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174869 | /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173529 | /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | 174870 | /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173530 | /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, | 174871 | /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 174872 | /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | ||
| 174873 | /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, | ||
| 174874 | /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, | ||
| 174875 | /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, | ||
| 174876 | /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, | ||
| 174877 | /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, | ||
| 174878 | /* 2390 */ 186, 186, 186, | ||
| 173531 | }; | 174879 | }; |
| 173532 | #define YY_SHIFT_COUNT (582) | 174880 | #define YY_SHIFT_COUNT (582) |
| 173533 | #define YY_SHIFT_MIN (0) | 174881 | #define YY_SHIFT_MIN (0) |
| 173534 | #define YY_SHIFT_MAX (2128) | 174882 | #define YY_SHIFT_MAX (2152) |
| 173535 | static const unsigned short int yy_shift_ofst[] = { | 174883 | static const unsigned short int yy_shift_ofst[] = { |
| 173536 | /* 0 */ 1792, 1588, 1494, 322, 322, 399, 306, 1319, 1339, 1430, | 174884 | /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642, |
| 173537 | /* 10 */ 1828, 1828, 1828, 580, 399, 399, 399, 399, 399, 0, | 174885 | /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0, |
| 173538 | /* 20 */ 0, 214, 1093, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174886 | /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, |
| 173539 | /* 30 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1130, 1130, | 174887 | /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406, |
| 173540 | /* 40 */ 365, 365, 55, 278, 436, 713, 713, 201, 201, 201, | 174888 | /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260, |
| 173541 | /* 50 */ 201, 40, 111, 258, 361, 469, 512, 583, 622, 693, | 174889 | /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741, |
| 173542 | /* 60 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, | 174890 | /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, |
| 173543 | /* 70 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, | 174891 | /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, |
| 173544 | /* 80 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1523, 1602, | 174892 | /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, |
| 173545 | /* 90 */ 1674, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174893 | /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, |
| 173546 | /* 100 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174894 | /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, |
| 173547 | /* 110 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174895 | /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, |
| 173548 | /* 120 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174896 | /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, |
| 173549 | /* 130 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, | 174897 | /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, |
| 173550 | /* 140 */ 137, 181, 181, 181, 181, 181, 181, 181, 96, 222, | 174898 | /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, |
| 173551 | /* 150 */ 143, 477, 713, 1133, 1268, 713, 713, 79, 79, 713, | 174899 | /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880, |
| 173552 | /* 160 */ 770, 83, 65, 65, 65, 288, 162, 162, 2142, 2142, | 174900 | /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113, |
| 173553 | /* 170 */ 696, 696, 696, 238, 474, 474, 474, 474, 1217, 1217, | 174901 | /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765, |
| 173554 | /* 180 */ 678, 477, 324, 398, 713, 713, 713, 713, 713, 713, | 174902 | /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598, |
| 173555 | /* 190 */ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, | 174903 | /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, |
| 173556 | /* 200 */ 713, 713, 713, 1220, 366, 366, 713, 917, 283, 283, | 174904 | /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147, |
| 173557 | /* 210 */ 434, 434, 605, 605, 1298, 2142, 2142, 2142, 2142, 2142, | 174905 | /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207, |
| 173558 | /* 220 */ 2142, 2142, 1179, 1157, 1157, 487, 527, 585, 645, 749, | 174906 | /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461, |
| 173559 | /* 230 */ 914, 968, 752, 713, 713, 713, 713, 713, 713, 713, | 174907 | /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598, |
| 173560 | /* 240 */ 713, 713, 713, 303, 713, 713, 713, 713, 713, 713, | 174908 | /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598, |
| 173561 | /* 250 */ 713, 713, 713, 713, 713, 713, 797, 797, 797, 713, | 174909 | /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105, |
| 173562 | /* 260 */ 713, 713, 959, 713, 713, 713, 1169, 1271, 713, 713, | 174910 | /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249, |
| 173563 | /* 270 */ 1330, 713, 713, 713, 713, 713, 713, 713, 713, 629, | 174911 | /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598, |
| 173564 | /* 280 */ 7, 91, 876, 876, 876, 876, 953, 91, 91, 1246, | 174912 | /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902, |
| 173565 | /* 290 */ 1065, 1106, 1374, 1329, 1348, 468, 1348, 1394, 785, 1329, | 174913 | /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162, |
| 173566 | /* 300 */ 1329, 785, 1329, 468, 1394, 859, 854, 1402, 1449, 1449, | 174914 | /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300, |
| 173567 | /* 310 */ 1449, 1173, 1173, 1173, 1173, 1355, 1355, 1030, 1341, 405, | 174915 | /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414, |
| 173568 | /* 320 */ 1230, 1795, 1795, 1711, 1711, 1829, 1829, 1711, 1717, 1719, | 174916 | /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683, |
| 173569 | /* 330 */ 1850, 1833, 1860, 1860, 1860, 1860, 1711, 1868, 1740, 1719, | 174917 | /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707, |
| 173570 | /* 340 */ 1719, 1740, 1850, 1833, 1740, 1833, 1740, 1711, 1868, 1745, | 174918 | /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836, |
| 173571 | /* 350 */ 1843, 1711, 1868, 1887, 1711, 1868, 1711, 1868, 1887, 1801, | 174919 | /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854, |
| 173572 | /* 360 */ 1801, 1801, 1855, 1900, 1900, 1887, 1801, 1797, 1801, 1855, | 174920 | /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769, |
| 173573 | /* 370 */ 1801, 1801, 1761, 1912, 1830, 1830, 1887, 1711, 1862, 1862, | 174921 | /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823, |
| 173574 | /* 380 */ 1875, 1875, 1810, 1815, 1940, 1711, 1807, 1810, 1821, 1823, | 174922 | /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789, |
| 173575 | /* 390 */ 1740, 1945, 1963, 1963, 1974, 1974, 1974, 2142, 2142, 2142, | 174923 | /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207, |
| 173576 | /* 400 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, | 174924 | /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, |
| 173577 | /* 410 */ 2142, 2142, 20, 1224, 256, 1111, 1115, 1114, 1192, 1496, | 174925 | /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415, |
| 173578 | /* 420 */ 1424, 1505, 1427, 355, 1383, 1537, 1506, 1538, 1553, 1583, | 174926 | /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567, |
| 173579 | /* 430 */ 1584, 1591, 1625, 541, 1445, 1562, 1450, 1572, 1515, 1428, | 174927 | /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275, |
| 173580 | /* 440 */ 1532, 1592, 1629, 1520, 1630, 1639, 1510, 1544, 1662, 1675, | 174928 | /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696, |
| 173581 | /* 450 */ 1551, 48, 1996, 2001, 1983, 1844, 1993, 1994, 1986, 1989, | 174929 | /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965, |
| 173582 | /* 460 */ 1874, 1863, 1885, 1991, 1991, 1995, 1876, 1997, 1877, 2004, | 174930 | /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855, |
| 173583 | /* 470 */ 2021, 1881, 1894, 1991, 1895, 1965, 1990, 1991, 1878, 1975, | 174931 | /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856, |
| 173584 | /* 480 */ 1977, 1978, 1979, 1903, 1918, 2002, 1896, 2034, 2033, 2017, | 174932 | /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015, |
| 173585 | /* 490 */ 1925, 1880, 1976, 2018, 1980, 1967, 2005, 1904, 1932, 2025, | 174933 | /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921, |
| 173586 | /* 500 */ 2030, 2032, 1921, 1928, 2035, 1987, 2036, 2037, 2038, 2040, | 174934 | /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, |
| 173587 | /* 510 */ 1988, 2006, 2039, 1960, 2041, 2042, 1999, 2023, 2044, 2043, | 174935 | /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, |
| 173588 | /* 520 */ 1919, 2048, 2049, 2050, 2046, 2051, 2053, 1981, 1935, 2056, | 174936 | /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959, |
| 173589 | /* 530 */ 2057, 1966, 2047, 2061, 1941, 2060, 2052, 2054, 2055, 2058, | 174937 | /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076, |
| 173590 | /* 540 */ 2003, 2012, 2007, 2059, 2015, 2008, 2062, 2071, 2073, 2074, | 174938 | /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094, |
| 173591 | /* 550 */ 2072, 2075, 2065, 1962, 1964, 2079, 2060, 2082, 2084, 2085, | 174939 | /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104, |
| 173592 | /* 560 */ 2087, 2086, 2089, 2088, 2091, 2093, 2099, 2094, 2095, 2096, | 174940 | /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117, |
| 173593 | /* 570 */ 2097, 2100, 2101, 2102, 1998, 1984, 1985, 2000, 2103, 2098, | 174941 | /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128, |
| 173594 | /* 580 */ 2109, 2117, 2128, | 174942 | /* 580 */ 2137, 2138, 2152, |
| 173595 | }; | 174943 | }; |
| 173596 | #define YY_REDUCE_COUNT (411) | 174944 | #define YY_REDUCE_COUNT (412) |
| 173597 | #define YY_REDUCE_MIN (-275) | 174945 | #define YY_REDUCE_MIN (-276) |
| 173598 | #define YY_REDUCE_MAX (1798) | 174946 | #define YY_REDUCE_MAX (1775) |
| 173599 | static const short yy_reduce_ofst[] = { | 174947 | static const short yy_reduce_ofst[] = { |
| 173600 | /* 0 */ -71, 194, 343, 835, -180, -177, 838, -194, -188, -185, | 174948 | /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162, |
| 173601 | /* 10 */ -183, 82, 183, -65, 133, 245, 346, 407, 458, -178, | 174949 | /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207, |
| 173602 | /* 20 */ 75, -275, -4, 310, 312, 489, 575, 596, 463, 686, | 174950 | /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945, |
| 173603 | /* 30 */ 707, 725, 780, 1098, 856, 778, 1059, 1090, 708, 887, | 174951 | /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224, |
| 173604 | /* 40 */ 86, 448, 980, 630, 680, 681, 684, 796, 801, 796, | 174952 | /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237, |
| 173605 | /* 50 */ 801, -261, -261, -261, -261, -261, -261, -261, -261, -261, | 174953 | /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45, |
| 173606 | /* 60 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, | 174954 | /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, |
| 173607 | /* 70 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, | 174955 | /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, |
| 173608 | /* 80 */ -261, -261, -261, -261, -261, -261, -261, -261, 391, 886, | 174956 | /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895, |
| 173609 | /* 90 */ 888, 1013, 1016, 1081, 1087, 1151, 1159, 1177, 1185, 1188, | 174957 | /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242, |
| 173610 | /* 100 */ 1190, 1194, 1197, 1203, 1247, 1260, 1264, 1267, 1269, 1273, | 174958 | /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286, |
| 173611 | /* 110 */ 1315, 1322, 1335, 1337, 1356, 1362, 1418, 1425, 1453, 1457, | 174959 | /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366, |
| 173612 | /* 120 */ 1465, 1473, 1487, 1495, 1507, 1517, 1521, 1534, 1543, 1546, | 174960 | /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427, |
| 173613 | /* 130 */ 1549, 1552, 1554, 1560, 1581, 1590, 1593, 1595, 1621, 1623, | 174961 | /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519, |
| 173614 | /* 140 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, | 174962 | /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45, |
| 173615 | /* 150 */ -261, -186, -117, 260, 263, 460, 631, -74, 497, -181, | 174963 | /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370, |
| 173616 | /* 160 */ -261, 939, 176, 274, 338, 676, -261, -261, -261, -261, | 174964 | /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45, |
| 173617 | /* 170 */ -212, -212, -212, -184, 149, 777, 1061, 1103, 265, 419, | 174965 | /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678, |
| 173618 | /* 180 */ -254, 670, 677, 677, -11, -129, 184, 488, 736, 789, | 174966 | /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419, |
| 173619 | /* 190 */ 805, 844, 403, 529, 579, 668, 783, 841, 1158, 1112, | 174967 | /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813, |
| 173620 | /* 200 */ 806, 861, 1095, 846, 839, 1031, -189, 1077, 1080, 1116, | 174968 | /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443, |
| 173621 | /* 210 */ 1084, 1156, 1139, 1221, 46, 1099, 1037, 1118, 1171, 1214, | 174969 | /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933, |
| 173622 | /* 220 */ 1210, 1258, -210, -190, -176, -115, 117, 262, 376, 490, | 174970 | /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277, |
| 173623 | /* 230 */ 511, 520, 618, 639, 743, 901, 907, 958, 1014, 1055, | 174971 | /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209, |
| 173624 | /* 240 */ 1108, 1193, 1244, 720, 1248, 1277, 1324, 1347, 1417, 1431, | 174972 | /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474, |
| 173625 | /* 250 */ 1432, 1440, 1451, 1452, 1463, 1478, 1286, 1350, 1369, 1490, | 174973 | /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764, |
| 173626 | /* 260 */ 1498, 1501, 773, 1509, 1513, 1528, 1292, 1367, 1535, 1536, | 174974 | /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260, |
| 173627 | /* 270 */ 1477, 1542, 376, 1547, 1550, 1555, 1559, 1568, 1571, 1441, | 174975 | /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576, |
| 173628 | /* 280 */ 1443, 1474, 1511, 1516, 1519, 1522, 773, 1474, 1474, 1503, | 174976 | /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520, |
| 173629 | /* 290 */ 1567, 1594, 1484, 1527, 1556, 1570, 1557, 1524, 1573, 1545, | 174977 | /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537, |
| 173630 | /* 300 */ 1548, 1576, 1561, 1587, 1540, 1575, 1606, 1611, 1622, 1624, | 174978 | /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585, |
| 173631 | /* 310 */ 1626, 1582, 1597, 1598, 1599, 1601, 1603, 1563, 1608, 1605, | 174979 | /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577, |
| 173632 | /* 320 */ 1604, 1564, 1566, 1655, 1660, 1578, 1579, 1665, 1586, 1607, | 174980 | /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560, |
| 173633 | /* 330 */ 1610, 1642, 1641, 1645, 1646, 1647, 1679, 1688, 1644, 1618, | 174981 | /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612, |
| 173634 | /* 340 */ 1619, 1648, 1628, 1659, 1649, 1663, 1650, 1700, 1702, 1612, | 174982 | /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668, |
| 173635 | /* 350 */ 1615, 1706, 1708, 1689, 1709, 1712, 1713, 1715, 1691, 1698, | 174983 | /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660, |
| 173636 | /* 360 */ 1699, 1701, 1693, 1704, 1707, 1705, 1714, 1703, 1718, 1710, | 174984 | /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692, |
| 173637 | /* 370 */ 1720, 1721, 1632, 1634, 1664, 1666, 1729, 1751, 1635, 1636, | 174985 | /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596, |
| 173638 | /* 380 */ 1692, 1694, 1716, 1722, 1684, 1763, 1685, 1723, 1724, 1727, | 174986 | /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690, |
| 173639 | /* 390 */ 1730, 1768, 1783, 1784, 1793, 1794, 1796, 1683, 1686, 1690, | 174987 | /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661, |
| 173640 | /* 400 */ 1782, 1779, 1780, 1781, 1785, 1788, 1774, 1775, 1786, 1787, | 174988 | /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765, |
| 173641 | /* 410 */ 1789, 1798, | 174989 | /* 410 */ 1771, 1767, 1775, |
| 173642 | }; | 174990 | }; |
| 173643 | static const YYACTIONTYPE yy_default[] = { | 174991 | static const YYACTIONTYPE yy_default[] = { |
| 173644 | /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, | 174992 | /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, |
| @@ -173647,57 +174995,57 @@ static const YYACTIONTYPE yy_default[] = { | |||
| 173647 | /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, | 174995 | /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, |
| 173648 | /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, | 174996 | /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, |
| 173649 | /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, | 174997 | /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, |
| 173650 | /* 60 */ 1492, 1493, 1254, 1254, 1254, 1543, 1545, 1508, 1420, 1419, | 174998 | /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, |
| 173651 | /* 70 */ 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, 1486, | 174999 | /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, |
| 173652 | /* 80 */ 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, 1254, | 175000 | /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, |
| 173653 | /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175001 | /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173654 | /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175002 | /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173655 | /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175003 | /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173656 | /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175004 | /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173657 | /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175005 | /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173658 | /* 140 */ 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, 1456, 1458, | 175006 | /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, |
| 173659 | /* 150 */ 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, 1254, 1254, | 175007 | /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, |
| 173660 | /* 160 */ 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, 1473, 1472, | 175008 | /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, |
| 173661 | /* 170 */ 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, 1254, 1254, | 175009 | /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, |
| 173662 | /* 180 */ 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175010 | /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173663 | /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175011 | /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173664 | /* 200 */ 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, 1578, 1578, | 175012 | /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, |
| 173665 | /* 210 */ 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, 1358, 1358, | 175013 | /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, |
| 173666 | /* 220 */ 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175014 | /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173667 | /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, 1546, 1254, | 175015 | /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, |
| 173668 | /* 240 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175016 | /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173669 | /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175017 | /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173670 | /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, 1254, 1254, | 175018 | /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, |
| 173671 | /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, 1254, | 175019 | /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, |
| 173672 | /* 280 */ 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, 1357, | 175020 | /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, |
| 173673 | /* 290 */ 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, 1423, | 175021 | /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, |
| 173674 | /* 300 */ 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, 1397, | 175022 | /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, |
| 173675 | /* 310 */ 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, 1357, | 175023 | /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, |
| 173676 | /* 320 */ 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, 1638, | 175024 | /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, |
| 173677 | /* 330 */ 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, 1638, | 175025 | /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, |
| 173678 | /* 340 */ 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, 1525, | 175026 | /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, |
| 173679 | /* 350 */ 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, 1330, | 175027 | /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, |
| 173680 | /* 360 */ 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, 1319, | 175028 | /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, |
| 173681 | /* 370 */ 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, 1588, | 175029 | /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, |
| 173682 | /* 380 */ 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, 1401, | 175030 | /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, |
| 173683 | /* 390 */ 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, 1558, | 175031 | /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, |
| 173684 | /* 400 */ 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, 1288, | 175032 | /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, |
| 173685 | /* 410 */ 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, 1254, | 175033 | /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, |
| 173686 | /* 420 */ 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175034 | /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173687 | /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1564, | 175035 | /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173688 | /* 440 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175036 | /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173689 | /* 450 */ 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, 1254, | 175037 | /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, |
| 173690 | /* 460 */ 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, 1254, | 175038 | /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, |
| 173691 | /* 470 */ 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, 1254, | 175039 | /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, |
| 173692 | /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, 1254, | 175040 | /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, |
| 173693 | /* 490 */ 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, 1254, | 175041 | /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, |
| 173694 | /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175042 | /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173695 | /* 510 */ 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175043 | /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173696 | /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175044 | /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173697 | /* 530 */ 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, 1254, | 175045 | /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, |
| 173698 | /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175046 | /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173699 | /* 550 */ 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, 1254, | 175047 | /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, |
| 173700 | /* 560 */ 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, | 175048 | /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 173701 | /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, | 175049 | /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, |
| 173702 | /* 580 */ 1266, 1254, 1254, | 175050 | /* 580 */ 1266, 1254, 1254, |
| 173703 | }; | 175051 | }; |
| @@ -173721,52 +175069,53 @@ static const YYACTIONTYPE yy_default[] = { | |||
| 173721 | static const YYCODETYPE yyFallback[] = { | 175069 | static const YYCODETYPE yyFallback[] = { |
| 173722 | 0, /* $ => nothing */ | 175070 | 0, /* $ => nothing */ |
| 173723 | 0, /* SEMI => nothing */ | 175071 | 0, /* SEMI => nothing */ |
| 173724 | 59, /* EXPLAIN => ID */ | 175072 | 60, /* EXPLAIN => ID */ |
| 173725 | 59, /* QUERY => ID */ | 175073 | 60, /* QUERY => ID */ |
| 173726 | 59, /* PLAN => ID */ | 175074 | 60, /* PLAN => ID */ |
| 173727 | 59, /* BEGIN => ID */ | 175075 | 60, /* BEGIN => ID */ |
| 173728 | 0, /* TRANSACTION => nothing */ | 175076 | 0, /* TRANSACTION => nothing */ |
| 173729 | 59, /* DEFERRED => ID */ | 175077 | 60, /* DEFERRED => ID */ |
| 173730 | 59, /* IMMEDIATE => ID */ | 175078 | 60, /* IMMEDIATE => ID */ |
| 173731 | 59, /* EXCLUSIVE => ID */ | 175079 | 60, /* EXCLUSIVE => ID */ |
| 173732 | 0, /* COMMIT => nothing */ | 175080 | 0, /* COMMIT => nothing */ |
| 173733 | 59, /* END => ID */ | 175081 | 60, /* END => ID */ |
| 173734 | 59, /* ROLLBACK => ID */ | 175082 | 60, /* ROLLBACK => ID */ |
| 173735 | 59, /* SAVEPOINT => ID */ | 175083 | 60, /* SAVEPOINT => ID */ |
| 173736 | 59, /* RELEASE => ID */ | 175084 | 60, /* RELEASE => ID */ |
| 173737 | 0, /* TO => nothing */ | 175085 | 0, /* TO => nothing */ |
| 173738 | 0, /* TABLE => nothing */ | 175086 | 0, /* TABLE => nothing */ |
| 173739 | 0, /* CREATE => nothing */ | 175087 | 0, /* CREATE => nothing */ |
| 173740 | 59, /* IF => ID */ | 175088 | 60, /* IF => ID */ |
| 173741 | 0, /* NOT => nothing */ | 175089 | 0, /* NOT => nothing */ |
| 173742 | 0, /* EXISTS => nothing */ | 175090 | 0, /* EXISTS => nothing */ |
| 173743 | 59, /* TEMP => ID */ | 175091 | 60, /* TEMP => ID */ |
| 173744 | 0, /* LP => nothing */ | 175092 | 0, /* LP => nothing */ |
| 173745 | 0, /* RP => nothing */ | 175093 | 0, /* RP => nothing */ |
| 173746 | 0, /* AS => nothing */ | 175094 | 0, /* AS => nothing */ |
| 173747 | 0, /* COMMA => nothing */ | 175095 | 0, /* COMMA => nothing */ |
| 173748 | 59, /* WITHOUT => ID */ | 175096 | 60, /* WITHOUT => ID */ |
| 173749 | 59, /* ABORT => ID */ | 175097 | 60, /* ABORT => ID */ |
| 173750 | 59, /* ACTION => ID */ | 175098 | 60, /* ACTION => ID */ |
| 173751 | 59, /* AFTER => ID */ | 175099 | 60, /* AFTER => ID */ |
| 173752 | 59, /* ANALYZE => ID */ | 175100 | 60, /* ANALYZE => ID */ |
| 173753 | 59, /* ASC => ID */ | 175101 | 60, /* ASC => ID */ |
| 173754 | 59, /* ATTACH => ID */ | 175102 | 60, /* ATTACH => ID */ |
| 173755 | 59, /* BEFORE => ID */ | 175103 | 60, /* BEFORE => ID */ |
| 173756 | 59, /* BY => ID */ | 175104 | 60, /* BY => ID */ |
| 173757 | 59, /* CASCADE => ID */ | 175105 | 60, /* CASCADE => ID */ |
| 173758 | 59, /* CAST => ID */ | 175106 | 60, /* CAST => ID */ |
| 173759 | 59, /* CONFLICT => ID */ | 175107 | 60, /* CONFLICT => ID */ |
| 173760 | 59, /* DATABASE => ID */ | 175108 | 60, /* DATABASE => ID */ |
| 173761 | 59, /* DESC => ID */ | 175109 | 60, /* DESC => ID */ |
| 173762 | 59, /* DETACH => ID */ | 175110 | 60, /* DETACH => ID */ |
| 173763 | 59, /* EACH => ID */ | 175111 | 60, /* EACH => ID */ |
| 173764 | 59, /* FAIL => ID */ | 175112 | 60, /* FAIL => ID */ |
| 173765 | 0, /* OR => nothing */ | 175113 | 0, /* OR => nothing */ |
| 173766 | 0, /* AND => nothing */ | 175114 | 0, /* AND => nothing */ |
| 173767 | 0, /* IS => nothing */ | 175115 | 0, /* IS => nothing */ |
| 173768 | 59, /* MATCH => ID */ | 175116 | 0, /* ISNOT => nothing */ |
| 173769 | 59, /* LIKE_KW => ID */ | 175117 | 60, /* MATCH => ID */ |
| 175118 | 60, /* LIKE_KW => ID */ | ||
| 173770 | 0, /* BETWEEN => nothing */ | 175119 | 0, /* BETWEEN => nothing */ |
| 173771 | 0, /* IN => nothing */ | 175120 | 0, /* IN => nothing */ |
| 173772 | 0, /* ISNULL => nothing */ | 175121 | 0, /* ISNULL => nothing */ |
| @@ -173779,47 +175128,47 @@ static const YYCODETYPE yyFallback[] = { | |||
| 173779 | 0, /* GE => nothing */ | 175128 | 0, /* GE => nothing */ |
| 173780 | 0, /* ESCAPE => nothing */ | 175129 | 0, /* ESCAPE => nothing */ |
| 173781 | 0, /* ID => nothing */ | 175130 | 0, /* ID => nothing */ |
| 173782 | 59, /* COLUMNKW => ID */ | 175131 | 60, /* COLUMNKW => ID */ |
| 173783 | 59, /* DO => ID */ | 175132 | 60, /* DO => ID */ |
| 173784 | 59, /* FOR => ID */ | 175133 | 60, /* FOR => ID */ |
| 173785 | 59, /* IGNORE => ID */ | 175134 | 60, /* IGNORE => ID */ |
| 173786 | 59, /* INITIALLY => ID */ | 175135 | 60, /* INITIALLY => ID */ |
| 173787 | 59, /* INSTEAD => ID */ | 175136 | 60, /* INSTEAD => ID */ |
| 173788 | 59, /* NO => ID */ | 175137 | 60, /* NO => ID */ |
| 173789 | 59, /* KEY => ID */ | 175138 | 60, /* KEY => ID */ |
| 173790 | 59, /* OF => ID */ | 175139 | 60, /* OF => ID */ |
| 173791 | 59, /* OFFSET => ID */ | 175140 | 60, /* OFFSET => ID */ |
| 173792 | 59, /* PRAGMA => ID */ | 175141 | 60, /* PRAGMA => ID */ |
| 173793 | 59, /* RAISE => ID */ | 175142 | 60, /* RAISE => ID */ |
| 173794 | 59, /* RECURSIVE => ID */ | 175143 | 60, /* RECURSIVE => ID */ |
| 173795 | 59, /* REPLACE => ID */ | 175144 | 60, /* REPLACE => ID */ |
| 173796 | 59, /* RESTRICT => ID */ | 175145 | 60, /* RESTRICT => ID */ |
| 173797 | 59, /* ROW => ID */ | 175146 | 60, /* ROW => ID */ |
| 173798 | 59, /* ROWS => ID */ | 175147 | 60, /* ROWS => ID */ |
| 173799 | 59, /* TRIGGER => ID */ | 175148 | 60, /* TRIGGER => ID */ |
| 173800 | 59, /* VACUUM => ID */ | 175149 | 60, /* VACUUM => ID */ |
| 173801 | 59, /* VIEW => ID */ | 175150 | 60, /* VIEW => ID */ |
| 173802 | 59, /* VIRTUAL => ID */ | 175151 | 60, /* VIRTUAL => ID */ |
| 173803 | 59, /* WITH => ID */ | 175152 | 60, /* WITH => ID */ |
| 173804 | 59, /* NULLS => ID */ | 175153 | 60, /* NULLS => ID */ |
| 173805 | 59, /* FIRST => ID */ | 175154 | 60, /* FIRST => ID */ |
| 173806 | 59, /* LAST => ID */ | 175155 | 60, /* LAST => ID */ |
| 173807 | 59, /* CURRENT => ID */ | 175156 | 60, /* CURRENT => ID */ |
| 173808 | 59, /* FOLLOWING => ID */ | 175157 | 60, /* FOLLOWING => ID */ |
| 173809 | 59, /* PARTITION => ID */ | 175158 | 60, /* PARTITION => ID */ |
| 173810 | 59, /* PRECEDING => ID */ | 175159 | 60, /* PRECEDING => ID */ |
| 173811 | 59, /* RANGE => ID */ | 175160 | 60, /* RANGE => ID */ |
| 173812 | 59, /* UNBOUNDED => ID */ | 175161 | 60, /* UNBOUNDED => ID */ |
| 173813 | 59, /* EXCLUDE => ID */ | 175162 | 60, /* EXCLUDE => ID */ |
| 173814 | 59, /* GROUPS => ID */ | 175163 | 60, /* GROUPS => ID */ |
| 173815 | 59, /* OTHERS => ID */ | 175164 | 60, /* OTHERS => ID */ |
| 173816 | 59, /* TIES => ID */ | 175165 | 60, /* TIES => ID */ |
| 173817 | 59, /* GENERATED => ID */ | 175166 | 60, /* GENERATED => ID */ |
| 173818 | 59, /* ALWAYS => ID */ | 175167 | 60, /* ALWAYS => ID */ |
| 173819 | 59, /* MATERIALIZED => ID */ | 175168 | 60, /* MATERIALIZED => ID */ |
| 173820 | 59, /* REINDEX => ID */ | 175169 | 60, /* REINDEX => ID */ |
| 173821 | 59, /* RENAME => ID */ | 175170 | 60, /* RENAME => ID */ |
| 173822 | 59, /* CTIME_KW => ID */ | 175171 | 60, /* CTIME_KW => ID */ |
| 173823 | 0, /* ANY => nothing */ | 175172 | 0, /* ANY => nothing */ |
| 173824 | 0, /* BITAND => nothing */ | 175173 | 0, /* BITAND => nothing */ |
| 173825 | 0, /* BITOR => nothing */ | 175174 | 0, /* BITOR => nothing */ |
| @@ -173890,7 +175239,6 @@ static const YYCODETYPE yyFallback[] = { | |||
| 173890 | 0, /* AGG_FUNCTION => nothing */ | 175239 | 0, /* AGG_FUNCTION => nothing */ |
| 173891 | 0, /* AGG_COLUMN => nothing */ | 175240 | 0, /* AGG_COLUMN => nothing */ |
| 173892 | 0, /* TRUEFALSE => nothing */ | 175241 | 0, /* TRUEFALSE => nothing */ |
| 173893 | 0, /* ISNOT => nothing */ | ||
| 173894 | 0, /* FUNCTION => nothing */ | 175242 | 0, /* FUNCTION => nothing */ |
| 173895 | 0, /* UPLUS => nothing */ | 175243 | 0, /* UPLUS => nothing */ |
| 173896 | 0, /* UMINUS => nothing */ | 175244 | 0, /* UMINUS => nothing */ |
| @@ -174034,132 +175382,132 @@ static const char *const yyTokenName[] = { | |||
| 174034 | /* 43 */ "OR", | 175382 | /* 43 */ "OR", |
| 174035 | /* 44 */ "AND", | 175383 | /* 44 */ "AND", |
| 174036 | /* 45 */ "IS", | 175384 | /* 45 */ "IS", |
| 174037 | /* 46 */ "MATCH", | 175385 | /* 46 */ "ISNOT", |
| 174038 | /* 47 */ "LIKE_KW", | 175386 | /* 47 */ "MATCH", |
| 174039 | /* 48 */ "BETWEEN", | 175387 | /* 48 */ "LIKE_KW", |
| 174040 | /* 49 */ "IN", | 175388 | /* 49 */ "BETWEEN", |
| 174041 | /* 50 */ "ISNULL", | 175389 | /* 50 */ "IN", |
| 174042 | /* 51 */ "NOTNULL", | 175390 | /* 51 */ "ISNULL", |
| 174043 | /* 52 */ "NE", | 175391 | /* 52 */ "NOTNULL", |
| 174044 | /* 53 */ "EQ", | 175392 | /* 53 */ "NE", |
| 174045 | /* 54 */ "GT", | 175393 | /* 54 */ "EQ", |
| 174046 | /* 55 */ "LE", | 175394 | /* 55 */ "GT", |
| 174047 | /* 56 */ "LT", | 175395 | /* 56 */ "LE", |
| 174048 | /* 57 */ "GE", | 175396 | /* 57 */ "LT", |
| 174049 | /* 58 */ "ESCAPE", | 175397 | /* 58 */ "GE", |
| 174050 | /* 59 */ "ID", | 175398 | /* 59 */ "ESCAPE", |
| 174051 | /* 60 */ "COLUMNKW", | 175399 | /* 60 */ "ID", |
| 174052 | /* 61 */ "DO", | 175400 | /* 61 */ "COLUMNKW", |
| 174053 | /* 62 */ "FOR", | 175401 | /* 62 */ "DO", |
| 174054 | /* 63 */ "IGNORE", | 175402 | /* 63 */ "FOR", |
| 174055 | /* 64 */ "INITIALLY", | 175403 | /* 64 */ "IGNORE", |
| 174056 | /* 65 */ "INSTEAD", | 175404 | /* 65 */ "INITIALLY", |
| 174057 | /* 66 */ "NO", | 175405 | /* 66 */ "INSTEAD", |
| 174058 | /* 67 */ "KEY", | 175406 | /* 67 */ "NO", |
| 174059 | /* 68 */ "OF", | 175407 | /* 68 */ "KEY", |
| 174060 | /* 69 */ "OFFSET", | 175408 | /* 69 */ "OF", |
| 174061 | /* 70 */ "PRAGMA", | 175409 | /* 70 */ "OFFSET", |
| 174062 | /* 71 */ "RAISE", | 175410 | /* 71 */ "PRAGMA", |
| 174063 | /* 72 */ "RECURSIVE", | 175411 | /* 72 */ "RAISE", |
| 174064 | /* 73 */ "REPLACE", | 175412 | /* 73 */ "RECURSIVE", |
| 174065 | /* 74 */ "RESTRICT", | 175413 | /* 74 */ "REPLACE", |
| 174066 | /* 75 */ "ROW", | 175414 | /* 75 */ "RESTRICT", |
| 174067 | /* 76 */ "ROWS", | 175415 | /* 76 */ "ROW", |
| 174068 | /* 77 */ "TRIGGER", | 175416 | /* 77 */ "ROWS", |
| 174069 | /* 78 */ "VACUUM", | 175417 | /* 78 */ "TRIGGER", |
| 174070 | /* 79 */ "VIEW", | 175418 | /* 79 */ "VACUUM", |
| 174071 | /* 80 */ "VIRTUAL", | 175419 | /* 80 */ "VIEW", |
| 174072 | /* 81 */ "WITH", | 175420 | /* 81 */ "VIRTUAL", |
| 174073 | /* 82 */ "NULLS", | 175421 | /* 82 */ "WITH", |
| 174074 | /* 83 */ "FIRST", | 175422 | /* 83 */ "NULLS", |
| 174075 | /* 84 */ "LAST", | 175423 | /* 84 */ "FIRST", |
| 174076 | /* 85 */ "CURRENT", | 175424 | /* 85 */ "LAST", |
| 174077 | /* 86 */ "FOLLOWING", | 175425 | /* 86 */ "CURRENT", |
| 174078 | /* 87 */ "PARTITION", | 175426 | /* 87 */ "FOLLOWING", |
| 174079 | /* 88 */ "PRECEDING", | 175427 | /* 88 */ "PARTITION", |
| 174080 | /* 89 */ "RANGE", | 175428 | /* 89 */ "PRECEDING", |
| 174081 | /* 90 */ "UNBOUNDED", | 175429 | /* 90 */ "RANGE", |
| 174082 | /* 91 */ "EXCLUDE", | 175430 | /* 91 */ "UNBOUNDED", |
| 174083 | /* 92 */ "GROUPS", | 175431 | /* 92 */ "EXCLUDE", |
| 174084 | /* 93 */ "OTHERS", | 175432 | /* 93 */ "GROUPS", |
| 174085 | /* 94 */ "TIES", | 175433 | /* 94 */ "OTHERS", |
| 174086 | /* 95 */ "GENERATED", | 175434 | /* 95 */ "TIES", |
| 174087 | /* 96 */ "ALWAYS", | 175435 | /* 96 */ "GENERATED", |
| 174088 | /* 97 */ "MATERIALIZED", | 175436 | /* 97 */ "ALWAYS", |
| 174089 | /* 98 */ "REINDEX", | 175437 | /* 98 */ "MATERIALIZED", |
| 174090 | /* 99 */ "RENAME", | 175438 | /* 99 */ "REINDEX", |
| 174091 | /* 100 */ "CTIME_KW", | 175439 | /* 100 */ "RENAME", |
| 174092 | /* 101 */ "ANY", | 175440 | /* 101 */ "CTIME_KW", |
| 174093 | /* 102 */ "BITAND", | 175441 | /* 102 */ "ANY", |
| 174094 | /* 103 */ "BITOR", | 175442 | /* 103 */ "BITAND", |
| 174095 | /* 104 */ "LSHIFT", | 175443 | /* 104 */ "BITOR", |
| 174096 | /* 105 */ "RSHIFT", | 175444 | /* 105 */ "LSHIFT", |
| 174097 | /* 106 */ "PLUS", | 175445 | /* 106 */ "RSHIFT", |
| 174098 | /* 107 */ "MINUS", | 175446 | /* 107 */ "PLUS", |
| 174099 | /* 108 */ "STAR", | 175447 | /* 108 */ "MINUS", |
| 174100 | /* 109 */ "SLASH", | 175448 | /* 109 */ "STAR", |
| 174101 | /* 110 */ "REM", | 175449 | /* 110 */ "SLASH", |
| 174102 | /* 111 */ "CONCAT", | 175450 | /* 111 */ "REM", |
| 174103 | /* 112 */ "PTR", | 175451 | /* 112 */ "CONCAT", |
| 174104 | /* 113 */ "COLLATE", | 175452 | /* 113 */ "PTR", |
| 174105 | /* 114 */ "BITNOT", | 175453 | /* 114 */ "COLLATE", |
| 174106 | /* 115 */ "ON", | 175454 | /* 115 */ "BITNOT", |
| 174107 | /* 116 */ "INDEXED", | 175455 | /* 116 */ "ON", |
| 174108 | /* 117 */ "STRING", | 175456 | /* 117 */ "INDEXED", |
| 174109 | /* 118 */ "JOIN_KW", | 175457 | /* 118 */ "STRING", |
| 174110 | /* 119 */ "CONSTRAINT", | 175458 | /* 119 */ "JOIN_KW", |
| 174111 | /* 120 */ "DEFAULT", | 175459 | /* 120 */ "CONSTRAINT", |
| 174112 | /* 121 */ "NULL", | 175460 | /* 121 */ "DEFAULT", |
| 174113 | /* 122 */ "PRIMARY", | 175461 | /* 122 */ "NULL", |
| 174114 | /* 123 */ "UNIQUE", | 175462 | /* 123 */ "PRIMARY", |
| 174115 | /* 124 */ "CHECK", | 175463 | /* 124 */ "UNIQUE", |
| 174116 | /* 125 */ "REFERENCES", | 175464 | /* 125 */ "CHECK", |
| 174117 | /* 126 */ "AUTOINCR", | 175465 | /* 126 */ "REFERENCES", |
| 174118 | /* 127 */ "INSERT", | 175466 | /* 127 */ "AUTOINCR", |
| 174119 | /* 128 */ "DELETE", | 175467 | /* 128 */ "INSERT", |
| 174120 | /* 129 */ "UPDATE", | 175468 | /* 129 */ "DELETE", |
| 174121 | /* 130 */ "SET", | 175469 | /* 130 */ "UPDATE", |
| 174122 | /* 131 */ "DEFERRABLE", | 175470 | /* 131 */ "SET", |
| 174123 | /* 132 */ "FOREIGN", | 175471 | /* 132 */ "DEFERRABLE", |
| 174124 | /* 133 */ "DROP", | 175472 | /* 133 */ "FOREIGN", |
| 174125 | /* 134 */ "UNION", | 175473 | /* 134 */ "DROP", |
| 174126 | /* 135 */ "ALL", | 175474 | /* 135 */ "UNION", |
| 174127 | /* 136 */ "EXCEPT", | 175475 | /* 136 */ "ALL", |
| 174128 | /* 137 */ "INTERSECT", | 175476 | /* 137 */ "EXCEPT", |
| 174129 | /* 138 */ "SELECT", | 175477 | /* 138 */ "INTERSECT", |
| 174130 | /* 139 */ "VALUES", | 175478 | /* 139 */ "SELECT", |
| 174131 | /* 140 */ "DISTINCT", | 175479 | /* 140 */ "VALUES", |
| 174132 | /* 141 */ "DOT", | 175480 | /* 141 */ "DISTINCT", |
| 174133 | /* 142 */ "FROM", | 175481 | /* 142 */ "DOT", |
| 174134 | /* 143 */ "JOIN", | 175482 | /* 143 */ "FROM", |
| 174135 | /* 144 */ "USING", | 175483 | /* 144 */ "JOIN", |
| 174136 | /* 145 */ "ORDER", | 175484 | /* 145 */ "USING", |
| 174137 | /* 146 */ "GROUP", | 175485 | /* 146 */ "ORDER", |
| 174138 | /* 147 */ "HAVING", | 175486 | /* 147 */ "GROUP", |
| 174139 | /* 148 */ "LIMIT", | 175487 | /* 148 */ "HAVING", |
| 174140 | /* 149 */ "WHERE", | 175488 | /* 149 */ "LIMIT", |
| 174141 | /* 150 */ "RETURNING", | 175489 | /* 150 */ "WHERE", |
| 174142 | /* 151 */ "INTO", | 175490 | /* 151 */ "RETURNING", |
| 174143 | /* 152 */ "NOTHING", | 175491 | /* 152 */ "INTO", |
| 174144 | /* 153 */ "FLOAT", | 175492 | /* 153 */ "NOTHING", |
| 174145 | /* 154 */ "BLOB", | 175493 | /* 154 */ "FLOAT", |
| 174146 | /* 155 */ "INTEGER", | 175494 | /* 155 */ "BLOB", |
| 174147 | /* 156 */ "VARIABLE", | 175495 | /* 156 */ "INTEGER", |
| 174148 | /* 157 */ "CASE", | 175496 | /* 157 */ "VARIABLE", |
| 174149 | /* 158 */ "WHEN", | 175497 | /* 158 */ "CASE", |
| 174150 | /* 159 */ "THEN", | 175498 | /* 159 */ "WHEN", |
| 174151 | /* 160 */ "ELSE", | 175499 | /* 160 */ "THEN", |
| 174152 | /* 161 */ "INDEX", | 175500 | /* 161 */ "ELSE", |
| 174153 | /* 162 */ "ALTER", | 175501 | /* 162 */ "INDEX", |
| 174154 | /* 163 */ "ADD", | 175502 | /* 163 */ "ALTER", |
| 174155 | /* 164 */ "WINDOW", | 175503 | /* 164 */ "ADD", |
| 174156 | /* 165 */ "OVER", | 175504 | /* 165 */ "WINDOW", |
| 174157 | /* 166 */ "FILTER", | 175505 | /* 166 */ "OVER", |
| 174158 | /* 167 */ "COLUMN", | 175506 | /* 167 */ "FILTER", |
| 174159 | /* 168 */ "AGG_FUNCTION", | 175507 | /* 168 */ "COLUMN", |
| 174160 | /* 169 */ "AGG_COLUMN", | 175508 | /* 169 */ "AGG_FUNCTION", |
| 174161 | /* 170 */ "TRUEFALSE", | 175509 | /* 170 */ "AGG_COLUMN", |
| 174162 | /* 171 */ "ISNOT", | 175510 | /* 171 */ "TRUEFALSE", |
| 174163 | /* 172 */ "FUNCTION", | 175511 | /* 172 */ "FUNCTION", |
| 174164 | /* 173 */ "UPLUS", | 175512 | /* 173 */ "UPLUS", |
| 174165 | /* 174 */ "UMINUS", | 175513 | /* 174 */ "UMINUS", |
| @@ -174597,7 +175945,7 @@ static const char *const yyRuleName[] = { | |||
| 174597 | /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", | 175945 | /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", |
| 174598 | /* 278 */ "trigger_cmd ::= scanpt select scanpt", | 175946 | /* 278 */ "trigger_cmd ::= scanpt select scanpt", |
| 174599 | /* 279 */ "expr ::= RAISE LP IGNORE RP", | 175947 | /* 279 */ "expr ::= RAISE LP IGNORE RP", |
| 174600 | /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", | 175948 | /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", |
| 174601 | /* 281 */ "raisetype ::= ROLLBACK", | 175949 | /* 281 */ "raisetype ::= ROLLBACK", |
| 174602 | /* 282 */ "raisetype ::= ABORT", | 175950 | /* 282 */ "raisetype ::= ABORT", |
| 174603 | /* 283 */ "raisetype ::= FAIL", | 175951 | /* 283 */ "raisetype ::= FAIL", |
| @@ -175522,7 +176870,7 @@ static const YYCODETYPE yyRuleInfoLhs[] = { | |||
| 175522 | 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 176870 | 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 175523 | 293, /* (278) trigger_cmd ::= scanpt select scanpt */ | 176871 | 293, /* (278) trigger_cmd ::= scanpt select scanpt */ |
| 175524 | 218, /* (279) expr ::= RAISE LP IGNORE RP */ | 176872 | 218, /* (279) expr ::= RAISE LP IGNORE RP */ |
| 175525 | 218, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ | 176873 | 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ |
| 175526 | 237, /* (281) raisetype ::= ROLLBACK */ | 176874 | 237, /* (281) raisetype ::= ROLLBACK */ |
| 175527 | 237, /* (282) raisetype ::= ABORT */ | 176875 | 237, /* (282) raisetype ::= ABORT */ |
| 175528 | 237, /* (283) raisetype ::= FAIL */ | 176876 | 237, /* (283) raisetype ::= FAIL */ |
| @@ -175936,7 +177284,7 @@ static const signed char yyRuleInfoNRhs[] = { | |||
| 175936 | -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 177284 | -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 175937 | -3, /* (278) trigger_cmd ::= scanpt select scanpt */ | 177285 | -3, /* (278) trigger_cmd ::= scanpt select scanpt */ |
| 175938 | -4, /* (279) expr ::= RAISE LP IGNORE RP */ | 177286 | -4, /* (279) expr ::= RAISE LP IGNORE RP */ |
| 175939 | -6, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ | 177287 | -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ |
| 175940 | -1, /* (281) raisetype ::= ROLLBACK */ | 177288 | -1, /* (281) raisetype ::= ROLLBACK */ |
| 175941 | -1, /* (282) raisetype ::= ABORT */ | 177289 | -1, /* (282) raisetype ::= ABORT */ |
| 175942 | -1, /* (283) raisetype ::= FAIL */ | 177290 | -1, /* (283) raisetype ::= FAIL */ |
| @@ -176574,11 +177922,21 @@ static YYACTIONTYPE yy_reduce( | |||
| 176574 | if( yymsp[-5].minor.yy203 ){ | 177922 | if( yymsp[-5].minor.yy203 ){ |
| 176575 | SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; | 177923 | SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; |
| 176576 | SrcItem *pOld = yymsp[-3].minor.yy203->a; | 177924 | SrcItem *pOld = yymsp[-3].minor.yy203->a; |
| 177925 | assert( pOld->fg.fixedSchema==0 ); | ||
| 176577 | pNew->zName = pOld->zName; | 177926 | pNew->zName = pOld->zName; |
| 176578 | pNew->zDatabase = pOld->zDatabase; | 177927 | assert( pOld->fg.fixedSchema==0 ); |
| 176579 | pNew->pSelect = pOld->pSelect; | 177928 | if( pOld->fg.isSubquery ){ |
| 176580 | if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ | 177929 | pNew->fg.isSubquery = 1; |
| 176581 | pNew->fg.isNestedFrom = 1; | 177930 | pNew->u4.pSubq = pOld->u4.pSubq; |
| 177931 | pOld->u4.pSubq = 0; | ||
| 177932 | pOld->fg.isSubquery = 0; | ||
| 177933 | assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); | ||
| 177934 | if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ | ||
| 177935 | pNew->fg.isNestedFrom = 1; | ||
| 177936 | } | ||
| 177937 | }else{ | ||
| 177938 | pNew->u4.zDatabase = pOld->u4.zDatabase; | ||
| 177939 | pOld->u4.zDatabase = 0; | ||
| 176582 | } | 177940 | } |
| 176583 | if( pOld->fg.isTabFunc ){ | 177941 | if( pOld->fg.isTabFunc ){ |
| 176584 | pNew->u1.pFuncArg = pOld->u1.pFuncArg; | 177942 | pNew->u1.pFuncArg = pOld->u1.pFuncArg; |
| @@ -176586,8 +177944,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 176586 | pOld->fg.isTabFunc = 0; | 177944 | pOld->fg.isTabFunc = 0; |
| 176587 | pNew->fg.isTabFunc = 1; | 177945 | pNew->fg.isTabFunc = 1; |
| 176588 | } | 177946 | } |
| 176589 | pOld->zName = pOld->zDatabase = 0; | 177947 | pOld->zName = 0; |
| 176590 | pOld->pSelect = 0; | ||
| 176591 | } | 177948 | } |
| 176592 | sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); | 177949 | sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); |
| 176593 | }else{ | 177950 | }else{ |
| @@ -177321,9 +178678,9 @@ static YYACTIONTYPE yy_reduce( | |||
| 177321 | } | 178678 | } |
| 177322 | } | 178679 | } |
| 177323 | break; | 178680 | break; |
| 177324 | case 280: /* expr ::= RAISE LP raisetype COMMA nm RP */ | 178681 | case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ |
| 177325 | { | 178682 | { |
| 177326 | yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); | 178683 | yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); |
| 177327 | if( yymsp[-5].minor.yy454 ) { | 178684 | if( yymsp[-5].minor.yy454 ) { |
| 177328 | yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; | 178685 | yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; |
| 177329 | } | 178686 | } |
| @@ -179915,32 +181272,6 @@ SQLITE_API char *sqlite3_temp_directory = 0; | |||
| 179915 | SQLITE_API char *sqlite3_data_directory = 0; | 181272 | SQLITE_API char *sqlite3_data_directory = 0; |
| 179916 | 181273 | ||
| 179917 | /* | 181274 | /* |
| 179918 | ** Determine whether or not high-precision (long double) floating point | ||
| 179919 | ** math works correctly on CPU currently running. | ||
| 179920 | */ | ||
| 179921 | static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ | ||
| 179922 | if( sizeof(LONGDOUBLE_TYPE)<=8 ){ | ||
| 179923 | /* If the size of "long double" is not more than 8, then | ||
| 179924 | ** high-precision math is not possible. */ | ||
| 179925 | return 0; | ||
| 179926 | }else{ | ||
| 179927 | /* Just because sizeof(long double)>8 does not mean that the underlying | ||
| 179928 | ** hardware actually supports high-precision floating point. For example, | ||
| 179929 | ** clearing the 0x100 bit in the floating-point control word on Intel | ||
| 179930 | ** processors will make long double work like double, even though long | ||
| 179931 | ** double takes up more space. The only way to determine if long double | ||
| 179932 | ** actually works is to run an experiment. */ | ||
| 179933 | LONGDOUBLE_TYPE a, b, c; | ||
| 179934 | rc++; | ||
| 179935 | a = 1.0+rc*0.1; | ||
| 179936 | b = 1.0e+18+rc*25.0; | ||
| 179937 | c = a+b; | ||
| 179938 | return b!=c; | ||
| 179939 | } | ||
| 179940 | } | ||
| 179941 | |||
| 179942 | |||
| 179943 | /* | ||
| 179944 | ** Initialize SQLite. | 181275 | ** Initialize SQLite. |
| 179945 | ** | 181276 | ** |
| 179946 | ** This routine must be called to initialize the memory allocation, | 181277 | ** This routine must be called to initialize the memory allocation, |
| @@ -180134,13 +181465,6 @@ SQLITE_API int sqlite3_initialize(void){ | |||
| 180134 | rc = SQLITE_EXTRA_INIT(0); | 181465 | rc = SQLITE_EXTRA_INIT(0); |
| 180135 | } | 181466 | } |
| 180136 | #endif | 181467 | #endif |
| 180137 | |||
| 180138 | /* Experimentally determine if high-precision floating point is | ||
| 180139 | ** available. */ | ||
| 180140 | #ifndef SQLITE_OMIT_WSD | ||
| 180141 | sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); | ||
| 180142 | #endif | ||
| 180143 | |||
| 180144 | return rc; | 181468 | return rc; |
| 180145 | } | 181469 | } |
| 180146 | 181470 | ||
| @@ -181681,7 +183005,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc( | |||
| 181681 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); | 183005 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); |
| 181682 | assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); | 183006 | assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); |
| 181683 | extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| | 183007 | extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| |
| 181684 | SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); | 183008 | SQLITE_SUBTYPE|SQLITE_INNOCUOUS| |
| 183009 | SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); | ||
| 181685 | enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); | 183010 | enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); |
| 181686 | 183011 | ||
| 181687 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But | 183012 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But |
| @@ -183236,6 +184561,7 @@ static int openDatabase( | |||
| 183236 | if( ((1<<(flags&7)) & 0x46)==0 ){ | 184561 | if( ((1<<(flags&7)) & 0x46)==0 ){ |
| 183237 | rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ | 184562 | rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ |
| 183238 | }else{ | 184563 | }else{ |
| 184564 | if( zFilename==0 ) zFilename = ":memory:"; | ||
| 183239 | rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); | 184565 | rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); |
| 183240 | } | 184566 | } |
| 183241 | if( rc!=SQLITE_OK ){ | 184567 | if( rc!=SQLITE_OK ){ |
| @@ -184148,6 +185474,18 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 184148 | break; | 185474 | break; |
| 184149 | } | 185475 | } |
| 184150 | 185476 | ||
| 185477 | /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) | ||
| 185478 | ** | ||
| 185479 | ** Write the current optimization settings into *N. A zero bit means that | ||
| 185480 | ** the optimization is on, and a 1 bit means that the optimization is off. | ||
| 185481 | */ | ||
| 185482 | case SQLITE_TESTCTRL_GETOPT: { | ||
| 185483 | sqlite3 *db = va_arg(ap, sqlite3*); | ||
| 185484 | int *pN = va_arg(ap, int*); | ||
| 185485 | *pN = db->dbOptFlags; | ||
| 185486 | break; | ||
| 185487 | } | ||
| 185488 | |||
| 184151 | /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); | 185489 | /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); |
| 184152 | ** | 185490 | ** |
| 184153 | ** If parameter onoff is 1, subsequent calls to localtime() fail. | 185491 | ** If parameter onoff is 1, subsequent calls to localtime() fail. |
| @@ -184379,24 +185717,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 184379 | break; | 185717 | break; |
| 184380 | } | 185718 | } |
| 184381 | 185719 | ||
| 184382 | #if !defined(SQLITE_OMIT_WSD) | ||
| 184383 | /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); | ||
| 184384 | ** | ||
| 184385 | ** X<0 Make no changes to the bUseLongDouble. Just report value. | ||
| 184386 | ** X==0 Disable bUseLongDouble | ||
| 184387 | ** X==1 Enable bUseLongDouble | ||
| 184388 | ** X>=2 Set bUseLongDouble to its default value for this platform | ||
| 184389 | */ | ||
| 184390 | case SQLITE_TESTCTRL_USELONGDOUBLE: { | ||
| 184391 | int b = va_arg(ap, int); | ||
| 184392 | if( b>=2 ) b = hasHighPrecisionDouble(b); | ||
| 184393 | if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; | ||
| 184394 | rc = sqlite3Config.bUseLongDouble!=0; | ||
| 184395 | break; | ||
| 184396 | } | ||
| 184397 | #endif | ||
| 184398 | |||
| 184399 | |||
| 184400 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) | 185720 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) |
| 184401 | /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) | 185721 | /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) |
| 184402 | ** | 185722 | ** |
| @@ -184704,7 +186024,11 @@ SQLITE_API int sqlite3_snapshot_get( | |||
| 184704 | if( iDb==0 || iDb>1 ){ | 186024 | if( iDb==0 || iDb>1 ){ |
| 184705 | Btree *pBt = db->aDb[iDb].pBt; | 186025 | Btree *pBt = db->aDb[iDb].pBt; |
| 184706 | if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ | 186026 | if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ |
| 186027 | Pager *pPager = sqlite3BtreePager(pBt); | ||
| 186028 | i64 dummy = 0; | ||
| 186029 | sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy); | ||
| 184707 | rc = sqlite3BtreeBeginTrans(pBt, 0, 0); | 186030 | rc = sqlite3BtreeBeginTrans(pBt, 0, 0); |
| 186031 | sqlite3PagerSnapshotOpen(pPager, 0); | ||
| 184708 | if( rc==SQLITE_OK ){ | 186032 | if( rc==SQLITE_OK ){ |
| 184709 | rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); | 186033 | rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); |
| 184710 | } | 186034 | } |
| @@ -188494,10 +189818,15 @@ static int fts3PoslistPhraseMerge( | |||
| 188494 | if( *p1==POS_COLUMN ){ | 189818 | if( *p1==POS_COLUMN ){ |
| 188495 | p1++; | 189819 | p1++; |
| 188496 | p1 += fts3GetVarint32(p1, &iCol1); | 189820 | p1 += fts3GetVarint32(p1, &iCol1); |
| 189821 | /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN | ||
| 189822 | ** entry, so this is actually end-of-doclist. */ | ||
| 189823 | if( iCol1==0 ) return 0; | ||
| 188497 | } | 189824 | } |
| 188498 | if( *p2==POS_COLUMN ){ | 189825 | if( *p2==POS_COLUMN ){ |
| 188499 | p2++; | 189826 | p2++; |
| 188500 | p2 += fts3GetVarint32(p2, &iCol2); | 189827 | p2 += fts3GetVarint32(p2, &iCol2); |
| 189828 | /* As above, iCol2==0 indicates corruption. */ | ||
| 189829 | if( iCol2==0 ) return 0; | ||
| 188501 | } | 189830 | } |
| 188502 | 189831 | ||
| 188503 | while( 1 ){ | 189832 | while( 1 ){ |
| @@ -191668,7 +192997,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ | |||
| 191668 | nTmp += p->pRight->pPhrase->doclist.nList; | 192997 | nTmp += p->pRight->pPhrase->doclist.nList; |
| 191669 | } | 192998 | } |
| 191670 | nTmp += p->pPhrase->doclist.nList; | 192999 | nTmp += p->pPhrase->doclist.nList; |
| 191671 | aTmp = sqlite3_malloc64(nTmp*2); | 193000 | aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); |
| 191672 | if( !aTmp ){ | 193001 | if( !aTmp ){ |
| 191673 | *pRc = SQLITE_NOMEM; | 193002 | *pRc = SQLITE_NOMEM; |
| 191674 | res = 0; | 193003 | res = 0; |
| @@ -193221,10 +194550,11 @@ static int getNextString( | |||
| 193221 | Fts3PhraseToken *pToken; | 194550 | Fts3PhraseToken *pToken; |
| 193222 | 194551 | ||
| 193223 | p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); | 194552 | p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); |
| 193224 | if( !p ) goto no_mem; | ||
| 193225 | |||
| 193226 | zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); | 194553 | zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); |
| 193227 | if( !zTemp ) goto no_mem; | 194554 | if( !zTemp || !p ){ |
| 194555 | rc = SQLITE_NOMEM; | ||
| 194556 | goto getnextstring_out; | ||
| 194557 | } | ||
| 193228 | 194558 | ||
| 193229 | assert( nToken==ii ); | 194559 | assert( nToken==ii ); |
| 193230 | pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; | 194560 | pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; |
| @@ -193239,9 +194569,6 @@ static int getNextString( | |||
| 193239 | nToken = ii+1; | 194569 | nToken = ii+1; |
| 193240 | } | 194570 | } |
| 193241 | } | 194571 | } |
| 193242 | |||
| 193243 | pModule->xClose(pCursor); | ||
| 193244 | pCursor = 0; | ||
| 193245 | } | 194572 | } |
| 193246 | 194573 | ||
| 193247 | if( rc==SQLITE_DONE ){ | 194574 | if( rc==SQLITE_DONE ){ |
| @@ -193249,7 +194576,10 @@ static int getNextString( | |||
| 193249 | char *zBuf = 0; | 194576 | char *zBuf = 0; |
| 193250 | 194577 | ||
| 193251 | p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); | 194578 | p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); |
| 193252 | if( !p ) goto no_mem; | 194579 | if( !p ){ |
| 194580 | rc = SQLITE_NOMEM; | ||
| 194581 | goto getnextstring_out; | ||
| 194582 | } | ||
| 193253 | memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); | 194583 | memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); |
| 193254 | p->eType = FTSQUERY_PHRASE; | 194584 | p->eType = FTSQUERY_PHRASE; |
| 193255 | p->pPhrase = (Fts3Phrase *)&p[1]; | 194585 | p->pPhrase = (Fts3Phrase *)&p[1]; |
| @@ -193257,11 +194587,9 @@ static int getNextString( | |||
| 193257 | p->pPhrase->nToken = nToken; | 194587 | p->pPhrase->nToken = nToken; |
| 193258 | 194588 | ||
| 193259 | zBuf = (char *)&p->pPhrase->aToken[nToken]; | 194589 | zBuf = (char *)&p->pPhrase->aToken[nToken]; |
| 194590 | assert( nTemp==0 || zTemp ); | ||
| 193260 | if( zTemp ){ | 194591 | if( zTemp ){ |
| 193261 | memcpy(zBuf, zTemp, nTemp); | 194592 | memcpy(zBuf, zTemp, nTemp); |
| 193262 | sqlite3_free(zTemp); | ||
| 193263 | }else{ | ||
| 193264 | assert( nTemp==0 ); | ||
| 193265 | } | 194593 | } |
| 193266 | 194594 | ||
| 193267 | for(jj=0; jj<p->pPhrase->nToken; jj++){ | 194595 | for(jj=0; jj<p->pPhrase->nToken; jj++){ |
| @@ -193271,17 +194599,17 @@ static int getNextString( | |||
| 193271 | rc = SQLITE_OK; | 194599 | rc = SQLITE_OK; |
| 193272 | } | 194600 | } |
| 193273 | 194601 | ||
| 193274 | *ppExpr = p; | 194602 | getnextstring_out: |
| 193275 | return rc; | ||
| 193276 | no_mem: | ||
| 193277 | |||
| 193278 | if( pCursor ){ | 194603 | if( pCursor ){ |
| 193279 | pModule->xClose(pCursor); | 194604 | pModule->xClose(pCursor); |
| 193280 | } | 194605 | } |
| 193281 | sqlite3_free(zTemp); | 194606 | sqlite3_free(zTemp); |
| 193282 | sqlite3_free(p); | 194607 | if( rc!=SQLITE_OK ){ |
| 193283 | *ppExpr = 0; | 194608 | sqlite3_free(p); |
| 193284 | return SQLITE_NOMEM; | 194609 | p = 0; |
| 194610 | } | ||
| 194611 | *ppExpr = p; | ||
| 194612 | return rc; | ||
| 193285 | } | 194613 | } |
| 193286 | 194614 | ||
| 193287 | /* | 194615 | /* |
| @@ -195475,11 +196803,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( | |||
| 195475 | 196803 | ||
| 195476 | #ifdef SQLITE_TEST | 196804 | #ifdef SQLITE_TEST |
| 195477 | 196805 | ||
| 195478 | #if defined(INCLUDE_SQLITE_TCL_H) | 196806 | #include "tclsqlite.h" |
| 195479 | # include "sqlite_tcl.h" | ||
| 195480 | #else | ||
| 195481 | # include "tcl.h" | ||
| 195482 | #endif | ||
| 195483 | /* #include <string.h> */ | 196807 | /* #include <string.h> */ |
| 195484 | 196808 | ||
| 195485 | /* | 196809 | /* |
| @@ -202706,6 +204030,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ | |||
| 202706 | return 1; | 204030 | return 1; |
| 202707 | } | 204031 | } |
| 202708 | 204032 | ||
| 204033 | assert( pIter->nSnippet>=0 ); | ||
| 202709 | pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; | 204034 | pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; |
| 202710 | for(i=0; i<pIter->nPhrase; i++){ | 204035 | for(i=0; i<pIter->nPhrase; i++){ |
| 202711 | SnippetPhrase *pPhrase = &pIter->aPhrase[i]; | 204036 | SnippetPhrase *pPhrase = &pIter->aPhrase[i]; |
| @@ -207699,7 +209024,9 @@ static u32 jsonLookupStep( | |||
| 207699 | zPath++; | 209024 | zPath++; |
| 207700 | if( zPath[0]=='"' ){ | 209025 | if( zPath[0]=='"' ){ |
| 207701 | zKey = zPath + 1; | 209026 | zKey = zPath + 1; |
| 207702 | for(i=1; zPath[i] && zPath[i]!='"'; i++){} | 209027 | for(i=1; zPath[i] && zPath[i]!='"'; i++){ |
| 209028 | if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; | ||
| 209029 | } | ||
| 207703 | nKey = i-1; | 209030 | nKey = i-1; |
| 207704 | if( zPath[i] ){ | 209031 | if( zPath[i] ){ |
| 207705 | i++; | 209032 | i++; |
| @@ -208709,10 +210036,16 @@ static void jsonExtractFunc( | |||
| 208709 | ** NUMBER ==> $[NUMBER] // PG compatible | 210036 | ** NUMBER ==> $[NUMBER] // PG compatible |
| 208710 | ** LABEL ==> $.LABEL // PG compatible | 210037 | ** LABEL ==> $.LABEL // PG compatible |
| 208711 | ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience | 210038 | ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience |
| 210039 | ** | ||
| 210040 | ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from | ||
| 210041 | ** the right of the array. Hence for negative NUMBER: | ||
| 210042 | ** | ||
| 210043 | ** NUMBER ==> $[#NUMBER] // PG compatible | ||
| 208712 | */ | 210044 | */ |
| 208713 | jsonStringInit(&jx, ctx); | 210045 | jsonStringInit(&jx, ctx); |
| 208714 | if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ | 210046 | if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ |
| 208715 | jsonAppendRawNZ(&jx, "[", 1); | 210047 | jsonAppendRawNZ(&jx, "[", 1); |
| 210048 | if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); | ||
| 208716 | jsonAppendRaw(&jx, zPath, nPath); | 210049 | jsonAppendRaw(&jx, zPath, nPath); |
| 208717 | jsonAppendRawNZ(&jx, "]", 2); | 210050 | jsonAppendRawNZ(&jx, "]", 2); |
| 208718 | }else if( jsonAllAlphanum(zPath, nPath) ){ | 210051 | }else if( jsonAllAlphanum(zPath, nPath) ){ |
| @@ -218454,6 +219787,27 @@ struct RbuFrame { | |||
| 218454 | u32 iWalFrame; | 219787 | u32 iWalFrame; |
| 218455 | }; | 219788 | }; |
| 218456 | 219789 | ||
| 219790 | #ifndef UNUSED_PARAMETER | ||
| 219791 | /* | ||
| 219792 | ** The following macros are used to suppress compiler warnings and to | ||
| 219793 | ** make it clear to human readers when a function parameter is deliberately | ||
| 219794 | ** left unused within the body of a function. This usually happens when | ||
| 219795 | ** a function is called via a function pointer. For example the | ||
| 219796 | ** implementation of an SQL aggregate step callback may not use the | ||
| 219797 | ** parameter indicating the number of arguments passed to the aggregate, | ||
| 219798 | ** if it knows that this is enforced elsewhere. | ||
| 219799 | ** | ||
| 219800 | ** When a function parameter is not used at all within the body of a function, | ||
| 219801 | ** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. | ||
| 219802 | ** However, these macros may also be used to suppress warnings related to | ||
| 219803 | ** parameters that may or may not be used depending on compilation options. | ||
| 219804 | ** For example those parameters only used in assert() statements. In these | ||
| 219805 | ** cases the parameters are named as per the usual conventions. | ||
| 219806 | */ | ||
| 219807 | #define UNUSED_PARAMETER(x) (void)(x) | ||
| 219808 | #define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) | ||
| 219809 | #endif | ||
| 219810 | |||
| 218457 | /* | 219811 | /* |
| 218458 | ** RBU handle. | 219812 | ** RBU handle. |
| 218459 | ** | 219813 | ** |
| @@ -218505,7 +219859,7 @@ struct sqlite3rbu { | |||
| 218505 | int rc; /* Value returned by last rbu_step() call */ | 219859 | int rc; /* Value returned by last rbu_step() call */ |
| 218506 | char *zErrmsg; /* Error message if rc!=SQLITE_OK */ | 219860 | char *zErrmsg; /* Error message if rc!=SQLITE_OK */ |
| 218507 | int nStep; /* Rows processed for current object */ | 219861 | int nStep; /* Rows processed for current object */ |
| 218508 | int nProgress; /* Rows processed for all objects */ | 219862 | sqlite3_int64 nProgress; /* Rows processed for all objects */ |
| 218509 | RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ | 219863 | RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ |
| 218510 | const char *zVfsName; /* Name of automatically created rbu vfs */ | 219864 | const char *zVfsName; /* Name of automatically created rbu vfs */ |
| 218511 | rbu_file *pTargetFd; /* File handle open on target db */ | 219865 | rbu_file *pTargetFd; /* File handle open on target db */ |
| @@ -218622,7 +219976,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ | |||
| 218622 | v = (v<<6) + c; | 219976 | v = (v<<6) + c; |
| 218623 | } | 219977 | } |
| 218624 | z--; | 219978 | z--; |
| 218625 | *pLen -= z - zStart; | 219979 | *pLen -= (int)(z - zStart); |
| 218626 | *pz = (char*)z; | 219980 | *pz = (char*)z; |
| 218627 | return v; | 219981 | return v; |
| 218628 | } | 219982 | } |
| @@ -218807,6 +220161,7 @@ static void rbuFossilDeltaFunc( | |||
| 218807 | char *aOut; | 220161 | char *aOut; |
| 218808 | 220162 | ||
| 218809 | assert( argc==2 ); | 220163 | assert( argc==2 ); |
| 220164 | UNUSED_PARAMETER(argc); | ||
| 218810 | 220165 | ||
| 218811 | nOrig = sqlite3_value_bytes(argv[0]); | 220166 | nOrig = sqlite3_value_bytes(argv[0]); |
| 218812 | aOrig = (const char*)sqlite3_value_blob(argv[0]); | 220167 | aOrig = (const char*)sqlite3_value_blob(argv[0]); |
| @@ -220386,13 +221741,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ | |||
| 220386 | else if( c==')' ){ | 221741 | else if( c==')' ){ |
| 220387 | nParen--; | 221742 | nParen--; |
| 220388 | if( nParen==0 ){ | 221743 | if( nParen==0 ){ |
| 220389 | int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; | 221744 | int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); |
| 220390 | pIter->aIdxCol[iIdxCol++].nSpan = nSpan; | 221745 | pIter->aIdxCol[iIdxCol++].nSpan = nSpan; |
| 220391 | i++; | 221746 | i++; |
| 220392 | break; | 221747 | break; |
| 220393 | } | 221748 | } |
| 220394 | }else if( c==',' && nParen==1 ){ | 221749 | }else if( c==',' && nParen==1 ){ |
| 220395 | int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; | 221750 | int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); |
| 220396 | pIter->aIdxCol[iIdxCol++].nSpan = nSpan; | 221751 | pIter->aIdxCol[iIdxCol++].nSpan = nSpan; |
| 220397 | pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; | 221752 | pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; |
| 220398 | }else if( c=='"' || c=='\'' || c=='`' ){ | 221753 | }else if( c=='"' || c=='\'' || c=='`' ){ |
| @@ -221082,6 +222437,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){ | |||
| 221082 | for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} | 222437 | for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} |
| 221083 | if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); | 222438 | if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); |
| 221084 | } | 222439 | } |
| 222440 | #else | ||
| 222441 | UNUSED_PARAMETER2(zBase,z); | ||
| 221085 | #endif | 222442 | #endif |
| 221086 | } | 222443 | } |
| 221087 | 222444 | ||
| @@ -221666,7 +223023,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ | |||
| 221666 | "(%d, %Q), " | 223023 | "(%d, %Q), " |
| 221667 | "(%d, %Q), " | 223024 | "(%d, %Q), " |
| 221668 | "(%d, %d), " | 223025 | "(%d, %d), " |
| 221669 | "(%d, %d), " | 223026 | "(%d, %lld), " |
| 221670 | "(%d, %lld), " | 223027 | "(%d, %lld), " |
| 221671 | "(%d, %lld), " | 223028 | "(%d, %lld), " |
| 221672 | "(%d, %lld), " | 223029 | "(%d, %lld), " |
| @@ -222024,6 +223381,7 @@ static void rbuIndexCntFunc( | |||
| 222024 | sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); | 223381 | sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); |
| 222025 | 223382 | ||
| 222026 | assert( nVal==1 ); | 223383 | assert( nVal==1 ); |
| 223384 | UNUSED_PARAMETER(nVal); | ||
| 222027 | 223385 | ||
| 222028 | rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, | 223386 | rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, |
| 222029 | sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " | 223387 | sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " |
| @@ -222299,7 +223657,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( | |||
| 222299 | ){ | 223657 | ){ |
| 222300 | if( zTarget==0 ){ return rbuMisuseError(); } | 223658 | if( zTarget==0 ){ return rbuMisuseError(); } |
| 222301 | if( zState ){ | 223659 | if( zState ){ |
| 222302 | int n = strlen(zState); | 223660 | size_t n = strlen(zState); |
| 222303 | if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ | 223661 | if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ |
| 222304 | return rbuMisuseError(); | 223662 | return rbuMisuseError(); |
| 222305 | } | 223663 | } |
| @@ -222516,6 +223874,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ | |||
| 222516 | */ | 223874 | */ |
| 222517 | static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ | 223875 | static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ |
| 222518 | int rc = SQLITE_OK; | 223876 | int rc = SQLITE_OK; |
| 223877 | UNUSED_PARAMETER(pArg); | ||
| 222519 | #if defined(_WIN32_WCE) | 223878 | #if defined(_WIN32_WCE) |
| 222520 | { | 223879 | { |
| 222521 | LPWSTR zWideOld; | 223880 | LPWSTR zWideOld; |
| @@ -223420,6 +224779,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | |||
| 223420 | ** No-op. | 224779 | ** No-op. |
| 223421 | */ | 224780 | */ |
| 223422 | static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ | 224781 | static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ |
| 224782 | UNUSED_PARAMETER(pVfs); | ||
| 224783 | UNUSED_PARAMETER(a); | ||
| 224784 | UNUSED_PARAMETER(b); | ||
| 223423 | return 0; | 224785 | return 0; |
| 223424 | } | 224786 | } |
| 223425 | 224787 | ||
| @@ -223818,6 +225180,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 223818 | pIdxInfo->orderByConsumed = 1; | 225180 | pIdxInfo->orderByConsumed = 1; |
| 223819 | pIdxInfo->idxNum |= 0x08; | 225181 | pIdxInfo->idxNum |= 0x08; |
| 223820 | } | 225182 | } |
| 225183 | pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX; | ||
| 223821 | 225184 | ||
| 223822 | return SQLITE_OK; | 225185 | return SQLITE_OK; |
| 223823 | } | 225186 | } |
| @@ -224475,7 +225838,13 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; } | |||
| 224475 | ** | 225838 | ** |
| 224476 | ** The data field of sqlite_dbpage table can be updated. The new | 225839 | ** The data field of sqlite_dbpage table can be updated. The new |
| 224477 | ** value must be a BLOB which is the correct page size, otherwise the | 225840 | ** value must be a BLOB which is the correct page size, otherwise the |
| 224478 | ** update fails. Rows may not be deleted or inserted. | 225841 | ** update fails. INSERT operations also work, and operate as if they |
| 225842 | ** where REPLACE. The size of the database can be extended by INSERT-ing | ||
| 225843 | ** new pages on the end. | ||
| 225844 | ** | ||
| 225845 | ** Rows may not be deleted. However, doing an INSERT to page number N | ||
| 225846 | ** with NULL page data causes the N-th page and all subsequent pages to be | ||
| 225847 | ** deleted and the database to be truncated. | ||
| 224479 | */ | 225848 | */ |
| 224480 | 225849 | ||
| 224481 | /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ | 225850 | /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ |
| @@ -224498,6 +225867,8 @@ struct DbpageCursor { | |||
| 224498 | struct DbpageTable { | 225867 | struct DbpageTable { |
| 224499 | sqlite3_vtab base; /* Base class. Must be first */ | 225868 | sqlite3_vtab base; /* Base class. Must be first */ |
| 224500 | sqlite3 *db; /* The database */ | 225869 | sqlite3 *db; /* The database */ |
| 225870 | int iDbTrunc; /* Database to truncate */ | ||
| 225871 | Pgno pgnoTrunc; /* Size to truncate to */ | ||
| 224501 | }; | 225872 | }; |
| 224502 | 225873 | ||
| 224503 | /* Columns */ | 225874 | /* Columns */ |
| @@ -224506,7 +225877,6 @@ struct DbpageTable { | |||
| 224506 | #define DBPAGE_COLUMN_SCHEMA 2 | 225877 | #define DBPAGE_COLUMN_SCHEMA 2 |
| 224507 | 225878 | ||
| 224508 | 225879 | ||
| 224509 | |||
| 224510 | /* | 225880 | /* |
| 224511 | ** Connect to or create a dbpagevfs virtual table. | 225881 | ** Connect to or create a dbpagevfs virtual table. |
| 224512 | */ | 225882 | */ |
| @@ -224768,11 +226138,11 @@ static int dbpageUpdate( | |||
| 224768 | DbPage *pDbPage = 0; | 226138 | DbPage *pDbPage = 0; |
| 224769 | int rc = SQLITE_OK; | 226139 | int rc = SQLITE_OK; |
| 224770 | char *zErr = 0; | 226140 | char *zErr = 0; |
| 224771 | const char *zSchema; | ||
| 224772 | int iDb; | 226141 | int iDb; |
| 224773 | Btree *pBt; | 226142 | Btree *pBt; |
| 224774 | Pager *pPager; | 226143 | Pager *pPager; |
| 224775 | int szPage; | 226144 | int szPage; |
| 226145 | int isInsert; | ||
| 224776 | 226146 | ||
| 224777 | (void)pRowid; | 226147 | (void)pRowid; |
| 224778 | if( pTab->db->flags & SQLITE_Defensive ){ | 226148 | if( pTab->db->flags & SQLITE_Defensive ){ |
| @@ -224783,21 +226153,29 @@ static int dbpageUpdate( | |||
| 224783 | zErr = "cannot delete"; | 226153 | zErr = "cannot delete"; |
| 224784 | goto update_fail; | 226154 | goto update_fail; |
| 224785 | } | 226155 | } |
| 224786 | pgno = sqlite3_value_int(argv[0]); | 226156 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ |
| 224787 | if( sqlite3_value_type(argv[0])==SQLITE_NULL | 226157 | pgno = (Pgno)sqlite3_value_int(argv[2]); |
| 224788 | || (Pgno)sqlite3_value_int(argv[1])!=pgno | 226158 | isInsert = 1; |
| 224789 | ){ | 226159 | }else{ |
| 224790 | zErr = "cannot insert"; | 226160 | pgno = sqlite3_value_int(argv[0]); |
| 224791 | goto update_fail; | 226161 | if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ |
| 226162 | zErr = "cannot insert"; | ||
| 226163 | goto update_fail; | ||
| 226164 | } | ||
| 226165 | isInsert = 0; | ||
| 224792 | } | 226166 | } |
| 224793 | zSchema = (const char*)sqlite3_value_text(argv[4]); | 226167 | if( sqlite3_value_type(argv[4])==SQLITE_NULL ){ |
| 224794 | iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; | 226168 | iDb = 0; |
| 224795 | if( NEVER(iDb<0) ){ | 226169 | }else{ |
| 224796 | zErr = "no such schema"; | 226170 | const char *zSchema = (const char*)sqlite3_value_text(argv[4]); |
| 224797 | goto update_fail; | 226171 | iDb = sqlite3FindDbName(pTab->db, zSchema); |
| 226172 | if( iDb<0 ){ | ||
| 226173 | zErr = "no such schema"; | ||
| 226174 | goto update_fail; | ||
| 226175 | } | ||
| 224798 | } | 226176 | } |
| 224799 | pBt = pTab->db->aDb[iDb].pBt; | 226177 | pBt = pTab->db->aDb[iDb].pBt; |
| 224800 | if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ | 226178 | if( pgno<1 || NEVER(pBt==0) ){ |
| 224801 | zErr = "bad page number"; | 226179 | zErr = "bad page number"; |
| 224802 | goto update_fail; | 226180 | goto update_fail; |
| 224803 | } | 226181 | } |
| @@ -224805,18 +226183,25 @@ static int dbpageUpdate( | |||
| 224805 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB | 226183 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB |
| 224806 | || sqlite3_value_bytes(argv[3])!=szPage | 226184 | || sqlite3_value_bytes(argv[3])!=szPage |
| 224807 | ){ | 226185 | ){ |
| 224808 | zErr = "bad page value"; | 226186 | if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ |
| 224809 | goto update_fail; | 226187 | /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and |
| 226188 | ** all subsequent pages to be deleted. */ | ||
| 226189 | pTab->iDbTrunc = iDb; | ||
| 226190 | pgno--; | ||
| 226191 | pTab->pgnoTrunc = pgno; | ||
| 226192 | }else{ | ||
| 226193 | zErr = "bad page value"; | ||
| 226194 | goto update_fail; | ||
| 226195 | } | ||
| 224810 | } | 226196 | } |
| 224811 | pPager = sqlite3BtreePager(pBt); | 226197 | pPager = sqlite3BtreePager(pBt); |
| 224812 | rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); | 226198 | rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); |
| 224813 | if( rc==SQLITE_OK ){ | 226199 | if( rc==SQLITE_OK ){ |
| 224814 | const void *pData = sqlite3_value_blob(argv[3]); | 226200 | const void *pData = sqlite3_value_blob(argv[3]); |
| 224815 | assert( pData!=0 || pTab->db->mallocFailed ); | 226201 | if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){ |
| 224816 | if( pData | 226202 | unsigned char *aPage = sqlite3PagerGetData(pDbPage); |
| 224817 | && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK | 226203 | memcpy(aPage, pData, szPage); |
| 224818 | ){ | 226204 | pTab->pgnoTrunc = 0; |
| 224819 | memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); | ||
| 224820 | } | 226205 | } |
| 224821 | } | 226206 | } |
| 224822 | sqlite3PagerUnref(pDbPage); | 226207 | sqlite3PagerUnref(pDbPage); |
| @@ -224840,9 +226225,31 @@ static int dbpageBegin(sqlite3_vtab *pVtab){ | |||
| 224840 | Btree *pBt = db->aDb[i].pBt; | 226225 | Btree *pBt = db->aDb[i].pBt; |
| 224841 | if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); | 226226 | if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); |
| 224842 | } | 226227 | } |
| 226228 | pTab->pgnoTrunc = 0; | ||
| 224843 | return SQLITE_OK; | 226229 | return SQLITE_OK; |
| 224844 | } | 226230 | } |
| 224845 | 226231 | ||
| 226232 | /* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT | ||
| 226233 | */ | ||
| 226234 | static int dbpageSync(sqlite3_vtab *pVtab){ | ||
| 226235 | DbpageTable *pTab = (DbpageTable *)pVtab; | ||
| 226236 | if( pTab->pgnoTrunc>0 ){ | ||
| 226237 | Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; | ||
| 226238 | Pager *pPager = sqlite3BtreePager(pBt); | ||
| 226239 | sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); | ||
| 226240 | } | ||
| 226241 | pTab->pgnoTrunc = 0; | ||
| 226242 | return SQLITE_OK; | ||
| 226243 | } | ||
| 226244 | |||
| 226245 | /* Cancel any pending truncate. | ||
| 226246 | */ | ||
| 226247 | static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ | ||
| 226248 | DbpageTable *pTab = (DbpageTable *)pVtab; | ||
| 226249 | pTab->pgnoTrunc = 0; | ||
| 226250 | (void)notUsed1; | ||
| 226251 | return SQLITE_OK; | ||
| 226252 | } | ||
| 224846 | 226253 | ||
| 224847 | /* | 226254 | /* |
| 224848 | ** Invoke this routine to register the "dbpage" virtual table module | 226255 | ** Invoke this routine to register the "dbpage" virtual table module |
| @@ -224864,14 +226271,14 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ | |||
| 224864 | dbpageRowid, /* xRowid - read data */ | 226271 | dbpageRowid, /* xRowid - read data */ |
| 224865 | dbpageUpdate, /* xUpdate */ | 226272 | dbpageUpdate, /* xUpdate */ |
| 224866 | dbpageBegin, /* xBegin */ | 226273 | dbpageBegin, /* xBegin */ |
| 224867 | 0, /* xSync */ | 226274 | dbpageSync, /* xSync */ |
| 224868 | 0, /* xCommit */ | 226275 | 0, /* xCommit */ |
| 224869 | 0, /* xRollback */ | 226276 | 0, /* xRollback */ |
| 224870 | 0, /* xFindMethod */ | 226277 | 0, /* xFindMethod */ |
| 224871 | 0, /* xRename */ | 226278 | 0, /* xRename */ |
| 224872 | 0, /* xSavepoint */ | 226279 | 0, /* xSavepoint */ |
| 224873 | 0, /* xRelease */ | 226280 | 0, /* xRelease */ |
| 224874 | 0, /* xRollbackTo */ | 226281 | dbpageRollbackTo, /* xRollbackTo */ |
| 224875 | 0, /* xShadowName */ | 226282 | 0, /* xShadowName */ |
| 224876 | 0 /* xIntegrity */ | 226283 | 0 /* xIntegrity */ |
| 224877 | }; | 226284 | }; |
| @@ -224959,6 +226366,10 @@ struct SessionBuffer { | |||
| 224959 | ** input data. Input data may be supplied either as a single large buffer | 226366 | ** input data. Input data may be supplied either as a single large buffer |
| 224960 | ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. | 226367 | ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. |
| 224961 | ** sqlite3changeset_start_strm()). | 226368 | ** sqlite3changeset_start_strm()). |
| 226369 | ** | ||
| 226370 | ** bNoDiscard: | ||
| 226371 | ** If true, then the only time data is discarded is as a result of explicit | ||
| 226372 | ** sessionDiscardData() calls. Not within every sessionInputBuffer() call. | ||
| 224962 | */ | 226373 | */ |
| 224963 | struct SessionInput { | 226374 | struct SessionInput { |
| 224964 | int bNoDiscard; /* If true, do not discard in InputBuffer() */ | 226375 | int bNoDiscard; /* If true, do not discard in InputBuffer() */ |
| @@ -226642,16 +228053,19 @@ static void sessionPreupdateOneChange( | |||
| 226642 | for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ | 228053 | for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ |
| 226643 | sqlite3_value *p = 0; | 228054 | sqlite3_value *p = 0; |
| 226644 | if( op!=SQLITE_INSERT ){ | 228055 | if( op!=SQLITE_INSERT ){ |
| 226645 | TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); | 228056 | /* This may fail if the column has a non-NULL default and was added |
| 226646 | assert( trc==SQLITE_OK ); | 228057 | ** using ALTER TABLE ADD COLUMN after this record was created. */ |
| 228058 | rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p); | ||
| 226647 | }else if( pTab->abPK[i] ){ | 228059 | }else if( pTab->abPK[i] ){ |
| 226648 | TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); | 228060 | TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); |
| 226649 | assert( trc==SQLITE_OK ); | 228061 | assert( trc==SQLITE_OK ); |
| 226650 | } | 228062 | } |
| 226651 | 228063 | ||
| 226652 | /* This may fail if SQLite value p contains a utf-16 string that must | 228064 | if( rc==SQLITE_OK ){ |
| 226653 | ** be converted to utf-8 and an OOM error occurs while doing so. */ | 228065 | /* This may fail if SQLite value p contains a utf-16 string that must |
| 226654 | rc = sessionSerializeValue(0, p, &nByte); | 228066 | ** be converted to utf-8 and an OOM error occurs while doing so. */ |
| 228067 | rc = sessionSerializeValue(0, p, &nByte); | ||
| 228068 | } | ||
| 226655 | if( rc!=SQLITE_OK ) goto error_out; | 228069 | if( rc!=SQLITE_OK ) goto error_out; |
| 226656 | } | 228070 | } |
| 226657 | if( pTab->bRowid ){ | 228071 | if( pTab->bRowid ){ |
| @@ -230009,15 +231423,21 @@ static int sessionChangesetApply( | |||
| 230009 | int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ | 231423 | int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ |
| 230010 | SessionApplyCtx sApply; /* changeset_apply() context object */ | 231424 | SessionApplyCtx sApply; /* changeset_apply() context object */ |
| 230011 | int bPatchset; | 231425 | int bPatchset; |
| 231426 | u64 savedFlag = db->flags & SQLITE_FkNoAction; | ||
| 230012 | 231427 | ||
| 230013 | assert( xConflict!=0 ); | 231428 | assert( xConflict!=0 ); |
| 230014 | 231429 | ||
| 231430 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); | ||
| 231431 | if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ | ||
| 231432 | db->flags |= ((u64)SQLITE_FkNoAction); | ||
| 231433 | db->aDb[0].pSchema->schema_cookie -= 32; | ||
| 231434 | } | ||
| 231435 | |||
| 230015 | pIter->in.bNoDiscard = 1; | 231436 | pIter->in.bNoDiscard = 1; |
| 230016 | memset(&sApply, 0, sizeof(sApply)); | 231437 | memset(&sApply, 0, sizeof(sApply)); |
| 230017 | sApply.bRebase = (ppRebase && pnRebase); | 231438 | sApply.bRebase = (ppRebase && pnRebase); |
| 230018 | sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); | 231439 | sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); |
| 230019 | sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); | 231440 | sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); |
| 230020 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); | ||
| 230021 | if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ | 231441 | if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ |
| 230022 | rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); | 231442 | rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); |
| 230023 | } | 231443 | } |
| @@ -230179,6 +231599,12 @@ static int sessionChangesetApply( | |||
| 230179 | sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ | 231599 | sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ |
| 230180 | sqlite3_free((char*)sApply.constraints.aBuf); | 231600 | sqlite3_free((char*)sApply.constraints.aBuf); |
| 230181 | sqlite3_free((char*)sApply.rebase.aBuf); | 231601 | sqlite3_free((char*)sApply.rebase.aBuf); |
| 231602 | |||
| 231603 | if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ | ||
| 231604 | assert( db->flags & SQLITE_FkNoAction ); | ||
| 231605 | db->flags &= ~((u64)SQLITE_FkNoAction); | ||
| 231606 | db->aDb[0].pSchema->schema_cookie -= 32; | ||
| 231607 | } | ||
| 230182 | sqlite3_mutex_leave(sqlite3_db_mutex(db)); | 231608 | sqlite3_mutex_leave(sqlite3_db_mutex(db)); |
| 230183 | return rc; | 231609 | return rc; |
| 230184 | } | 231610 | } |
| @@ -230207,12 +231633,6 @@ SQLITE_API int sqlite3changeset_apply_v2( | |||
| 230207 | sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ | 231633 | sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ |
| 230208 | int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); | 231634 | int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); |
| 230209 | int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); | 231635 | int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); |
| 230210 | u64 savedFlag = db->flags & SQLITE_FkNoAction; | ||
| 230211 | |||
| 230212 | if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ | ||
| 230213 | db->flags |= ((u64)SQLITE_FkNoAction); | ||
| 230214 | db->aDb[0].pSchema->schema_cookie -= 32; | ||
| 230215 | } | ||
| 230216 | 231636 | ||
| 230217 | if( rc==SQLITE_OK ){ | 231637 | if( rc==SQLITE_OK ){ |
| 230218 | rc = sessionChangesetApply( | 231638 | rc = sessionChangesetApply( |
| @@ -230220,11 +231640,6 @@ SQLITE_API int sqlite3changeset_apply_v2( | |||
| 230220 | ); | 231640 | ); |
| 230221 | } | 231641 | } |
| 230222 | 231642 | ||
| 230223 | if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ | ||
| 230224 | assert( db->flags & SQLITE_FkNoAction ); | ||
| 230225 | db->flags &= ~((u64)SQLITE_FkNoAction); | ||
| 230226 | db->aDb[0].pSchema->schema_cookie -= 32; | ||
| 230227 | } | ||
| 230228 | return rc; | 231643 | return rc; |
| 230229 | } | 231644 | } |
| 230230 | 231645 | ||
| @@ -230545,6 +231960,9 @@ static int sessionChangesetExtendRecord( | |||
| 230545 | sessionAppendBlob(pOut, aRec, nRec, &rc); | 231960 | sessionAppendBlob(pOut, aRec, nRec, &rc); |
| 230546 | if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ | 231961 | if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ |
| 230547 | rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); | 231962 | rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); |
| 231963 | if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){ | ||
| 231964 | rc = sqlite3_errcode(pGrp->db); | ||
| 231965 | } | ||
| 230548 | } | 231966 | } |
| 230549 | for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){ | 231967 | for(ii=nCol; rc==SQLITE_OK && ii<pTab->nCol; ii++){ |
| 230550 | int eType = sqlite3_column_type(pTab->pDfltStmt, ii); | 231968 | int eType = sqlite3_column_type(pTab->pDfltStmt, ii); |
| @@ -230561,6 +231979,7 @@ static int sessionChangesetExtendRecord( | |||
| 230561 | } | 231979 | } |
| 230562 | if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ | 231980 | if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ |
| 230563 | sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); | 231981 | sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); |
| 231982 | pOut->nBuf += 8; | ||
| 230564 | } | 231983 | } |
| 230565 | break; | 231984 | break; |
| 230566 | } | 231985 | } |
| @@ -230700,6 +232119,8 @@ static int sessionOneChangeToHash( | |||
| 230700 | u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; | 232119 | u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; |
| 230701 | int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; | 232120 | int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; |
| 230702 | 232121 | ||
| 232122 | assert( nRec>0 ); | ||
| 232123 | |||
| 230703 | /* Ensure that only changesets, or only patchsets, but not a mixture | 232124 | /* Ensure that only changesets, or only patchsets, but not a mixture |
| 230704 | ** of both, are being combined. It is an error to try to combine a | 232125 | ** of both, are being combined. It is an error to try to combine a |
| 230705 | ** changeset and a patchset. */ | 232126 | ** changeset and a patchset. */ |
| @@ -230777,6 +232198,7 @@ static int sessionChangesetToHash( | |||
| 230777 | int nRec; | 232198 | int nRec; |
| 230778 | int rc = SQLITE_OK; | 232199 | int rc = SQLITE_OK; |
| 230779 | 232200 | ||
| 232201 | pIter->in.bNoDiscard = 1; | ||
| 230780 | while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ | 232202 | while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ |
| 230781 | rc = sessionOneChangeToHash(pGrp, pIter, bRebase); | 232203 | rc = sessionOneChangeToHash(pGrp, pIter, bRebase); |
| 230782 | if( rc!=SQLITE_OK ) break; | 232204 | if( rc!=SQLITE_OK ) break; |
| @@ -231408,7 +232830,27 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ | |||
| 231408 | /************** End of sqlite3session.c **************************************/ | 232830 | /************** End of sqlite3session.c **************************************/ |
| 231409 | /************** Begin file fts5.c ********************************************/ | 232831 | /************** Begin file fts5.c ********************************************/ |
| 231410 | 232832 | ||
| 231411 | 232833 | /* | |
| 232834 | ** This, the "fts5.c" source file, is a composite file that is itself | ||
| 232835 | ** assembled from the following files: | ||
| 232836 | ** | ||
| 232837 | ** fts5.h | ||
| 232838 | ** fts5Int.h | ||
| 232839 | ** fts5parse.h <--- Generated from fts5parse.y by Lemon | ||
| 232840 | ** fts5parse.c <--- Generated from fts5parse.y by Lemon | ||
| 232841 | ** fts5_aux.c | ||
| 232842 | ** fts5_buffer.c | ||
| 232843 | ** fts5_config.c | ||
| 232844 | ** fts5_expr.c | ||
| 232845 | ** fts5_hash.c | ||
| 232846 | ** fts5_index.c | ||
| 232847 | ** fts5_main.c | ||
| 232848 | ** fts5_storage.c | ||
| 232849 | ** fts5_tokenize.c | ||
| 232850 | ** fts5_unicode2.c | ||
| 232851 | ** fts5_varint.c | ||
| 232852 | ** fts5_vocab.c | ||
| 232853 | */ | ||
| 231412 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) | 232854 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) |
| 231413 | 232855 | ||
| 231414 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) | 232856 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| @@ -231418,6 +232860,12 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ | |||
| 231418 | # undef NDEBUG | 232860 | # undef NDEBUG |
| 231419 | #endif | 232861 | #endif |
| 231420 | 232862 | ||
| 232863 | #ifdef HAVE_STDINT_H | ||
| 232864 | /* #include <stdint.h> */ | ||
| 232865 | #endif | ||
| 232866 | #ifdef HAVE_INTTYPES_H | ||
| 232867 | /* #include <inttypes.h> */ | ||
| 232868 | #endif | ||
| 231421 | /* | 232869 | /* |
| 231422 | ** 2014 May 31 | 232870 | ** 2014 May 31 |
| 231423 | ** | 232871 | ** |
| @@ -231658,6 +233106,10 @@ struct Fts5PhraseIter { | |||
| 231658 | ** (i.e. if it is a contentless table), then this API always iterates | 233106 | ** (i.e. if it is a contentless table), then this API always iterates |
| 231659 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). | 233107 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). |
| 231660 | ** | 233108 | ** |
| 233109 | ** In all cases, matches are visited in (column ASC, offset ASC) order. | ||
| 233110 | ** i.e. all those in column 0, sorted by offset, followed by those in | ||
| 233111 | ** column 1, etc. | ||
| 233112 | ** | ||
| 231661 | ** xPhraseNext() | 233113 | ** xPhraseNext() |
| 231662 | ** See xPhraseFirst above. | 233114 | ** See xPhraseFirst above. |
| 231663 | ** | 233115 | ** |
| @@ -231724,9 +233176,32 @@ struct Fts5PhraseIter { | |||
| 231724 | ** | 233176 | ** |
| 231725 | ** This API can be quite slow if used with an FTS5 table created with the | 233177 | ** This API can be quite slow if used with an FTS5 table created with the |
| 231726 | ** "detail=none" or "detail=column" option. | 233178 | ** "detail=none" or "detail=column" option. |
| 233179 | ** | ||
| 233180 | ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) | ||
| 233181 | ** If parameter iCol is less than zero, or greater than or equal to the | ||
| 233182 | ** number of columns in the table, SQLITE_RANGE is returned. | ||
| 233183 | ** | ||
| 233184 | ** Otherwise, this function attempts to retrieve the locale associated | ||
| 233185 | ** with column iCol of the current row. Usually, there is no associated | ||
| 233186 | ** locale, and output parameters (*pzLocale) and (*pnLocale) are set | ||
| 233187 | ** to NULL and 0, respectively. However, if the fts5_locale() function | ||
| 233188 | ** was used to associate a locale with the value when it was inserted | ||
| 233189 | ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated | ||
| 233190 | ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) | ||
| 233191 | ** is set to the size in bytes of the buffer, not including the | ||
| 233192 | ** nul-terminator. | ||
| 233193 | ** | ||
| 233194 | ** If successful, SQLITE_OK is returned. Or, if an error occurs, an | ||
| 233195 | ** SQLite error code is returned. The final value of the output parameters | ||
| 233196 | ** is undefined in this case. | ||
| 233197 | ** | ||
| 233198 | ** xTokenize_v2: | ||
| 233199 | ** Tokenize text using the tokenizer belonging to the FTS5 table. This | ||
| 233200 | ** API is the same as the xTokenize() API, except that it allows a tokenizer | ||
| 233201 | ** locale to be specified. | ||
| 231727 | */ | 233202 | */ |
| 231728 | struct Fts5ExtensionApi { | 233203 | struct Fts5ExtensionApi { |
| 231729 | int iVersion; /* Currently always set to 3 */ | 233204 | int iVersion; /* Currently always set to 4 */ |
| 231730 | 233205 | ||
| 231731 | void *(*xUserData)(Fts5Context*); | 233206 | void *(*xUserData)(Fts5Context*); |
| 231732 | 233207 | ||
| @@ -231768,6 +233243,15 @@ struct Fts5ExtensionApi { | |||
| 231768 | const char **ppToken, int *pnToken | 233243 | const char **ppToken, int *pnToken |
| 231769 | ); | 233244 | ); |
| 231770 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | 233245 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); |
| 233246 | |||
| 233247 | /* Below this point are iVersion>=4 only */ | ||
| 233248 | int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); | ||
| 233249 | int (*xTokenize_v2)(Fts5Context*, | ||
| 233250 | const char *pText, int nText, /* Text to tokenize */ | ||
| 233251 | const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ | ||
| 233252 | void *pCtx, /* Context passed to xToken() */ | ||
| 233253 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ | ||
| 233254 | ); | ||
| 231771 | }; | 233255 | }; |
| 231772 | 233256 | ||
| 231773 | /* | 233257 | /* |
| @@ -231788,7 +233272,7 @@ struct Fts5ExtensionApi { | |||
| 231788 | ** A tokenizer instance is required to actually tokenize text. | 233272 | ** A tokenizer instance is required to actually tokenize text. |
| 231789 | ** | 233273 | ** |
| 231790 | ** The first argument passed to this function is a copy of the (void*) | 233274 | ** The first argument passed to this function is a copy of the (void*) |
| 231791 | ** pointer provided by the application when the fts5_tokenizer object | 233275 | ** pointer provided by the application when the fts5_tokenizer_v2 object |
| 231792 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). | 233276 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). |
| 231793 | ** The second and third arguments are an array of nul-terminated strings | 233277 | ** The second and third arguments are an array of nul-terminated strings |
| 231794 | ** containing the tokenizer arguments, if any, specified following the | 233278 | ** containing the tokenizer arguments, if any, specified following the |
| @@ -231812,7 +233296,7 @@ struct Fts5ExtensionApi { | |||
| 231812 | ** argument passed to this function is a pointer to an Fts5Tokenizer object | 233296 | ** argument passed to this function is a pointer to an Fts5Tokenizer object |
| 231813 | ** returned by an earlier call to xCreate(). | 233297 | ** returned by an earlier call to xCreate(). |
| 231814 | ** | 233298 | ** |
| 231815 | ** The second argument indicates the reason that FTS5 is requesting | 233299 | ** The third argument indicates the reason that FTS5 is requesting |
| 231816 | ** tokenization of the supplied text. This is always one of the following | 233300 | ** tokenization of the supplied text. This is always one of the following |
| 231817 | ** four values: | 233301 | ** four values: |
| 231818 | ** | 233302 | ** |
| @@ -231836,6 +233320,13 @@ struct Fts5ExtensionApi { | |||
| 231836 | ** on a columnsize=0 database. | 233320 | ** on a columnsize=0 database. |
| 231837 | ** </ul> | 233321 | ** </ul> |
| 231838 | ** | 233322 | ** |
| 233323 | ** The sixth and seventh arguments passed to xTokenize() - pLocale and | ||
| 233324 | ** nLocale - are a pointer to a buffer containing the locale to use for | ||
| 233325 | ** tokenization (e.g. "en_US") and its size in bytes, respectively. The | ||
| 233326 | ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in | ||
| 233327 | ** which case nLocale is always 0) to indicate that the tokenizer should | ||
| 233328 | ** use its default locale. | ||
| 233329 | ** | ||
| 231839 | ** For each token in the input string, the supplied callback xToken() must | 233330 | ** For each token in the input string, the supplied callback xToken() must |
| 231840 | ** be invoked. The first argument to it should be a copy of the pointer | 233331 | ** be invoked. The first argument to it should be a copy of the pointer |
| 231841 | ** passed as the second argument to xTokenize(). The third and fourth | 233332 | ** passed as the second argument to xTokenize(). The third and fourth |
| @@ -231859,6 +233350,30 @@ struct Fts5ExtensionApi { | |||
| 231859 | ** may abandon the tokenization and return any error code other than | 233350 | ** may abandon the tokenization and return any error code other than |
| 231860 | ** SQLITE_OK or SQLITE_DONE. | 233351 | ** SQLITE_OK or SQLITE_DONE. |
| 231861 | ** | 233352 | ** |
| 233353 | ** If the tokenizer is registered using an fts5_tokenizer_v2 object, | ||
| 233354 | ** then the xTokenize() method has two additional arguments - pLocale | ||
| 233355 | ** and nLocale. These specify the locale that the tokenizer should use | ||
| 233356 | ** for the current request. If pLocale and nLocale are both 0, then the | ||
| 233357 | ** tokenizer should use its default locale. Otherwise, pLocale points to | ||
| 233358 | ** an nLocale byte buffer containing the name of the locale to use as utf-8 | ||
| 233359 | ** text. pLocale is not nul-terminated. | ||
| 233360 | ** | ||
| 233361 | ** FTS5_TOKENIZER | ||
| 233362 | ** | ||
| 233363 | ** There is also an fts5_tokenizer object. This is an older, deprecated, | ||
| 233364 | ** version of fts5_tokenizer_v2. It is similar except that: | ||
| 233365 | ** | ||
| 233366 | ** <ul> | ||
| 233367 | ** <li> There is no "iVersion" field, and | ||
| 233368 | ** <li> The xTokenize() method does not take a locale argument. | ||
| 233369 | ** </ul> | ||
| 233370 | ** | ||
| 233371 | ** Legacy fts5_tokenizer tokenizers must be registered using the | ||
| 233372 | ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). | ||
| 233373 | ** | ||
| 233374 | ** Tokenizer implementations registered using either API may be retrieved | ||
| 233375 | ** using both xFindTokenizer() and xFindTokenizer_v2(). | ||
| 233376 | ** | ||
| 231862 | ** SYNONYM SUPPORT | 233377 | ** SYNONYM SUPPORT |
| 231863 | ** | 233378 | ** |
| 231864 | ** Custom tokenizers may also support synonyms. Consider a case in which a | 233379 | ** Custom tokenizers may also support synonyms. Consider a case in which a |
| @@ -231967,6 +233482,33 @@ struct Fts5ExtensionApi { | |||
| 231967 | ** inefficient. | 233482 | ** inefficient. |
| 231968 | */ | 233483 | */ |
| 231969 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 233484 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 233485 | typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; | ||
| 233486 | struct fts5_tokenizer_v2 { | ||
| 233487 | int iVersion; /* Currently always 2 */ | ||
| 233488 | |||
| 233489 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | ||
| 233490 | void (*xDelete)(Fts5Tokenizer*); | ||
| 233491 | int (*xTokenize)(Fts5Tokenizer*, | ||
| 233492 | void *pCtx, | ||
| 233493 | int flags, /* Mask of FTS5_TOKENIZE_* flags */ | ||
| 233494 | const char *pText, int nText, | ||
| 233495 | const char *pLocale, int nLocale, | ||
| 233496 | int (*xToken)( | ||
| 233497 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ | ||
| 233498 | int tflags, /* Mask of FTS5_TOKEN_* flags */ | ||
| 233499 | const char *pToken, /* Pointer to buffer containing token */ | ||
| 233500 | int nToken, /* Size of token in bytes */ | ||
| 233501 | int iStart, /* Byte offset of token within input text */ | ||
| 233502 | int iEnd /* Byte offset of end of token within input text */ | ||
| 233503 | ) | ||
| 233504 | ); | ||
| 233505 | }; | ||
| 233506 | |||
| 233507 | /* | ||
| 233508 | ** New code should use the fts5_tokenizer_v2 type to define tokenizer | ||
| 233509 | ** implementations. The following type is included for legacy applications | ||
| 233510 | ** that still use it. | ||
| 233511 | */ | ||
| 231970 | typedef struct fts5_tokenizer fts5_tokenizer; | 233512 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 231971 | struct fts5_tokenizer { | 233513 | struct fts5_tokenizer { |
| 231972 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | 233514 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); |
| @@ -231986,6 +233528,7 @@ struct fts5_tokenizer { | |||
| 231986 | ); | 233528 | ); |
| 231987 | }; | 233529 | }; |
| 231988 | 233530 | ||
| 233531 | |||
| 231989 | /* Flags that may be passed as the third argument to xTokenize() */ | 233532 | /* Flags that may be passed as the third argument to xTokenize() */ |
| 231990 | #define FTS5_TOKENIZE_QUERY 0x0001 | 233533 | #define FTS5_TOKENIZE_QUERY 0x0001 |
| 231991 | #define FTS5_TOKENIZE_PREFIX 0x0002 | 233534 | #define FTS5_TOKENIZE_PREFIX 0x0002 |
| @@ -232005,7 +233548,7 @@ struct fts5_tokenizer { | |||
| 232005 | */ | 233548 | */ |
| 232006 | typedef struct fts5_api fts5_api; | 233549 | typedef struct fts5_api fts5_api; |
| 232007 | struct fts5_api { | 233550 | struct fts5_api { |
| 232008 | int iVersion; /* Currently always set to 2 */ | 233551 | int iVersion; /* Currently always set to 3 */ |
| 232009 | 233552 | ||
| 232010 | /* Create a new tokenizer */ | 233553 | /* Create a new tokenizer */ |
| 232011 | int (*xCreateTokenizer)( | 233554 | int (*xCreateTokenizer)( |
| @@ -232032,6 +233575,25 @@ struct fts5_api { | |||
| 232032 | fts5_extension_function xFunction, | 233575 | fts5_extension_function xFunction, |
| 232033 | void (*xDestroy)(void*) | 233576 | void (*xDestroy)(void*) |
| 232034 | ); | 233577 | ); |
| 233578 | |||
| 233579 | /* APIs below this point are only available if iVersion>=3 */ | ||
| 233580 | |||
| 233581 | /* Create a new tokenizer */ | ||
| 233582 | int (*xCreateTokenizer_v2)( | ||
| 233583 | fts5_api *pApi, | ||
| 233584 | const char *zName, | ||
| 233585 | void *pUserData, | ||
| 233586 | fts5_tokenizer_v2 *pTokenizer, | ||
| 233587 | void (*xDestroy)(void*) | ||
| 233588 | ); | ||
| 233589 | |||
| 233590 | /* Find an existing tokenizer */ | ||
| 233591 | int (*xFindTokenizer_v2)( | ||
| 233592 | fts5_api *pApi, | ||
| 233593 | const char *zName, | ||
| 233594 | void **ppUserData, | ||
| 233595 | fts5_tokenizer_v2 **ppTokenizer | ||
| 233596 | ); | ||
| 232035 | }; | 233597 | }; |
| 232036 | 233598 | ||
| 232037 | /* | 233599 | /* |
| @@ -232105,6 +233667,22 @@ typedef sqlite3_uint64 u64; | |||
| 232105 | # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) | 233667 | # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) |
| 232106 | # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) | 233668 | # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) |
| 232107 | 233669 | ||
| 233670 | /* The uptr type is an unsigned integer large enough to hold a pointer | ||
| 233671 | */ | ||
| 233672 | #if defined(HAVE_STDINT_H) | ||
| 233673 | typedef uintptr_t uptr; | ||
| 233674 | #elif SQLITE_PTRSIZE==4 | ||
| 233675 | typedef u32 uptr; | ||
| 233676 | #else | ||
| 233677 | typedef u64 uptr; | ||
| 233678 | #endif | ||
| 233679 | |||
| 233680 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC | ||
| 233681 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) | ||
| 233682 | #else | ||
| 233683 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) | ||
| 233684 | #endif | ||
| 233685 | |||
| 232108 | #endif | 233686 | #endif |
| 232109 | 233687 | ||
| 232110 | /* Truncate very long tokens to this many bytes. Hard limit is | 233688 | /* Truncate very long tokens to this many bytes. Hard limit is |
| @@ -232188,6 +233766,18 @@ struct Fts5Colset { | |||
| 232188 | */ | 233766 | */ |
| 232189 | 233767 | ||
| 232190 | typedef struct Fts5Config Fts5Config; | 233768 | typedef struct Fts5Config Fts5Config; |
| 233769 | typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; | ||
| 233770 | |||
| 233771 | struct Fts5TokenizerConfig { | ||
| 233772 | Fts5Tokenizer *pTok; | ||
| 233773 | fts5_tokenizer_v2 *pApi2; | ||
| 233774 | fts5_tokenizer *pApi1; | ||
| 233775 | const char **azArg; | ||
| 233776 | int nArg; | ||
| 233777 | int ePattern; /* FTS_PATTERN_XXX constant */ | ||
| 233778 | const char *pLocale; /* Current locale to use */ | ||
| 233779 | int nLocale; /* Size of pLocale in bytes */ | ||
| 233780 | }; | ||
| 232191 | 233781 | ||
| 232192 | /* | 233782 | /* |
| 232193 | ** An instance of the following structure encodes all information that can | 233783 | ** An instance of the following structure encodes all information that can |
| @@ -232227,9 +233817,12 @@ typedef struct Fts5Config Fts5Config; | |||
| 232227 | ** | 233817 | ** |
| 232228 | ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); | 233818 | ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); |
| 232229 | ** | 233819 | ** |
| 233820 | ** bLocale: | ||
| 233821 | ** Set to true if locale=1 was specified when the table was created. | ||
| 232230 | */ | 233822 | */ |
| 232231 | struct Fts5Config { | 233823 | struct Fts5Config { |
| 232232 | sqlite3 *db; /* Database handle */ | 233824 | sqlite3 *db; /* Database handle */ |
| 233825 | Fts5Global *pGlobal; /* Global fts5 object for handle db */ | ||
| 232233 | char *zDb; /* Database holding FTS index (e.g. "main") */ | 233826 | char *zDb; /* Database holding FTS index (e.g. "main") */ |
| 232234 | char *zName; /* Name of FTS index */ | 233827 | char *zName; /* Name of FTS index */ |
| 232235 | int nCol; /* Number of columns */ | 233828 | int nCol; /* Number of columns */ |
| @@ -232239,16 +233832,17 @@ struct Fts5Config { | |||
| 232239 | int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ | 233832 | int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ |
| 232240 | int eContent; /* An FTS5_CONTENT value */ | 233833 | int eContent; /* An FTS5_CONTENT value */ |
| 232241 | int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ | 233834 | int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ |
| 233835 | int bContentlessUnindexed; /* "contentless_unindexed=" option (dflt=0) */ | ||
| 232242 | char *zContent; /* content table */ | 233836 | char *zContent; /* content table */ |
| 232243 | char *zContentRowid; /* "content_rowid=" option value */ | 233837 | char *zContentRowid; /* "content_rowid=" option value */ |
| 232244 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ | 233838 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ |
| 232245 | int bTokendata; /* "tokendata=" option value (dflt==0) */ | 233839 | int bTokendata; /* "tokendata=" option value (dflt==0) */ |
| 233840 | int bLocale; /* "locale=" option value (dflt==0) */ | ||
| 232246 | int eDetail; /* FTS5_DETAIL_XXX value */ | 233841 | int eDetail; /* FTS5_DETAIL_XXX value */ |
| 232247 | char *zContentExprlist; | 233842 | char *zContentExprlist; |
| 232248 | Fts5Tokenizer *pTok; | 233843 | Fts5TokenizerConfig t; |
| 232249 | fts5_tokenizer *pTokApi; | ||
| 232250 | int bLock; /* True when table is preparing statement */ | 233844 | int bLock; /* True when table is preparing statement */ |
| 232251 | int ePattern; /* FTS_PATTERN_XXX constant */ | 233845 | |
| 232252 | 233846 | ||
| 232253 | /* Values loaded from the %_config table */ | 233847 | /* Values loaded from the %_config table */ |
| 232254 | int iVersion; /* fts5 file format 'version' */ | 233848 | int iVersion; /* fts5 file format 'version' */ |
| @@ -232277,9 +233871,10 @@ struct Fts5Config { | |||
| 232277 | #define FTS5_CURRENT_VERSION 4 | 233871 | #define FTS5_CURRENT_VERSION 4 |
| 232278 | #define FTS5_CURRENT_VERSION_SECUREDELETE 5 | 233872 | #define FTS5_CURRENT_VERSION_SECUREDELETE 5 |
| 232279 | 233873 | ||
| 232280 | #define FTS5_CONTENT_NORMAL 0 | 233874 | #define FTS5_CONTENT_NORMAL 0 |
| 232281 | #define FTS5_CONTENT_NONE 1 | 233875 | #define FTS5_CONTENT_NONE 1 |
| 232282 | #define FTS5_CONTENT_EXTERNAL 2 | 233876 | #define FTS5_CONTENT_EXTERNAL 2 |
| 233877 | #define FTS5_CONTENT_UNINDEXED 3 | ||
| 232283 | 233878 | ||
| 232284 | #define FTS5_DETAIL_FULL 0 | 233879 | #define FTS5_DETAIL_FULL 0 |
| 232285 | #define FTS5_DETAIL_NONE 1 | 233880 | #define FTS5_DETAIL_NONE 1 |
| @@ -232314,6 +233909,8 @@ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, i | |||
| 232314 | 233909 | ||
| 232315 | static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); | 233910 | static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); |
| 232316 | 233911 | ||
| 233912 | static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...); | ||
| 233913 | |||
| 232317 | /* | 233914 | /* |
| 232318 | ** End of interface to code in fts5_config.c. | 233915 | ** End of interface to code in fts5_config.c. |
| 232319 | **************************************************************************/ | 233916 | **************************************************************************/ |
| @@ -232358,7 +233955,7 @@ static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); | |||
| 232358 | static void sqlite3Fts5Put32(u8*, int); | 233955 | static void sqlite3Fts5Put32(u8*, int); |
| 232359 | static int sqlite3Fts5Get32(const u8*); | 233956 | static int sqlite3Fts5Get32(const u8*); |
| 232360 | 233957 | ||
| 232361 | #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) | 233958 | #define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF) |
| 232362 | #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) | 233959 | #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) |
| 232363 | 233960 | ||
| 232364 | typedef struct Fts5PoslistReader Fts5PoslistReader; | 233961 | typedef struct Fts5PoslistReader Fts5PoslistReader; |
| @@ -232643,18 +234240,20 @@ struct Fts5Table { | |||
| 232643 | Fts5Index *pIndex; /* Full-text index */ | 234240 | Fts5Index *pIndex; /* Full-text index */ |
| 232644 | }; | 234241 | }; |
| 232645 | 234242 | ||
| 232646 | static int sqlite3Fts5GetTokenizer( | 234243 | static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); |
| 232647 | Fts5Global*, | ||
| 232648 | const char **azArg, | ||
| 232649 | int nArg, | ||
| 232650 | Fts5Config*, | ||
| 232651 | char **pzErr | ||
| 232652 | ); | ||
| 232653 | 234244 | ||
| 232654 | static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); | 234245 | static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); |
| 232655 | 234246 | ||
| 232656 | static int sqlite3Fts5FlushToDisk(Fts5Table*); | 234247 | static int sqlite3Fts5FlushToDisk(Fts5Table*); |
| 232657 | 234248 | ||
| 234249 | static void sqlite3Fts5ClearLocale(Fts5Config *pConfig); | ||
| 234250 | static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc); | ||
| 234251 | |||
| 234252 | static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal); | ||
| 234253 | static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal, | ||
| 234254 | const char **ppText, int *pnText, const char **ppLoc, int *pnLoc | ||
| 234255 | ); | ||
| 234256 | |||
| 232658 | /* | 234257 | /* |
| 232659 | ** End of interface to code in fts5.c. | 234258 | ** End of interface to code in fts5.c. |
| 232660 | **************************************************************************/ | 234259 | **************************************************************************/ |
| @@ -232734,8 +234333,8 @@ static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); | |||
| 232734 | static int sqlite3Fts5DropAll(Fts5Config*); | 234333 | static int sqlite3Fts5DropAll(Fts5Config*); |
| 232735 | static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); | 234334 | static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); |
| 232736 | 234335 | ||
| 232737 | static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); | 234336 | static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int); |
| 232738 | static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); | 234337 | static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, int, sqlite3_value**, i64*); |
| 232739 | static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); | 234338 | static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); |
| 232740 | 234339 | ||
| 232741 | static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); | 234340 | static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); |
| @@ -232760,6 +234359,9 @@ static int sqlite3Fts5StorageOptimize(Fts5Storage *p); | |||
| 232760 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); | 234359 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); |
| 232761 | static int sqlite3Fts5StorageReset(Fts5Storage *p); | 234360 | static int sqlite3Fts5StorageReset(Fts5Storage *p); |
| 232762 | 234361 | ||
| 234362 | static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*); | ||
| 234363 | static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel); | ||
| 234364 | |||
| 232763 | /* | 234365 | /* |
| 232764 | ** End of interface to code in fts5_storage.c. | 234366 | ** End of interface to code in fts5_storage.c. |
| 232765 | **************************************************************************/ | 234367 | **************************************************************************/ |
| @@ -232912,6 +234514,7 @@ static int sqlite3Fts5TokenizerPattern( | |||
| 232912 | int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), | 234514 | int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), |
| 232913 | Fts5Tokenizer *pTok | 234515 | Fts5Tokenizer *pTok |
| 232914 | ); | 234516 | ); |
| 234517 | static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); | ||
| 232915 | /* | 234518 | /* |
| 232916 | ** End of interface to code in fts5_tokenizer.c. | 234519 | ** End of interface to code in fts5_tokenizer.c. |
| 232917 | **************************************************************************/ | 234520 | **************************************************************************/ |
| @@ -234689,6 +236292,7 @@ static int fts5HighlightCb( | |||
| 234689 | return rc; | 236292 | return rc; |
| 234690 | } | 236293 | } |
| 234691 | 236294 | ||
| 236295 | |||
| 234692 | /* | 236296 | /* |
| 234693 | ** Implementation of highlight() function. | 236297 | ** Implementation of highlight() function. |
| 234694 | */ | 236298 | */ |
| @@ -234719,12 +236323,19 @@ static void fts5HighlightFunction( | |||
| 234719 | sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); | 236323 | sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); |
| 234720 | rc = SQLITE_OK; | 236324 | rc = SQLITE_OK; |
| 234721 | }else if( ctx.zIn ){ | 236325 | }else if( ctx.zIn ){ |
| 236326 | const char *pLoc = 0; /* Locale of column iCol */ | ||
| 236327 | int nLoc = 0; /* Size of pLoc in bytes */ | ||
| 234722 | if( rc==SQLITE_OK ){ | 236328 | if( rc==SQLITE_OK ){ |
| 234723 | rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); | 236329 | rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); |
| 234724 | } | 236330 | } |
| 234725 | 236331 | ||
| 234726 | if( rc==SQLITE_OK ){ | 236332 | if( rc==SQLITE_OK ){ |
| 234727 | rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); | 236333 | rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc); |
| 236334 | } | ||
| 236335 | if( rc==SQLITE_OK ){ | ||
| 236336 | rc = pApi->xTokenize_v2( | ||
| 236337 | pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb | ||
| 236338 | ); | ||
| 234728 | } | 236339 | } |
| 234729 | if( ctx.bOpen ){ | 236340 | if( ctx.bOpen ){ |
| 234730 | fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); | 236341 | fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); |
| @@ -234921,6 +236532,8 @@ static void fts5SnippetFunction( | |||
| 234921 | memset(&sFinder, 0, sizeof(Fts5SFinder)); | 236532 | memset(&sFinder, 0, sizeof(Fts5SFinder)); |
| 234922 | for(i=0; i<nCol; i++){ | 236533 | for(i=0; i<nCol; i++){ |
| 234923 | if( iCol<0 || iCol==i ){ | 236534 | if( iCol<0 || iCol==i ){ |
| 236535 | const char *pLoc = 0; /* Locale of column iCol */ | ||
| 236536 | int nLoc = 0; /* Size of pLoc in bytes */ | ||
| 234924 | int nDoc; | 236537 | int nDoc; |
| 234925 | int nDocsize; | 236538 | int nDocsize; |
| 234926 | int ii; | 236539 | int ii; |
| @@ -234928,8 +236541,10 @@ static void fts5SnippetFunction( | |||
| 234928 | sFinder.nFirst = 0; | 236541 | sFinder.nFirst = 0; |
| 234929 | rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc); | 236542 | rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc); |
| 234930 | if( rc!=SQLITE_OK ) break; | 236543 | if( rc!=SQLITE_OK ) break; |
| 234931 | rc = pApi->xTokenize(pFts, | 236544 | rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc); |
| 234932 | sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb | 236545 | if( rc!=SQLITE_OK ) break; |
| 236546 | rc = pApi->xTokenize_v2(pFts, | ||
| 236547 | sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb | ||
| 234933 | ); | 236548 | ); |
| 234934 | if( rc!=SQLITE_OK ) break; | 236549 | if( rc!=SQLITE_OK ) break; |
| 234935 | rc = pApi->xColumnSize(pFts, i, &nDocsize); | 236550 | rc = pApi->xColumnSize(pFts, i, &nDocsize); |
| @@ -234987,6 +236602,9 @@ static void fts5SnippetFunction( | |||
| 234987 | rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); | 236602 | rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); |
| 234988 | } | 236603 | } |
| 234989 | if( ctx.zIn ){ | 236604 | if( ctx.zIn ){ |
| 236605 | const char *pLoc = 0; /* Locale of column iBestCol */ | ||
| 236606 | int nLoc = 0; /* Bytes in pLoc */ | ||
| 236607 | |||
| 234990 | if( rc==SQLITE_OK ){ | 236608 | if( rc==SQLITE_OK ){ |
| 234991 | rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); | 236609 | rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); |
| 234992 | } | 236610 | } |
| @@ -235005,7 +236623,12 @@ static void fts5SnippetFunction( | |||
| 235005 | } | 236623 | } |
| 235006 | 236624 | ||
| 235007 | if( rc==SQLITE_OK ){ | 236625 | if( rc==SQLITE_OK ){ |
| 235008 | rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); | 236626 | rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc); |
| 236627 | } | ||
| 236628 | if( rc==SQLITE_OK ){ | ||
| 236629 | rc = pApi->xTokenize_v2( | ||
| 236630 | pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb | ||
| 236631 | ); | ||
| 235009 | } | 236632 | } |
| 235010 | if( ctx.bOpen ){ | 236633 | if( ctx.bOpen ){ |
| 235011 | fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); | 236634 | fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); |
| @@ -235189,6 +236812,53 @@ static void fts5Bm25Function( | |||
| 235189 | } | 236812 | } |
| 235190 | } | 236813 | } |
| 235191 | 236814 | ||
| 236815 | /* | ||
| 236816 | ** Implementation of fts5_get_locale() function. | ||
| 236817 | */ | ||
| 236818 | static void fts5GetLocaleFunction( | ||
| 236819 | const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ | ||
| 236820 | Fts5Context *pFts, /* First arg to pass to pApi functions */ | ||
| 236821 | sqlite3_context *pCtx, /* Context for returning result/error */ | ||
| 236822 | int nVal, /* Number of values in apVal[] array */ | ||
| 236823 | sqlite3_value **apVal /* Array of trailing arguments */ | ||
| 236824 | ){ | ||
| 236825 | int iCol = 0; | ||
| 236826 | int eType = 0; | ||
| 236827 | int rc = SQLITE_OK; | ||
| 236828 | const char *zLocale = 0; | ||
| 236829 | int nLocale = 0; | ||
| 236830 | |||
| 236831 | /* xColumnLocale() must be available */ | ||
| 236832 | assert( pApi->iVersion>=4 ); | ||
| 236833 | |||
| 236834 | if( nVal!=1 ){ | ||
| 236835 | const char *z = "wrong number of arguments to function fts5_get_locale()"; | ||
| 236836 | sqlite3_result_error(pCtx, z, -1); | ||
| 236837 | return; | ||
| 236838 | } | ||
| 236839 | |||
| 236840 | eType = sqlite3_value_numeric_type(apVal[0]); | ||
| 236841 | if( eType!=SQLITE_INTEGER ){ | ||
| 236842 | const char *z = "non-integer argument passed to function fts5_get_locale()"; | ||
| 236843 | sqlite3_result_error(pCtx, z, -1); | ||
| 236844 | return; | ||
| 236845 | } | ||
| 236846 | |||
| 236847 | iCol = sqlite3_value_int(apVal[0]); | ||
| 236848 | if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ | ||
| 236849 | sqlite3_result_error_code(pCtx, SQLITE_RANGE); | ||
| 236850 | return; | ||
| 236851 | } | ||
| 236852 | |||
| 236853 | rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale); | ||
| 236854 | if( rc!=SQLITE_OK ){ | ||
| 236855 | sqlite3_result_error_code(pCtx, rc); | ||
| 236856 | return; | ||
| 236857 | } | ||
| 236858 | |||
| 236859 | sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT); | ||
| 236860 | } | ||
| 236861 | |||
| 235192 | static int sqlite3Fts5AuxInit(fts5_api *pApi){ | 236862 | static int sqlite3Fts5AuxInit(fts5_api *pApi){ |
| 235193 | struct Builtin { | 236863 | struct Builtin { |
| 235194 | const char *zFunc; /* Function name (nul-terminated) */ | 236864 | const char *zFunc; /* Function name (nul-terminated) */ |
| @@ -235196,9 +236866,10 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ | |||
| 235196 | fts5_extension_function xFunc;/* Callback function */ | 236866 | fts5_extension_function xFunc;/* Callback function */ |
| 235197 | void (*xDestroy)(void*); /* Destructor function */ | 236867 | void (*xDestroy)(void*); /* Destructor function */ |
| 235198 | } aBuiltin [] = { | 236868 | } aBuiltin [] = { |
| 235199 | { "snippet", 0, fts5SnippetFunction, 0 }, | 236869 | { "snippet", 0, fts5SnippetFunction, 0 }, |
| 235200 | { "highlight", 0, fts5HighlightFunction, 0 }, | 236870 | { "highlight", 0, fts5HighlightFunction, 0 }, |
| 235201 | { "bm25", 0, fts5Bm25Function, 0 }, | 236871 | { "bm25", 0, fts5Bm25Function, 0 }, |
| 236872 | { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 }, | ||
| 235202 | }; | 236873 | }; |
| 235203 | int rc = SQLITE_OK; /* Return code */ | 236874 | int rc = SQLITE_OK; /* Return code */ |
| 235204 | int i; /* To iterate through builtin functions */ | 236875 | int i; /* To iterate through builtin functions */ |
| @@ -235863,7 +237534,6 @@ static int fts5ConfigSetEnum( | |||
| 235863 | ** eventually free any such error message using sqlite3_free(). | 237534 | ** eventually free any such error message using sqlite3_free(). |
| 235864 | */ | 237535 | */ |
| 235865 | static int fts5ConfigParseSpecial( | 237536 | static int fts5ConfigParseSpecial( |
| 235866 | Fts5Global *pGlobal, | ||
| 235867 | Fts5Config *pConfig, /* Configuration object to update */ | 237537 | Fts5Config *pConfig, /* Configuration object to update */ |
| 235868 | const char *zCmd, /* Special command to parse */ | 237538 | const char *zCmd, /* Special command to parse */ |
| 235869 | const char *zArg, /* Argument to parse */ | 237539 | const char *zArg, /* Argument to parse */ |
| @@ -235871,6 +237541,7 @@ static int fts5ConfigParseSpecial( | |||
| 235871 | ){ | 237541 | ){ |
| 235872 | int rc = SQLITE_OK; | 237542 | int rc = SQLITE_OK; |
| 235873 | int nCmd = (int)strlen(zCmd); | 237543 | int nCmd = (int)strlen(zCmd); |
| 237544 | |||
| 235874 | if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ | 237545 | if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ |
| 235875 | const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; | 237546 | const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; |
| 235876 | const char *p; | 237547 | const char *p; |
| @@ -235927,12 +237598,11 @@ static int fts5ConfigParseSpecial( | |||
| 235927 | if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ | 237598 | if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ |
| 235928 | const char *p = (const char*)zArg; | 237599 | const char *p = (const char*)zArg; |
| 235929 | sqlite3_int64 nArg = strlen(zArg) + 1; | 237600 | sqlite3_int64 nArg = strlen(zArg) + 1; |
| 235930 | char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); | 237601 | char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); |
| 235931 | char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); | ||
| 235932 | char *pSpace = pDel; | ||
| 235933 | 237602 | ||
| 235934 | if( azArg && pSpace ){ | 237603 | if( azArg ){ |
| 235935 | if( pConfig->pTok ){ | 237604 | char *pSpace = (char*)&azArg[nArg]; |
| 237605 | if( pConfig->t.azArg ){ | ||
| 235936 | *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); | 237606 | *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); |
| 235937 | rc = SQLITE_ERROR; | 237607 | rc = SQLITE_ERROR; |
| 235938 | }else{ | 237608 | }else{ |
| @@ -235955,16 +237625,14 @@ static int fts5ConfigParseSpecial( | |||
| 235955 | *pzErr = sqlite3_mprintf("parse error in tokenize directive"); | 237625 | *pzErr = sqlite3_mprintf("parse error in tokenize directive"); |
| 235956 | rc = SQLITE_ERROR; | 237626 | rc = SQLITE_ERROR; |
| 235957 | }else{ | 237627 | }else{ |
| 235958 | rc = sqlite3Fts5GetTokenizer(pGlobal, | 237628 | pConfig->t.azArg = (const char**)azArg; |
| 235959 | (const char**)azArg, (int)nArg, pConfig, | 237629 | pConfig->t.nArg = nArg; |
| 235960 | pzErr | 237630 | azArg = 0; |
| 235961 | ); | ||
| 235962 | } | 237631 | } |
| 235963 | } | 237632 | } |
| 235964 | } | 237633 | } |
| 235965 | |||
| 235966 | sqlite3_free(azArg); | 237634 | sqlite3_free(azArg); |
| 235967 | sqlite3_free(pDel); | 237635 | |
| 235968 | return rc; | 237636 | return rc; |
| 235969 | } | 237637 | } |
| 235970 | 237638 | ||
| @@ -235993,6 +237661,16 @@ static int fts5ConfigParseSpecial( | |||
| 235993 | return rc; | 237661 | return rc; |
| 235994 | } | 237662 | } |
| 235995 | 237663 | ||
| 237664 | if( sqlite3_strnicmp("contentless_unindexed", zCmd, nCmd)==0 ){ | ||
| 237665 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ | ||
| 237666 | *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); | ||
| 237667 | rc = SQLITE_ERROR; | ||
| 237668 | }else{ | ||
| 237669 | pConfig->bContentlessUnindexed = (zArg[0]=='1'); | ||
| 237670 | } | ||
| 237671 | return rc; | ||
| 237672 | } | ||
| 237673 | |||
| 235996 | if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ | 237674 | if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ |
| 235997 | if( pConfig->zContentRowid ){ | 237675 | if( pConfig->zContentRowid ){ |
| 235998 | *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); | 237676 | *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); |
| @@ -236013,6 +237691,16 @@ static int fts5ConfigParseSpecial( | |||
| 236013 | return rc; | 237691 | return rc; |
| 236014 | } | 237692 | } |
| 236015 | 237693 | ||
| 237694 | if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){ | ||
| 237695 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ | ||
| 237696 | *pzErr = sqlite3_mprintf("malformed locale=... directive"); | ||
| 237697 | rc = SQLITE_ERROR; | ||
| 237698 | }else{ | ||
| 237699 | pConfig->bLocale = (zArg[0]=='1'); | ||
| 237700 | } | ||
| 237701 | return rc; | ||
| 237702 | } | ||
| 237703 | |||
| 236016 | if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ | 237704 | if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ |
| 236017 | const Fts5Enum aDetail[] = { | 237705 | const Fts5Enum aDetail[] = { |
| 236018 | { "none", FTS5_DETAIL_NONE }, | 237706 | { "none", FTS5_DETAIL_NONE }, |
| @@ -236042,16 +237730,6 @@ static int fts5ConfigParseSpecial( | |||
| 236042 | } | 237730 | } |
| 236043 | 237731 | ||
| 236044 | /* | 237732 | /* |
| 236045 | ** Allocate an instance of the default tokenizer ("simple") at | ||
| 236046 | ** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error | ||
| 236047 | ** code if an error occurs. | ||
| 236048 | */ | ||
| 236049 | static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ | ||
| 236050 | assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); | ||
| 236051 | return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); | ||
| 236052 | } | ||
| 236053 | |||
| 236054 | /* | ||
| 236055 | ** Gobble up the first bareword or quoted word from the input buffer zIn. | 237733 | ** Gobble up the first bareword or quoted word from the input buffer zIn. |
| 236056 | ** Return a pointer to the character immediately following the last in | 237734 | ** Return a pointer to the character immediately following the last in |
| 236057 | ** the gobbled word if successful, or a NULL pointer otherwise (failed | 237735 | ** the gobbled word if successful, or a NULL pointer otherwise (failed |
| @@ -236110,7 +237788,8 @@ static int fts5ConfigParseColumn( | |||
| 236110 | Fts5Config *p, | 237788 | Fts5Config *p, |
| 236111 | char *zCol, | 237789 | char *zCol, |
| 236112 | char *zArg, | 237790 | char *zArg, |
| 236113 | char **pzErr | 237791 | char **pzErr, |
| 237792 | int *pbUnindexed | ||
| 236114 | ){ | 237793 | ){ |
| 236115 | int rc = SQLITE_OK; | 237794 | int rc = SQLITE_OK; |
| 236116 | if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) | 237795 | if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) |
| @@ -236121,6 +237800,7 @@ static int fts5ConfigParseColumn( | |||
| 236121 | }else if( zArg ){ | 237800 | }else if( zArg ){ |
| 236122 | if( 0==sqlite3_stricmp(zArg, "unindexed") ){ | 237801 | if( 0==sqlite3_stricmp(zArg, "unindexed") ){ |
| 236123 | p->abUnindexed[p->nCol] = 1; | 237802 | p->abUnindexed[p->nCol] = 1; |
| 237803 | *pbUnindexed = 1; | ||
| 236124 | }else{ | 237804 | }else{ |
| 236125 | *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); | 237805 | *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); |
| 236126 | rc = SQLITE_ERROR; | 237806 | rc = SQLITE_ERROR; |
| @@ -236141,11 +237821,26 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ | |||
| 236141 | 237821 | ||
| 236142 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); | 237822 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); |
| 236143 | if( p->eContent!=FTS5_CONTENT_NONE ){ | 237823 | if( p->eContent!=FTS5_CONTENT_NONE ){ |
| 237824 | assert( p->eContent==FTS5_CONTENT_EXTERNAL | ||
| 237825 | || p->eContent==FTS5_CONTENT_NORMAL | ||
| 237826 | || p->eContent==FTS5_CONTENT_UNINDEXED | ||
| 237827 | ); | ||
| 236144 | for(i=0; i<p->nCol; i++){ | 237828 | for(i=0; i<p->nCol; i++){ |
| 236145 | if( p->eContent==FTS5_CONTENT_EXTERNAL ){ | 237829 | if( p->eContent==FTS5_CONTENT_EXTERNAL ){ |
| 236146 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); | 237830 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); |
| 236147 | }else{ | 237831 | }else if( p->eContent==FTS5_CONTENT_NORMAL || p->abUnindexed[i] ){ |
| 236148 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); | 237832 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); |
| 237833 | }else{ | ||
| 237834 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); | ||
| 237835 | } | ||
| 237836 | } | ||
| 237837 | } | ||
| 237838 | if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){ | ||
| 237839 | for(i=0; i<p->nCol; i++){ | ||
| 237840 | if( p->abUnindexed[i]==0 ){ | ||
| 237841 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i); | ||
| 237842 | }else{ | ||
| 237843 | sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); | ||
| 236149 | } | 237844 | } |
| 236150 | } | 237845 | } |
| 236151 | } | 237846 | } |
| @@ -236179,10 +237874,12 @@ static int sqlite3Fts5ConfigParse( | |||
| 236179 | Fts5Config *pRet; /* New object to return */ | 237874 | Fts5Config *pRet; /* New object to return */ |
| 236180 | int i; | 237875 | int i; |
| 236181 | sqlite3_int64 nByte; | 237876 | sqlite3_int64 nByte; |
| 237877 | int bUnindexed = 0; /* True if there are one or more UNINDEXED */ | ||
| 236182 | 237878 | ||
| 236183 | *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); | 237879 | *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); |
| 236184 | if( pRet==0 ) return SQLITE_NOMEM; | 237880 | if( pRet==0 ) return SQLITE_NOMEM; |
| 236185 | memset(pRet, 0, sizeof(Fts5Config)); | 237881 | memset(pRet, 0, sizeof(Fts5Config)); |
| 237882 | pRet->pGlobal = pGlobal; | ||
| 236186 | pRet->db = db; | 237883 | pRet->db = db; |
| 236187 | pRet->iCookie = -1; | 237884 | pRet->iCookie = -1; |
| 236188 | 237885 | ||
| @@ -236231,13 +237928,13 @@ static int sqlite3Fts5ConfigParse( | |||
| 236231 | rc = SQLITE_ERROR; | 237928 | rc = SQLITE_ERROR; |
| 236232 | }else{ | 237929 | }else{ |
| 236233 | if( bOption ){ | 237930 | if( bOption ){ |
| 236234 | rc = fts5ConfigParseSpecial(pGlobal, pRet, | 237931 | rc = fts5ConfigParseSpecial(pRet, |
| 236235 | ALWAYS(zOne)?zOne:"", | 237932 | ALWAYS(zOne)?zOne:"", |
| 236236 | zTwo?zTwo:"", | 237933 | zTwo?zTwo:"", |
| 236237 | pzErr | 237934 | pzErr |
| 236238 | ); | 237935 | ); |
| 236239 | }else{ | 237936 | }else{ |
| 236240 | rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); | 237937 | rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr, &bUnindexed); |
| 236241 | zOne = 0; | 237938 | zOne = 0; |
| 236242 | } | 237939 | } |
| 236243 | } | 237940 | } |
| @@ -236269,11 +237966,17 @@ static int sqlite3Fts5ConfigParse( | |||
| 236269 | rc = SQLITE_ERROR; | 237966 | rc = SQLITE_ERROR; |
| 236270 | } | 237967 | } |
| 236271 | 237968 | ||
| 236272 | /* If a tokenizer= option was successfully parsed, the tokenizer has | 237969 | /* We only allow contentless_unindexed=1 if the table is actually a |
| 236273 | ** already been allocated. Otherwise, allocate an instance of the default | 237970 | ** contentless one. |
| 236274 | ** tokenizer (unicode61) now. */ | 237971 | */ |
| 236275 | if( rc==SQLITE_OK && pRet->pTok==0 ){ | 237972 | if( rc==SQLITE_OK |
| 236276 | rc = fts5ConfigDefaultTokenizer(pGlobal, pRet); | 237973 | && pRet->bContentlessUnindexed |
| 237974 | && pRet->eContent!=FTS5_CONTENT_NONE | ||
| 237975 | ){ | ||
| 237976 | *pzErr = sqlite3_mprintf( | ||
| 237977 | "contentless_unindexed=1 requires a contentless table" | ||
| 237978 | ); | ||
| 237979 | rc = SQLITE_ERROR; | ||
| 236277 | } | 237980 | } |
| 236278 | 237981 | ||
| 236279 | /* If no zContent option was specified, fill in the default values. */ | 237982 | /* If no zContent option was specified, fill in the default values. */ |
| @@ -236284,6 +237987,9 @@ static int sqlite3Fts5ConfigParse( | |||
| 236284 | ); | 237987 | ); |
| 236285 | if( pRet->eContent==FTS5_CONTENT_NORMAL ){ | 237988 | if( pRet->eContent==FTS5_CONTENT_NORMAL ){ |
| 236286 | zTail = "content"; | 237989 | zTail = "content"; |
| 237990 | }else if( bUnindexed && pRet->bContentlessUnindexed ){ | ||
| 237991 | pRet->eContent = FTS5_CONTENT_UNINDEXED; | ||
| 237992 | zTail = "content"; | ||
| 236287 | }else if( pRet->bColumnsize ){ | 237993 | }else if( pRet->bColumnsize ){ |
| 236288 | zTail = "docsize"; | 237994 | zTail = "docsize"; |
| 236289 | } | 237995 | } |
| @@ -236317,9 +238023,14 @@ static int sqlite3Fts5ConfigParse( | |||
| 236317 | static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ | 238023 | static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ |
| 236318 | if( pConfig ){ | 238024 | if( pConfig ){ |
| 236319 | int i; | 238025 | int i; |
| 236320 | if( pConfig->pTok ){ | 238026 | if( pConfig->t.pTok ){ |
| 236321 | pConfig->pTokApi->xDelete(pConfig->pTok); | 238027 | if( pConfig->t.pApi1 ){ |
| 238028 | pConfig->t.pApi1->xDelete(pConfig->t.pTok); | ||
| 238029 | }else{ | ||
| 238030 | pConfig->t.pApi2->xDelete(pConfig->t.pTok); | ||
| 238031 | } | ||
| 236322 | } | 238032 | } |
| 238033 | sqlite3_free((char*)pConfig->t.azArg); | ||
| 236323 | sqlite3_free(pConfig->zDb); | 238034 | sqlite3_free(pConfig->zDb); |
| 236324 | sqlite3_free(pConfig->zName); | 238035 | sqlite3_free(pConfig->zName); |
| 236325 | for(i=0; i<pConfig->nCol; i++){ | 238036 | for(i=0; i<pConfig->nCol; i++){ |
| @@ -236394,10 +238105,24 @@ static int sqlite3Fts5Tokenize( | |||
| 236394 | void *pCtx, /* Context passed to xToken() */ | 238105 | void *pCtx, /* Context passed to xToken() */ |
| 236395 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ | 238106 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ |
| 236396 | ){ | 238107 | ){ |
| 236397 | if( pText==0 ) return SQLITE_OK; | 238108 | int rc = SQLITE_OK; |
| 236398 | return pConfig->pTokApi->xTokenize( | 238109 | if( pText ){ |
| 236399 | pConfig->pTok, pCtx, flags, pText, nText, xToken | 238110 | if( pConfig->t.pTok==0 ){ |
| 236400 | ); | 238111 | rc = sqlite3Fts5LoadTokenizer(pConfig); |
| 238112 | } | ||
| 238113 | if( rc==SQLITE_OK ){ | ||
| 238114 | if( pConfig->t.pApi1 ){ | ||
| 238115 | rc = pConfig->t.pApi1->xTokenize( | ||
| 238116 | pConfig->t.pTok, pCtx, flags, pText, nText, xToken | ||
| 238117 | ); | ||
| 238118 | }else{ | ||
| 238119 | rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags, | ||
| 238120 | pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken | ||
| 238121 | ); | ||
| 238122 | } | ||
| 238123 | } | ||
| 238124 | } | ||
| 238125 | return rc; | ||
| 236401 | } | 238126 | } |
| 236402 | 238127 | ||
| 236403 | /* | 238128 | /* |
| @@ -236651,13 +238376,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ | |||
| 236651 | && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE | 238376 | && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE |
| 236652 | ){ | 238377 | ){ |
| 236653 | rc = SQLITE_ERROR; | 238378 | rc = SQLITE_ERROR; |
| 236654 | if( pConfig->pzErrmsg ){ | 238379 | sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format " |
| 236655 | assert( 0==*pConfig->pzErrmsg ); | 238380 | "(found %d, expected %d or %d) - run 'rebuild'", |
| 236656 | *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " | 238381 | iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE |
| 236657 | "(found %d, expected %d or %d) - run 'rebuild'", | 238382 | ); |
| 236658 | iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE | ||
| 236659 | ); | ||
| 236660 | } | ||
| 236661 | }else{ | 238383 | }else{ |
| 236662 | pConfig->iVersion = iVersion; | 238384 | pConfig->iVersion = iVersion; |
| 236663 | } | 238385 | } |
| @@ -236669,6 +238391,29 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ | |||
| 236669 | } | 238391 | } |
| 236670 | 238392 | ||
| 236671 | /* | 238393 | /* |
| 238394 | ** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer | ||
| 238395 | ** containing the error message created using printf() style formatting | ||
| 238396 | ** string zFmt and its trailing arguments. | ||
| 238397 | */ | ||
| 238398 | static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ | ||
| 238399 | va_list ap; /* ... printf arguments */ | ||
| 238400 | char *zMsg = 0; | ||
| 238401 | |||
| 238402 | va_start(ap, zFmt); | ||
| 238403 | zMsg = sqlite3_vmprintf(zFmt, ap); | ||
| 238404 | if( pConfig->pzErrmsg ){ | ||
| 238405 | assert( *pConfig->pzErrmsg==0 ); | ||
| 238406 | *pConfig->pzErrmsg = zMsg; | ||
| 238407 | }else{ | ||
| 238408 | sqlite3_free(zMsg); | ||
| 238409 | } | ||
| 238410 | |||
| 238411 | va_end(ap); | ||
| 238412 | } | ||
| 238413 | |||
| 238414 | |||
| 238415 | |||
| 238416 | /* | ||
| 236672 | ** 2014 May 31 | 238417 | ** 2014 May 31 |
| 236673 | ** | 238418 | ** |
| 236674 | ** The author disclaims copyright to this source code. In place of | 238419 | ** The author disclaims copyright to this source code. In place of |
| @@ -236724,7 +238469,7 @@ struct Fts5Expr { | |||
| 236724 | 238469 | ||
| 236725 | /* | 238470 | /* |
| 236726 | ** eType: | 238471 | ** eType: |
| 236727 | ** Expression node type. Always one of: | 238472 | ** Expression node type. Usually one of: |
| 236728 | ** | 238473 | ** |
| 236729 | ** FTS5_AND (nChild, apChild valid) | 238474 | ** FTS5_AND (nChild, apChild valid) |
| 236730 | ** FTS5_OR (nChild, apChild valid) | 238475 | ** FTS5_OR (nChild, apChild valid) |
| @@ -236732,6 +238477,10 @@ struct Fts5Expr { | |||
| 236732 | ** FTS5_STRING (pNear valid) | 238477 | ** FTS5_STRING (pNear valid) |
| 236733 | ** FTS5_TERM (pNear valid) | 238478 | ** FTS5_TERM (pNear valid) |
| 236734 | ** | 238479 | ** |
| 238480 | ** An expression node with eType==0 may also exist. It always matches zero | ||
| 238481 | ** rows. This is created when a phrase containing no tokens is parsed. | ||
| 238482 | ** e.g. "". | ||
| 238483 | ** | ||
| 236735 | ** iHeight: | 238484 | ** iHeight: |
| 236736 | ** Distance from this node to furthest leaf. This is always 0 for nodes | 238485 | ** Distance from this node to furthest leaf. This is always 0 for nodes |
| 236737 | ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one | 238486 | ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one |
| @@ -236952,11 +238701,12 @@ static int sqlite3Fts5ExprNew( | |||
| 236952 | }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); | 238701 | }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); |
| 236953 | sqlite3Fts5ParserFree(pEngine, fts5ParseFree); | 238702 | sqlite3Fts5ParserFree(pEngine, fts5ParseFree); |
| 236954 | 238703 | ||
| 238704 | assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); | ||
| 236955 | assert_expr_depth_ok(sParse.rc, sParse.pExpr); | 238705 | assert_expr_depth_ok(sParse.rc, sParse.pExpr); |
| 236956 | 238706 | ||
| 236957 | /* If the LHS of the MATCH expression was a user column, apply the | 238707 | /* If the LHS of the MATCH expression was a user column, apply the |
| 236958 | ** implicit column-filter. */ | 238708 | ** implicit column-filter. */ |
| 236959 | if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ | 238709 | if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ |
| 236960 | int n = sizeof(Fts5Colset); | 238710 | int n = sizeof(Fts5Colset); |
| 236961 | Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); | 238711 | Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); |
| 236962 | if( pColset ){ | 238712 | if( pColset ){ |
| @@ -236973,15 +238723,7 @@ static int sqlite3Fts5ExprNew( | |||
| 236973 | sParse.rc = SQLITE_NOMEM; | 238723 | sParse.rc = SQLITE_NOMEM; |
| 236974 | sqlite3Fts5ParseNodeFree(sParse.pExpr); | 238724 | sqlite3Fts5ParseNodeFree(sParse.pExpr); |
| 236975 | }else{ | 238725 | }else{ |
| 236976 | if( !sParse.pExpr ){ | 238726 | pNew->pRoot = sParse.pExpr; |
| 236977 | const int nByte = sizeof(Fts5ExprNode); | ||
| 236978 | pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); | ||
| 236979 | if( pNew->pRoot ){ | ||
| 236980 | pNew->pRoot->bEof = 1; | ||
| 236981 | } | ||
| 236982 | }else{ | ||
| 236983 | pNew->pRoot = sParse.pExpr; | ||
| 236984 | } | ||
| 236985 | pNew->pIndex = 0; | 238727 | pNew->pIndex = 0; |
| 236986 | pNew->pConfig = pConfig; | 238728 | pNew->pConfig = pConfig; |
| 236987 | pNew->apExprPhrase = sParse.apPhrase; | 238729 | pNew->apExprPhrase = sParse.apPhrase; |
| @@ -237799,7 +239541,7 @@ static int fts5ExprNodeTest_STRING( | |||
| 237799 | } | 239541 | } |
| 237800 | }else{ | 239542 | }else{ |
| 237801 | Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; | 239543 | Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; |
| 237802 | if( pIter->iRowid==iLast || pIter->bEof ) continue; | 239544 | if( pIter->iRowid==iLast ) continue; |
| 237803 | bMatch = 0; | 239545 | bMatch = 0; |
| 237804 | if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ | 239546 | if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ |
| 237805 | return rc; | 239547 | return rc; |
| @@ -238321,9 +240063,6 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( | |||
| 238321 | Fts5ExprNearset *pRet = 0; | 240063 | Fts5ExprNearset *pRet = 0; |
| 238322 | 240064 | ||
| 238323 | if( pParse->rc==SQLITE_OK ){ | 240065 | if( pParse->rc==SQLITE_OK ){ |
| 238324 | if( pPhrase==0 ){ | ||
| 238325 | return pNear; | ||
| 238326 | } | ||
| 238327 | if( pNear==0 ){ | 240066 | if( pNear==0 ){ |
| 238328 | sqlite3_int64 nByte; | 240067 | sqlite3_int64 nByte; |
| 238329 | nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); | 240068 | nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); |
| @@ -238545,6 +240284,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( | |||
| 238545 | }else if( sCtx.pPhrase->nTerm ){ | 240284 | }else if( sCtx.pPhrase->nTerm ){ |
| 238546 | sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; | 240285 | sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; |
| 238547 | } | 240286 | } |
| 240287 | assert( pParse->apPhrase!=0 ); | ||
| 238548 | pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; | 240288 | pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; |
| 238549 | } | 240289 | } |
| 238550 | 240290 | ||
| @@ -238564,7 +240304,7 @@ static int sqlite3Fts5ExprClonePhrase( | |||
| 238564 | Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ | 240304 | Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ |
| 238565 | Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ | 240305 | Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ |
| 238566 | TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ | 240306 | TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ |
| 238567 | if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ | 240307 | if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){ |
| 238568 | rc = SQLITE_RANGE; | 240308 | rc = SQLITE_RANGE; |
| 238569 | }else{ | 240309 | }else{ |
| 238570 | pOrig = pExpr->apExprPhrase[iPhrase]; | 240310 | pOrig = pExpr->apExprPhrase[iPhrase]; |
| @@ -238932,6 +240672,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ | |||
| 238932 | } | 240672 | } |
| 238933 | } | 240673 | } |
| 238934 | 240674 | ||
| 240675 | /* | ||
| 240676 | ** Add pSub as a child of p. | ||
| 240677 | */ | ||
| 238935 | static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ | 240678 | static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ |
| 238936 | int ii = p->nChild; | 240679 | int ii = p->nChild; |
| 238937 | if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ | 240680 | if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ |
| @@ -239076,19 +240819,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( | |||
| 239076 | "fts5: %s queries are not supported (detail!=full)", | 240819 | "fts5: %s queries are not supported (detail!=full)", |
| 239077 | pNear->nPhrase==1 ? "phrase": "NEAR" | 240820 | pNear->nPhrase==1 ? "phrase": "NEAR" |
| 239078 | ); | 240821 | ); |
| 239079 | sqlite3_free(pRet); | 240822 | sqlite3Fts5ParseNodeFree(pRet); |
| 239080 | pRet = 0; | 240823 | pRet = 0; |
| 240824 | pNear = 0; | ||
| 240825 | assert( pLeft==0 && pRight==0 ); | ||
| 239081 | } | 240826 | } |
| 239082 | } | 240827 | } |
| 239083 | }else{ | 240828 | }else{ |
| 240829 | assert( pNear==0 ); | ||
| 239084 | fts5ExprAddChildren(pRet, pLeft); | 240830 | fts5ExprAddChildren(pRet, pLeft); |
| 239085 | fts5ExprAddChildren(pRet, pRight); | 240831 | fts5ExprAddChildren(pRet, pRight); |
| 240832 | pLeft = pRight = 0; | ||
| 239086 | if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ | 240833 | if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ |
| 239087 | sqlite3Fts5ParseError(pParse, | 240834 | sqlite3Fts5ParseError(pParse, |
| 239088 | "fts5 expression tree is too large (maximum depth %d)", | 240835 | "fts5 expression tree is too large (maximum depth %d)", |
| 239089 | SQLITE_FTS5_MAX_EXPR_DEPTH | 240836 | SQLITE_FTS5_MAX_EXPR_DEPTH |
| 239090 | ); | 240837 | ); |
| 239091 | sqlite3_free(pRet); | 240838 | sqlite3Fts5ParseNodeFree(pRet); |
| 239092 | pRet = 0; | 240839 | pRet = 0; |
| 239093 | } | 240840 | } |
| 239094 | } | 240841 | } |
| @@ -239140,6 +240887,8 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( | |||
| 239140 | ); | 240887 | ); |
| 239141 | 240888 | ||
| 239142 | if( pRight->eType==FTS5_EOF ){ | 240889 | if( pRight->eType==FTS5_EOF ){ |
| 240890 | assert( pParse->apPhrase!=0 ); | ||
| 240891 | assert( pParse->nPhrase>0 ); | ||
| 239143 | assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); | 240892 | assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); |
| 239144 | sqlite3Fts5ParseNodeFree(pRight); | 240893 | sqlite3Fts5ParseNodeFree(pRight); |
| 239145 | pRet = pLeft; | 240894 | pRet = pLeft; |
| @@ -239772,6 +241521,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ | |||
| 239772 | pNode->iRowid = iRowid; | 241521 | pNode->iRowid = iRowid; |
| 239773 | pNode->bEof = 0; | 241522 | pNode->bEof = 0; |
| 239774 | switch( pNode->eType ){ | 241523 | switch( pNode->eType ){ |
| 241524 | case 0: | ||
| 239775 | case FTS5_TERM: | 241525 | case FTS5_TERM: |
| 239776 | case FTS5_STRING: | 241526 | case FTS5_STRING: |
| 239777 | return (pNode->pNear->apPhrase[0]->poslist.n>0); | 241527 | return (pNode->pNear->apPhrase[0]->poslist.n>0); |
| @@ -241355,11 +243105,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ | |||
| 241355 | if( rc==SQLITE_OK ){ | 243105 | if( rc==SQLITE_OK ){ |
| 241356 | u8 *aOut = 0; /* Read blob data into this buffer */ | 243106 | u8 *aOut = 0; /* Read blob data into this buffer */ |
| 241357 | int nByte = sqlite3_blob_bytes(p->pReader); | 243107 | int nByte = sqlite3_blob_bytes(p->pReader); |
| 241358 | sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; | 243108 | int szData = (sizeof(Fts5Data) + 7) & ~7; |
| 243109 | sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; | ||
| 241359 | pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); | 243110 | pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); |
| 241360 | if( pRet ){ | 243111 | if( pRet ){ |
| 241361 | pRet->nn = nByte; | 243112 | pRet->nn = nByte; |
| 241362 | aOut = pRet->p = (u8*)&pRet[1]; | 243113 | aOut = pRet->p = (u8*)pRet + szData; |
| 241363 | }else{ | 243114 | }else{ |
| 241364 | rc = SQLITE_NOMEM; | 243115 | rc = SQLITE_NOMEM; |
| 241365 | } | 243116 | } |
| @@ -241382,6 +243133,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ | |||
| 241382 | } | 243133 | } |
| 241383 | 243134 | ||
| 241384 | assert( (pRet==0)==(p->rc!=SQLITE_OK) ); | 243135 | assert( (pRet==0)==(p->rc!=SQLITE_OK) ); |
| 243136 | assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); | ||
| 241385 | return pRet; | 243137 | return pRet; |
| 241386 | } | 243138 | } |
| 241387 | 243139 | ||
| @@ -242707,7 +244459,7 @@ static void fts5SegIterNext_None( | |||
| 242707 | 244459 | ||
| 242708 | if( iOff<pIter->iEndofDoclist ){ | 244460 | if( iOff<pIter->iEndofDoclist ){ |
| 242709 | /* Next entry is on the current page */ | 244461 | /* Next entry is on the current page */ |
| 242710 | i64 iDelta; | 244462 | u64 iDelta; |
| 242711 | iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); | 244463 | iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); |
| 242712 | pIter->iLeafOffset = iOff; | 244464 | pIter->iLeafOffset = iOff; |
| 242713 | pIter->iRowid += iDelta; | 244465 | pIter->iRowid += iDelta; |
| @@ -245411,6 +247163,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ | |||
| 245411 | nBest = nPercent; | 247163 | nBest = nPercent; |
| 245412 | } | 247164 | } |
| 245413 | } | 247165 | } |
| 247166 | |||
| 247167 | /* If pLvl is already the input level to an ongoing merge, look no | ||
| 247168 | ** further for a merge candidate. The caller should be allowed to | ||
| 247169 | ** continue merging from pLvl first. */ | ||
| 247170 | if( pLvl->nMerge ) break; | ||
| 245414 | } | 247171 | } |
| 245415 | } | 247172 | } |
| 245416 | return iRet; | 247173 | return iRet; |
| @@ -249335,7 +251092,7 @@ static int fts5structConnectMethod( | |||
| 249335 | 251092 | ||
| 249336 | /* | 251093 | /* |
| 249337 | ** We must have a single struct=? constraint that will be passed through | 251094 | ** We must have a single struct=? constraint that will be passed through |
| 249338 | ** into the xFilter method. If there is no valid stmt=? constraint, | 251095 | ** into the xFilter method. If there is no valid struct=? constraint, |
| 249339 | ** then return an SQLITE_CONSTRAINT error. | 251096 | ** then return an SQLITE_CONSTRAINT error. |
| 249340 | */ | 251097 | */ |
| 249341 | static int fts5structBestIndexMethod( | 251098 | static int fts5structBestIndexMethod( |
| @@ -249677,9 +251434,18 @@ struct Fts5Global { | |||
| 249677 | Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ | 251434 | Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ |
| 249678 | Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ | 251435 | Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ |
| 249679 | Fts5Cursor *pCsr; /* First in list of all open cursors */ | 251436 | Fts5Cursor *pCsr; /* First in list of all open cursors */ |
| 251437 | u32 aLocaleHdr[4]; | ||
| 249680 | }; | 251438 | }; |
| 249681 | 251439 | ||
| 249682 | /* | 251440 | /* |
| 251441 | ** Size of header on fts5_locale() values. And macro to access a buffer | ||
| 251442 | ** containing a copy of the header from an Fts5Config pointer. | ||
| 251443 | */ | ||
| 251444 | #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) | ||
| 251445 | #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) | ||
| 251446 | |||
| 251447 | |||
| 251448 | /* | ||
| 249683 | ** Each auxiliary function registered with the FTS5 module is represented | 251449 | ** Each auxiliary function registered with the FTS5 module is represented |
| 249684 | ** by an object of the following type. All such objects are stored as part | 251450 | ** by an object of the following type. All such objects are stored as part |
| 249685 | ** of the Fts5Global.pAux list. | 251451 | ** of the Fts5Global.pAux list. |
| @@ -249697,11 +251463,28 @@ struct Fts5Auxiliary { | |||
| 249697 | ** Each tokenizer module registered with the FTS5 module is represented | 251463 | ** Each tokenizer module registered with the FTS5 module is represented |
| 249698 | ** by an object of the following type. All such objects are stored as part | 251464 | ** by an object of the following type. All such objects are stored as part |
| 249699 | ** of the Fts5Global.pTok list. | 251465 | ** of the Fts5Global.pTok list. |
| 251466 | ** | ||
| 251467 | ** bV2Native: | ||
| 251468 | ** True if the tokenizer was registered using xCreateTokenizer_v2(), false | ||
| 251469 | ** for xCreateTokenizer(). If this variable is true, then x2 is populated | ||
| 251470 | ** with the routines as supplied by the caller and x1 contains synthesized | ||
| 251471 | ** wrapper routines. In this case the user-data pointer passed to | ||
| 251472 | ** x1.xCreate should be a pointer to the Fts5TokenizerModule structure, | ||
| 251473 | ** not a copy of pUserData. | ||
| 251474 | ** | ||
| 251475 | ** Of course, if bV2Native is false, then x1 contains the real routines and | ||
| 251476 | ** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule | ||
| 251477 | ** object should be passed to x2.xCreate. | ||
| 251478 | ** | ||
| 251479 | ** The synthesized wrapper routines are necessary for xFindTokenizer(_v2) | ||
| 251480 | ** calls. | ||
| 249700 | */ | 251481 | */ |
| 249701 | struct Fts5TokenizerModule { | 251482 | struct Fts5TokenizerModule { |
| 249702 | char *zName; /* Name of tokenizer */ | 251483 | char *zName; /* Name of tokenizer */ |
| 249703 | void *pUserData; /* User pointer passed to xCreate() */ | 251484 | void *pUserData; /* User pointer passed to xCreate() */ |
| 249704 | fts5_tokenizer x; /* Tokenizer functions */ | 251485 | int bV2Native; /* True if v2 native tokenizer */ |
| 251486 | fts5_tokenizer x1; /* Tokenizer functions */ | ||
| 251487 | fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ | ||
| 249705 | void (*xDestroy)(void*); /* Destructor function */ | 251488 | void (*xDestroy)(void*); /* Destructor function */ |
| 249706 | Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ | 251489 | Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ |
| 249707 | }; | 251490 | }; |
| @@ -249789,7 +251572,7 @@ struct Fts5Cursor { | |||
| 249789 | Fts5Auxiliary *pAux; /* Currently executing extension function */ | 251572 | Fts5Auxiliary *pAux; /* Currently executing extension function */ |
| 249790 | Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ | 251573 | Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ |
| 249791 | 251574 | ||
| 249792 | /* Cache used by auxiliary functions xInst() and xInstCount() */ | 251575 | /* Cache used by auxiliary API functions xInst() and xInstCount() */ |
| 249793 | Fts5PoslistReader *aInstIter; /* One for each phrase */ | 251576 | Fts5PoslistReader *aInstIter; /* One for each phrase */ |
| 249794 | int nInstAlloc; /* Size of aInst[] array (entries / 3) */ | 251577 | int nInstAlloc; /* Size of aInst[] array (entries / 3) */ |
| 249795 | int nInstCount; /* Number of phrase instances */ | 251578 | int nInstCount; /* Number of phrase instances */ |
| @@ -249900,10 +251683,16 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ | |||
| 249900 | #endif | 251683 | #endif |
| 249901 | 251684 | ||
| 249902 | /* | 251685 | /* |
| 249903 | ** Return true if pTab is a contentless table. | 251686 | ** Return true if pTab is a contentless table. If parameter bIncludeUnindexed |
| 251687 | ** is true, this includes contentless tables that store UNINDEXED columns | ||
| 251688 | ** only. | ||
| 249904 | */ | 251689 | */ |
| 249905 | static int fts5IsContentless(Fts5FullTable *pTab){ | 251690 | static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){ |
| 249906 | return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE; | 251691 | int eContent = pTab->p.pConfig->eContent; |
| 251692 | return ( | ||
| 251693 | eContent==FTS5_CONTENT_NONE | ||
| 251694 | || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED) | ||
| 251695 | ); | ||
| 249907 | } | 251696 | } |
| 249908 | 251697 | ||
| 249909 | /* | 251698 | /* |
| @@ -249971,8 +251760,12 @@ static int fts5InitVtab( | |||
| 249971 | assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); | 251760 | assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); |
| 249972 | } | 251761 | } |
| 249973 | if( rc==SQLITE_OK ){ | 251762 | if( rc==SQLITE_OK ){ |
| 251763 | pConfig->pzErrmsg = pzErr; | ||
| 249974 | pTab->p.pConfig = pConfig; | 251764 | pTab->p.pConfig = pConfig; |
| 249975 | pTab->pGlobal = pGlobal; | 251765 | pTab->pGlobal = pGlobal; |
| 251766 | if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ | ||
| 251767 | rc = sqlite3Fts5LoadTokenizer(pConfig); | ||
| 251768 | } | ||
| 249976 | } | 251769 | } |
| 249977 | 251770 | ||
| 249978 | /* Open the index sub-system */ | 251771 | /* Open the index sub-system */ |
| @@ -249994,11 +251787,7 @@ static int fts5InitVtab( | |||
| 249994 | 251787 | ||
| 249995 | /* Load the initial configuration */ | 251788 | /* Load the initial configuration */ |
| 249996 | if( rc==SQLITE_OK ){ | 251789 | if( rc==SQLITE_OK ){ |
| 249997 | assert( pConfig->pzErrmsg==0 ); | 251790 | rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1); |
| 249998 | pConfig->pzErrmsg = pzErr; | ||
| 249999 | rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); | ||
| 250000 | sqlite3Fts5IndexRollback(pTab->p.pIndex); | ||
| 250001 | pConfig->pzErrmsg = 0; | ||
| 250002 | } | 251791 | } |
| 250003 | 251792 | ||
| 250004 | if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ | 251793 | if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ |
| @@ -250008,6 +251797,7 @@ static int fts5InitVtab( | |||
| 250008 | rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); | 251797 | rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); |
| 250009 | } | 251798 | } |
| 250010 | 251799 | ||
| 251800 | if( pConfig ) pConfig->pzErrmsg = 0; | ||
| 250011 | if( rc!=SQLITE_OK ){ | 251801 | if( rc!=SQLITE_OK ){ |
| 250012 | fts5FreeVtab(pTab); | 251802 | fts5FreeVtab(pTab); |
| 250013 | pTab = 0; | 251803 | pTab = 0; |
| @@ -250075,10 +251865,10 @@ static int fts5UsePatternMatch( | |||
| 250075 | ){ | 251865 | ){ |
| 250076 | assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); | 251866 | assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); |
| 250077 | assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); | 251867 | assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); |
| 250078 | if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ | 251868 | if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ |
| 250079 | return 1; | 251869 | return 1; |
| 250080 | } | 251870 | } |
| 250081 | if( pConfig->ePattern==FTS5_PATTERN_LIKE | 251871 | if( pConfig->t.ePattern==FTS5_PATTERN_LIKE |
| 250082 | && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) | 251872 | && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) |
| 250083 | ){ | 251873 | ){ |
| 250084 | return 1; | 251874 | return 1; |
| @@ -250125,10 +251915,10 @@ static int fts5UsePatternMatch( | |||
| 250125 | ** This function ensures that there is at most one "r" or "=". And that if | 251915 | ** This function ensures that there is at most one "r" or "=". And that if |
| 250126 | ** there exists an "=" then there is no "<" or ">". | 251916 | ** there exists an "=" then there is no "<" or ">". |
| 250127 | ** | 251917 | ** |
| 250128 | ** Costs are assigned as follows: | 251918 | ** If an unusable MATCH operator is present in the WHERE clause, then |
| 251919 | ** SQLITE_CONSTRAINT is returned. | ||
| 250129 | ** | 251920 | ** |
| 250130 | ** a) If an unusable MATCH operator is present in the WHERE clause, the | 251921 | ** Costs are assigned as follows: |
| 250131 | ** cost is unconditionally set to 1e50 (a really big number). | ||
| 250132 | ** | 251922 | ** |
| 250133 | ** a) If a MATCH operator is present, the cost depends on the other | 251923 | ** a) If a MATCH operator is present, the cost depends on the other |
| 250134 | ** constraints also present. As follows: | 251924 | ** constraints also present. As follows: |
| @@ -250161,7 +251951,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 250161 | int bSeenEq = 0; | 251951 | int bSeenEq = 0; |
| 250162 | int bSeenGt = 0; | 251952 | int bSeenGt = 0; |
| 250163 | int bSeenLt = 0; | 251953 | int bSeenLt = 0; |
| 250164 | int bSeenMatch = 0; | 251954 | int nSeenMatch = 0; |
| 250165 | int bSeenRank = 0; | 251955 | int bSeenRank = 0; |
| 250166 | 251956 | ||
| 250167 | 251957 | ||
| @@ -250192,18 +251982,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 250192 | /* A MATCH operator or equivalent */ | 251982 | /* A MATCH operator or equivalent */ |
| 250193 | if( p->usable==0 || iCol<0 ){ | 251983 | if( p->usable==0 || iCol<0 ){ |
| 250194 | /* As there exists an unusable MATCH constraint this is an | 251984 | /* As there exists an unusable MATCH constraint this is an |
| 250195 | ** unusable plan. Set a prohibitively high cost. */ | 251985 | ** unusable plan. Return SQLITE_CONSTRAINT. */ |
| 250196 | pInfo->estimatedCost = 1e50; | 251986 | return SQLITE_CONSTRAINT; |
| 250197 | assert( iIdxStr < pInfo->nConstraint*6 + 1 ); | ||
| 250198 | idxStr[iIdxStr] = 0; | ||
| 250199 | return SQLITE_OK; | ||
| 250200 | }else{ | 251987 | }else{ |
| 250201 | if( iCol==nCol+1 ){ | 251988 | if( iCol==nCol+1 ){ |
| 250202 | if( bSeenRank ) continue; | 251989 | if( bSeenRank ) continue; |
| 250203 | idxStr[iIdxStr++] = 'r'; | 251990 | idxStr[iIdxStr++] = 'r'; |
| 250204 | bSeenRank = 1; | 251991 | bSeenRank = 1; |
| 250205 | }else if( iCol>=0 ){ | 251992 | }else{ |
| 250206 | bSeenMatch = 1; | 251993 | nSeenMatch++; |
| 250207 | idxStr[iIdxStr++] = 'M'; | 251994 | idxStr[iIdxStr++] = 'M'; |
| 250208 | sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); | 251995 | sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); |
| 250209 | idxStr += strlen(&idxStr[iIdxStr]); | 251996 | idxStr += strlen(&idxStr[iIdxStr]); |
| @@ -250220,6 +252007,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 250220 | idxStr += strlen(&idxStr[iIdxStr]); | 252007 | idxStr += strlen(&idxStr[iIdxStr]); |
| 250221 | pInfo->aConstraintUsage[i].argvIndex = ++iCons; | 252008 | pInfo->aConstraintUsage[i].argvIndex = ++iCons; |
| 250222 | assert( idxStr[iIdxStr]=='\0' ); | 252009 | assert( idxStr[iIdxStr]=='\0' ); |
| 252010 | nSeenMatch++; | ||
| 250223 | }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ | 252011 | }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ |
| 250224 | idxStr[iIdxStr++] = '='; | 252012 | idxStr[iIdxStr++] = '='; |
| 250225 | bSeenEq = 1; | 252013 | bSeenEq = 1; |
| @@ -250256,7 +252044,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 250256 | */ | 252044 | */ |
| 250257 | if( pInfo->nOrderBy==1 ){ | 252045 | if( pInfo->nOrderBy==1 ){ |
| 250258 | int iSort = pInfo->aOrderBy[0].iColumn; | 252046 | int iSort = pInfo->aOrderBy[0].iColumn; |
| 250259 | if( iSort==(pConfig->nCol+1) && bSeenMatch ){ | 252047 | if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){ |
| 250260 | idxFlags |= FTS5_BI_ORDER_RANK; | 252048 | idxFlags |= FTS5_BI_ORDER_RANK; |
| 250261 | }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ | 252049 | }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ |
| 250262 | idxFlags |= FTS5_BI_ORDER_ROWID; | 252050 | idxFlags |= FTS5_BI_ORDER_ROWID; |
| @@ -250271,14 +252059,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 250271 | 252059 | ||
| 250272 | /* Calculate the estimated cost based on the flags set in idxFlags. */ | 252060 | /* Calculate the estimated cost based on the flags set in idxFlags. */ |
| 250273 | if( bSeenEq ){ | 252061 | if( bSeenEq ){ |
| 250274 | pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; | 252062 | pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0; |
| 250275 | if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); | 252063 | if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo); |
| 250276 | }else if( bSeenLt && bSeenGt ){ | 252064 | }else if( bSeenLt && bSeenGt ){ |
| 250277 | pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; | 252065 | pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0; |
| 250278 | }else if( bSeenLt || bSeenGt ){ | 252066 | }else if( bSeenLt || bSeenGt ){ |
| 250279 | pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; | 252067 | pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0; |
| 250280 | }else{ | 252068 | }else{ |
| 250281 | pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; | 252069 | pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0; |
| 252070 | } | ||
| 252071 | for(i=1; i<nSeenMatch; i++){ | ||
| 252072 | pInfo->estimatedCost *= 0.4; | ||
| 250282 | } | 252073 | } |
| 250283 | 252074 | ||
| 250284 | pInfo->idxNum = idxFlags; | 252075 | pInfo->idxNum = idxFlags; |
| @@ -250554,6 +252345,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ | |||
| 250554 | } | 252345 | } |
| 250555 | }else{ | 252346 | }else{ |
| 250556 | rc = SQLITE_OK; | 252347 | rc = SQLITE_OK; |
| 252348 | CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE); | ||
| 250557 | } | 252349 | } |
| 250558 | break; | 252350 | break; |
| 250559 | } | 252351 | } |
| @@ -250583,7 +252375,7 @@ static int fts5PrepareStatement( | |||
| 250583 | rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, | 252375 | rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, |
| 250584 | SQLITE_PREPARE_PERSISTENT, &pRet, 0); | 252376 | SQLITE_PREPARE_PERSISTENT, &pRet, 0); |
| 250585 | if( rc!=SQLITE_OK ){ | 252377 | if( rc!=SQLITE_OK ){ |
| 250586 | *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); | 252378 | sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db)); |
| 250587 | } | 252379 | } |
| 250588 | sqlite3_free(zSql); | 252380 | sqlite3_free(zSql); |
| 250589 | } | 252381 | } |
| @@ -250808,6 +252600,145 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ | |||
| 250808 | } | 252600 | } |
| 250809 | 252601 | ||
| 250810 | /* | 252602 | /* |
| 252603 | ** Set the error message on the virtual table passed as the first argument. | ||
| 252604 | */ | ||
| 252605 | static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ | ||
| 252606 | va_list ap; /* ... printf arguments */ | ||
| 252607 | va_start(ap, zFormat); | ||
| 252608 | sqlite3_free(p->p.base.zErrMsg); | ||
| 252609 | p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); | ||
| 252610 | va_end(ap); | ||
| 252611 | } | ||
| 252612 | |||
| 252613 | /* | ||
| 252614 | ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale | ||
| 252615 | ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain | ||
| 252616 | ** valid until after the final call to sqlite3Fts5Tokenize() that will use | ||
| 252617 | ** the locale. | ||
| 252618 | */ | ||
| 252619 | static void sqlite3Fts5SetLocale( | ||
| 252620 | Fts5Config *pConfig, | ||
| 252621 | const char *zLocale, | ||
| 252622 | int nLocale | ||
| 252623 | ){ | ||
| 252624 | Fts5TokenizerConfig *pT = &pConfig->t; | ||
| 252625 | pT->pLocale = zLocale; | ||
| 252626 | pT->nLocale = nLocale; | ||
| 252627 | } | ||
| 252628 | |||
| 252629 | /* | ||
| 252630 | ** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale(). | ||
| 252631 | */ | ||
| 252632 | static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){ | ||
| 252633 | sqlite3Fts5SetLocale(pConfig, 0, 0); | ||
| 252634 | } | ||
| 252635 | |||
| 252636 | /* | ||
| 252637 | ** Return true if the value passed as the only argument is an | ||
| 252638 | ** fts5_locale() value. | ||
| 252639 | */ | ||
| 252640 | static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){ | ||
| 252641 | int ret = 0; | ||
| 252642 | if( sqlite3_value_type(pVal)==SQLITE_BLOB ){ | ||
| 252643 | /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case. | ||
| 252644 | ** If the blob was created using zeroblob(), then sqlite3_value_blob() | ||
| 252645 | ** may call malloc(). If this malloc() fails, then the values returned | ||
| 252646 | ** by both value_blob() and value_bytes() will be 0. If value_bytes() were | ||
| 252647 | ** called first, then the NULL pointer returned by value_blob() might | ||
| 252648 | ** be dereferenced. */ | ||
| 252649 | const u8 *pBlob = sqlite3_value_blob(pVal); | ||
| 252650 | int nBlob = sqlite3_value_bytes(pVal); | ||
| 252651 | if( nBlob>FTS5_LOCALE_HDR_SIZE | ||
| 252652 | && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE) | ||
| 252653 | ){ | ||
| 252654 | ret = 1; | ||
| 252655 | } | ||
| 252656 | } | ||
| 252657 | return ret; | ||
| 252658 | } | ||
| 252659 | |||
| 252660 | /* | ||
| 252661 | ** Value pVal is guaranteed to be an fts5_locale() value, according to | ||
| 252662 | ** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale | ||
| 252663 | ** from the value and returns them separately. | ||
| 252664 | ** | ||
| 252665 | ** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set | ||
| 252666 | ** to point to buffers containing the text and locale, as utf-8, | ||
| 252667 | ** respectively. In this case output parameters (*pnText) and (*pnLoc) are | ||
| 252668 | ** set to the sizes in bytes of these two buffers. | ||
| 252669 | ** | ||
| 252670 | ** Or, if an error occurs, then an SQLite error code is returned. The final | ||
| 252671 | ** value of the four output parameters is undefined in this case. | ||
| 252672 | */ | ||
| 252673 | static int sqlite3Fts5DecodeLocaleValue( | ||
| 252674 | sqlite3_value *pVal, | ||
| 252675 | const char **ppText, | ||
| 252676 | int *pnText, | ||
| 252677 | const char **ppLoc, | ||
| 252678 | int *pnLoc | ||
| 252679 | ){ | ||
| 252680 | const char *p = sqlite3_value_blob(pVal); | ||
| 252681 | int n = sqlite3_value_bytes(pVal); | ||
| 252682 | int nLoc = 0; | ||
| 252683 | |||
| 252684 | assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); | ||
| 252685 | assert( n>FTS5_LOCALE_HDR_SIZE ); | ||
| 252686 | |||
| 252687 | for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){ | ||
| 252688 | if( nLoc==(n-1) ){ | ||
| 252689 | return SQLITE_MISMATCH; | ||
| 252690 | } | ||
| 252691 | } | ||
| 252692 | *ppLoc = &p[FTS5_LOCALE_HDR_SIZE]; | ||
| 252693 | *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE; | ||
| 252694 | |||
| 252695 | *ppText = &p[nLoc+1]; | ||
| 252696 | *pnText = n - nLoc - 1; | ||
| 252697 | return SQLITE_OK; | ||
| 252698 | } | ||
| 252699 | |||
| 252700 | /* | ||
| 252701 | ** Argument pVal is the text of a full-text search expression. It may or | ||
| 252702 | ** may not have been wrapped by fts5_locale(). This function extracts | ||
| 252703 | ** the text of the expression, and sets output variable (*pzText) to | ||
| 252704 | ** point to a nul-terminated buffer containing the expression. | ||
| 252705 | ** | ||
| 252706 | ** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called | ||
| 252707 | ** to set the tokenizer to use the specified locale. | ||
| 252708 | ** | ||
| 252709 | ** If output variable (*pbFreeAndReset) is set to true, then the caller | ||
| 252710 | ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer | ||
| 252711 | ** locale, and (b) call sqlite3_free() to free (*pzText). | ||
| 252712 | */ | ||
| 252713 | static int fts5ExtractExprText( | ||
| 252714 | Fts5Config *pConfig, /* Fts5 configuration */ | ||
| 252715 | sqlite3_value *pVal, /* Value to extract expression text from */ | ||
| 252716 | char **pzText, /* OUT: nul-terminated buffer of text */ | ||
| 252717 | int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */ | ||
| 252718 | ){ | ||
| 252719 | int rc = SQLITE_OK; | ||
| 252720 | |||
| 252721 | if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ | ||
| 252722 | const char *pText = 0; | ||
| 252723 | int nText = 0; | ||
| 252724 | const char *pLoc = 0; | ||
| 252725 | int nLoc = 0; | ||
| 252726 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); | ||
| 252727 | *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText); | ||
| 252728 | if( rc==SQLITE_OK ){ | ||
| 252729 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 252730 | } | ||
| 252731 | *pbFreeAndReset = 1; | ||
| 252732 | }else{ | ||
| 252733 | *pzText = (char*)sqlite3_value_text(pVal); | ||
| 252734 | *pbFreeAndReset = 0; | ||
| 252735 | } | ||
| 252736 | |||
| 252737 | return rc; | ||
| 252738 | } | ||
| 252739 | |||
| 252740 | |||
| 252741 | /* | ||
| 250811 | ** This is the xFilter interface for the virtual table. See | 252742 | ** This is the xFilter interface for the virtual table. See |
| 250812 | ** the virtual table xFilter method documentation for additional | 252743 | ** the virtual table xFilter method documentation for additional |
| 250813 | ** information. | 252744 | ** information. |
| @@ -250841,13 +252772,7 @@ static int fts5FilterMethod( | |||
| 250841 | int iIdxStr = 0; | 252772 | int iIdxStr = 0; |
| 250842 | Fts5Expr *pExpr = 0; | 252773 | Fts5Expr *pExpr = 0; |
| 250843 | 252774 | ||
| 250844 | if( pConfig->bLock ){ | 252775 | assert( pConfig->bLock==0 ); |
| 250845 | pTab->p.base.zErrMsg = sqlite3_mprintf( | ||
| 250846 | "recursively defined fts5 content table" | ||
| 250847 | ); | ||
| 250848 | return SQLITE_ERROR; | ||
| 250849 | } | ||
| 250850 | |||
| 250851 | if( pCsr->ePlan ){ | 252776 | if( pCsr->ePlan ){ |
| 250852 | fts5FreeCursorComponents(pCsr); | 252777 | fts5FreeCursorComponents(pCsr); |
| 250853 | memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); | 252778 | memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); |
| @@ -250871,8 +252796,14 @@ static int fts5FilterMethod( | |||
| 250871 | pRank = apVal[i]; | 252796 | pRank = apVal[i]; |
| 250872 | break; | 252797 | break; |
| 250873 | case 'M': { | 252798 | case 'M': { |
| 250874 | const char *zText = (const char*)sqlite3_value_text(apVal[i]); | 252799 | char *zText = 0; |
| 252800 | int bFreeAndReset = 0; | ||
| 252801 | int bInternal = 0; | ||
| 252802 | |||
| 252803 | rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); | ||
| 252804 | if( rc!=SQLITE_OK ) goto filter_out; | ||
| 250875 | if( zText==0 ) zText = ""; | 252805 | if( zText==0 ) zText = ""; |
| 252806 | |||
| 250876 | iCol = 0; | 252807 | iCol = 0; |
| 250877 | do{ | 252808 | do{ |
| 250878 | iCol = iCol*10 + (idxStr[iIdxStr]-'0'); | 252809 | iCol = iCol*10 + (idxStr[iIdxStr]-'0'); |
| @@ -250884,7 +252815,7 @@ static int fts5FilterMethod( | |||
| 250884 | ** indicates that the MATCH expression is not a full text query, | 252815 | ** indicates that the MATCH expression is not a full text query, |
| 250885 | ** but a request for an internal parameter. */ | 252816 | ** but a request for an internal parameter. */ |
| 250886 | rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); | 252817 | rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); |
| 250887 | goto filter_out; | 252818 | bInternal = 1; |
| 250888 | }else{ | 252819 | }else{ |
| 250889 | char **pzErr = &pTab->p.base.zErrMsg; | 252820 | char **pzErr = &pTab->p.base.zErrMsg; |
| 250890 | rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); | 252821 | rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); |
| @@ -250892,9 +252823,15 @@ static int fts5FilterMethod( | |||
| 250892 | rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); | 252823 | rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); |
| 250893 | pExpr = 0; | 252824 | pExpr = 0; |
| 250894 | } | 252825 | } |
| 250895 | if( rc!=SQLITE_OK ) goto filter_out; | ||
| 250896 | } | 252826 | } |
| 250897 | 252827 | ||
| 252828 | if( bFreeAndReset ){ | ||
| 252829 | sqlite3_free(zText); | ||
| 252830 | sqlite3Fts5ClearLocale(pConfig); | ||
| 252831 | } | ||
| 252832 | |||
| 252833 | if( bInternal || rc!=SQLITE_OK ) goto filter_out; | ||
| 252834 | |||
| 250898 | break; | 252835 | break; |
| 250899 | } | 252836 | } |
| 250900 | case 'L': | 252837 | case 'L': |
| @@ -250982,9 +252919,7 @@ static int fts5FilterMethod( | |||
| 250982 | } | 252919 | } |
| 250983 | } | 252920 | } |
| 250984 | }else if( pConfig->zContent==0 ){ | 252921 | }else if( pConfig->zContent==0 ){ |
| 250985 | *pConfig->pzErrmsg = sqlite3_mprintf( | 252922 | fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); |
| 250986 | "%s: table does not support scanning", pConfig->zName | ||
| 250987 | ); | ||
| 250988 | rc = SQLITE_ERROR; | 252923 | rc = SQLITE_ERROR; |
| 250989 | }else{ | 252924 | }else{ |
| 250990 | /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup | 252925 | /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup |
| @@ -251027,9 +252962,13 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ | |||
| 251027 | assert( pCsr->ePlan==FTS5_PLAN_MATCH | 252962 | assert( pCsr->ePlan==FTS5_PLAN_MATCH |
| 251028 | || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH | 252963 | || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH |
| 251029 | || pCsr->ePlan==FTS5_PLAN_SOURCE | 252964 | || pCsr->ePlan==FTS5_PLAN_SOURCE |
| 252965 | || pCsr->ePlan==FTS5_PLAN_SCAN | ||
| 252966 | || pCsr->ePlan==FTS5_PLAN_ROWID | ||
| 251030 | ); | 252967 | ); |
| 251031 | if( pCsr->pSorter ){ | 252968 | if( pCsr->pSorter ){ |
| 251032 | return pCsr->pSorter->iRowid; | 252969 | return pCsr->pSorter->iRowid; |
| 252970 | }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){ | ||
| 252971 | return sqlite3_column_int64(pCsr->pStmt, 0); | ||
| 251033 | }else{ | 252972 | }else{ |
| 251034 | return sqlite3Fts5ExprRowid(pCsr->pExpr); | 252973 | return sqlite3Fts5ExprRowid(pCsr->pExpr); |
| 251035 | } | 252974 | } |
| @@ -251046,25 +252985,16 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ | |||
| 251046 | int ePlan = pCsr->ePlan; | 252985 | int ePlan = pCsr->ePlan; |
| 251047 | 252986 | ||
| 251048 | assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); | 252987 | assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); |
| 251049 | switch( ePlan ){ | 252988 | if( ePlan==FTS5_PLAN_SPECIAL ){ |
| 251050 | case FTS5_PLAN_SPECIAL: | 252989 | *pRowid = 0; |
| 251051 | *pRowid = 0; | 252990 | }else{ |
| 251052 | break; | 252991 | *pRowid = fts5CursorRowid(pCsr); |
| 251053 | |||
| 251054 | case FTS5_PLAN_SOURCE: | ||
| 251055 | case FTS5_PLAN_MATCH: | ||
| 251056 | case FTS5_PLAN_SORTED_MATCH: | ||
| 251057 | *pRowid = fts5CursorRowid(pCsr); | ||
| 251058 | break; | ||
| 251059 | |||
| 251060 | default: | ||
| 251061 | *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); | ||
| 251062 | break; | ||
| 251063 | } | 252992 | } |
| 251064 | 252993 | ||
| 251065 | return SQLITE_OK; | 252994 | return SQLITE_OK; |
| 251066 | } | 252995 | } |
| 251067 | 252996 | ||
| 252997 | |||
| 251068 | /* | 252998 | /* |
| 251069 | ** If the cursor requires seeking (bSeekRequired flag is set), seek it. | 252999 | ** If the cursor requires seeking (bSeekRequired flag is set), seek it. |
| 251070 | ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. | 253000 | ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. |
| @@ -251101,8 +253031,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ | |||
| 251101 | rc = sqlite3_reset(pCsr->pStmt); | 253031 | rc = sqlite3_reset(pCsr->pStmt); |
| 251102 | if( rc==SQLITE_OK ){ | 253032 | if( rc==SQLITE_OK ){ |
| 251103 | rc = FTS5_CORRUPT; | 253033 | rc = FTS5_CORRUPT; |
| 253034 | fts5SetVtabError((Fts5FullTable*)pTab, | ||
| 253035 | "fts5: missing row %lld from content table %s", | ||
| 253036 | fts5CursorRowid(pCsr), | ||
| 253037 | pTab->pConfig->zContent | ||
| 253038 | ); | ||
| 251104 | }else if( pTab->pConfig->pzErrmsg ){ | 253039 | }else if( pTab->pConfig->pzErrmsg ){ |
| 251105 | *pTab->pConfig->pzErrmsg = sqlite3_mprintf( | 253040 | fts5SetVtabError((Fts5FullTable*)pTab, |
| 251106 | "%s", sqlite3_errmsg(pTab->pConfig->db) | 253041 | "%s", sqlite3_errmsg(pTab->pConfig->db) |
| 251107 | ); | 253042 | ); |
| 251108 | } | 253043 | } |
| @@ -251111,14 +253046,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ | |||
| 251111 | return rc; | 253046 | return rc; |
| 251112 | } | 253047 | } |
| 251113 | 253048 | ||
| 251114 | static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ | ||
| 251115 | va_list ap; /* ... printf arguments */ | ||
| 251116 | va_start(ap, zFormat); | ||
| 251117 | assert( p->p.base.zErrMsg==0 ); | ||
| 251118 | p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); | ||
| 251119 | va_end(ap); | ||
| 251120 | } | ||
| 251121 | |||
| 251122 | /* | 253049 | /* |
| 251123 | ** This function is called to handle an FTS INSERT command. In other words, | 253050 | ** This function is called to handle an FTS INSERT command. In other words, |
| 251124 | ** an INSERT statement of the form: | 253051 | ** an INSERT statement of the form: |
| @@ -251156,7 +253083,7 @@ static int fts5SpecialInsert( | |||
| 251156 | } | 253083 | } |
| 251157 | bLoadConfig = 1; | 253084 | bLoadConfig = 1; |
| 251158 | }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ | 253085 | }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ |
| 251159 | if( pConfig->eContent==FTS5_CONTENT_NONE ){ | 253086 | if( fts5IsContentless(pTab, 1) ){ |
| 251160 | fts5SetVtabError(pTab, | 253087 | fts5SetVtabError(pTab, |
| 251161 | "'rebuild' may not be used with a contentless fts5 table" | 253088 | "'rebuild' may not be used with a contentless fts5 table" |
| 251162 | ); | 253089 | ); |
| @@ -251212,7 +253139,7 @@ static int fts5SpecialDelete( | |||
| 251212 | int eType1 = sqlite3_value_type(apVal[1]); | 253139 | int eType1 = sqlite3_value_type(apVal[1]); |
| 251213 | if( eType1==SQLITE_INTEGER ){ | 253140 | if( eType1==SQLITE_INTEGER ){ |
| 251214 | sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); | 253141 | sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); |
| 251215 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); | 253142 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0); |
| 251216 | } | 253143 | } |
| 251217 | return rc; | 253144 | return rc; |
| 251218 | } | 253145 | } |
| @@ -251225,7 +253152,7 @@ static void fts5StorageInsert( | |||
| 251225 | ){ | 253152 | ){ |
| 251226 | int rc = *pRc; | 253153 | int rc = *pRc; |
| 251227 | if( rc==SQLITE_OK ){ | 253154 | if( rc==SQLITE_OK ){ |
| 251228 | rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); | 253155 | rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid); |
| 251229 | } | 253156 | } |
| 251230 | if( rc==SQLITE_OK ){ | 253157 | if( rc==SQLITE_OK ){ |
| 251231 | rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); | 253158 | rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); |
| @@ -251234,6 +253161,67 @@ static void fts5StorageInsert( | |||
| 251234 | } | 253161 | } |
| 251235 | 253162 | ||
| 251236 | /* | 253163 | /* |
| 253164 | ** | ||
| 253165 | ** This function is called when the user attempts an UPDATE on a contentless | ||
| 253166 | ** table. Parameter bRowidModified is true if the UPDATE statement modifies | ||
| 253167 | ** the rowid value. Parameter apVal[] contains the new values for each user | ||
| 253168 | ** defined column of the fts5 table. pConfig is the configuration object of the | ||
| 253169 | ** table being updated (guaranteed to be contentless). The contentless_delete=1 | ||
| 253170 | ** and contentless_unindexed=1 options may or may not be set. | ||
| 253171 | ** | ||
| 253172 | ** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite | ||
| 253173 | ** error code if it cannot. In this case an error message is also loaded into | ||
| 253174 | ** pConfig. Output parameter (*pbContent) is set to true if the caller should | ||
| 253175 | ** update the %_content table only - not the FTS index or any other shadow | ||
| 253176 | ** table. This occurs when an UPDATE modifies only UNINDEXED columns of the | ||
| 253177 | ** table. | ||
| 253178 | ** | ||
| 253179 | ** An UPDATE may proceed if: | ||
| 253180 | ** | ||
| 253181 | ** * The only columns modified are UNINDEXED columns, or | ||
| 253182 | ** | ||
| 253183 | ** * The contentless_delete=1 option was specified and all of the indexed | ||
| 253184 | ** columns (not a subset) have been modified. | ||
| 253185 | */ | ||
| 253186 | static int fts5ContentlessUpdate( | ||
| 253187 | Fts5Config *pConfig, | ||
| 253188 | sqlite3_value **apVal, | ||
| 253189 | int bRowidModified, | ||
| 253190 | int *pbContent | ||
| 253191 | ){ | ||
| 253192 | int ii; | ||
| 253193 | int bSeenIndex = 0; /* Have seen modified indexed column */ | ||
| 253194 | int bSeenIndexNC = 0; /* Have seen unmodified indexed column */ | ||
| 253195 | int rc = SQLITE_OK; | ||
| 253196 | |||
| 253197 | for(ii=0; ii<pConfig->nCol; ii++){ | ||
| 253198 | if( pConfig->abUnindexed[ii]==0 ){ | ||
| 253199 | if( sqlite3_value_nochange(apVal[ii]) ){ | ||
| 253200 | bSeenIndexNC++; | ||
| 253201 | }else{ | ||
| 253202 | bSeenIndex++; | ||
| 253203 | } | ||
| 253204 | } | ||
| 253205 | } | ||
| 253206 | |||
| 253207 | if( bSeenIndex==0 && bRowidModified==0 ){ | ||
| 253208 | *pbContent = 1; | ||
| 253209 | }else{ | ||
| 253210 | if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){ | ||
| 253211 | rc = SQLITE_ERROR; | ||
| 253212 | sqlite3Fts5ConfigErrmsg(pConfig, | ||
| 253213 | (pConfig->bContentlessDelete ? | ||
| 253214 | "%s a subset of columns on fts5 contentless-delete table: %s" : | ||
| 253215 | "%s contentless fts5 table: %s") | ||
| 253216 | , "cannot UPDATE", pConfig->zName | ||
| 253217 | ); | ||
| 253218 | } | ||
| 253219 | } | ||
| 253220 | |||
| 253221 | return rc; | ||
| 253222 | } | ||
| 253223 | |||
| 253224 | /* | ||
| 251237 | ** This function is the implementation of the xUpdate callback used by | 253225 | ** This function is the implementation of the xUpdate callback used by |
| 251238 | ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be | 253226 | ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be |
| 251239 | ** inserted, updated or deleted. | 253227 | ** inserted, updated or deleted. |
| @@ -251319,41 +253307,46 @@ static int fts5UpdateMethod( | |||
| 251319 | assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); | 253307 | assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); |
| 251320 | assert( nArg!=1 || eType0==SQLITE_INTEGER ); | 253308 | assert( nArg!=1 || eType0==SQLITE_INTEGER ); |
| 251321 | 253309 | ||
| 251322 | /* Filter out attempts to run UPDATE or DELETE on contentless tables. | ||
| 251323 | ** This is not suported. Except - they are both supported if the CREATE | ||
| 251324 | ** VIRTUAL TABLE statement contained "contentless_delete=1". */ | ||
| 251325 | if( eType0==SQLITE_INTEGER | ||
| 251326 | && pConfig->eContent==FTS5_CONTENT_NONE | ||
| 251327 | && pConfig->bContentlessDelete==0 | ||
| 251328 | ){ | ||
| 251329 | pTab->p.base.zErrMsg = sqlite3_mprintf( | ||
| 251330 | "cannot %s contentless fts5 table: %s", | ||
| 251331 | (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName | ||
| 251332 | ); | ||
| 251333 | rc = SQLITE_ERROR; | ||
| 251334 | } | ||
| 251335 | |||
| 251336 | /* DELETE */ | 253310 | /* DELETE */ |
| 251337 | else if( nArg==1 ){ | 253311 | if( nArg==1 ){ |
| 251338 | i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ | 253312 | /* It is only possible to DELETE from a contentless table if the |
| 251339 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); | 253313 | ** contentless_delete=1 flag is set. */ |
| 251340 | bUpdateOrDelete = 1; | 253314 | if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){ |
| 253315 | fts5SetVtabError(pTab, | ||
| 253316 | "cannot DELETE from contentless fts5 table: %s", pConfig->zName | ||
| 253317 | ); | ||
| 253318 | rc = SQLITE_ERROR; | ||
| 253319 | }else{ | ||
| 253320 | i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ | ||
| 253321 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); | ||
| 253322 | bUpdateOrDelete = 1; | ||
| 253323 | } | ||
| 251341 | } | 253324 | } |
| 251342 | 253325 | ||
| 251343 | /* INSERT or UPDATE */ | 253326 | /* INSERT or UPDATE */ |
| 251344 | else{ | 253327 | else{ |
| 251345 | int eType1 = sqlite3_value_numeric_type(apVal[1]); | 253328 | int eType1 = sqlite3_value_numeric_type(apVal[1]); |
| 251346 | 253329 | ||
| 251347 | if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ | 253330 | /* It is an error to write an fts5_locale() value to a table without |
| 251348 | rc = SQLITE_MISMATCH; | 253331 | ** the locale=1 option. */ |
| 253332 | if( pConfig->bLocale==0 ){ | ||
| 253333 | int ii; | ||
| 253334 | for(ii=0; ii<pConfig->nCol; ii++){ | ||
| 253335 | sqlite3_value *pVal = apVal[ii+2]; | ||
| 253336 | if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ | ||
| 253337 | fts5SetVtabError(pTab, "fts5_locale() requires locale=1"); | ||
| 253338 | rc = SQLITE_MISMATCH; | ||
| 253339 | goto update_out; | ||
| 253340 | } | ||
| 253341 | } | ||
| 251349 | } | 253342 | } |
| 251350 | 253343 | ||
| 251351 | else if( eType0!=SQLITE_INTEGER ){ | 253344 | if( eType0!=SQLITE_INTEGER ){ |
| 251352 | /* An INSERT statement. If the conflict-mode is REPLACE, first remove | 253345 | /* An INSERT statement. If the conflict-mode is REPLACE, first remove |
| 251353 | ** the current entry (if any). */ | 253346 | ** the current entry (if any). */ |
| 251354 | if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ | 253347 | if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ |
| 251355 | i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ | 253348 | i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ |
| 251356 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); | 253349 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); |
| 251357 | bUpdateOrDelete = 1; | 253350 | bUpdateOrDelete = 1; |
| 251358 | } | 253351 | } |
| 251359 | fts5StorageInsert(&rc, pTab, apVal, pRowid); | 253352 | fts5StorageInsert(&rc, pTab, apVal, pRowid); |
| @@ -251361,30 +253354,57 @@ static int fts5UpdateMethod( | |||
| 251361 | 253354 | ||
| 251362 | /* UPDATE */ | 253355 | /* UPDATE */ |
| 251363 | else{ | 253356 | else{ |
| 253357 | Fts5Storage *pStorage = pTab->pStorage; | ||
| 251364 | i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ | 253358 | i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ |
| 251365 | i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ | 253359 | i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ |
| 251366 | if( eType1==SQLITE_INTEGER && iOld!=iNew ){ | 253360 | int bContent = 0; /* Content only update */ |
| 253361 | |||
| 253362 | /* If this is a contentless table (including contentless_unindexed=1 | ||
| 253363 | ** tables), check if the UPDATE may proceed. */ | ||
| 253364 | if( fts5IsContentless(pTab, 1) ){ | ||
| 253365 | rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent); | ||
| 253366 | if( rc!=SQLITE_OK ) goto update_out; | ||
| 253367 | } | ||
| 253368 | |||
| 253369 | if( eType1!=SQLITE_INTEGER ){ | ||
| 253370 | rc = SQLITE_MISMATCH; | ||
| 253371 | }else if( iOld!=iNew ){ | ||
| 253372 | assert( bContent==0 ); | ||
| 251367 | if( eConflict==SQLITE_REPLACE ){ | 253373 | if( eConflict==SQLITE_REPLACE ){ |
| 251368 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); | 253374 | rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); |
| 251369 | if( rc==SQLITE_OK ){ | 253375 | if( rc==SQLITE_OK ){ |
| 251370 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); | 253376 | rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0); |
| 251371 | } | 253377 | } |
| 251372 | fts5StorageInsert(&rc, pTab, apVal, pRowid); | 253378 | fts5StorageInsert(&rc, pTab, apVal, pRowid); |
| 251373 | }else{ | 253379 | }else{ |
| 251374 | rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); | 253380 | rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); |
| 253381 | if( rc==SQLITE_OK ){ | ||
| 253382 | rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid); | ||
| 253383 | } | ||
| 251375 | if( rc==SQLITE_OK ){ | 253384 | if( rc==SQLITE_OK ){ |
| 251376 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); | 253385 | rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0); |
| 251377 | } | 253386 | } |
| 251378 | if( rc==SQLITE_OK ){ | 253387 | if( rc==SQLITE_OK ){ |
| 251379 | rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); | 253388 | rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid); |
| 251380 | } | 253389 | } |
| 251381 | } | 253390 | } |
| 253391 | }else if( bContent ){ | ||
| 253392 | /* This occurs when an UPDATE on a contentless table affects *only* | ||
| 253393 | ** UNINDEXED columns. This is a no-op for contentless_unindexed=0 | ||
| 253394 | ** tables, or a write to the %_content table only for =1 tables. */ | ||
| 253395 | assert( fts5IsContentless(pTab, 1) ); | ||
| 253396 | rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); | ||
| 253397 | if( rc==SQLITE_OK ){ | ||
| 253398 | rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid); | ||
| 253399 | } | ||
| 251382 | }else{ | 253400 | }else{ |
| 251383 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); | 253401 | rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); |
| 251384 | fts5StorageInsert(&rc, pTab, apVal, pRowid); | 253402 | fts5StorageInsert(&rc, pTab, apVal, pRowid); |
| 251385 | } | 253403 | } |
| 251386 | bUpdateOrDelete = 1; | 253404 | bUpdateOrDelete = 1; |
| 253405 | sqlite3Fts5StorageReleaseDeleteRow(pStorage); | ||
| 251387 | } | 253406 | } |
| 253407 | |||
| 251388 | } | 253408 | } |
| 251389 | } | 253409 | } |
| 251390 | 253410 | ||
| @@ -251401,6 +253421,7 @@ static int fts5UpdateMethod( | |||
| 251401 | } | 253421 | } |
| 251402 | } | 253422 | } |
| 251403 | 253423 | ||
| 253424 | update_out: | ||
| 251404 | pTab->p.pConfig->pzErrmsg = 0; | 253425 | pTab->p.pConfig->pzErrmsg = 0; |
| 251405 | return rc; | 253426 | return rc; |
| 251406 | } | 253427 | } |
| @@ -251422,9 +253443,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ | |||
| 251422 | ** Implementation of xBegin() method. | 253443 | ** Implementation of xBegin() method. |
| 251423 | */ | 253444 | */ |
| 251424 | static int fts5BeginMethod(sqlite3_vtab *pVtab){ | 253445 | static int fts5BeginMethod(sqlite3_vtab *pVtab){ |
| 251425 | fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); | 253446 | int rc = fts5NewTransaction((Fts5FullTable*)pVtab); |
| 251426 | fts5NewTransaction((Fts5FullTable*)pVtab); | 253447 | if( rc==SQLITE_OK ){ |
| 251427 | return SQLITE_OK; | 253448 | fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); |
| 253449 | } | ||
| 253450 | return rc; | ||
| 251428 | } | 253451 | } |
| 251429 | 253452 | ||
| 251430 | /* | 253453 | /* |
| @@ -251478,17 +253501,40 @@ static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ | |||
| 251478 | return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); | 253501 | return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); |
| 251479 | } | 253502 | } |
| 251480 | 253503 | ||
| 251481 | static int fts5ApiTokenize( | 253504 | /* |
| 253505 | ** Implementation of xTokenize_v2() API. | ||
| 253506 | */ | ||
| 253507 | static int fts5ApiTokenize_v2( | ||
| 251482 | Fts5Context *pCtx, | 253508 | Fts5Context *pCtx, |
| 251483 | const char *pText, int nText, | 253509 | const char *pText, int nText, |
| 253510 | const char *pLoc, int nLoc, | ||
| 251484 | void *pUserData, | 253511 | void *pUserData, |
| 251485 | int (*xToken)(void*, int, const char*, int, int, int) | 253512 | int (*xToken)(void*, int, const char*, int, int, int) |
| 251486 | ){ | 253513 | ){ |
| 251487 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | 253514 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; |
| 251488 | Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); | 253515 | Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); |
| 251489 | return sqlite3Fts5Tokenize( | 253516 | int rc = SQLITE_OK; |
| 251490 | pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken | 253517 | |
| 253518 | sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc); | ||
| 253519 | rc = sqlite3Fts5Tokenize(pTab->pConfig, | ||
| 253520 | FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken | ||
| 251491 | ); | 253521 | ); |
| 253522 | sqlite3Fts5SetLocale(pTab->pConfig, 0, 0); | ||
| 253523 | |||
| 253524 | return rc; | ||
| 253525 | } | ||
| 253526 | |||
| 253527 | /* | ||
| 253528 | ** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0 | ||
| 253529 | ** passed as the locale. | ||
| 253530 | */ | ||
| 253531 | static int fts5ApiTokenize( | ||
| 253532 | Fts5Context *pCtx, | ||
| 253533 | const char *pText, int nText, | ||
| 253534 | void *pUserData, | ||
| 253535 | int (*xToken)(void*, int, const char*, int, int, int) | ||
| 253536 | ){ | ||
| 253537 | return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken); | ||
| 251492 | } | 253538 | } |
| 251493 | 253539 | ||
| 251494 | static int fts5ApiPhraseCount(Fts5Context *pCtx){ | 253540 | static int fts5ApiPhraseCount(Fts5Context *pCtx){ |
| @@ -251501,6 +253547,49 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ | |||
| 251501 | return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); | 253547 | return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); |
| 251502 | } | 253548 | } |
| 251503 | 253549 | ||
| 253550 | /* | ||
| 253551 | ** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This | ||
| 253552 | ** function extracts the text value of column iCol of the current row. | ||
| 253553 | ** Additionally, if there is an associated locale, it invokes | ||
| 253554 | ** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller | ||
| 253555 | ** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point | ||
| 253556 | ** after this function returns. | ||
| 253557 | ** | ||
| 253558 | ** If successful, (*ppText) is set to point to a buffer containing the text | ||
| 253559 | ** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that | ||
| 253560 | ** buffer in bytes. It is not guaranteed to be nul-terminated. If an error | ||
| 253561 | ** occurs, an SQLite error code is returned. The final values of the two | ||
| 253562 | ** output parameters are undefined in this case. | ||
| 253563 | */ | ||
| 253564 | static int fts5TextFromStmt( | ||
| 253565 | Fts5Config *pConfig, | ||
| 253566 | sqlite3_stmt *pStmt, | ||
| 253567 | int iCol, | ||
| 253568 | const char **ppText, | ||
| 253569 | int *pnText | ||
| 253570 | ){ | ||
| 253571 | sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1); | ||
| 253572 | const char *pLoc = 0; | ||
| 253573 | int nLoc = 0; | ||
| 253574 | int rc = SQLITE_OK; | ||
| 253575 | |||
| 253576 | if( pConfig->bLocale | ||
| 253577 | && pConfig->eContent==FTS5_CONTENT_EXTERNAL | ||
| 253578 | && sqlite3Fts5IsLocaleValue(pConfig, pVal) | ||
| 253579 | ){ | ||
| 253580 | rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc); | ||
| 253581 | }else{ | ||
| 253582 | *ppText = (const char*)sqlite3_value_text(pVal); | ||
| 253583 | *pnText = sqlite3_value_bytes(pVal); | ||
| 253584 | if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){ | ||
| 253585 | pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol); | ||
| 253586 | nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol); | ||
| 253587 | } | ||
| 253588 | } | ||
| 253589 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 253590 | return rc; | ||
| 253591 | } | ||
| 253592 | |||
| 251504 | static int fts5ApiColumnText( | 253593 | static int fts5ApiColumnText( |
| 251505 | Fts5Context *pCtx, | 253594 | Fts5Context *pCtx, |
| 251506 | int iCol, | 253595 | int iCol, |
| @@ -251510,28 +253599,35 @@ static int fts5ApiColumnText( | |||
| 251510 | int rc = SQLITE_OK; | 253599 | int rc = SQLITE_OK; |
| 251511 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | 253600 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; |
| 251512 | Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); | 253601 | Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); |
| 253602 | |||
| 253603 | assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); | ||
| 251513 | if( iCol<0 || iCol>=pTab->pConfig->nCol ){ | 253604 | if( iCol<0 || iCol>=pTab->pConfig->nCol ){ |
| 251514 | rc = SQLITE_RANGE; | 253605 | rc = SQLITE_RANGE; |
| 251515 | }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) | 253606 | }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){ |
| 251516 | || pCsr->ePlan==FTS5_PLAN_SPECIAL | ||
| 251517 | ){ | ||
| 251518 | *pz = 0; | 253607 | *pz = 0; |
| 251519 | *pn = 0; | 253608 | *pn = 0; |
| 251520 | }else{ | 253609 | }else{ |
| 251521 | rc = fts5SeekCursor(pCsr, 0); | 253610 | rc = fts5SeekCursor(pCsr, 0); |
| 251522 | if( rc==SQLITE_OK ){ | 253611 | if( rc==SQLITE_OK ){ |
| 251523 | *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1); | 253612 | rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn); |
| 251524 | *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1); | 253613 | sqlite3Fts5ClearLocale(pTab->pConfig); |
| 251525 | } | 253614 | } |
| 251526 | } | 253615 | } |
| 251527 | return rc; | 253616 | return rc; |
| 251528 | } | 253617 | } |
| 251529 | 253618 | ||
| 253619 | /* | ||
| 253620 | ** This is called by various API functions - xInst, xPhraseFirst, | ||
| 253621 | ** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase | ||
| 253622 | ** of the current row. This function works for both detail=full tables (in | ||
| 253623 | ** which case the position-list was read from the fts index) or for other | ||
| 253624 | ** detail= modes if the row content is available. | ||
| 253625 | */ | ||
| 251530 | static int fts5CsrPoslist( | 253626 | static int fts5CsrPoslist( |
| 251531 | Fts5Cursor *pCsr, | 253627 | Fts5Cursor *pCsr, /* Fts5 cursor object */ |
| 251532 | int iPhrase, | 253628 | int iPhrase, /* Phrase to find position list for */ |
| 251533 | const u8 **pa, | 253629 | const u8 **pa, /* OUT: Pointer to position list buffer */ |
| 251534 | int *pn | 253630 | int *pn /* OUT: Size of (*pa) in bytes */ |
| 251535 | ){ | 253631 | ){ |
| 251536 | Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; | 253632 | Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; |
| 251537 | int rc = SQLITE_OK; | 253633 | int rc = SQLITE_OK; |
| @@ -251539,20 +253635,32 @@ static int fts5CsrPoslist( | |||
| 251539 | 253635 | ||
| 251540 | if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ | 253636 | if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ |
| 251541 | rc = SQLITE_RANGE; | 253637 | rc = SQLITE_RANGE; |
| 253638 | }else if( pConfig->eDetail!=FTS5_DETAIL_FULL | ||
| 253639 | && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) | ||
| 253640 | ){ | ||
| 253641 | *pa = 0; | ||
| 253642 | *pn = 0; | ||
| 253643 | return SQLITE_OK; | ||
| 251542 | }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ | 253644 | }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ |
| 251543 | if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ | 253645 | if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ |
| 251544 | Fts5PoslistPopulator *aPopulator; | 253646 | Fts5PoslistPopulator *aPopulator; |
| 251545 | int i; | 253647 | int i; |
| 253648 | |||
| 251546 | aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); | 253649 | aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); |
| 251547 | if( aPopulator==0 ) rc = SQLITE_NOMEM; | 253650 | if( aPopulator==0 ) rc = SQLITE_NOMEM; |
| 253651 | if( rc==SQLITE_OK ){ | ||
| 253652 | rc = fts5SeekCursor(pCsr, 0); | ||
| 253653 | } | ||
| 251548 | for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){ | 253654 | for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){ |
| 251549 | int n; const char *z; | 253655 | const char *z = 0; |
| 251550 | rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n); | 253656 | int n = 0; |
| 253657 | rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); | ||
| 251551 | if( rc==SQLITE_OK ){ | 253658 | if( rc==SQLITE_OK ){ |
| 251552 | rc = sqlite3Fts5ExprPopulatePoslists( | 253659 | rc = sqlite3Fts5ExprPopulatePoslists( |
| 251553 | pConfig, pCsr->pExpr, aPopulator, i, z, n | 253660 | pConfig, pCsr->pExpr, aPopulator, i, z, n |
| 251554 | ); | 253661 | ); |
| 251555 | } | 253662 | } |
| 253663 | sqlite3Fts5ClearLocale(pConfig); | ||
| 251556 | } | 253664 | } |
| 251557 | sqlite3_free(aPopulator); | 253665 | sqlite3_free(aPopulator); |
| 251558 | 253666 | ||
| @@ -251577,7 +253685,6 @@ static int fts5CsrPoslist( | |||
| 251577 | *pn = 0; | 253685 | *pn = 0; |
| 251578 | } | 253686 | } |
| 251579 | 253687 | ||
| 251580 | |||
| 251581 | return rc; | 253688 | return rc; |
| 251582 | } | 253689 | } |
| 251583 | 253690 | ||
| @@ -251646,7 +253753,8 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ | |||
| 251646 | aInst[0] = iBest; | 253753 | aInst[0] = iBest; |
| 251647 | aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); | 253754 | aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); |
| 251648 | aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); | 253755 | aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); |
| 251649 | if( aInst[1]<0 || aInst[1]>=nCol ){ | 253756 | assert( aInst[1]>=0 ); |
| 253757 | if( aInst[1]>=nCol ){ | ||
| 251650 | rc = FTS5_CORRUPT; | 253758 | rc = FTS5_CORRUPT; |
| 251651 | break; | 253759 | break; |
| 251652 | } | 253760 | } |
| @@ -251724,7 +253832,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ | |||
| 251724 | if( pConfig->bColumnsize ){ | 253832 | if( pConfig->bColumnsize ){ |
| 251725 | i64 iRowid = fts5CursorRowid(pCsr); | 253833 | i64 iRowid = fts5CursorRowid(pCsr); |
| 251726 | rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); | 253834 | rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); |
| 251727 | }else if( pConfig->zContent==0 ){ | 253835 | }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ |
| 251728 | int i; | 253836 | int i; |
| 251729 | for(i=0; i<pConfig->nCol; i++){ | 253837 | for(i=0; i<pConfig->nCol; i++){ |
| 251730 | if( pConfig->abUnindexed[i]==0 ){ | 253838 | if( pConfig->abUnindexed[i]==0 ){ |
| @@ -251733,17 +253841,19 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ | |||
| 251733 | } | 253841 | } |
| 251734 | }else{ | 253842 | }else{ |
| 251735 | int i; | 253843 | int i; |
| 253844 | rc = fts5SeekCursor(pCsr, 0); | ||
| 251736 | for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ | 253845 | for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ |
| 251737 | if( pConfig->abUnindexed[i]==0 ){ | 253846 | if( pConfig->abUnindexed[i]==0 ){ |
| 251738 | const char *z; int n; | 253847 | const char *z = 0; |
| 251739 | void *p = (void*)(&pCsr->aColumnSize[i]); | 253848 | int n = 0; |
| 251740 | pCsr->aColumnSize[i] = 0; | 253849 | pCsr->aColumnSize[i] = 0; |
| 251741 | rc = fts5ApiColumnText(pCtx, i, &z, &n); | 253850 | rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); |
| 251742 | if( rc==SQLITE_OK ){ | 253851 | if( rc==SQLITE_OK ){ |
| 251743 | rc = sqlite3Fts5Tokenize( | 253852 | rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX, |
| 251744 | pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb | 253853 | z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb |
| 251745 | ); | 253854 | ); |
| 251746 | } | 253855 | } |
| 253856 | sqlite3Fts5ClearLocale(pConfig); | ||
| 251747 | } | 253857 | } |
| 251748 | } | 253858 | } |
| 251749 | } | 253859 | } |
| @@ -251823,11 +253933,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){ | |||
| 251823 | } | 253933 | } |
| 251824 | 253934 | ||
| 251825 | static void fts5ApiPhraseNext( | 253935 | static void fts5ApiPhraseNext( |
| 251826 | Fts5Context *pUnused, | 253936 | Fts5Context *pCtx, |
| 251827 | Fts5PhraseIter *pIter, | 253937 | Fts5PhraseIter *pIter, |
| 251828 | int *piCol, int *piOff | 253938 | int *piCol, int *piOff |
| 251829 | ){ | 253939 | ){ |
| 251830 | UNUSED_PARAM(pUnused); | ||
| 251831 | if( pIter->a>=pIter->b ){ | 253940 | if( pIter->a>=pIter->b ){ |
| 251832 | *piCol = -1; | 253941 | *piCol = -1; |
| 251833 | *piOff = -1; | 253942 | *piOff = -1; |
| @@ -251835,8 +253944,12 @@ static void fts5ApiPhraseNext( | |||
| 251835 | int iVal; | 253944 | int iVal; |
| 251836 | pIter->a += fts5GetVarint32(pIter->a, iVal); | 253945 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 251837 | if( iVal==1 ){ | 253946 | if( iVal==1 ){ |
| 253947 | /* Avoid returning a (*piCol) value that is too large for the table, | ||
| 253948 | ** even if the position-list is corrupt. The caller might not be | ||
| 253949 | ** expecting it. */ | ||
| 253950 | int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; | ||
| 251838 | pIter->a += fts5GetVarint32(pIter->a, iVal); | 253951 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 251839 | *piCol = iVal; | 253952 | *piCol = (iVal>=nCol ? nCol-1 : iVal); |
| 251840 | *piOff = 0; | 253953 | *piOff = 0; |
| 251841 | pIter->a += fts5GetVarint32(pIter->a, iVal); | 253954 | pIter->a += fts5GetVarint32(pIter->a, iVal); |
| 251842 | } | 253955 | } |
| @@ -251986,8 +254099,48 @@ static int fts5ApiQueryPhrase(Fts5Context*, int, void*, | |||
| 251986 | int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) | 254099 | int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) |
| 251987 | ); | 254100 | ); |
| 251988 | 254101 | ||
| 254102 | /* | ||
| 254103 | ** The xColumnLocale() API. | ||
| 254104 | */ | ||
| 254105 | static int fts5ApiColumnLocale( | ||
| 254106 | Fts5Context *pCtx, | ||
| 254107 | int iCol, | ||
| 254108 | const char **pzLocale, | ||
| 254109 | int *pnLocale | ||
| 254110 | ){ | ||
| 254111 | int rc = SQLITE_OK; | ||
| 254112 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | ||
| 254113 | Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; | ||
| 254114 | |||
| 254115 | *pzLocale = 0; | ||
| 254116 | *pnLocale = 0; | ||
| 254117 | |||
| 254118 | assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); | ||
| 254119 | if( iCol<0 || iCol>=pConfig->nCol ){ | ||
| 254120 | rc = SQLITE_RANGE; | ||
| 254121 | }else if( | ||
| 254122 | pConfig->abUnindexed[iCol]==0 | ||
| 254123 | && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) | ||
| 254124 | && pConfig->bLocale | ||
| 254125 | ){ | ||
| 254126 | rc = fts5SeekCursor(pCsr, 0); | ||
| 254127 | if( rc==SQLITE_OK ){ | ||
| 254128 | const char *zDummy = 0; | ||
| 254129 | int nDummy = 0; | ||
| 254130 | rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy); | ||
| 254131 | if( rc==SQLITE_OK ){ | ||
| 254132 | *pzLocale = pConfig->t.pLocale; | ||
| 254133 | *pnLocale = pConfig->t.nLocale; | ||
| 254134 | } | ||
| 254135 | sqlite3Fts5ClearLocale(pConfig); | ||
| 254136 | } | ||
| 254137 | } | ||
| 254138 | |||
| 254139 | return rc; | ||
| 254140 | } | ||
| 254141 | |||
| 251989 | static const Fts5ExtensionApi sFts5Api = { | 254142 | static const Fts5ExtensionApi sFts5Api = { |
| 251990 | 3, /* iVersion */ | 254143 | 4, /* iVersion */ |
| 251991 | fts5ApiUserData, | 254144 | fts5ApiUserData, |
| 251992 | fts5ApiColumnCount, | 254145 | fts5ApiColumnCount, |
| 251993 | fts5ApiRowCount, | 254146 | fts5ApiRowCount, |
| @@ -252008,7 +254161,9 @@ static const Fts5ExtensionApi sFts5Api = { | |||
| 252008 | fts5ApiPhraseFirstColumn, | 254161 | fts5ApiPhraseFirstColumn, |
| 252009 | fts5ApiPhraseNextColumn, | 254162 | fts5ApiPhraseNextColumn, |
| 252010 | fts5ApiQueryToken, | 254163 | fts5ApiQueryToken, |
| 252011 | fts5ApiInstToken | 254164 | fts5ApiInstToken, |
| 254165 | fts5ApiColumnLocale, | ||
| 254166 | fts5ApiTokenize_v2 | ||
| 252012 | }; | 254167 | }; |
| 252013 | 254168 | ||
| 252014 | /* | 254169 | /* |
| @@ -252059,6 +254214,7 @@ static void fts5ApiInvoke( | |||
| 252059 | sqlite3_value **argv | 254214 | sqlite3_value **argv |
| 252060 | ){ | 254215 | ){ |
| 252061 | assert( pCsr->pAux==0 ); | 254216 | assert( pCsr->pAux==0 ); |
| 254217 | assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); | ||
| 252062 | pCsr->pAux = pAux; | 254218 | pCsr->pAux = pAux; |
| 252063 | pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); | 254219 | pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); |
| 252064 | pCsr->pAux = 0; | 254220 | pCsr->pAux = 0; |
| @@ -252072,6 +254228,21 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ | |||
| 252072 | return pCsr; | 254228 | return pCsr; |
| 252073 | } | 254229 | } |
| 252074 | 254230 | ||
| 254231 | /* | ||
| 254232 | ** Parameter zFmt is a printf() style formatting string. This function | ||
| 254233 | ** formats it using the trailing arguments and returns the result as | ||
| 254234 | ** an error message to the context passed as the first argument. | ||
| 254235 | */ | ||
| 254236 | static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){ | ||
| 254237 | char *zErr = 0; | ||
| 254238 | va_list ap; | ||
| 254239 | va_start(ap, zFmt); | ||
| 254240 | zErr = sqlite3_vmprintf(zFmt, ap); | ||
| 254241 | sqlite3_result_error(pCtx, zErr, -1); | ||
| 254242 | sqlite3_free(zErr); | ||
| 254243 | va_end(ap); | ||
| 254244 | } | ||
| 254245 | |||
| 252075 | static void fts5ApiCallback( | 254246 | static void fts5ApiCallback( |
| 252076 | sqlite3_context *context, | 254247 | sqlite3_context *context, |
| 252077 | int argc, | 254248 | int argc, |
| @@ -252087,12 +254258,13 @@ static void fts5ApiCallback( | |||
| 252087 | iCsrId = sqlite3_value_int64(argv[0]); | 254258 | iCsrId = sqlite3_value_int64(argv[0]); |
| 252088 | 254259 | ||
| 252089 | pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); | 254260 | pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); |
| 252090 | if( pCsr==0 || pCsr->ePlan==0 ){ | 254261 | if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){ |
| 252091 | char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); | 254262 | fts5ResultError(context, "no such cursor: %lld", iCsrId); |
| 252092 | sqlite3_result_error(context, zErr, -1); | ||
| 252093 | sqlite3_free(zErr); | ||
| 252094 | }else{ | 254263 | }else{ |
| 254264 | sqlite3_vtab *pTab = pCsr->base.pVtab; | ||
| 252095 | fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); | 254265 | fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); |
| 254266 | sqlite3_free(pTab->zErrMsg); | ||
| 254267 | pTab->zErrMsg = 0; | ||
| 252096 | } | 254268 | } |
| 252097 | } | 254269 | } |
| 252098 | 254270 | ||
| @@ -252210,8 +254382,8 @@ static int fts5ColumnMethod( | |||
| 252210 | ** auxiliary function. */ | 254382 | ** auxiliary function. */ |
| 252211 | sqlite3_result_int64(pCtx, pCsr->iCsrId); | 254383 | sqlite3_result_int64(pCtx, pCsr->iCsrId); |
| 252212 | }else if( iCol==pConfig->nCol+1 ){ | 254384 | }else if( iCol==pConfig->nCol+1 ){ |
| 252213 | |||
| 252214 | /* The value of the "rank" column. */ | 254385 | /* The value of the "rank" column. */ |
| 254386 | |||
| 252215 | if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ | 254387 | if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ |
| 252216 | fts5PoslistBlob(pCtx, pCsr); | 254388 | fts5PoslistBlob(pCtx, pCsr); |
| 252217 | }else if( | 254389 | }else if( |
| @@ -252222,20 +254394,32 @@ static int fts5ColumnMethod( | |||
| 252222 | fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); | 254394 | fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); |
| 252223 | } | 254395 | } |
| 252224 | } | 254396 | } |
| 252225 | }else if( !fts5IsContentless(pTab) ){ | 254397 | }else{ |
| 252226 | pConfig->pzErrmsg = &pTab->p.base.zErrMsg; | 254398 | if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){ |
| 252227 | rc = fts5SeekCursor(pCsr, 1); | 254399 | pConfig->pzErrmsg = &pTab->p.base.zErrMsg; |
| 252228 | if( rc==SQLITE_OK ){ | 254400 | rc = fts5SeekCursor(pCsr, 1); |
| 252229 | sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); | 254401 | if( rc==SQLITE_OK ){ |
| 254402 | sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1); | ||
| 254403 | if( pConfig->bLocale | ||
| 254404 | && pConfig->eContent==FTS5_CONTENT_EXTERNAL | ||
| 254405 | && sqlite3Fts5IsLocaleValue(pConfig, pVal) | ||
| 254406 | ){ | ||
| 254407 | const char *z = 0; | ||
| 254408 | int n = 0; | ||
| 254409 | rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n); | ||
| 254410 | if( rc==SQLITE_OK ){ | ||
| 254411 | sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT); | ||
| 254412 | } | ||
| 254413 | sqlite3Fts5ClearLocale(pConfig); | ||
| 254414 | }else{ | ||
| 254415 | sqlite3_result_value(pCtx, pVal); | ||
| 254416 | } | ||
| 254417 | } | ||
| 254418 | |||
| 254419 | pConfig->pzErrmsg = 0; | ||
| 252230 | } | 254420 | } |
| 252231 | pConfig->pzErrmsg = 0; | ||
| 252232 | }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ | ||
| 252233 | char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " | ||
| 252234 | "columns on fts5 contentless-delete table: %s", pConfig->zName | ||
| 252235 | ); | ||
| 252236 | sqlite3_result_error(pCtx, zErr, -1); | ||
| 252237 | sqlite3_free(zErr); | ||
| 252238 | } | 254421 | } |
| 254422 | |||
| 252239 | return rc; | 254423 | return rc; |
| 252240 | } | 254424 | } |
| 252241 | 254425 | ||
| @@ -252375,47 +254559,210 @@ static int fts5CreateAux( | |||
| 252375 | } | 254559 | } |
| 252376 | 254560 | ||
| 252377 | /* | 254561 | /* |
| 252378 | ** Register a new tokenizer. This is the implementation of the | 254562 | ** This function is used by xCreateTokenizer_v2() and xCreateTokenizer(). |
| 252379 | ** fts5_api.xCreateTokenizer() method. | 254563 | ** It allocates and partially populates a new Fts5TokenizerModule object. |
| 254564 | ** The new object is already linked into the Fts5Global context before | ||
| 254565 | ** returning. | ||
| 254566 | ** | ||
| 254567 | ** If successful, SQLITE_OK is returned and a pointer to the new | ||
| 254568 | ** Fts5TokenizerModule object returned via output parameter (*ppNew). All | ||
| 254569 | ** that is required is for the caller to fill in the methods in | ||
| 254570 | ** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native | ||
| 254571 | ** as appropriate. | ||
| 254572 | ** | ||
| 254573 | ** If an error occurs, an SQLite error code is returned and the final value | ||
| 254574 | ** of (*ppNew) undefined. | ||
| 252380 | */ | 254575 | */ |
| 252381 | static int fts5CreateTokenizer( | 254576 | static int fts5NewTokenizerModule( |
| 252382 | fts5_api *pApi, /* Global context (one per db handle) */ | 254577 | Fts5Global *pGlobal, /* Global context (one per db handle) */ |
| 252383 | const char *zName, /* Name of new function */ | 254578 | const char *zName, /* Name of new function */ |
| 252384 | void *pUserData, /* User data for aux. function */ | 254579 | void *pUserData, /* User data for aux. function */ |
| 252385 | fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ | 254580 | void(*xDestroy)(void*), /* Destructor for pUserData */ |
| 252386 | void(*xDestroy)(void*) /* Destructor for pUserData */ | 254581 | Fts5TokenizerModule **ppNew |
| 252387 | ){ | 254582 | ){ |
| 252388 | Fts5Global *pGlobal = (Fts5Global*)pApi; | ||
| 252389 | Fts5TokenizerModule *pNew; | ||
| 252390 | sqlite3_int64 nName; /* Size of zName and its \0 terminator */ | ||
| 252391 | sqlite3_int64 nByte; /* Bytes of space to allocate */ | ||
| 252392 | int rc = SQLITE_OK; | 254583 | int rc = SQLITE_OK; |
| 254584 | Fts5TokenizerModule *pNew; | ||
| 254585 | sqlite3_int64 nName; /* Size of zName and its \0 terminator */ | ||
| 254586 | sqlite3_int64 nByte; /* Bytes of space to allocate */ | ||
| 252393 | 254587 | ||
| 252394 | nName = strlen(zName) + 1; | 254588 | nName = strlen(zName) + 1; |
| 252395 | nByte = sizeof(Fts5TokenizerModule) + nName; | 254589 | nByte = sizeof(Fts5TokenizerModule) + nName; |
| 252396 | pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte); | 254590 | *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte); |
| 252397 | if( pNew ){ | 254591 | if( pNew ){ |
| 252398 | memset(pNew, 0, (size_t)nByte); | ||
| 252399 | pNew->zName = (char*)&pNew[1]; | 254592 | pNew->zName = (char*)&pNew[1]; |
| 252400 | memcpy(pNew->zName, zName, nName); | 254593 | memcpy(pNew->zName, zName, nName); |
| 252401 | pNew->pUserData = pUserData; | 254594 | pNew->pUserData = pUserData; |
| 252402 | pNew->x = *pTokenizer; | ||
| 252403 | pNew->xDestroy = xDestroy; | 254595 | pNew->xDestroy = xDestroy; |
| 252404 | pNew->pNext = pGlobal->pTok; | 254596 | pNew->pNext = pGlobal->pTok; |
| 252405 | pGlobal->pTok = pNew; | 254597 | pGlobal->pTok = pNew; |
| 252406 | if( pNew->pNext==0 ){ | 254598 | if( pNew->pNext==0 ){ |
| 252407 | pGlobal->pDfltTok = pNew; | 254599 | pGlobal->pDfltTok = pNew; |
| 252408 | } | 254600 | } |
| 254601 | } | ||
| 254602 | |||
| 254603 | return rc; | ||
| 254604 | } | ||
| 254605 | |||
| 254606 | /* | ||
| 254607 | ** An instance of this type is used as the Fts5Tokenizer object for | ||
| 254608 | ** wrapper tokenizers - those that provide access to a v1 tokenizer via | ||
| 254609 | ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer | ||
| 254610 | ** via the fts5_tokenizer API. | ||
| 254611 | */ | ||
| 254612 | typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer; | ||
| 254613 | struct Fts5VtoVTokenizer { | ||
| 254614 | int bV2Native; /* True if v2 native tokenizer */ | ||
| 254615 | fts5_tokenizer x1; /* Tokenizer functions */ | ||
| 254616 | fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ | ||
| 254617 | Fts5Tokenizer *pReal; | ||
| 254618 | }; | ||
| 254619 | |||
| 254620 | /* | ||
| 254621 | ** Create a wrapper tokenizer. The context argument pCtx points to the | ||
| 254622 | ** Fts5TokenizerModule object. | ||
| 254623 | */ | ||
| 254624 | static int fts5VtoVCreate( | ||
| 254625 | void *pCtx, | ||
| 254626 | const char **azArg, | ||
| 254627 | int nArg, | ||
| 254628 | Fts5Tokenizer **ppOut | ||
| 254629 | ){ | ||
| 254630 | Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx; | ||
| 254631 | Fts5VtoVTokenizer *pNew = 0; | ||
| 254632 | int rc = SQLITE_OK; | ||
| 254633 | |||
| 254634 | pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); | ||
| 254635 | if( rc==SQLITE_OK ){ | ||
| 254636 | pNew->x1 = pMod->x1; | ||
| 254637 | pNew->x2 = pMod->x2; | ||
| 254638 | pNew->bV2Native = pMod->bV2Native; | ||
| 254639 | if( pMod->bV2Native ){ | ||
| 254640 | rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); | ||
| 254641 | }else{ | ||
| 254642 | rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); | ||
| 254643 | } | ||
| 254644 | if( rc!=SQLITE_OK ){ | ||
| 254645 | sqlite3_free(pNew); | ||
| 254646 | pNew = 0; | ||
| 254647 | } | ||
| 254648 | } | ||
| 254649 | |||
| 254650 | *ppOut = (Fts5Tokenizer*)pNew; | ||
| 254651 | return rc; | ||
| 254652 | } | ||
| 254653 | |||
| 254654 | /* | ||
| 254655 | ** Delete an Fts5VtoVTokenizer wrapper tokenizer. | ||
| 254656 | */ | ||
| 254657 | static void fts5VtoVDelete(Fts5Tokenizer *pTok){ | ||
| 254658 | Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; | ||
| 254659 | if( p ){ | ||
| 254660 | if( p->bV2Native ){ | ||
| 254661 | p->x2.xDelete(p->pReal); | ||
| 254662 | }else{ | ||
| 254663 | p->x1.xDelete(p->pReal); | ||
| 254664 | } | ||
| 254665 | sqlite3_free(p); | ||
| 254666 | } | ||
| 254667 | } | ||
| 254668 | |||
| 254669 | |||
| 254670 | /* | ||
| 254671 | ** xTokenizer method for a wrapper tokenizer that offers the v1 interface | ||
| 254672 | ** (no support for locales). | ||
| 254673 | */ | ||
| 254674 | static int fts5V1toV2Tokenize( | ||
| 254675 | Fts5Tokenizer *pTok, | ||
| 254676 | void *pCtx, int flags, | ||
| 254677 | const char *pText, int nText, | ||
| 254678 | int (*xToken)(void*, int, const char*, int, int, int) | ||
| 254679 | ){ | ||
| 254680 | Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; | ||
| 254681 | assert( p->bV2Native ); | ||
| 254682 | return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken); | ||
| 254683 | } | ||
| 254684 | |||
| 254685 | /* | ||
| 254686 | ** xTokenizer method for a wrapper tokenizer that offers the v2 interface | ||
| 254687 | ** (with locale support). | ||
| 254688 | */ | ||
| 254689 | static int fts5V2toV1Tokenize( | ||
| 254690 | Fts5Tokenizer *pTok, | ||
| 254691 | void *pCtx, int flags, | ||
| 254692 | const char *pText, int nText, | ||
| 254693 | const char *pLocale, int nLocale, | ||
| 254694 | int (*xToken)(void*, int, const char*, int, int, int) | ||
| 254695 | ){ | ||
| 254696 | Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; | ||
| 254697 | assert( p->bV2Native==0 ); | ||
| 254698 | UNUSED_PARAM2(pLocale,nLocale); | ||
| 254699 | return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken); | ||
| 254700 | } | ||
| 254701 | |||
| 254702 | /* | ||
| 254703 | ** Register a new tokenizer. This is the implementation of the | ||
| 254704 | ** fts5_api.xCreateTokenizer_v2() method. | ||
| 254705 | */ | ||
| 254706 | static int fts5CreateTokenizer_v2( | ||
| 254707 | fts5_api *pApi, /* Global context (one per db handle) */ | ||
| 254708 | const char *zName, /* Name of new function */ | ||
| 254709 | void *pUserData, /* User data for aux. function */ | ||
| 254710 | fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */ | ||
| 254711 | void(*xDestroy)(void*) /* Destructor for pUserData */ | ||
| 254712 | ){ | ||
| 254713 | Fts5Global *pGlobal = (Fts5Global*)pApi; | ||
| 254714 | int rc = SQLITE_OK; | ||
| 254715 | |||
| 254716 | if( pTokenizer->iVersion>2 ){ | ||
| 254717 | rc = SQLITE_ERROR; | ||
| 252409 | }else{ | 254718 | }else{ |
| 252410 | rc = SQLITE_NOMEM; | 254719 | Fts5TokenizerModule *pNew = 0; |
| 254720 | rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew); | ||
| 254721 | if( pNew ){ | ||
| 254722 | pNew->x2 = *pTokenizer; | ||
| 254723 | pNew->bV2Native = 1; | ||
| 254724 | pNew->x1.xCreate = fts5VtoVCreate; | ||
| 254725 | pNew->x1.xTokenize = fts5V1toV2Tokenize; | ||
| 254726 | pNew->x1.xDelete = fts5VtoVDelete; | ||
| 254727 | } | ||
| 252411 | } | 254728 | } |
| 252412 | 254729 | ||
| 252413 | return rc; | 254730 | return rc; |
| 252414 | } | 254731 | } |
| 252415 | 254732 | ||
| 254733 | /* | ||
| 254734 | ** The fts5_api.xCreateTokenizer() method. | ||
| 254735 | */ | ||
| 254736 | static int fts5CreateTokenizer( | ||
| 254737 | fts5_api *pApi, /* Global context (one per db handle) */ | ||
| 254738 | const char *zName, /* Name of new function */ | ||
| 254739 | void *pUserData, /* User data for aux. function */ | ||
| 254740 | fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ | ||
| 254741 | void(*xDestroy)(void*) /* Destructor for pUserData */ | ||
| 254742 | ){ | ||
| 254743 | Fts5TokenizerModule *pNew = 0; | ||
| 254744 | int rc = SQLITE_OK; | ||
| 254745 | |||
| 254746 | rc = fts5NewTokenizerModule( | ||
| 254747 | (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew | ||
| 254748 | ); | ||
| 254749 | if( pNew ){ | ||
| 254750 | pNew->x1 = *pTokenizer; | ||
| 254751 | pNew->x2.xCreate = fts5VtoVCreate; | ||
| 254752 | pNew->x2.xTokenize = fts5V2toV1Tokenize; | ||
| 254753 | pNew->x2.xDelete = fts5VtoVDelete; | ||
| 254754 | } | ||
| 254755 | return rc; | ||
| 254756 | } | ||
| 254757 | |||
| 254758 | /* | ||
| 254759 | ** Search the global context passed as the first argument for a tokenizer | ||
| 254760 | ** module named zName. If found, return a pointer to the Fts5TokenizerModule | ||
| 254761 | ** object. Otherwise, return NULL. | ||
| 254762 | */ | ||
| 252416 | static Fts5TokenizerModule *fts5LocateTokenizer( | 254763 | static Fts5TokenizerModule *fts5LocateTokenizer( |
| 252417 | Fts5Global *pGlobal, | 254764 | Fts5Global *pGlobal, /* Global (one per db handle) object */ |
| 252418 | const char *zName | 254765 | const char *zName /* Name of tokenizer module to find */ |
| 252419 | ){ | 254766 | ){ |
| 252420 | Fts5TokenizerModule *pMod = 0; | 254767 | Fts5TokenizerModule *pMod = 0; |
| 252421 | 254768 | ||
| @@ -252432,6 +254779,36 @@ static Fts5TokenizerModule *fts5LocateTokenizer( | |||
| 252432 | 254779 | ||
| 252433 | /* | 254780 | /* |
| 252434 | ** Find a tokenizer. This is the implementation of the | 254781 | ** Find a tokenizer. This is the implementation of the |
| 254782 | ** fts5_api.xFindTokenizer_v2() method. | ||
| 254783 | */ | ||
| 254784 | static int fts5FindTokenizer_v2( | ||
| 254785 | fts5_api *pApi, /* Global context (one per db handle) */ | ||
| 254786 | const char *zName, /* Name of tokenizer */ | ||
| 254787 | void **ppUserData, | ||
| 254788 | fts5_tokenizer_v2 **ppTokenizer /* Populate this object */ | ||
| 254789 | ){ | ||
| 254790 | int rc = SQLITE_OK; | ||
| 254791 | Fts5TokenizerModule *pMod; | ||
| 254792 | |||
| 254793 | pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); | ||
| 254794 | if( pMod ){ | ||
| 254795 | if( pMod->bV2Native ){ | ||
| 254796 | *ppUserData = pMod->pUserData; | ||
| 254797 | }else{ | ||
| 254798 | *ppUserData = (void*)pMod; | ||
| 254799 | } | ||
| 254800 | *ppTokenizer = &pMod->x2; | ||
| 254801 | }else{ | ||
| 254802 | *ppTokenizer = 0; | ||
| 254803 | *ppUserData = 0; | ||
| 254804 | rc = SQLITE_ERROR; | ||
| 254805 | } | ||
| 254806 | |||
| 254807 | return rc; | ||
| 254808 | } | ||
| 254809 | |||
| 254810 | /* | ||
| 254811 | ** Find a tokenizer. This is the implementation of the | ||
| 252435 | ** fts5_api.xFindTokenizer() method. | 254812 | ** fts5_api.xFindTokenizer() method. |
| 252436 | */ | 254813 | */ |
| 252437 | static int fts5FindTokenizer( | 254814 | static int fts5FindTokenizer( |
| @@ -252445,55 +254822,75 @@ static int fts5FindTokenizer( | |||
| 252445 | 254822 | ||
| 252446 | pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); | 254823 | pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); |
| 252447 | if( pMod ){ | 254824 | if( pMod ){ |
| 252448 | *pTokenizer = pMod->x; | 254825 | if( pMod->bV2Native==0 ){ |
| 252449 | *ppUserData = pMod->pUserData; | 254826 | *ppUserData = pMod->pUserData; |
| 254827 | }else{ | ||
| 254828 | *ppUserData = (void*)pMod; | ||
| 254829 | } | ||
| 254830 | *pTokenizer = pMod->x1; | ||
| 252450 | }else{ | 254831 | }else{ |
| 252451 | memset(pTokenizer, 0, sizeof(fts5_tokenizer)); | 254832 | memset(pTokenizer, 0, sizeof(*pTokenizer)); |
| 254833 | *ppUserData = 0; | ||
| 252452 | rc = SQLITE_ERROR; | 254834 | rc = SQLITE_ERROR; |
| 252453 | } | 254835 | } |
| 252454 | 254836 | ||
| 252455 | return rc; | 254837 | return rc; |
| 252456 | } | 254838 | } |
| 252457 | 254839 | ||
| 252458 | static int sqlite3Fts5GetTokenizer( | 254840 | /* |
| 252459 | Fts5Global *pGlobal, | 254841 | ** Attempt to instantiate the tokenizer. |
| 252460 | const char **azArg, | 254842 | */ |
| 252461 | int nArg, | 254843 | static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ |
| 252462 | Fts5Config *pConfig, | 254844 | const char **azArg = pConfig->t.azArg; |
| 252463 | char **pzErr | 254845 | const int nArg = pConfig->t.nArg; |
| 252464 | ){ | 254846 | Fts5TokenizerModule *pMod = 0; |
| 252465 | Fts5TokenizerModule *pMod; | ||
| 252466 | int rc = SQLITE_OK; | 254847 | int rc = SQLITE_OK; |
| 252467 | 254848 | ||
| 252468 | pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]); | 254849 | pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]); |
| 252469 | if( pMod==0 ){ | 254850 | if( pMod==0 ){ |
| 252470 | assert( nArg>0 ); | 254851 | assert( nArg>0 ); |
| 252471 | rc = SQLITE_ERROR; | 254852 | rc = SQLITE_ERROR; |
| 252472 | if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); | 254853 | sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]); |
| 252473 | }else{ | 254854 | }else{ |
| 252474 | rc = pMod->x.xCreate( | 254855 | int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0; |
| 252475 | pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok | 254856 | if( pMod->bV2Native ){ |
| 254857 | xCreate = pMod->x2.xCreate; | ||
| 254858 | pConfig->t.pApi2 = &pMod->x2; | ||
| 254859 | }else{ | ||
| 254860 | pConfig->t.pApi1 = &pMod->x1; | ||
| 254861 | xCreate = pMod->x1.xCreate; | ||
| 254862 | } | ||
| 254863 | |||
| 254864 | rc = xCreate(pMod->pUserData, | ||
| 254865 | (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok | ||
| 252476 | ); | 254866 | ); |
| 252477 | pConfig->pTokApi = &pMod->x; | 254867 | |
| 252478 | if( rc!=SQLITE_OK ){ | 254868 | if( rc!=SQLITE_OK ){ |
| 252479 | if( pzErr && rc!=SQLITE_NOMEM ){ | 254869 | if( rc!=SQLITE_NOMEM ){ |
| 252480 | *pzErr = sqlite3_mprintf("error in tokenizer constructor"); | 254870 | sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor"); |
| 252481 | } | 254871 | } |
| 252482 | }else{ | 254872 | }else if( pMod->bV2Native==0 ){ |
| 252483 | pConfig->ePattern = sqlite3Fts5TokenizerPattern( | 254873 | pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( |
| 252484 | pMod->x.xCreate, pConfig->pTok | 254874 | pMod->x1.xCreate, pConfig->t.pTok |
| 252485 | ); | 254875 | ); |
| 252486 | } | 254876 | } |
| 252487 | } | 254877 | } |
| 252488 | 254878 | ||
| 252489 | if( rc!=SQLITE_OK ){ | 254879 | if( rc!=SQLITE_OK ){ |
| 252490 | pConfig->pTokApi = 0; | 254880 | pConfig->t.pApi1 = 0; |
| 252491 | pConfig->pTok = 0; | 254881 | pConfig->t.pApi2 = 0; |
| 254882 | pConfig->t.pTok = 0; | ||
| 252492 | } | 254883 | } |
| 252493 | 254884 | ||
| 252494 | return rc; | 254885 | return rc; |
| 252495 | } | 254886 | } |
| 252496 | 254887 | ||
| 254888 | |||
| 254889 | /* | ||
| 254890 | ** xDestroy callback passed to sqlite3_create_module(). This is invoked | ||
| 254891 | ** when the db handle is being closed. Free memory associated with | ||
| 254892 | ** tokenizers and aux functions registered with this db handle. | ||
| 254893 | */ | ||
| 252497 | static void fts5ModuleDestroy(void *pCtx){ | 254894 | static void fts5ModuleDestroy(void *pCtx){ |
| 252498 | Fts5TokenizerModule *pTok, *pNextTok; | 254895 | Fts5TokenizerModule *pTok, *pNextTok; |
| 252499 | Fts5Auxiliary *pAux, *pNextAux; | 254896 | Fts5Auxiliary *pAux, *pNextAux; |
| @@ -252514,6 +254911,10 @@ static void fts5ModuleDestroy(void *pCtx){ | |||
| 252514 | sqlite3_free(pGlobal); | 254911 | sqlite3_free(pGlobal); |
| 252515 | } | 254912 | } |
| 252516 | 254913 | ||
| 254914 | /* | ||
| 254915 | ** Implementation of the fts5() function used by clients to obtain the | ||
| 254916 | ** API pointer. | ||
| 254917 | */ | ||
| 252517 | static void fts5Fts5Func( | 254918 | static void fts5Fts5Func( |
| 252518 | sqlite3_context *pCtx, /* Function call context */ | 254919 | sqlite3_context *pCtx, /* Function call context */ |
| 252519 | int nArg, /* Number of args */ | 254920 | int nArg, /* Number of args */ |
| @@ -252537,7 +254938,68 @@ static void fts5SourceIdFunc( | |||
| 252537 | ){ | 254938 | ){ |
| 252538 | assert( nArg==0 ); | 254939 | assert( nArg==0 ); |
| 252539 | UNUSED_PARAM2(nArg, apUnused); | 254940 | UNUSED_PARAM2(nArg, apUnused); |
| 252540 | sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT); | 254941 | sqlite3_result_text(pCtx, "fts5: 2024-11-25 12:07:48 b95d11e958643b969c47a8e5857f3793b9e69700b8f1469371386369a26e577e", -1, SQLITE_TRANSIENT); |
| 254942 | } | ||
| 254943 | |||
| 254944 | /* | ||
| 254945 | ** Implementation of fts5_locale(LOCALE, TEXT) function. | ||
| 254946 | ** | ||
| 254947 | ** If parameter LOCALE is NULL, or a zero-length string, then a copy of | ||
| 254948 | ** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as | ||
| 254949 | ** text, and the value returned is a blob consisting of: | ||
| 254950 | ** | ||
| 254951 | ** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER). | ||
| 254952 | ** * The LOCALE, as utf-8 text, followed by | ||
| 254953 | ** * 0x00, followed by | ||
| 254954 | ** * The TEXT, as utf-8 text. | ||
| 254955 | ** | ||
| 254956 | ** There is no final nul-terminator following the TEXT value. | ||
| 254957 | */ | ||
| 254958 | static void fts5LocaleFunc( | ||
| 254959 | sqlite3_context *pCtx, /* Function call context */ | ||
| 254960 | int nArg, /* Number of args */ | ||
| 254961 | sqlite3_value **apArg /* Function arguments */ | ||
| 254962 | ){ | ||
| 254963 | const char *zLocale = 0; | ||
| 254964 | int nLocale = 0; | ||
| 254965 | const char *zText = 0; | ||
| 254966 | int nText = 0; | ||
| 254967 | |||
| 254968 | assert( nArg==2 ); | ||
| 254969 | UNUSED_PARAM(nArg); | ||
| 254970 | |||
| 254971 | zLocale = (const char*)sqlite3_value_text(apArg[0]); | ||
| 254972 | nLocale = sqlite3_value_bytes(apArg[0]); | ||
| 254973 | |||
| 254974 | zText = (const char*)sqlite3_value_text(apArg[1]); | ||
| 254975 | nText = sqlite3_value_bytes(apArg[1]); | ||
| 254976 | |||
| 254977 | if( zLocale==0 || zLocale[0]=='\0' ){ | ||
| 254978 | sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT); | ||
| 254979 | }else{ | ||
| 254980 | Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx); | ||
| 254981 | u8 *pBlob = 0; | ||
| 254982 | u8 *pCsr = 0; | ||
| 254983 | int nBlob = 0; | ||
| 254984 | |||
| 254985 | nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText; | ||
| 254986 | pBlob = (u8*)sqlite3_malloc(nBlob); | ||
| 254987 | if( pBlob==0 ){ | ||
| 254988 | sqlite3_result_error_nomem(pCtx); | ||
| 254989 | return; | ||
| 254990 | } | ||
| 254991 | |||
| 254992 | pCsr = pBlob; | ||
| 254993 | memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE); | ||
| 254994 | pCsr += FTS5_LOCALE_HDR_SIZE; | ||
| 254995 | memcpy(pCsr, zLocale, nLocale); | ||
| 254996 | pCsr += nLocale; | ||
| 254997 | (*pCsr++) = 0x00; | ||
| 254998 | if( zText ) memcpy(pCsr, zText, nText); | ||
| 254999 | assert( &pCsr[nText]==&pBlob[nBlob] ); | ||
| 255000 | |||
| 255001 | sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free); | ||
| 255002 | } | ||
| 252541 | } | 255003 | } |
| 252542 | 255004 | ||
| 252543 | /* | 255005 | /* |
| @@ -252632,10 +255094,22 @@ static int fts5Init(sqlite3 *db){ | |||
| 252632 | void *p = (void*)pGlobal; | 255094 | void *p = (void*)pGlobal; |
| 252633 | memset(pGlobal, 0, sizeof(Fts5Global)); | 255095 | memset(pGlobal, 0, sizeof(Fts5Global)); |
| 252634 | pGlobal->db = db; | 255096 | pGlobal->db = db; |
| 252635 | pGlobal->api.iVersion = 2; | 255097 | pGlobal->api.iVersion = 3; |
| 252636 | pGlobal->api.xCreateFunction = fts5CreateAux; | 255098 | pGlobal->api.xCreateFunction = fts5CreateAux; |
| 252637 | pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; | 255099 | pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; |
| 252638 | pGlobal->api.xFindTokenizer = fts5FindTokenizer; | 255100 | pGlobal->api.xFindTokenizer = fts5FindTokenizer; |
| 255101 | pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2; | ||
| 255102 | pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2; | ||
| 255103 | |||
| 255104 | /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector. | ||
| 255105 | ** The constants below were generated randomly. */ | ||
| 255106 | sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr); | ||
| 255107 | pGlobal->aLocaleHdr[0] ^= 0xF924976D; | ||
| 255108 | pGlobal->aLocaleHdr[1] ^= 0x16596E13; | ||
| 255109 | pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA; | ||
| 255110 | pGlobal->aLocaleHdr[3] ^= 0x9B03A67F; | ||
| 255111 | assert( sizeof(pGlobal->aLocaleHdr)==16 ); | ||
| 255112 | |||
| 252639 | rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); | 255113 | rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); |
| 252640 | if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); | 255114 | if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); |
| 252641 | if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); | 255115 | if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); |
| @@ -252654,6 +255128,13 @@ static int fts5Init(sqlite3 *db){ | |||
| 252654 | p, fts5SourceIdFunc, 0, 0 | 255128 | p, fts5SourceIdFunc, 0, 0 |
| 252655 | ); | 255129 | ); |
| 252656 | } | 255130 | } |
| 255131 | if( rc==SQLITE_OK ){ | ||
| 255132 | rc = sqlite3_create_function( | ||
| 255133 | db, "fts5_locale", 2, | ||
| 255134 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, | ||
| 255135 | p, fts5LocaleFunc, 0, 0 | ||
| 255136 | ); | ||
| 255137 | } | ||
| 252657 | } | 255138 | } |
| 252658 | 255139 | ||
| 252659 | /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file | 255140 | /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file |
| @@ -252728,13 +255209,40 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){ | |||
| 252728 | 255209 | ||
| 252729 | /* #include "fts5Int.h" */ | 255210 | /* #include "fts5Int.h" */ |
| 252730 | 255211 | ||
| 255212 | /* | ||
| 255213 | ** pSavedRow: | ||
| 255214 | ** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it | ||
| 255215 | ** does a by-rowid lookup to retrieve a single row from the %_content | ||
| 255216 | ** table or equivalent external-content table/view. | ||
| 255217 | ** | ||
| 255218 | ** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original | ||
| 255219 | ** values for a row being UPDATEd. In that case, the SQL statement is | ||
| 255220 | ** not reset and pSavedRow is set to point at it. This is so that the | ||
| 255221 | ** insert operation that follows the delete may access the original | ||
| 255222 | ** row values for any new values for which sqlite3_value_nochange() returns | ||
| 255223 | ** true. i.e. if the user executes: | ||
| 255224 | ** | ||
| 255225 | ** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1); | ||
| 255226 | ** ... | ||
| 255227 | ** UPDATE fts SET a=?, b=? WHERE rowid=?; | ||
| 255228 | ** | ||
| 255229 | ** then the value passed to the xUpdate() method of this table as the | ||
| 255230 | ** new.c value is an sqlite3_value_nochange() value. So in this case it | ||
| 255231 | ** must be read from the saved row stored in Fts5Storage.pSavedRow. | ||
| 255232 | ** | ||
| 255233 | ** This is necessary - using sqlite3_value_nochange() instead of just having | ||
| 255234 | ** SQLite pass the original value back via xUpdate() - so as not to discard | ||
| 255235 | ** any locale information associated with such values. | ||
| 255236 | ** | ||
| 255237 | */ | ||
| 252731 | struct Fts5Storage { | 255238 | struct Fts5Storage { |
| 252732 | Fts5Config *pConfig; | 255239 | Fts5Config *pConfig; |
| 252733 | Fts5Index *pIndex; | 255240 | Fts5Index *pIndex; |
| 252734 | int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ | 255241 | int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ |
| 252735 | i64 nTotalRow; /* Total number of rows in FTS table */ | 255242 | i64 nTotalRow; /* Total number of rows in FTS table */ |
| 252736 | i64 *aTotalSize; /* Total sizes of each column */ | 255243 | i64 *aTotalSize; /* Total sizes of each column */ |
| 252737 | sqlite3_stmt *aStmt[11]; | 255244 | sqlite3_stmt *pSavedRow; |
| 255245 | sqlite3_stmt *aStmt[12]; | ||
| 252738 | }; | 255246 | }; |
| 252739 | 255247 | ||
| 252740 | 255248 | ||
| @@ -252748,14 +255256,15 @@ struct Fts5Storage { | |||
| 252748 | # error "FTS5_STMT_LOOKUP mismatch" | 255256 | # error "FTS5_STMT_LOOKUP mismatch" |
| 252749 | #endif | 255257 | #endif |
| 252750 | 255258 | ||
| 252751 | #define FTS5_STMT_INSERT_CONTENT 3 | 255259 | #define FTS5_STMT_LOOKUP2 3 |
| 252752 | #define FTS5_STMT_REPLACE_CONTENT 4 | 255260 | #define FTS5_STMT_INSERT_CONTENT 4 |
| 252753 | #define FTS5_STMT_DELETE_CONTENT 5 | 255261 | #define FTS5_STMT_REPLACE_CONTENT 5 |
| 252754 | #define FTS5_STMT_REPLACE_DOCSIZE 6 | 255262 | #define FTS5_STMT_DELETE_CONTENT 6 |
| 252755 | #define FTS5_STMT_DELETE_DOCSIZE 7 | 255263 | #define FTS5_STMT_REPLACE_DOCSIZE 7 |
| 252756 | #define FTS5_STMT_LOOKUP_DOCSIZE 8 | 255264 | #define FTS5_STMT_DELETE_DOCSIZE 8 |
| 252757 | #define FTS5_STMT_REPLACE_CONFIG 9 | 255265 | #define FTS5_STMT_LOOKUP_DOCSIZE 9 |
| 252758 | #define FTS5_STMT_SCAN 10 | 255266 | #define FTS5_STMT_REPLACE_CONFIG 10 |
| 255267 | #define FTS5_STMT_SCAN 11 | ||
| 252759 | 255268 | ||
| 252760 | /* | 255269 | /* |
| 252761 | ** Prepare the two insert statements - Fts5Storage.pInsertContent and | 255270 | ** Prepare the two insert statements - Fts5Storage.pInsertContent and |
| @@ -252785,6 +255294,7 @@ static int fts5StorageGetStmt( | |||
| 252785 | "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", | 255294 | "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", |
| 252786 | "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", | 255295 | "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", |
| 252787 | "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ | 255296 | "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ |
| 255297 | "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */ | ||
| 252788 | 255298 | ||
| 252789 | "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ | 255299 | "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ |
| 252790 | "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ | 255300 | "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ |
| @@ -252800,6 +255310,8 @@ static int fts5StorageGetStmt( | |||
| 252800 | Fts5Config *pC = p->pConfig; | 255310 | Fts5Config *pC = p->pConfig; |
| 252801 | char *zSql = 0; | 255311 | char *zSql = 0; |
| 252802 | 255312 | ||
| 255313 | assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); | ||
| 255314 | |||
| 252803 | switch( eStmt ){ | 255315 | switch( eStmt ){ |
| 252804 | case FTS5_STMT_SCAN: | 255316 | case FTS5_STMT_SCAN: |
| 252805 | zSql = sqlite3_mprintf(azStmt[eStmt], | 255317 | zSql = sqlite3_mprintf(azStmt[eStmt], |
| @@ -252816,6 +255328,7 @@ static int fts5StorageGetStmt( | |||
| 252816 | break; | 255328 | break; |
| 252817 | 255329 | ||
| 252818 | case FTS5_STMT_LOOKUP: | 255330 | case FTS5_STMT_LOOKUP: |
| 255331 | case FTS5_STMT_LOOKUP2: | ||
| 252819 | zSql = sqlite3_mprintf(azStmt[eStmt], | 255332 | zSql = sqlite3_mprintf(azStmt[eStmt], |
| 252820 | pC->zContentExprlist, pC->zContent, pC->zContentRowid | 255333 | pC->zContentExprlist, pC->zContent, pC->zContentRowid |
| 252821 | ); | 255334 | ); |
| @@ -252823,20 +255336,35 @@ static int fts5StorageGetStmt( | |||
| 252823 | 255336 | ||
| 252824 | case FTS5_STMT_INSERT_CONTENT: | 255337 | case FTS5_STMT_INSERT_CONTENT: |
| 252825 | case FTS5_STMT_REPLACE_CONTENT: { | 255338 | case FTS5_STMT_REPLACE_CONTENT: { |
| 252826 | int nCol = pC->nCol + 1; | 255339 | char *zBind = 0; |
| 252827 | char *zBind; | ||
| 252828 | int i; | 255340 | int i; |
| 252829 | 255341 | ||
| 252830 | zBind = sqlite3_malloc64(1 + nCol*2); | 255342 | assert( pC->eContent==FTS5_CONTENT_NORMAL |
| 252831 | if( zBind ){ | 255343 | || pC->eContent==FTS5_CONTENT_UNINDEXED |
| 252832 | for(i=0; i<nCol; i++){ | 255344 | ); |
| 252833 | zBind[i*2] = '?'; | 255345 | |
| 252834 | zBind[i*2 + 1] = ','; | 255346 | /* Add bindings for the "c*" columns - those that store the actual |
| 255347 | ** table content. If eContent==NORMAL, then there is one binding | ||
| 255348 | ** for each column. Or, if eContent==UNINDEXED, then there are only | ||
| 255349 | ** bindings for the UNINDEXED columns. */ | ||
| 255350 | for(i=0; rc==SQLITE_OK && i<(pC->nCol+1); i++){ | ||
| 255351 | if( !i || pC->eContent==FTS5_CONTENT_NORMAL || pC->abUnindexed[i-1] ){ | ||
| 255352 | zBind = sqlite3Fts5Mprintf(&rc, "%z%s?%d", zBind, zBind?",":"",i+1); | ||
| 255353 | } | ||
| 255354 | } | ||
| 255355 | |||
| 255356 | /* Add bindings for any "l*" columns. Only non-UNINDEXED columns | ||
| 255357 | ** require these. */ | ||
| 255358 | if( pC->bLocale && pC->eContent==FTS5_CONTENT_NORMAL ){ | ||
| 255359 | for(i=0; rc==SQLITE_OK && i<pC->nCol; i++){ | ||
| 255360 | if( pC->abUnindexed[i]==0 ){ | ||
| 255361 | zBind = sqlite3Fts5Mprintf(&rc, "%z,?%d", zBind, pC->nCol+i+2); | ||
| 255362 | } | ||
| 252835 | } | 255363 | } |
| 252836 | zBind[i*2-1] = '\0'; | ||
| 252837 | zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); | ||
| 252838 | sqlite3_free(zBind); | ||
| 252839 | } | 255364 | } |
| 255365 | |||
| 255366 | zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind); | ||
| 255367 | sqlite3_free(zBind); | ||
| 252840 | break; | 255368 | break; |
| 252841 | } | 255369 | } |
| 252842 | 255370 | ||
| @@ -252862,7 +255390,7 @@ static int fts5StorageGetStmt( | |||
| 252862 | rc = SQLITE_NOMEM; | 255390 | rc = SQLITE_NOMEM; |
| 252863 | }else{ | 255391 | }else{ |
| 252864 | int f = SQLITE_PREPARE_PERSISTENT; | 255392 | int f = SQLITE_PREPARE_PERSISTENT; |
| 252865 | if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; | 255393 | if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB; |
| 252866 | p->pConfig->bLock++; | 255394 | p->pConfig->bLock++; |
| 252867 | rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); | 255395 | rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); |
| 252868 | p->pConfig->bLock--; | 255396 | p->pConfig->bLock--; |
| @@ -253022,9 +255550,11 @@ static int sqlite3Fts5StorageOpen( | |||
| 253022 | p->pIndex = pIndex; | 255550 | p->pIndex = pIndex; |
| 253023 | 255551 | ||
| 253024 | if( bCreate ){ | 255552 | if( bCreate ){ |
| 253025 | if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ | 255553 | if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 255554 | || pConfig->eContent==FTS5_CONTENT_UNINDEXED | ||
| 255555 | ){ | ||
| 253026 | int nDefn = 32 + pConfig->nCol*10; | 255556 | int nDefn = 32 + pConfig->nCol*10; |
| 253027 | char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); | 255557 | char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); |
| 253028 | if( zDefn==0 ){ | 255558 | if( zDefn==0 ){ |
| 253029 | rc = SQLITE_NOMEM; | 255559 | rc = SQLITE_NOMEM; |
| 253030 | }else{ | 255560 | }else{ |
| @@ -253033,8 +255563,20 @@ static int sqlite3Fts5StorageOpen( | |||
| 253033 | sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); | 255563 | sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); |
| 253034 | iOff = (int)strlen(zDefn); | 255564 | iOff = (int)strlen(zDefn); |
| 253035 | for(i=0; i<pConfig->nCol; i++){ | 255565 | for(i=0; i<pConfig->nCol; i++){ |
| 253036 | sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); | 255566 | if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 253037 | iOff += (int)strlen(&zDefn[iOff]); | 255567 | || pConfig->abUnindexed[i] |
| 255568 | ){ | ||
| 255569 | sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); | ||
| 255570 | iOff += (int)strlen(&zDefn[iOff]); | ||
| 255571 | } | ||
| 255572 | } | ||
| 255573 | if( pConfig->bLocale ){ | ||
| 255574 | for(i=0; i<pConfig->nCol; i++){ | ||
| 255575 | if( pConfig->abUnindexed[i]==0 ){ | ||
| 255576 | sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); | ||
| 255577 | iOff += (int)strlen(&zDefn[iOff]); | ||
| 255578 | } | ||
| 255579 | } | ||
| 253038 | } | 255580 | } |
| 253039 | rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); | 255581 | rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); |
| 253040 | } | 255582 | } |
| @@ -253112,14 +255654,48 @@ static int fts5StorageInsertCallback( | |||
| 253112 | } | 255654 | } |
| 253113 | 255655 | ||
| 253114 | /* | 255656 | /* |
| 255657 | ** This function is used as part of an UPDATE statement that modifies the | ||
| 255658 | ** rowid of a row. In that case, this function is called first to set | ||
| 255659 | ** Fts5Storage.pSavedRow to point to a statement that may be used to | ||
| 255660 | ** access the original values of the row being deleted - iDel. | ||
| 255661 | ** | ||
| 255662 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. | ||
| 255663 | ** It is not considered an error if row iDel does not exist. In this case | ||
| 255664 | ** pSavedRow is not set and SQLITE_OK returned. | ||
| 255665 | */ | ||
| 255666 | static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){ | ||
| 255667 | int rc = SQLITE_OK; | ||
| 255668 | sqlite3_stmt *pSeek = 0; | ||
| 255669 | |||
| 255670 | assert( p->pSavedRow==0 ); | ||
| 255671 | rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0); | ||
| 255672 | if( rc==SQLITE_OK ){ | ||
| 255673 | sqlite3_bind_int64(pSeek, 1, iDel); | ||
| 255674 | if( sqlite3_step(pSeek)!=SQLITE_ROW ){ | ||
| 255675 | rc = sqlite3_reset(pSeek); | ||
| 255676 | }else{ | ||
| 255677 | p->pSavedRow = pSeek; | ||
| 255678 | } | ||
| 255679 | } | ||
| 255680 | |||
| 255681 | return rc; | ||
| 255682 | } | ||
| 255683 | |||
| 255684 | /* | ||
| 253115 | ** If a row with rowid iDel is present in the %_content table, add the | 255685 | ** If a row with rowid iDel is present in the %_content table, add the |
| 253116 | ** delete-markers to the FTS index necessary to delete it. Do not actually | 255686 | ** delete-markers to the FTS index necessary to delete it. Do not actually |
| 253117 | ** remove the %_content row at this time though. | 255687 | ** remove the %_content row at this time though. |
| 255688 | ** | ||
| 255689 | ** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left | ||
| 255690 | ** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access | ||
| 255691 | ** the original values of the row being deleted. This is used by UPDATE | ||
| 255692 | ** statements. | ||
| 253118 | */ | 255693 | */ |
| 253119 | static int fts5StorageDeleteFromIndex( | 255694 | static int fts5StorageDeleteFromIndex( |
| 253120 | Fts5Storage *p, | 255695 | Fts5Storage *p, |
| 253121 | i64 iDel, | 255696 | i64 iDel, |
| 253122 | sqlite3_value **apVal | 255697 | sqlite3_value **apVal, |
| 255698 | int bSaveRow /* True to set pSavedRow */ | ||
| 253123 | ){ | 255699 | ){ |
| 253124 | Fts5Config *pConfig = p->pConfig; | 255700 | Fts5Config *pConfig = p->pConfig; |
| 253125 | sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ | 255701 | sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ |
| @@ -253128,12 +255704,21 @@ static int fts5StorageDeleteFromIndex( | |||
| 253128 | int iCol; | 255704 | int iCol; |
| 253129 | Fts5InsertCtx ctx; | 255705 | Fts5InsertCtx ctx; |
| 253130 | 255706 | ||
| 255707 | assert( bSaveRow==0 || apVal==0 ); | ||
| 255708 | assert( bSaveRow==0 || bSaveRow==1 ); | ||
| 255709 | assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 ); | ||
| 255710 | |||
| 253131 | if( apVal==0 ){ | 255711 | if( apVal==0 ){ |
| 253132 | rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); | 255712 | if( p->pSavedRow && bSaveRow ){ |
| 253133 | if( rc!=SQLITE_OK ) return rc; | 255713 | pSeek = p->pSavedRow; |
| 253134 | sqlite3_bind_int64(pSeek, 1, iDel); | 255714 | p->pSavedRow = 0; |
| 253135 | if( sqlite3_step(pSeek)!=SQLITE_ROW ){ | 255715 | }else{ |
| 253136 | return sqlite3_reset(pSeek); | 255716 | rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0); |
| 255717 | if( rc!=SQLITE_OK ) return rc; | ||
| 255718 | sqlite3_bind_int64(pSeek, 1, iDel); | ||
| 255719 | if( sqlite3_step(pSeek)!=SQLITE_ROW ){ | ||
| 255720 | return sqlite3_reset(pSeek); | ||
| 255721 | } | ||
| 253137 | } | 255722 | } |
| 253138 | } | 255723 | } |
| 253139 | 255724 | ||
| @@ -253141,26 +255726,42 @@ static int fts5StorageDeleteFromIndex( | |||
| 253141 | ctx.iCol = -1; | 255726 | ctx.iCol = -1; |
| 253142 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ | 255727 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 253143 | if( pConfig->abUnindexed[iCol-1]==0 ){ | 255728 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 253144 | const char *zText; | 255729 | sqlite3_value *pVal = 0; |
| 253145 | int nText; | 255730 | const char *pText = 0; |
| 255731 | int nText = 0; | ||
| 255732 | const char *pLoc = 0; | ||
| 255733 | int nLoc = 0; | ||
| 255734 | |||
| 253146 | assert( pSeek==0 || apVal==0 ); | 255735 | assert( pSeek==0 || apVal==0 ); |
| 253147 | assert( pSeek!=0 || apVal!=0 ); | 255736 | assert( pSeek!=0 || apVal!=0 ); |
| 253148 | if( pSeek ){ | 255737 | if( pSeek ){ |
| 253149 | zText = (const char*)sqlite3_column_text(pSeek, iCol); | 255738 | pVal = sqlite3_column_value(pSeek, iCol); |
| 253150 | nText = sqlite3_column_bytes(pSeek, iCol); | ||
| 253151 | }else if( ALWAYS(apVal) ){ | ||
| 253152 | zText = (const char*)sqlite3_value_text(apVal[iCol-1]); | ||
| 253153 | nText = sqlite3_value_bytes(apVal[iCol-1]); | ||
| 253154 | }else{ | 255739 | }else{ |
| 253155 | continue; | 255740 | pVal = apVal[iCol-1]; |
| 253156 | } | 255741 | } |
| 253157 | ctx.szCol = 0; | 255742 | |
| 253158 | rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, | 255743 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ |
| 253159 | zText, nText, (void*)&ctx, fts5StorageInsertCallback | 255744 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); |
| 253160 | ); | 255745 | }else{ |
| 253161 | p->aTotalSize[iCol-1] -= (i64)ctx.szCol; | 255746 | pText = (const char*)sqlite3_value_text(pVal); |
| 253162 | if( p->aTotalSize[iCol-1]<0 ){ | 255747 | nText = sqlite3_value_bytes(pVal); |
| 253163 | rc = FTS5_CORRUPT; | 255748 | if( pConfig->bLocale && pSeek ){ |
| 255749 | pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); | ||
| 255750 | nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); | ||
| 255751 | } | ||
| 255752 | } | ||
| 255753 | |||
| 255754 | if( rc==SQLITE_OK ){ | ||
| 255755 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 255756 | ctx.szCol = 0; | ||
| 255757 | rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, | ||
| 255758 | pText, nText, (void*)&ctx, fts5StorageInsertCallback | ||
| 255759 | ); | ||
| 255760 | p->aTotalSize[iCol-1] -= (i64)ctx.szCol; | ||
| 255761 | if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ | ||
| 255762 | rc = FTS5_CORRUPT; | ||
| 255763 | } | ||
| 255764 | sqlite3Fts5ClearLocale(pConfig); | ||
| 253164 | } | 255765 | } |
| 253165 | } | 255766 | } |
| 253166 | } | 255767 | } |
| @@ -253170,12 +255771,30 @@ static int fts5StorageDeleteFromIndex( | |||
| 253170 | p->nTotalRow--; | 255771 | p->nTotalRow--; |
| 253171 | } | 255772 | } |
| 253172 | 255773 | ||
| 253173 | rc2 = sqlite3_reset(pSeek); | 255774 | if( rc==SQLITE_OK && bSaveRow ){ |
| 253174 | if( rc==SQLITE_OK ) rc = rc2; | 255775 | assert( p->pSavedRow==0 ); |
| 255776 | p->pSavedRow = pSeek; | ||
| 255777 | }else{ | ||
| 255778 | rc2 = sqlite3_reset(pSeek); | ||
| 255779 | if( rc==SQLITE_OK ) rc = rc2; | ||
| 255780 | } | ||
| 253175 | return rc; | 255781 | return rc; |
| 253176 | } | 255782 | } |
| 253177 | 255783 | ||
| 253178 | /* | 255784 | /* |
| 255785 | ** Reset any saved statement pSavedRow. Zero pSavedRow as well. This | ||
| 255786 | ** should be called by the xUpdate() method of the fts5 table before | ||
| 255787 | ** returning from any operation that may have set Fts5Storage.pSavedRow. | ||
| 255788 | */ | ||
| 255789 | static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ | ||
| 255790 | assert( pStorage->pSavedRow==0 | ||
| 255791 | || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2] | ||
| 255792 | ); | ||
| 255793 | sqlite3_reset(pStorage->pSavedRow); | ||
| 255794 | pStorage->pSavedRow = 0; | ||
| 255795 | } | ||
| 255796 | |||
| 255797 | /* | ||
| 253179 | ** This function is called to process a DELETE on a contentless_delete=1 | 255798 | ** This function is called to process a DELETE on a contentless_delete=1 |
| 253180 | ** table. It adds the tombstone required to delete the entry with rowid | 255799 | ** table. It adds the tombstone required to delete the entry with rowid |
| 253181 | ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, | 255800 | ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, |
| @@ -253187,7 +255806,9 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ | |||
| 253187 | int rc = SQLITE_OK; | 255806 | int rc = SQLITE_OK; |
| 253188 | 255807 | ||
| 253189 | assert( p->pConfig->bContentlessDelete ); | 255808 | assert( p->pConfig->bContentlessDelete ); |
| 253190 | assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); | 255809 | assert( p->pConfig->eContent==FTS5_CONTENT_NONE |
| 255810 | || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED | ||
| 255811 | ); | ||
| 253191 | 255812 | ||
| 253192 | /* Look up the origin of the document in the %_docsize table. Store | 255813 | /* Look up the origin of the document in the %_docsize table. Store |
| 253193 | ** this in stack variable iOrigin. */ | 255814 | ** this in stack variable iOrigin. */ |
| @@ -253231,12 +255852,12 @@ static int fts5StorageInsertDocsize( | |||
| 253231 | rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); | 255852 | rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); |
| 253232 | sqlite3_bind_int64(pReplace, 3, iOrigin); | 255853 | sqlite3_bind_int64(pReplace, 3, iOrigin); |
| 253233 | } | 255854 | } |
| 253234 | if( rc==SQLITE_OK ){ | 255855 | } |
| 253235 | sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); | 255856 | if( rc==SQLITE_OK ){ |
| 253236 | sqlite3_step(pReplace); | 255857 | sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); |
| 253237 | rc = sqlite3_reset(pReplace); | 255858 | sqlite3_step(pReplace); |
| 253238 | sqlite3_bind_null(pReplace, 2); | 255859 | rc = sqlite3_reset(pReplace); |
| 253239 | } | 255860 | sqlite3_bind_null(pReplace, 2); |
| 253240 | } | 255861 | } |
| 253241 | } | 255862 | } |
| 253242 | return rc; | 255863 | return rc; |
| @@ -253290,7 +255911,12 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ | |||
| 253290 | /* | 255911 | /* |
| 253291 | ** Remove a row from the FTS table. | 255912 | ** Remove a row from the FTS table. |
| 253292 | */ | 255913 | */ |
| 253293 | static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ | 255914 | static int sqlite3Fts5StorageDelete( |
| 255915 | Fts5Storage *p, /* Storage object */ | ||
| 255916 | i64 iDel, /* Rowid to delete from table */ | ||
| 255917 | sqlite3_value **apVal, /* Optional - values to remove from index */ | ||
| 255918 | int bSaveRow /* If true, set pSavedRow for deleted row */ | ||
| 255919 | ){ | ||
| 253294 | Fts5Config *pConfig = p->pConfig; | 255920 | Fts5Config *pConfig = p->pConfig; |
| 253295 | int rc; | 255921 | int rc; |
| 253296 | sqlite3_stmt *pDel = 0; | 255922 | sqlite3_stmt *pDel = 0; |
| @@ -253306,8 +255932,14 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap | |||
| 253306 | if( rc==SQLITE_OK ){ | 255932 | if( rc==SQLITE_OK ){ |
| 253307 | if( p->pConfig->bContentlessDelete ){ | 255933 | if( p->pConfig->bContentlessDelete ){ |
| 253308 | rc = fts5StorageContentlessDelete(p, iDel); | 255934 | rc = fts5StorageContentlessDelete(p, iDel); |
| 255935 | if( rc==SQLITE_OK | ||
| 255936 | && bSaveRow | ||
| 255937 | && p->pConfig->eContent==FTS5_CONTENT_UNINDEXED | ||
| 255938 | ){ | ||
| 255939 | rc = sqlite3Fts5StorageFindDeleteRow(p, iDel); | ||
| 255940 | } | ||
| 253309 | }else{ | 255941 | }else{ |
| 253310 | rc = fts5StorageDeleteFromIndex(p, iDel, apVal); | 255942 | rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow); |
| 253311 | } | 255943 | } |
| 253312 | } | 255944 | } |
| 253313 | 255945 | ||
| @@ -253322,7 +255954,9 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap | |||
| 253322 | } | 255954 | } |
| 253323 | 255955 | ||
| 253324 | /* Delete the %_content record */ | 255956 | /* Delete the %_content record */ |
| 253325 | if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ | 255957 | if( pConfig->eContent==FTS5_CONTENT_NORMAL |
| 255958 | || pConfig->eContent==FTS5_CONTENT_UNINDEXED | ||
| 255959 | ){ | ||
| 253326 | if( rc==SQLITE_OK ){ | 255960 | if( rc==SQLITE_OK ){ |
| 253327 | rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); | 255961 | rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); |
| 253328 | } | 255962 | } |
| @@ -253354,8 +255988,13 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ | |||
| 253354 | ); | 255988 | ); |
| 253355 | if( rc==SQLITE_OK && pConfig->bColumnsize ){ | 255989 | if( rc==SQLITE_OK && pConfig->bColumnsize ){ |
| 253356 | rc = fts5ExecPrintf(pConfig->db, 0, | 255990 | rc = fts5ExecPrintf(pConfig->db, 0, |
| 253357 | "DELETE FROM %Q.'%q_docsize';", | 255991 | "DELETE FROM %Q.'%q_docsize';", pConfig->zDb, pConfig->zName |
| 253358 | pConfig->zDb, pConfig->zName | 255992 | ); |
| 255993 | } | ||
| 255994 | |||
| 255995 | if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ | ||
| 255996 | rc = fts5ExecPrintf(pConfig->db, 0, | ||
| 255997 | "DELETE FROM %Q.'%q_content';", pConfig->zDb, pConfig->zName | ||
| 253359 | ); | 255998 | ); |
| 253360 | } | 255999 | } |
| 253361 | 256000 | ||
| @@ -253396,14 +256035,36 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ | |||
| 253396 | for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ | 256035 | for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ |
| 253397 | ctx.szCol = 0; | 256036 | ctx.szCol = 0; |
| 253398 | if( pConfig->abUnindexed[ctx.iCol]==0 ){ | 256037 | if( pConfig->abUnindexed[ctx.iCol]==0 ){ |
| 253399 | const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); | 256038 | int nText = 0; /* Size of pText in bytes */ |
| 253400 | int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); | 256039 | const char *pText = 0; /* Pointer to buffer containing text value */ |
| 253401 | rc = sqlite3Fts5Tokenize(pConfig, | 256040 | int nLoc = 0; /* Size of pLoc in bytes */ |
| 253402 | FTS5_TOKENIZE_DOCUMENT, | 256041 | const char *pLoc = 0; /* Pointer to buffer containing text value */ |
| 253403 | zText, nText, | 256042 | |
| 253404 | (void*)&ctx, | 256043 | sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1); |
| 253405 | fts5StorageInsertCallback | 256044 | if( pConfig->eContent==FTS5_CONTENT_EXTERNAL |
| 253406 | ); | 256045 | && sqlite3Fts5IsLocaleValue(pConfig, pVal) |
| 256046 | ){ | ||
| 256047 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); | ||
| 256048 | }else{ | ||
| 256049 | pText = (const char*)sqlite3_value_text(pVal); | ||
| 256050 | nText = sqlite3_value_bytes(pVal); | ||
| 256051 | if( pConfig->bLocale ){ | ||
| 256052 | int iCol = ctx.iCol + 1 + pConfig->nCol; | ||
| 256053 | pLoc = (const char*)sqlite3_column_text(pScan, iCol); | ||
| 256054 | nLoc = sqlite3_column_bytes(pScan, iCol); | ||
| 256055 | } | ||
| 256056 | } | ||
| 256057 | |||
| 256058 | if( rc==SQLITE_OK ){ | ||
| 256059 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 256060 | rc = sqlite3Fts5Tokenize(pConfig, | ||
| 256061 | FTS5_TOKENIZE_DOCUMENT, | ||
| 256062 | pText, nText, | ||
| 256063 | (void*)&ctx, | ||
| 256064 | fts5StorageInsertCallback | ||
| 256065 | ); | ||
| 256066 | sqlite3Fts5ClearLocale(pConfig); | ||
| 256067 | } | ||
| 253407 | } | 256068 | } |
| 253408 | sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); | 256069 | sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); |
| 253409 | p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; | 256070 | p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; |
| @@ -253469,6 +256130,7 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ | |||
| 253469 | */ | 256130 | */ |
| 253470 | static int sqlite3Fts5StorageContentInsert( | 256131 | static int sqlite3Fts5StorageContentInsert( |
| 253471 | Fts5Storage *p, | 256132 | Fts5Storage *p, |
| 256133 | int bReplace, /* True to use REPLACE instead of INSERT */ | ||
| 253472 | sqlite3_value **apVal, | 256134 | sqlite3_value **apVal, |
| 253473 | i64 *piRowid | 256135 | i64 *piRowid |
| 253474 | ){ | 256136 | ){ |
| @@ -253476,7 +256138,9 @@ static int sqlite3Fts5StorageContentInsert( | |||
| 253476 | int rc = SQLITE_OK; | 256138 | int rc = SQLITE_OK; |
| 253477 | 256139 | ||
| 253478 | /* Insert the new row into the %_content table. */ | 256140 | /* Insert the new row into the %_content table. */ |
| 253479 | if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ | 256141 | if( pConfig->eContent!=FTS5_CONTENT_NORMAL |
| 256142 | && pConfig->eContent!=FTS5_CONTENT_UNINDEXED | ||
| 256143 | ){ | ||
| 253480 | if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ | 256144 | if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ |
| 253481 | *piRowid = sqlite3_value_int64(apVal[1]); | 256145 | *piRowid = sqlite3_value_int64(apVal[1]); |
| 253482 | }else{ | 256146 | }else{ |
| @@ -253485,9 +256149,52 @@ static int sqlite3Fts5StorageContentInsert( | |||
| 253485 | }else{ | 256149 | }else{ |
| 253486 | sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ | 256150 | sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ |
| 253487 | int i; /* Counter variable */ | 256151 | int i; /* Counter variable */ |
| 253488 | rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); | 256152 | |
| 253489 | for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ | 256153 | assert( FTS5_STMT_INSERT_CONTENT+1==FTS5_STMT_REPLACE_CONTENT ); |
| 253490 | rc = sqlite3_bind_value(pInsert, i, apVal[i]); | 256154 | assert( bReplace==0 || bReplace==1 ); |
| 256155 | rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT+bReplace, &pInsert, 0); | ||
| 256156 | if( pInsert ) sqlite3_clear_bindings(pInsert); | ||
| 256157 | |||
| 256158 | /* Bind the rowid value */ | ||
| 256159 | sqlite3_bind_value(pInsert, 1, apVal[1]); | ||
| 256160 | |||
| 256161 | /* Loop through values for user-defined columns. i=2 is the leftmost | ||
| 256162 | ** user-defined column. As is column 1 of pSavedRow. */ | ||
| 256163 | for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ | ||
| 256164 | int bUnindexed = pConfig->abUnindexed[i-2]; | ||
| 256165 | if( pConfig->eContent==FTS5_CONTENT_NORMAL || bUnindexed ){ | ||
| 256166 | sqlite3_value *pVal = apVal[i]; | ||
| 256167 | |||
| 256168 | if( sqlite3_value_nochange(pVal) && p->pSavedRow ){ | ||
| 256169 | /* This is an UPDATE statement, and user-defined column (i-2) was not | ||
| 256170 | ** modified. Retrieve the value from Fts5Storage.pSavedRow. */ | ||
| 256171 | pVal = sqlite3_column_value(p->pSavedRow, i-1); | ||
| 256172 | if( pConfig->bLocale && bUnindexed==0 ){ | ||
| 256173 | sqlite3_bind_value(pInsert, pConfig->nCol + i, | ||
| 256174 | sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1) | ||
| 256175 | ); | ||
| 256176 | } | ||
| 256177 | }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ | ||
| 256178 | const char *pText = 0; | ||
| 256179 | const char *pLoc = 0; | ||
| 256180 | int nText = 0; | ||
| 256181 | int nLoc = 0; | ||
| 256182 | assert( pConfig->bLocale ); | ||
| 256183 | |||
| 256184 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); | ||
| 256185 | if( rc==SQLITE_OK ){ | ||
| 256186 | sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT); | ||
| 256187 | if( bUnindexed==0 ){ | ||
| 256188 | int iLoc = pConfig->nCol + i; | ||
| 256189 | sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT); | ||
| 256190 | } | ||
| 256191 | } | ||
| 256192 | |||
| 256193 | continue; | ||
| 256194 | } | ||
| 256195 | |||
| 256196 | rc = sqlite3_bind_value(pInsert, i, pVal); | ||
| 256197 | } | ||
| 253491 | } | 256198 | } |
| 253492 | if( rc==SQLITE_OK ){ | 256199 | if( rc==SQLITE_OK ){ |
| 253493 | sqlite3_step(pInsert); | 256200 | sqlite3_step(pInsert); |
| @@ -253522,14 +256229,38 @@ static int sqlite3Fts5StorageIndexInsert( | |||
| 253522 | for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ | 256229 | for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ |
| 253523 | ctx.szCol = 0; | 256230 | ctx.szCol = 0; |
| 253524 | if( pConfig->abUnindexed[ctx.iCol]==0 ){ | 256231 | if( pConfig->abUnindexed[ctx.iCol]==0 ){ |
| 253525 | const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); | 256232 | int nText = 0; /* Size of pText in bytes */ |
| 253526 | int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); | 256233 | const char *pText = 0; /* Pointer to buffer containing text value */ |
| 253527 | rc = sqlite3Fts5Tokenize(pConfig, | 256234 | int nLoc = 0; /* Size of pText in bytes */ |
| 253528 | FTS5_TOKENIZE_DOCUMENT, | 256235 | const char *pLoc = 0; /* Pointer to buffer containing text value */ |
| 253529 | zText, nText, | 256236 | |
| 253530 | (void*)&ctx, | 256237 | sqlite3_value *pVal = apVal[ctx.iCol+2]; |
| 253531 | fts5StorageInsertCallback | 256238 | if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ |
| 253532 | ); | 256239 | pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); |
| 256240 | if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ | ||
| 256241 | int iCol = ctx.iCol + 1 + pConfig->nCol; | ||
| 256242 | pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol); | ||
| 256243 | nLoc = sqlite3_column_bytes(p->pSavedRow, iCol); | ||
| 256244 | } | ||
| 256245 | }else{ | ||
| 256246 | pVal = apVal[ctx.iCol+2]; | ||
| 256247 | } | ||
| 256248 | |||
| 256249 | if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ | ||
| 256250 | rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); | ||
| 256251 | }else{ | ||
| 256252 | pText = (const char*)sqlite3_value_text(pVal); | ||
| 256253 | nText = sqlite3_value_bytes(pVal); | ||
| 256254 | } | ||
| 256255 | |||
| 256256 | if( rc==SQLITE_OK ){ | ||
| 256257 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 256258 | rc = sqlite3Fts5Tokenize(pConfig, | ||
| 256259 | FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, | ||
| 256260 | fts5StorageInsertCallback | ||
| 256261 | ); | ||
| 256262 | sqlite3Fts5ClearLocale(pConfig); | ||
| 256263 | } | ||
| 253533 | } | 256264 | } |
| 253534 | sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); | 256265 | sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); |
| 253535 | p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; | 256266 | p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; |
| @@ -253693,29 +256424,61 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ | |||
| 253693 | rc = sqlite3Fts5TermsetNew(&ctx.pTermset); | 256424 | rc = sqlite3Fts5TermsetNew(&ctx.pTermset); |
| 253694 | } | 256425 | } |
| 253695 | for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ | 256426 | for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ |
| 253696 | if( pConfig->abUnindexed[i] ) continue; | 256427 | if( pConfig->abUnindexed[i]==0 ){ |
| 253697 | ctx.iCol = i; | 256428 | const char *pText = 0; |
| 253698 | ctx.szCol = 0; | 256429 | int nText = 0; |
| 253699 | if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ | 256430 | const char *pLoc = 0; |
| 253700 | rc = sqlite3Fts5TermsetNew(&ctx.pTermset); | 256431 | int nLoc = 0; |
| 253701 | } | 256432 | sqlite3_value *pVal = sqlite3_column_value(pScan, i+1); |
| 253702 | if( rc==SQLITE_OK ){ | 256433 | |
| 253703 | const char *zText = (const char*)sqlite3_column_text(pScan, i+1); | 256434 | if( pConfig->eContent==FTS5_CONTENT_EXTERNAL |
| 253704 | int nText = sqlite3_column_bytes(pScan, i+1); | 256435 | && sqlite3Fts5IsLocaleValue(pConfig, pVal) |
| 253705 | rc = sqlite3Fts5Tokenize(pConfig, | 256436 | ){ |
| 253706 | FTS5_TOKENIZE_DOCUMENT, | 256437 | rc = sqlite3Fts5DecodeLocaleValue( |
| 253707 | zText, nText, | 256438 | pVal, &pText, &nText, &pLoc, &nLoc |
| 253708 | (void*)&ctx, | 256439 | ); |
| 253709 | fts5StorageIntegrityCallback | 256440 | }else{ |
| 253710 | ); | 256441 | if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ |
| 253711 | } | 256442 | int iCol = i + 1 + pConfig->nCol; |
| 253712 | if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ | 256443 | pLoc = (const char*)sqlite3_column_text(pScan, iCol); |
| 253713 | rc = FTS5_CORRUPT; | 256444 | nLoc = sqlite3_column_bytes(pScan, iCol); |
| 253714 | } | 256445 | } |
| 253715 | aTotalSize[i] += ctx.szCol; | 256446 | pText = (const char*)sqlite3_value_text(pVal); |
| 253716 | if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ | 256447 | nText = sqlite3_value_bytes(pVal); |
| 253717 | sqlite3Fts5TermsetFree(ctx.pTermset); | 256448 | } |
| 253718 | ctx.pTermset = 0; | 256449 | |
| 256450 | ctx.iCol = i; | ||
| 256451 | ctx.szCol = 0; | ||
| 256452 | |||
| 256453 | if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ | ||
| 256454 | rc = sqlite3Fts5TermsetNew(&ctx.pTermset); | ||
| 256455 | } | ||
| 256456 | |||
| 256457 | if( rc==SQLITE_OK ){ | ||
| 256458 | sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); | ||
| 256459 | rc = sqlite3Fts5Tokenize(pConfig, | ||
| 256460 | FTS5_TOKENIZE_DOCUMENT, | ||
| 256461 | pText, nText, | ||
| 256462 | (void*)&ctx, | ||
| 256463 | fts5StorageIntegrityCallback | ||
| 256464 | ); | ||
| 256465 | sqlite3Fts5ClearLocale(pConfig); | ||
| 256466 | } | ||
| 256467 | |||
| 256468 | /* If this is not a columnsize=0 database, check that the number | ||
| 256469 | ** of tokens in the value matches the aColSize[] value read from | ||
| 256470 | ** the %_docsize table. */ | ||
| 256471 | if( rc==SQLITE_OK | ||
| 256472 | && pConfig->bColumnsize | ||
| 256473 | && ctx.szCol!=aColSize[i] | ||
| 256474 | ){ | ||
| 256475 | rc = FTS5_CORRUPT; | ||
| 256476 | } | ||
| 256477 | aTotalSize[i] += ctx.szCol; | ||
| 256478 | if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ | ||
| 256479 | sqlite3Fts5TermsetFree(ctx.pTermset); | ||
| 256480 | ctx.pTermset = 0; | ||
| 256481 | } | ||
| 253719 | } | 256482 | } |
| 253720 | } | 256483 | } |
| 253721 | sqlite3Fts5TermsetFree(ctx.pTermset); | 256484 | sqlite3Fts5TermsetFree(ctx.pTermset); |
| @@ -254022,7 +256785,7 @@ static int fts5AsciiCreate( | |||
| 254022 | int i; | 256785 | int i; |
| 254023 | memset(p, 0, sizeof(AsciiTokenizer)); | 256786 | memset(p, 0, sizeof(AsciiTokenizer)); |
| 254024 | memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); | 256787 | memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); |
| 254025 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ | 256788 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ |
| 254026 | const char *zArg = azArg[i+1]; | 256789 | const char *zArg = azArg[i+1]; |
| 254027 | if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ | 256790 | if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ |
| 254028 | fts5AsciiAddExceptions(p, zArg, 1); | 256791 | fts5AsciiAddExceptions(p, zArg, 1); |
| @@ -254033,7 +256796,6 @@ static int fts5AsciiCreate( | |||
| 254033 | rc = SQLITE_ERROR; | 256796 | rc = SQLITE_ERROR; |
| 254034 | } | 256797 | } |
| 254035 | } | 256798 | } |
| 254036 | if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR; | ||
| 254037 | if( rc!=SQLITE_OK ){ | 256799 | if( rc!=SQLITE_OK ){ |
| 254038 | fts5AsciiDelete((Fts5Tokenizer*)p); | 256800 | fts5AsciiDelete((Fts5Tokenizer*)p); |
| 254039 | p = 0; | 256801 | p = 0; |
| @@ -254142,7 +256904,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { | |||
| 254142 | c = *(zIn++); \ | 256904 | c = *(zIn++); \ |
| 254143 | if( c>=0xc0 ){ \ | 256905 | if( c>=0xc0 ){ \ |
| 254144 | c = sqlite3Utf8Trans1[c-0xc0]; \ | 256906 | c = sqlite3Utf8Trans1[c-0xc0]; \ |
| 254145 | while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ | 256907 | while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \ |
| 254146 | c = (c<<6) + (0x3f & *(zIn++)); \ | 256908 | c = (c<<6) + (0x3f & *(zIn++)); \ |
| 254147 | } \ | 256909 | } \ |
| 254148 | if( c<0x80 \ | 256910 | if( c<0x80 \ |
| @@ -254325,7 +257087,7 @@ static int fts5UnicodeCreate( | |||
| 254325 | } | 257087 | } |
| 254326 | 257088 | ||
| 254327 | /* Search for a "categories" argument */ | 257089 | /* Search for a "categories" argument */ |
| 254328 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ | 257090 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ |
| 254329 | if( 0==sqlite3_stricmp(azArg[i], "categories") ){ | 257091 | if( 0==sqlite3_stricmp(azArg[i], "categories") ){ |
| 254330 | zCat = azArg[i+1]; | 257092 | zCat = azArg[i+1]; |
| 254331 | } | 257093 | } |
| @@ -254334,7 +257096,7 @@ static int fts5UnicodeCreate( | |||
| 254334 | rc = unicodeSetCategories(p, zCat); | 257096 | rc = unicodeSetCategories(p, zCat); |
| 254335 | } | 257097 | } |
| 254336 | 257098 | ||
| 254337 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ | 257099 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ |
| 254338 | const char *zArg = azArg[i+1]; | 257100 | const char *zArg = azArg[i+1]; |
| 254339 | if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ | 257101 | if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ |
| 254340 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ | 257102 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ |
| @@ -254359,8 +257121,6 @@ static int fts5UnicodeCreate( | |||
| 254359 | rc = SQLITE_ERROR; | 257121 | rc = SQLITE_ERROR; |
| 254360 | } | 257122 | } |
| 254361 | } | 257123 | } |
| 254362 | if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; | ||
| 254363 | |||
| 254364 | }else{ | 257124 | }else{ |
| 254365 | rc = SQLITE_NOMEM; | 257125 | rc = SQLITE_NOMEM; |
| 254366 | } | 257126 | } |
| @@ -254499,7 +257259,7 @@ static int fts5UnicodeTokenize( | |||
| 254499 | 257259 | ||
| 254500 | typedef struct PorterTokenizer PorterTokenizer; | 257260 | typedef struct PorterTokenizer PorterTokenizer; |
| 254501 | struct PorterTokenizer { | 257261 | struct PorterTokenizer { |
| 254502 | fts5_tokenizer tokenizer; /* Parent tokenizer module */ | 257262 | fts5_tokenizer_v2 tokenizer_v2; /* Parent tokenizer module */ |
| 254503 | Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */ | 257263 | Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */ |
| 254504 | char aBuf[FTS5_PORTER_MAX_TOKEN + 64]; | 257264 | char aBuf[FTS5_PORTER_MAX_TOKEN + 64]; |
| 254505 | }; | 257265 | }; |
| @@ -254511,7 +257271,7 @@ static void fts5PorterDelete(Fts5Tokenizer *pTok){ | |||
| 254511 | if( pTok ){ | 257271 | if( pTok ){ |
| 254512 | PorterTokenizer *p = (PorterTokenizer*)pTok; | 257272 | PorterTokenizer *p = (PorterTokenizer*)pTok; |
| 254513 | if( p->pTokenizer ){ | 257273 | if( p->pTokenizer ){ |
| 254514 | p->tokenizer.xDelete(p->pTokenizer); | 257274 | p->tokenizer_v2.xDelete(p->pTokenizer); |
| 254515 | } | 257275 | } |
| 254516 | sqlite3_free(p); | 257276 | sqlite3_free(p); |
| 254517 | } | 257277 | } |
| @@ -254530,6 +257290,7 @@ static int fts5PorterCreate( | |||
| 254530 | PorterTokenizer *pRet; | 257290 | PorterTokenizer *pRet; |
| 254531 | void *pUserdata = 0; | 257291 | void *pUserdata = 0; |
| 254532 | const char *zBase = "unicode61"; | 257292 | const char *zBase = "unicode61"; |
| 257293 | fts5_tokenizer_v2 *pV2 = 0; | ||
| 254533 | 257294 | ||
| 254534 | if( nArg>0 ){ | 257295 | if( nArg>0 ){ |
| 254535 | zBase = azArg[0]; | 257296 | zBase = azArg[0]; |
| @@ -254538,14 +257299,15 @@ static int fts5PorterCreate( | |||
| 254538 | pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); | 257299 | pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); |
| 254539 | if( pRet ){ | 257300 | if( pRet ){ |
| 254540 | memset(pRet, 0, sizeof(PorterTokenizer)); | 257301 | memset(pRet, 0, sizeof(PorterTokenizer)); |
| 254541 | rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer); | 257302 | rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); |
| 254542 | }else{ | 257303 | }else{ |
| 254543 | rc = SQLITE_NOMEM; | 257304 | rc = SQLITE_NOMEM; |
| 254544 | } | 257305 | } |
| 254545 | if( rc==SQLITE_OK ){ | 257306 | if( rc==SQLITE_OK ){ |
| 254546 | int nArg2 = (nArg>0 ? nArg-1 : 0); | 257307 | int nArg2 = (nArg>0 ? nArg-1 : 0); |
| 254547 | const char **azArg2 = (nArg2 ? &azArg[1] : 0); | 257308 | const char **az2 = (nArg2 ? &azArg[1] : 0); |
| 254548 | rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer); | 257309 | memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2)); |
| 257310 | rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer); | ||
| 254549 | } | 257311 | } |
| 254550 | 257312 | ||
| 254551 | if( rc!=SQLITE_OK ){ | 257313 | if( rc!=SQLITE_OK ){ |
| @@ -255196,6 +257958,7 @@ static int fts5PorterTokenize( | |||
| 255196 | void *pCtx, | 257958 | void *pCtx, |
| 255197 | int flags, | 257959 | int flags, |
| 255198 | const char *pText, int nText, | 257960 | const char *pText, int nText, |
| 257961 | const char *pLoc, int nLoc, | ||
| 255199 | int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) | 257962 | int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) |
| 255200 | ){ | 257963 | ){ |
| 255201 | PorterTokenizer *p = (PorterTokenizer*)pTokenizer; | 257964 | PorterTokenizer *p = (PorterTokenizer*)pTokenizer; |
| @@ -255203,8 +257966,8 @@ static int fts5PorterTokenize( | |||
| 255203 | sCtx.xToken = xToken; | 257966 | sCtx.xToken = xToken; |
| 255204 | sCtx.pCtx = pCtx; | 257967 | sCtx.pCtx = pCtx; |
| 255205 | sCtx.aBuf = p->aBuf; | 257968 | sCtx.aBuf = p->aBuf; |
| 255206 | return p->tokenizer.xTokenize( | 257969 | return p->tokenizer_v2.xTokenize( |
| 255207 | p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb | 257970 | p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb |
| 255208 | ); | 257971 | ); |
| 255209 | } | 257972 | } |
| 255210 | 257973 | ||
| @@ -255234,41 +257997,46 @@ static int fts5TriCreate( | |||
| 255234 | Fts5Tokenizer **ppOut | 257997 | Fts5Tokenizer **ppOut |
| 255235 | ){ | 257998 | ){ |
| 255236 | int rc = SQLITE_OK; | 257999 | int rc = SQLITE_OK; |
| 255237 | TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); | 258000 | TrigramTokenizer *pNew = 0; |
| 255238 | UNUSED_PARAM(pUnused); | 258001 | UNUSED_PARAM(pUnused); |
| 255239 | if( pNew==0 ){ | 258002 | if( nArg%2 ){ |
| 255240 | rc = SQLITE_NOMEM; | 258003 | rc = SQLITE_ERROR; |
| 255241 | }else{ | 258004 | }else{ |
| 255242 | int i; | 258005 | int i; |
| 255243 | pNew->bFold = 1; | 258006 | pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); |
| 255244 | pNew->iFoldParam = 0; | 258007 | if( pNew==0 ){ |
| 255245 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ | 258008 | rc = SQLITE_NOMEM; |
| 255246 | const char *zArg = azArg[i+1]; | 258009 | }else{ |
| 255247 | if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ | 258010 | pNew->bFold = 1; |
| 255248 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ | 258011 | pNew->iFoldParam = 0; |
| 255249 | rc = SQLITE_ERROR; | 258012 | |
| 258013 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ | ||
| 258014 | const char *zArg = azArg[i+1]; | ||
| 258015 | if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ | ||
| 258016 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ | ||
| 258017 | rc = SQLITE_ERROR; | ||
| 258018 | }else{ | ||
| 258019 | pNew->bFold = (zArg[0]=='0'); | ||
| 258020 | } | ||
| 258021 | }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ | ||
| 258022 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ | ||
| 258023 | rc = SQLITE_ERROR; | ||
| 258024 | }else{ | ||
| 258025 | pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; | ||
| 258026 | } | ||
| 255250 | }else{ | 258027 | }else{ |
| 255251 | pNew->bFold = (zArg[0]=='0'); | ||
| 255252 | } | ||
| 255253 | }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ | ||
| 255254 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ | ||
| 255255 | rc = SQLITE_ERROR; | 258028 | rc = SQLITE_ERROR; |
| 255256 | }else{ | ||
| 255257 | pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; | ||
| 255258 | } | 258029 | } |
| 255259 | }else{ | ||
| 255260 | rc = SQLITE_ERROR; | ||
| 255261 | } | 258030 | } |
| 255262 | } | ||
| 255263 | if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; | ||
| 255264 | 258031 | ||
| 255265 | if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ | 258032 | if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ |
| 255266 | rc = SQLITE_ERROR; | 258033 | rc = SQLITE_ERROR; |
| 255267 | } | 258034 | } |
| 255268 | 258035 | ||
| 255269 | if( rc!=SQLITE_OK ){ | 258036 | if( rc!=SQLITE_OK ){ |
| 255270 | fts5TriDelete((Fts5Tokenizer*)pNew); | 258037 | fts5TriDelete((Fts5Tokenizer*)pNew); |
| 255271 | pNew = 0; | 258038 | pNew = 0; |
| 258039 | } | ||
| 255272 | } | 258040 | } |
| 255273 | } | 258041 | } |
| 255274 | *ppOut = (Fts5Tokenizer*)pNew; | 258042 | *ppOut = (Fts5Tokenizer*)pNew; |
| @@ -255374,6 +258142,16 @@ static int sqlite3Fts5TokenizerPattern( | |||
| 255374 | } | 258142 | } |
| 255375 | 258143 | ||
| 255376 | /* | 258144 | /* |
| 258145 | ** Return true if the tokenizer described by p->azArg[] is the trigram | ||
| 258146 | ** tokenizer. This tokenizer needs to be loaded before xBestIndex is | ||
| 258147 | ** called for the first time in order to correctly handle LIKE/GLOB. | ||
| 258148 | */ | ||
| 258149 | static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ | ||
| 258150 | return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); | ||
| 258151 | } | ||
| 258152 | |||
| 258153 | |||
| 258154 | /* | ||
| 255377 | ** Register all built-in tokenizers with FTS5. | 258155 | ** Register all built-in tokenizers with FTS5. |
| 255378 | */ | 258156 | */ |
| 255379 | static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ | 258157 | static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ |
| @@ -255383,7 +258161,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ | |||
| 255383 | } aBuiltin[] = { | 258161 | } aBuiltin[] = { |
| 255384 | { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, | 258162 | { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, |
| 255385 | { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, | 258163 | { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, |
| 255386 | { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, | ||
| 255387 | { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, | 258164 | { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, |
| 255388 | }; | 258165 | }; |
| 255389 | 258166 | ||
| @@ -255398,7 +258175,20 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ | |||
| 255398 | 0 | 258175 | 0 |
| 255399 | ); | 258176 | ); |
| 255400 | } | 258177 | } |
| 255401 | 258178 | if( rc==SQLITE_OK ){ | |
| 258179 | fts5_tokenizer_v2 sPorter = { | ||
| 258180 | 2, | ||
| 258181 | fts5PorterCreate, | ||
| 258182 | fts5PorterDelete, | ||
| 258183 | fts5PorterTokenize | ||
| 258184 | }; | ||
| 258185 | rc = pApi->xCreateTokenizer_v2(pApi, | ||
| 258186 | "porter", | ||
| 258187 | (void*)pApi, | ||
| 258188 | &sPorter, | ||
| 258189 | 0 | ||
| 258190 | ); | ||
| 258191 | } | ||
| 255402 | return rc; | 258192 | return rc; |
| 255403 | } | 258193 | } |
| 255404 | 258194 | ||
| @@ -255768,6 +258558,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ | |||
| 255768 | default: return 1; } | 258558 | default: return 1; } |
| 255769 | break; | 258559 | break; |
| 255770 | 258560 | ||
| 258561 | |||
| 258562 | default: | ||
| 258563 | return 1; | ||
| 255771 | } | 258564 | } |
| 255772 | return 0; | 258565 | return 0; |
| 255773 | } | 258566 | } |
| @@ -256592,6 +259385,7 @@ struct Fts5VocabCursor { | |||
| 256592 | 259385 | ||
| 256593 | int nLeTerm; /* Size of zLeTerm in bytes */ | 259386 | int nLeTerm; /* Size of zLeTerm in bytes */ |
| 256594 | char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ | 259387 | char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ |
| 259388 | int colUsed; /* Copy of sqlite3_index_info.colUsed */ | ||
| 256595 | 259389 | ||
| 256596 | /* These are used by 'col' tables only */ | 259390 | /* These are used by 'col' tables only */ |
| 256597 | int iCol; | 259391 | int iCol; |
| @@ -256618,9 +259412,11 @@ struct Fts5VocabCursor { | |||
| 256618 | /* | 259412 | /* |
| 256619 | ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. | 259413 | ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. |
| 256620 | */ | 259414 | */ |
| 256621 | #define FTS5_VOCAB_TERM_EQ 0x01 | 259415 | #define FTS5_VOCAB_TERM_EQ 0x0100 |
| 256622 | #define FTS5_VOCAB_TERM_GE 0x02 | 259416 | #define FTS5_VOCAB_TERM_GE 0x0200 |
| 256623 | #define FTS5_VOCAB_TERM_LE 0x04 | 259417 | #define FTS5_VOCAB_TERM_LE 0x0400 |
| 259418 | |||
| 259419 | #define FTS5_VOCAB_COLUSED_MASK 0xFF | ||
| 256624 | 259420 | ||
| 256625 | 259421 | ||
| 256626 | /* | 259422 | /* |
| @@ -256797,11 +259593,13 @@ static int fts5VocabBestIndexMethod( | |||
| 256797 | int iTermEq = -1; | 259593 | int iTermEq = -1; |
| 256798 | int iTermGe = -1; | 259594 | int iTermGe = -1; |
| 256799 | int iTermLe = -1; | 259595 | int iTermLe = -1; |
| 256800 | int idxNum = 0; | 259596 | int idxNum = (int)pInfo->colUsed; |
| 256801 | int nArg = 0; | 259597 | int nArg = 0; |
| 256802 | 259598 | ||
| 256803 | UNUSED_PARAM(pUnused); | 259599 | UNUSED_PARAM(pUnused); |
| 256804 | 259600 | ||
| 259601 | assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); | ||
| 259602 | |||
| 256805 | for(i=0; i<pInfo->nConstraint; i++){ | 259603 | for(i=0; i<pInfo->nConstraint; i++){ |
| 256806 | struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; | 259604 | struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; |
| 256807 | if( p->usable==0 ) continue; | 259605 | if( p->usable==0 ) continue; |
| @@ -256893,7 +259691,7 @@ static int fts5VocabOpenMethod( | |||
| 256893 | if( rc==SQLITE_OK ){ | 259691 | if( rc==SQLITE_OK ){ |
| 256894 | pVTab->zErrMsg = sqlite3_mprintf( | 259692 | pVTab->zErrMsg = sqlite3_mprintf( |
| 256895 | "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl | 259693 | "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl |
| 256896 | ); | 259694 | ); |
| 256897 | rc = SQLITE_ERROR; | 259695 | rc = SQLITE_ERROR; |
| 256898 | } | 259696 | } |
| 256899 | }else{ | 259697 | }else{ |
| @@ -257053,9 +259851,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ | |||
| 257053 | 259851 | ||
| 257054 | switch( pTab->eType ){ | 259852 | switch( pTab->eType ){ |
| 257055 | case FTS5_VOCAB_ROW: | 259853 | case FTS5_VOCAB_ROW: |
| 257056 | if( eDetail==FTS5_DETAIL_FULL ){ | 259854 | /* Do not bother counting the number of instances if the "cnt" |
| 257057 | while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ | 259855 | ** column is not being read (according to colUsed). */ |
| 257058 | pCsr->aCnt[0]++; | 259856 | if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ |
| 259857 | while( iPos<nPos ){ | ||
| 259858 | u32 ii; | ||
| 259859 | fts5FastGetVarint32(pPos, iPos, ii); | ||
| 259860 | if( ii==1 ){ | ||
| 259861 | /* New column in the position list */ | ||
| 259862 | fts5FastGetVarint32(pPos, iPos, ii); | ||
| 259863 | }else{ | ||
| 259864 | /* An instance - increment pCsr->aCnt[] */ | ||
| 259865 | pCsr->aCnt[0]++; | ||
| 259866 | } | ||
| 257059 | } | 259867 | } |
| 257060 | } | 259868 | } |
| 257061 | pCsr->aDoc[0]++; | 259869 | pCsr->aDoc[0]++; |
| @@ -257153,6 +259961,7 @@ static int fts5VocabFilterMethod( | |||
| 257153 | if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; | 259961 | if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; |
| 257154 | if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; | 259962 | if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; |
| 257155 | if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; | 259963 | if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; |
| 259964 | pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); | ||
| 257156 | 259965 | ||
| 257157 | if( pEq ){ | 259966 | if( pEq ){ |
| 257158 | zTerm = (const char *)sqlite3_value_text(pEq); | 259967 | zTerm = (const char *)sqlite3_value_text(pEq); |
| @@ -257320,7 +260129,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ | |||
| 257320 | } | 260129 | } |
| 257321 | 260130 | ||
| 257322 | 260131 | ||
| 257323 | 260132 | /* Here ends the fts5.c composite file. */ | |
| 257324 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ | 260133 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ |
| 257325 | 260134 | ||
| 257326 | /************** End of fts5.c ************************************************/ | 260135 | /************** End of fts5.c ************************************************/ |
diff --git a/c/sqlite3.h b/c/sqlite3.h index f64ca01..dbecc3f 100644 --- a/c/sqlite3.h +++ b/c/sqlite3.h | |||
| @@ -146,9 +146,9 @@ extern "C" { | |||
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ | 148 | */ |
| 149 | #define SQLITE_VERSION "3.46.1" | 149 | #define SQLITE_VERSION "3.47.1" |
| 150 | #define SQLITE_VERSION_NUMBER 3046001 | 150 | #define SQLITE_VERSION_NUMBER 3047001 |
| 151 | #define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" | 151 | #define SQLITE_SOURCE_ID "2024-11-25 12:07:48 b95d11e958643b969c47a8e5857f3793b9e69700b8f1469371386369a26e577e" |
| 152 | 152 | ||
| 153 | /* | 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| @@ -652,6 +652,13 @@ SQLITE_API int sqlite3_exec( | |||
| 652 | ** filesystem supports doing multiple write operations atomically when those | 652 | ** filesystem supports doing multiple write operations atomically when those |
| 653 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and | 653 | ** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and |
| 654 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. | 654 | ** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. |
| 655 | ** | ||
| 656 | ** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read | ||
| 657 | ** from the database file in amounts that are not a multiple of the | ||
| 658 | ** page size and that do not begin at a page boundary. Without this | ||
| 659 | ** property, SQLite is careful to only do full-page reads and write | ||
| 660 | ** on aligned pages, with the one exception that it will do a sub-page | ||
| 661 | ** read of the first page to access the database header. | ||
| 655 | */ | 662 | */ |
| 656 | #define SQLITE_IOCAP_ATOMIC 0x00000001 | 663 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 657 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 | 664 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| @@ -668,6 +675,7 @@ SQLITE_API int sqlite3_exec( | |||
| 668 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 | 675 | #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 |
| 669 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 | 676 | #define SQLITE_IOCAP_IMMUTABLE 0x00002000 |
| 670 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 | 677 | #define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 |
| 678 | #define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 | ||
| 671 | 679 | ||
| 672 | /* | 680 | /* |
| 673 | ** CAPI3REF: File Locking Levels | 681 | ** CAPI3REF: File Locking Levels |
| @@ -772,8 +780,8 @@ struct sqlite3_file { | |||
| 772 | ** to xUnlock() is a no-op. | 780 | ** to xUnlock() is a no-op. |
| 773 | ** The xCheckReservedLock() method checks whether any database connection, | 781 | ** The xCheckReservedLock() method checks whether any database connection, |
| 774 | ** either in this process or in some other process, is holding a RESERVED, | 782 | ** either in this process or in some other process, is holding a RESERVED, |
| 775 | ** PENDING, or EXCLUSIVE lock on the file. It returns true | 783 | ** PENDING, or EXCLUSIVE lock on the file. It returns, via its output |
| 776 | ** if such a lock exists and false otherwise. | 784 | ** pointer parameter, true if such a lock exists and false otherwise. |
| 777 | ** | 785 | ** |
| 778 | ** The xFileControl() method is a generic interface that allows custom | 786 | ** The xFileControl() method is a generic interface that allows custom |
| 779 | ** VFS implementations to directly control an open file using the | 787 | ** VFS implementations to directly control an open file using the |
| @@ -814,6 +822,7 @@ struct sqlite3_file { | |||
| 814 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] | 822 | ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE] |
| 815 | ** <li> [SQLITE_IOCAP_IMMUTABLE] | 823 | ** <li> [SQLITE_IOCAP_IMMUTABLE] |
| 816 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] | 824 | ** <li> [SQLITE_IOCAP_BATCH_ATOMIC] |
| 825 | ** <li> [SQLITE_IOCAP_SUBPAGE_READ] | ||
| 817 | ** </ul> | 826 | ** </ul> |
| 818 | ** | 827 | ** |
| 819 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of | 828 | ** The SQLITE_IOCAP_ATOMIC property means that all writes of |
| @@ -3570,8 +3579,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | |||
| 3570 | ** | 3579 | ** |
| 3571 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> | 3580 | ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt> |
| 3572 | ** <dd>The database connection comes up in "extended result code mode". | 3581 | ** <dd>The database connection comes up in "extended result code mode". |
| 3573 | ** In other words, the database behaves has if | 3582 | ** In other words, the database behaves as if |
| 3574 | ** [sqlite3_extended_result_codes(db,1)] where called on the database | 3583 | ** [sqlite3_extended_result_codes(db,1)] were called on the database |
| 3575 | ** connection as soon as the connection is created. In addition to setting | 3584 | ** connection as soon as the connection is created. In addition to setting |
| 3576 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] | 3585 | ** the extended result code mode, this flag also causes [sqlite3_open_v2()] |
| 3577 | ** to return an extended result code.</dd> | 3586 | ** to return an extended result code.</dd> |
| @@ -4222,13 +4231,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); | |||
| 4222 | ** and sqlite3_prepare16_v3() use UTF-16. | 4231 | ** and sqlite3_prepare16_v3() use UTF-16. |
| 4223 | ** | 4232 | ** |
| 4224 | ** ^If the nByte argument is negative, then zSql is read up to the | 4233 | ** ^If the nByte argument is negative, then zSql is read up to the |
| 4225 | ** first zero terminator. ^If nByte is positive, then it is the | 4234 | ** first zero terminator. ^If nByte is positive, then it is the maximum |
| 4226 | ** number of bytes read from zSql. ^If nByte is zero, then no prepared | 4235 | ** number of bytes read from zSql. When nByte is positive, zSql is read |
| 4236 | ** up to the first zero terminator or until the nByte bytes have been read, | ||
| 4237 | ** whichever comes first. ^If nByte is zero, then no prepared | ||
| 4227 | ** statement is generated. | 4238 | ** statement is generated. |
| 4228 | ** If the caller knows that the supplied string is nul-terminated, then | 4239 | ** If the caller knows that the supplied string is nul-terminated, then |
| 4229 | ** there is a small performance advantage to passing an nByte parameter that | 4240 | ** there is a small performance advantage to passing an nByte parameter that |
| 4230 | ** is the number of bytes in the input string <i>including</i> | 4241 | ** is the number of bytes in the input string <i>including</i> |
| 4231 | ** the nul-terminator. | 4242 | ** the nul-terminator. |
| 4243 | ** Note that nByte measure the length of the input in bytes, not | ||
| 4244 | ** characters, even for the UTF-16 interfaces. | ||
| 4232 | ** | 4245 | ** |
| 4233 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte | 4246 | ** ^If pzTail is not NULL then *pzTail is made to point to the first byte |
| 4234 | ** past the end of the first SQL statement in zSql. These routines only | 4247 | ** past the end of the first SQL statement in zSql. These routines only |
| @@ -5599,7 +5612,7 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5599 | ** This flag instructs SQLite to omit some corner-case optimizations that | 5612 | ** This flag instructs SQLite to omit some corner-case optimizations that |
| 5600 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, | 5613 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, |
| 5601 | ** causing it to return zero rather than the correct subtype(). | 5614 | ** causing it to return zero rather than the correct subtype(). |
| 5602 | ** SQL functions that invokes [sqlite3_value_subtype()] should have this | 5615 | ** All SQL functions that invoke [sqlite3_value_subtype()] should have this |
| 5603 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return | 5616 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return |
| 5604 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though | 5617 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though |
| 5605 | ** a non-zero subtype was specified by the function argument expression. | 5618 | ** a non-zero subtype was specified by the function argument expression. |
| @@ -5615,6 +5628,15 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5615 | ** [sqlite3_result_subtype()] should avoid setting this property, as the | 5628 | ** [sqlite3_result_subtype()] should avoid setting this property, as the |
| 5616 | ** purpose of this property is to disable certain optimizations that are | 5629 | ** purpose of this property is to disable certain optimizations that are |
| 5617 | ** incompatible with subtypes. | 5630 | ** incompatible with subtypes. |
| 5631 | ** | ||
| 5632 | ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> | ||
| 5633 | ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate | ||
| 5634 | ** that internally orders the values provided to the first argument. The | ||
| 5635 | ** ordered-set aggregate SQL notation with a single ORDER BY term can be | ||
| 5636 | ** used to invoke this function. If the ordered-set aggregate notation is | ||
| 5637 | ** used on a function that lacks this flag, then an error is raised. Note | ||
| 5638 | ** that the ordered-set aggregate syntax is only available if SQLite is | ||
| 5639 | ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. | ||
| 5618 | ** </dd> | 5640 | ** </dd> |
| 5619 | ** </dl> | 5641 | ** </dl> |
| 5620 | */ | 5642 | */ |
| @@ -5623,6 +5645,7 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5623 | #define SQLITE_SUBTYPE 0x000100000 | 5645 | #define SQLITE_SUBTYPE 0x000100000 |
| 5624 | #define SQLITE_INNOCUOUS 0x000200000 | 5646 | #define SQLITE_INNOCUOUS 0x000200000 |
| 5625 | #define SQLITE_RESULT_SUBTYPE 0x001000000 | 5647 | #define SQLITE_RESULT_SUBTYPE 0x001000000 |
| 5648 | #define SQLITE_SELFORDER1 0x002000000 | ||
| 5626 | 5649 | ||
| 5627 | /* | 5650 | /* |
| 5628 | ** CAPI3REF: Deprecated Functions | 5651 | ** CAPI3REF: Deprecated Functions |
| @@ -5820,7 +5843,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); | |||
| 5820 | ** one SQL function to another. Use the [sqlite3_result_subtype()] | 5843 | ** one SQL function to another. Use the [sqlite3_result_subtype()] |
| 5821 | ** routine to set the subtype for the return value of an SQL function. | 5844 | ** routine to set the subtype for the return value of an SQL function. |
| 5822 | ** | 5845 | ** |
| 5823 | ** Every [application-defined SQL function] that invoke this interface | 5846 | ** Every [application-defined SQL function] that invokes this interface |
| 5824 | ** should include the [SQLITE_SUBTYPE] property in the text | 5847 | ** should include the [SQLITE_SUBTYPE] property in the text |
| 5825 | ** encoding argument when the function is [sqlite3_create_function|registered]. | 5848 | ** encoding argument when the function is [sqlite3_create_function|registered]. |
| 5826 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() | 5849 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() |
| @@ -7427,9 +7450,11 @@ struct sqlite3_module { | |||
| 7427 | ** will be returned by the strategy. | 7450 | ** will be returned by the strategy. |
| 7428 | ** | 7451 | ** |
| 7429 | ** The xBestIndex method may optionally populate the idxFlags field with a | 7452 | ** The xBestIndex method may optionally populate the idxFlags field with a |
| 7430 | ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - | 7453 | ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is |
| 7431 | ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite | 7454 | ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] |
| 7432 | ** assumes that the strategy may visit at most one row. | 7455 | ** output to show the idxNum has hex instead of as decimal. Another flag is |
| 7456 | ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will | ||
| 7457 | ** return at most one row. | ||
| 7433 | ** | 7458 | ** |
| 7434 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then | 7459 | ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then |
| 7435 | ** SQLite also assumes that if a call to the xUpdate() method is made as | 7460 | ** SQLite also assumes that if a call to the xUpdate() method is made as |
| @@ -7493,7 +7518,9 @@ struct sqlite3_index_info { | |||
| 7493 | ** [sqlite3_index_info].idxFlags field to some combination of | 7518 | ** [sqlite3_index_info].idxFlags field to some combination of |
| 7494 | ** these bits. | 7519 | ** these bits. |
| 7495 | */ | 7520 | */ |
| 7496 | #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ | 7521 | #define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ |
| 7522 | #define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ | ||
| 7523 | /* in EXPLAIN QUERY PLAN */ | ||
| 7497 | 7524 | ||
| 7498 | /* | 7525 | /* |
| 7499 | ** CAPI3REF: Virtual Table Constraint Operator Codes | 7526 | ** CAPI3REF: Virtual Table Constraint Operator Codes |
| @@ -8330,6 +8357,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8330 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 | 8357 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 |
| 8331 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 | 8358 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 8332 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ | 8359 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ |
| 8360 | #define SQLITE_TESTCTRL_GETOPT 16 | ||
| 8333 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ | 8361 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ |
| 8334 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 | 8362 | #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 |
| 8335 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 | 8363 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| @@ -8349,7 +8377,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8349 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 | 8377 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 |
| 8350 | #define SQLITE_TESTCTRL_TUNE 32 | 8378 | #define SQLITE_TESTCTRL_TUNE 32 |
| 8351 | #define SQLITE_TESTCTRL_LOGEST 33 | 8379 | #define SQLITE_TESTCTRL_LOGEST 33 |
| 8352 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 | 8380 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ |
| 8353 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ | 8381 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ |
| 8354 | 8382 | ||
| 8355 | /* | 8383 | /* |
| @@ -9325,6 +9353,16 @@ typedef struct sqlite3_backup sqlite3_backup; | |||
| 9325 | ** APIs are not strictly speaking threadsafe. If they are invoked at the | 9353 | ** APIs are not strictly speaking threadsafe. If they are invoked at the |
| 9326 | ** same time as another thread is invoking sqlite3_backup_step() it is | 9354 | ** same time as another thread is invoking sqlite3_backup_step() it is |
| 9327 | ** possible that they return invalid values. | 9355 | ** possible that they return invalid values. |
| 9356 | ** | ||
| 9357 | ** <b>Alternatives To Using The Backup API</b> | ||
| 9358 | ** | ||
| 9359 | ** Other techniques for safely creating a consistent backup of an SQLite | ||
| 9360 | ** database include: | ||
| 9361 | ** | ||
| 9362 | ** <ul> | ||
| 9363 | ** <li> The [VACUUM INTO] command. | ||
| 9364 | ** <li> The [sqlite3_rsync] utility program. | ||
| 9365 | ** </ul> | ||
| 9328 | */ | 9366 | */ |
| 9329 | SQLITE_API sqlite3_backup *sqlite3_backup_init( | 9367 | SQLITE_API sqlite3_backup *sqlite3_backup_init( |
| 9330 | sqlite3 *pDest, /* Destination database handle */ | 9368 | sqlite3 *pDest, /* Destination database handle */ |
| @@ -10524,6 +10562,14 @@ typedef struct sqlite3_snapshot { | |||
| 10524 | ** If there is not already a read-transaction open on schema S when | 10562 | ** If there is not already a read-transaction open on schema S when |
| 10525 | ** this function is called, one is opened automatically. | 10563 | ** this function is called, one is opened automatically. |
| 10526 | ** | 10564 | ** |
| 10565 | ** If a read-transaction is opened by this function, then it is guaranteed | ||
| 10566 | ** that the returned snapshot object may not be invalidated by a database | ||
| 10567 | ** writer or checkpointer until after the read-transaction is closed. This | ||
| 10568 | ** is not guaranteed if a read-transaction is already open when this | ||
| 10569 | ** function is called. In that case, any subsequent write or checkpoint | ||
| 10570 | ** operation on the database may invalidate the returned snapshot handle, | ||
| 10571 | ** even while the read-transaction remains open. | ||
| 10572 | ** | ||
| 10527 | ** The following must be true for this function to succeed. If any of | 10573 | ** The following must be true for this function to succeed. If any of |
| 10528 | ** the following statements are false when sqlite3_snapshot_get() is | 10574 | ** the following statements are false when sqlite3_snapshot_get() is |
| 10529 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined | 10575 | ** called, SQLITE_ERROR is returned. The final value of *P is undefined |
| @@ -10832,8 +10878,6 @@ SQLITE_API int sqlite3_deserialize( | |||
| 10832 | #if defined(__wasi__) | 10878 | #if defined(__wasi__) |
| 10833 | # undef SQLITE_WASI | 10879 | # undef SQLITE_WASI |
| 10834 | # define SQLITE_WASI 1 | 10880 | # define SQLITE_WASI 1 |
| 10835 | # undef SQLITE_OMIT_WAL | ||
| 10836 | # define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ | ||
| 10837 | # ifndef SQLITE_OMIT_LOAD_EXTENSION | 10881 | # ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 10838 | # define SQLITE_OMIT_LOAD_EXTENSION | 10882 | # define SQLITE_OMIT_LOAD_EXTENSION |
| 10839 | # endif | 10883 | # endif |
| @@ -13036,6 +13080,10 @@ struct Fts5PhraseIter { | |||
| 13036 | ** (i.e. if it is a contentless table), then this API always iterates | 13080 | ** (i.e. if it is a contentless table), then this API always iterates |
| 13037 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). | 13081 | ** through an empty set (all calls to xPhraseFirst() set iCol to -1). |
| 13038 | ** | 13082 | ** |
| 13083 | ** In all cases, matches are visited in (column ASC, offset ASC) order. | ||
| 13084 | ** i.e. all those in column 0, sorted by offset, followed by those in | ||
| 13085 | ** column 1, etc. | ||
| 13086 | ** | ||
| 13039 | ** xPhraseNext() | 13087 | ** xPhraseNext() |
| 13040 | ** See xPhraseFirst above. | 13088 | ** See xPhraseFirst above. |
| 13041 | ** | 13089 | ** |
| @@ -13102,9 +13150,32 @@ struct Fts5PhraseIter { | |||
| 13102 | ** | 13150 | ** |
| 13103 | ** This API can be quite slow if used with an FTS5 table created with the | 13151 | ** This API can be quite slow if used with an FTS5 table created with the |
| 13104 | ** "detail=none" or "detail=column" option. | 13152 | ** "detail=none" or "detail=column" option. |
| 13153 | ** | ||
| 13154 | ** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) | ||
| 13155 | ** If parameter iCol is less than zero, or greater than or equal to the | ||
| 13156 | ** number of columns in the table, SQLITE_RANGE is returned. | ||
| 13157 | ** | ||
| 13158 | ** Otherwise, this function attempts to retrieve the locale associated | ||
| 13159 | ** with column iCol of the current row. Usually, there is no associated | ||
| 13160 | ** locale, and output parameters (*pzLocale) and (*pnLocale) are set | ||
| 13161 | ** to NULL and 0, respectively. However, if the fts5_locale() function | ||
| 13162 | ** was used to associate a locale with the value when it was inserted | ||
| 13163 | ** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated | ||
| 13164 | ** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) | ||
| 13165 | ** is set to the size in bytes of the buffer, not including the | ||
| 13166 | ** nul-terminator. | ||
| 13167 | ** | ||
| 13168 | ** If successful, SQLITE_OK is returned. Or, if an error occurs, an | ||
| 13169 | ** SQLite error code is returned. The final value of the output parameters | ||
| 13170 | ** is undefined in this case. | ||
| 13171 | ** | ||
| 13172 | ** xTokenize_v2: | ||
| 13173 | ** Tokenize text using the tokenizer belonging to the FTS5 table. This | ||
| 13174 | ** API is the same as the xTokenize() API, except that it allows a tokenizer | ||
| 13175 | ** locale to be specified. | ||
| 13105 | */ | 13176 | */ |
| 13106 | struct Fts5ExtensionApi { | 13177 | struct Fts5ExtensionApi { |
| 13107 | int iVersion; /* Currently always set to 3 */ | 13178 | int iVersion; /* Currently always set to 4 */ |
| 13108 | 13179 | ||
| 13109 | void *(*xUserData)(Fts5Context*); | 13180 | void *(*xUserData)(Fts5Context*); |
| 13110 | 13181 | ||
| @@ -13146,6 +13217,15 @@ struct Fts5ExtensionApi { | |||
| 13146 | const char **ppToken, int *pnToken | 13217 | const char **ppToken, int *pnToken |
| 13147 | ); | 13218 | ); |
| 13148 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | 13219 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); |
| 13220 | |||
| 13221 | /* Below this point are iVersion>=4 only */ | ||
| 13222 | int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); | ||
| 13223 | int (*xTokenize_v2)(Fts5Context*, | ||
| 13224 | const char *pText, int nText, /* Text to tokenize */ | ||
| 13225 | const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ | ||
| 13226 | void *pCtx, /* Context passed to xToken() */ | ||
| 13227 | int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ | ||
| 13228 | ); | ||
| 13149 | }; | 13229 | }; |
| 13150 | 13230 | ||
| 13151 | /* | 13231 | /* |
| @@ -13166,7 +13246,7 @@ struct Fts5ExtensionApi { | |||
| 13166 | ** A tokenizer instance is required to actually tokenize text. | 13246 | ** A tokenizer instance is required to actually tokenize text. |
| 13167 | ** | 13247 | ** |
| 13168 | ** The first argument passed to this function is a copy of the (void*) | 13248 | ** The first argument passed to this function is a copy of the (void*) |
| 13169 | ** pointer provided by the application when the fts5_tokenizer object | 13249 | ** pointer provided by the application when the fts5_tokenizer_v2 object |
| 13170 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). | 13250 | ** was registered with FTS5 (the third argument to xCreateTokenizer()). |
| 13171 | ** The second and third arguments are an array of nul-terminated strings | 13251 | ** The second and third arguments are an array of nul-terminated strings |
| 13172 | ** containing the tokenizer arguments, if any, specified following the | 13252 | ** containing the tokenizer arguments, if any, specified following the |
| @@ -13190,7 +13270,7 @@ struct Fts5ExtensionApi { | |||
| 13190 | ** argument passed to this function is a pointer to an Fts5Tokenizer object | 13270 | ** argument passed to this function is a pointer to an Fts5Tokenizer object |
| 13191 | ** returned by an earlier call to xCreate(). | 13271 | ** returned by an earlier call to xCreate(). |
| 13192 | ** | 13272 | ** |
| 13193 | ** The second argument indicates the reason that FTS5 is requesting | 13273 | ** The third argument indicates the reason that FTS5 is requesting |
| 13194 | ** tokenization of the supplied text. This is always one of the following | 13274 | ** tokenization of the supplied text. This is always one of the following |
| 13195 | ** four values: | 13275 | ** four values: |
| 13196 | ** | 13276 | ** |
| @@ -13214,6 +13294,13 @@ struct Fts5ExtensionApi { | |||
| 13214 | ** on a columnsize=0 database. | 13294 | ** on a columnsize=0 database. |
| 13215 | ** </ul> | 13295 | ** </ul> |
| 13216 | ** | 13296 | ** |
| 13297 | ** The sixth and seventh arguments passed to xTokenize() - pLocale and | ||
| 13298 | ** nLocale - are a pointer to a buffer containing the locale to use for | ||
| 13299 | ** tokenization (e.g. "en_US") and its size in bytes, respectively. The | ||
| 13300 | ** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in | ||
| 13301 | ** which case nLocale is always 0) to indicate that the tokenizer should | ||
| 13302 | ** use its default locale. | ||
| 13303 | ** | ||
| 13217 | ** For each token in the input string, the supplied callback xToken() must | 13304 | ** For each token in the input string, the supplied callback xToken() must |
| 13218 | ** be invoked. The first argument to it should be a copy of the pointer | 13305 | ** be invoked. The first argument to it should be a copy of the pointer |
| 13219 | ** passed as the second argument to xTokenize(). The third and fourth | 13306 | ** passed as the second argument to xTokenize(). The third and fourth |
| @@ -13237,6 +13324,30 @@ struct Fts5ExtensionApi { | |||
| 13237 | ** may abandon the tokenization and return any error code other than | 13324 | ** may abandon the tokenization and return any error code other than |
| 13238 | ** SQLITE_OK or SQLITE_DONE. | 13325 | ** SQLITE_OK or SQLITE_DONE. |
| 13239 | ** | 13326 | ** |
| 13327 | ** If the tokenizer is registered using an fts5_tokenizer_v2 object, | ||
| 13328 | ** then the xTokenize() method has two additional arguments - pLocale | ||
| 13329 | ** and nLocale. These specify the locale that the tokenizer should use | ||
| 13330 | ** for the current request. If pLocale and nLocale are both 0, then the | ||
| 13331 | ** tokenizer should use its default locale. Otherwise, pLocale points to | ||
| 13332 | ** an nLocale byte buffer containing the name of the locale to use as utf-8 | ||
| 13333 | ** text. pLocale is not nul-terminated. | ||
| 13334 | ** | ||
| 13335 | ** FTS5_TOKENIZER | ||
| 13336 | ** | ||
| 13337 | ** There is also an fts5_tokenizer object. This is an older, deprecated, | ||
| 13338 | ** version of fts5_tokenizer_v2. It is similar except that: | ||
| 13339 | ** | ||
| 13340 | ** <ul> | ||
| 13341 | ** <li> There is no "iVersion" field, and | ||
| 13342 | ** <li> The xTokenize() method does not take a locale argument. | ||
| 13343 | ** </ul> | ||
| 13344 | ** | ||
| 13345 | ** Legacy fts5_tokenizer tokenizers must be registered using the | ||
| 13346 | ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). | ||
| 13347 | ** | ||
| 13348 | ** Tokenizer implementations registered using either API may be retrieved | ||
| 13349 | ** using both xFindTokenizer() and xFindTokenizer_v2(). | ||
| 13350 | ** | ||
| 13240 | ** SYNONYM SUPPORT | 13351 | ** SYNONYM SUPPORT |
| 13241 | ** | 13352 | ** |
| 13242 | ** Custom tokenizers may also support synonyms. Consider a case in which a | 13353 | ** Custom tokenizers may also support synonyms. Consider a case in which a |
| @@ -13345,6 +13456,33 @@ struct Fts5ExtensionApi { | |||
| 13345 | ** inefficient. | 13456 | ** inefficient. |
| 13346 | */ | 13457 | */ |
| 13347 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 13458 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| 13459 | typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; | ||
| 13460 | struct fts5_tokenizer_v2 { | ||
| 13461 | int iVersion; /* Currently always 2 */ | ||
| 13462 | |||
| 13463 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | ||
| 13464 | void (*xDelete)(Fts5Tokenizer*); | ||
| 13465 | int (*xTokenize)(Fts5Tokenizer*, | ||
| 13466 | void *pCtx, | ||
| 13467 | int flags, /* Mask of FTS5_TOKENIZE_* flags */ | ||
| 13468 | const char *pText, int nText, | ||
| 13469 | const char *pLocale, int nLocale, | ||
| 13470 | int (*xToken)( | ||
| 13471 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ | ||
| 13472 | int tflags, /* Mask of FTS5_TOKEN_* flags */ | ||
| 13473 | const char *pToken, /* Pointer to buffer containing token */ | ||
| 13474 | int nToken, /* Size of token in bytes */ | ||
| 13475 | int iStart, /* Byte offset of token within input text */ | ||
| 13476 | int iEnd /* Byte offset of end of token within input text */ | ||
| 13477 | ) | ||
| 13478 | ); | ||
| 13479 | }; | ||
| 13480 | |||
| 13481 | /* | ||
| 13482 | ** New code should use the fts5_tokenizer_v2 type to define tokenizer | ||
| 13483 | ** implementations. The following type is included for legacy applications | ||
| 13484 | ** that still use it. | ||
| 13485 | */ | ||
| 13348 | typedef struct fts5_tokenizer fts5_tokenizer; | 13486 | typedef struct fts5_tokenizer fts5_tokenizer; |
| 13349 | struct fts5_tokenizer { | 13487 | struct fts5_tokenizer { |
| 13350 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); | 13488 | int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); |
| @@ -13364,6 +13502,7 @@ struct fts5_tokenizer { | |||
| 13364 | ); | 13502 | ); |
| 13365 | }; | 13503 | }; |
| 13366 | 13504 | ||
| 13505 | |||
| 13367 | /* Flags that may be passed as the third argument to xTokenize() */ | 13506 | /* Flags that may be passed as the third argument to xTokenize() */ |
| 13368 | #define FTS5_TOKENIZE_QUERY 0x0001 | 13507 | #define FTS5_TOKENIZE_QUERY 0x0001 |
| 13369 | #define FTS5_TOKENIZE_PREFIX 0x0002 | 13508 | #define FTS5_TOKENIZE_PREFIX 0x0002 |
| @@ -13383,7 +13522,7 @@ struct fts5_tokenizer { | |||
| 13383 | */ | 13522 | */ |
| 13384 | typedef struct fts5_api fts5_api; | 13523 | typedef struct fts5_api fts5_api; |
| 13385 | struct fts5_api { | 13524 | struct fts5_api { |
| 13386 | int iVersion; /* Currently always set to 2 */ | 13525 | int iVersion; /* Currently always set to 3 */ |
| 13387 | 13526 | ||
| 13388 | /* Create a new tokenizer */ | 13527 | /* Create a new tokenizer */ |
| 13389 | int (*xCreateTokenizer)( | 13528 | int (*xCreateTokenizer)( |
| @@ -13410,6 +13549,25 @@ struct fts5_api { | |||
| 13410 | fts5_extension_function xFunction, | 13549 | fts5_extension_function xFunction, |
| 13411 | void (*xDestroy)(void*) | 13550 | void (*xDestroy)(void*) |
| 13412 | ); | 13551 | ); |
| 13552 | |||
| 13553 | /* APIs below this point are only available if iVersion>=3 */ | ||
| 13554 | |||
| 13555 | /* Create a new tokenizer */ | ||
| 13556 | int (*xCreateTokenizer_v2)( | ||
| 13557 | fts5_api *pApi, | ||
| 13558 | const char *zName, | ||
| 13559 | void *pUserData, | ||
| 13560 | fts5_tokenizer_v2 *pTokenizer, | ||
| 13561 | void (*xDestroy)(void*) | ||
| 13562 | ); | ||
| 13563 | |||
| 13564 | /* Find an existing tokenizer */ | ||
| 13565 | int (*xFindTokenizer_v2)( | ||
| 13566 | fts5_api *pApi, | ||
| 13567 | const char *zName, | ||
| 13568 | void **ppUserData, | ||
| 13569 | fts5_tokenizer_v2 **ppTokenizer | ||
| 13570 | ); | ||
| 13413 | }; | 13571 | }; |
| 13414 | 13572 | ||
| 13415 | /* | 13573 | /* |