diff options
| author | 2024-09-07 21:21:21 +0200 | |
|---|---|---|
| committer | 2024-09-07 21:21:21 +0200 | |
| commit | 7e4261acbd30477536cd429623f257c3408212b7 (patch) | |
| tree | 476b2a810cdbbc349a57873da9a590d0d84326ea /c/sqlite3.c | |
| parent | readme: link the demo repository (diff) | |
| download | zig-sqlite-7e4261acbd30477536cd429623f257c3408212b7.tar.gz zig-sqlite-7e4261acbd30477536cd429623f257c3408212b7.tar.xz zig-sqlite-7e4261acbd30477536cd429623f257c3408212b7.zip | |
update sqlite
Diffstat (limited to 'c/sqlite3.c')
| -rw-r--r-- | c/sqlite3.c | 17180 |
1 files changed, 11124 insertions, 6056 deletions
diff --git a/c/sqlite3.c b/c/sqlite3.c index 8f9309a..946815f 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.44.0. By combining all the individual C code files into this | 3 | ** version 3.46.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 | ** 17129ba1ff7f0daf37100ee82d507aef7827. | 21 | ** c9c2ab54ba1f5f46360f1b4f35d849cd3f08. |
| 22 | */ | 22 | */ |
| 23 | #define SQLITE_CORE 1 | 23 | #define SQLITE_CORE 1 |
| 24 | #define SQLITE_AMALGAMATION 1 | 24 | #define SQLITE_AMALGAMATION 1 |
| @@ -459,9 +459,9 @@ extern "C" { | |||
| 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 460 | ** [sqlite_version()] and [sqlite_source_id()]. | 460 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 461 | */ | 461 | */ |
| 462 | #define SQLITE_VERSION "3.44.0" | 462 | #define SQLITE_VERSION "3.46.1" |
| 463 | #define SQLITE_VERSION_NUMBER 3044000 | 463 | #define SQLITE_VERSION_NUMBER 3046001 |
| 464 | #define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" | 464 | #define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" |
| 465 | 465 | ||
| 466 | /* | 466 | /* |
| 467 | ** CAPI3REF: Run-Time Library Version Numbers | 467 | ** CAPI3REF: Run-Time Library Version Numbers |
| @@ -733,6 +733,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); | |||
| 733 | ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. | 733 | ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. |
| 734 | ** <li> The application must not modify the SQL statement text passed into | 734 | ** <li> The application must not modify the SQL statement text passed into |
| 735 | ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. | 735 | ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. |
| 736 | ** <li> The application must not dereference the arrays or string pointers | ||
| 737 | ** passed as the 3rd and 4th callback parameters after it returns. | ||
| 736 | ** </ul> | 738 | ** </ul> |
| 737 | */ | 739 | */ |
| 738 | SQLITE_API int sqlite3_exec( | 740 | SQLITE_API int sqlite3_exec( |
| @@ -1075,11 +1077,11 @@ struct sqlite3_file { | |||
| 1075 | ** </ul> | 1077 | ** </ul> |
| 1076 | ** xLock() upgrades the database file lock. In other words, xLock() moves the | 1078 | ** xLock() upgrades the database file lock. In other words, xLock() moves the |
| 1077 | ** database file lock in the direction NONE toward EXCLUSIVE. The argument to | 1079 | ** database file lock in the direction NONE toward EXCLUSIVE. The argument to |
| 1078 | ** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never | 1080 | ** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never |
| 1079 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the | 1081 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the |
| 1080 | ** requested lock, then the call to xLock() is a no-op. | 1082 | ** requested lock, then the call to xLock() is a no-op. |
| 1081 | ** xUnlock() downgrades the database file lock to either SHARED or NONE. | 1083 | ** xUnlock() downgrades the database file lock to either SHARED or NONE. |
| 1082 | * If the lock is already at or below the requested lock state, then the call | 1084 | ** If the lock is already at or below the requested lock state, then the call |
| 1083 | ** to xUnlock() is a no-op. | 1085 | ** to xUnlock() is a no-op. |
| 1084 | ** The xCheckReservedLock() method checks whether any database connection, | 1086 | ** The xCheckReservedLock() method checks whether any database connection, |
| 1085 | ** either in this process or in some other process, is holding a RESERVED, | 1087 | ** either in this process or in some other process, is holding a RESERVED, |
| @@ -2454,6 +2456,22 @@ struct sqlite3_mem_methods { | |||
| 2454 | ** configuration setting is never used, then the default maximum is determined | 2456 | ** configuration setting is never used, then the default maximum is determined |
| 2455 | ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that | 2457 | ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that |
| 2456 | ** compile-time option is not set, then the default maximum is 1073741824. | 2458 | ** compile-time option is not set, then the default maximum is 1073741824. |
| 2459 | ** | ||
| 2460 | ** [[SQLITE_CONFIG_ROWID_IN_VIEW]] | ||
| 2461 | ** <dt>SQLITE_CONFIG_ROWID_IN_VIEW | ||
| 2462 | ** <dd>The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability | ||
| 2463 | ** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is | ||
| 2464 | ** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability | ||
| 2465 | ** defaults to on. This configuration option queries the current setting or | ||
| 2466 | ** changes the setting to off or on. The argument is a pointer to an integer. | ||
| 2467 | ** If that integer initially holds a value of 1, then the ability for VIEWs to | ||
| 2468 | ** have ROWIDs is activated. If the integer initially holds zero, then the | ||
| 2469 | ** ability is deactivated. Any other initial value for the integer leaves the | ||
| 2470 | ** setting unchanged. After changes, if any, the integer is written with | ||
| 2471 | ** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite | ||
| 2472 | ** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and | ||
| 2473 | ** recommended case) then the integer is always filled with zero, regardless | ||
| 2474 | ** if its initial value. | ||
| 2457 | ** </dl> | 2475 | ** </dl> |
| 2458 | */ | 2476 | */ |
| 2459 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ | 2477 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| @@ -2485,6 +2503,7 @@ struct sqlite3_mem_methods { | |||
| 2485 | #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ | 2503 | #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ |
| 2486 | #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ | 2504 | #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ |
| 2487 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ | 2505 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ |
| 2506 | #define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ | ||
| 2488 | 2507 | ||
| 2489 | /* | 2508 | /* |
| 2490 | ** CAPI3REF: Database Connection Configuration Options | 2509 | ** CAPI3REF: Database Connection Configuration Options |
| @@ -3599,8 +3618,8 @@ SQLITE_API int sqlite3_set_authorizer( | |||
| 3599 | #define SQLITE_RECURSIVE 33 /* NULL NULL */ | 3618 | #define SQLITE_RECURSIVE 33 /* NULL NULL */ |
| 3600 | 3619 | ||
| 3601 | /* | 3620 | /* |
| 3602 | ** CAPI3REF: Tracing And Profiling Functions | 3621 | ** CAPI3REF: Deprecated Tracing And Profiling Functions |
| 3603 | ** METHOD: sqlite3 | 3622 | ** DEPRECATED |
| 3604 | ** | 3623 | ** |
| 3605 | ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface | 3624 | ** These routines are deprecated. Use the [sqlite3_trace_v2()] interface |
| 3606 | ** instead of the routines described here. | 3625 | ** instead of the routines described here. |
| @@ -4267,15 +4286,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); | |||
| 4267 | ** </ul> | 4286 | ** </ul> |
| 4268 | ** | 4287 | ** |
| 4269 | ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language | 4288 | ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language |
| 4270 | ** text that describes the error, as either UTF-8 or UTF-16 respectively. | 4289 | ** text that describes the error, as either UTF-8 or UTF-16 respectively, |
| 4290 | ** or NULL if no error message is available. | ||
| 4271 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) | 4291 | ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) |
| 4272 | ** ^(Memory to hold the error message string is managed internally. | 4292 | ** ^(Memory to hold the error message string is managed internally. |
| 4273 | ** The application does not need to worry about freeing the result. | 4293 | ** The application does not need to worry about freeing the result. |
| 4274 | ** However, the error string might be overwritten or deallocated by | 4294 | ** However, the error string might be overwritten or deallocated by |
| 4275 | ** subsequent calls to other SQLite interface functions.)^ | 4295 | ** subsequent calls to other SQLite interface functions.)^ |
| 4276 | ** | 4296 | ** |
| 4277 | ** ^The sqlite3_errstr() interface returns the English-language text | 4297 | ** ^The sqlite3_errstr(E) interface returns the English-language text |
| 4278 | ** that describes the [result code], as UTF-8. | 4298 | ** that describes the [result code] E, as UTF-8, or NULL if E is not an |
| 4299 | ** result code for which a text error message is available. | ||
| 4279 | ** ^(Memory to hold the error message string is managed internally | 4300 | ** ^(Memory to hold the error message string is managed internally |
| 4280 | ** and must not be freed by the application)^. | 4301 | ** and must not be freed by the application)^. |
| 4281 | ** | 4302 | ** |
| @@ -5886,13 +5907,27 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5886 | ** </dd> | 5907 | ** </dd> |
| 5887 | ** | 5908 | ** |
| 5888 | ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> | 5909 | ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> |
| 5889 | ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call | 5910 | ** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call |
| 5890 | ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. | 5911 | ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. |
| 5891 | ** Specifying this flag makes no difference for scalar or aggregate user | 5912 | ** This flag instructs SQLite to omit some corner-case optimizations that |
| 5892 | ** functions. However, if it is not specified for a user-defined window | 5913 | ** might disrupt the operation of the [sqlite3_value_subtype()] function, |
| 5893 | ** function, then any sub-types belonging to arguments passed to the window | 5914 | ** causing it to return zero rather than the correct subtype(). |
| 5894 | ** function may be discarded before the window function is called (i.e. | 5915 | ** SQL functions that invokes [sqlite3_value_subtype()] should have this |
| 5895 | ** sqlite3_value_subtype() will always return 0). | 5916 | ** property. If the SQLITE_SUBTYPE property is omitted, then the return |
| 5917 | ** value from [sqlite3_value_subtype()] might sometimes be zero even though | ||
| 5918 | ** a non-zero subtype was specified by the function argument expression. | ||
| 5919 | ** | ||
| 5920 | ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> | ||
| 5921 | ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call | ||
| 5922 | ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its | ||
| 5923 | ** result. | ||
| 5924 | ** Every function that invokes [sqlite3_result_subtype()] should have this | ||
| 5925 | ** property. If it does not, then the call to [sqlite3_result_subtype()] | ||
| 5926 | ** might become a no-op if the function is used as term in an | ||
| 5927 | ** [expression index]. On the other hand, SQL functions that never invoke | ||
| 5928 | ** [sqlite3_result_subtype()] should avoid setting this property, as the | ||
| 5929 | ** purpose of this property is to disable certain optimizations that are | ||
| 5930 | ** incompatible with subtypes. | ||
| 5896 | ** </dd> | 5931 | ** </dd> |
| 5897 | ** </dl> | 5932 | ** </dl> |
| 5898 | */ | 5933 | */ |
| @@ -5900,6 +5935,7 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5900 | #define SQLITE_DIRECTONLY 0x000080000 | 5935 | #define SQLITE_DIRECTONLY 0x000080000 |
| 5901 | #define SQLITE_SUBTYPE 0x000100000 | 5936 | #define SQLITE_SUBTYPE 0x000100000 |
| 5902 | #define SQLITE_INNOCUOUS 0x000200000 | 5937 | #define SQLITE_INNOCUOUS 0x000200000 |
| 5938 | #define SQLITE_RESULT_SUBTYPE 0x001000000 | ||
| 5903 | 5939 | ||
| 5904 | /* | 5940 | /* |
| 5905 | ** CAPI3REF: Deprecated Functions | 5941 | ** CAPI3REF: Deprecated Functions |
| @@ -6096,6 +6132,12 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); | |||
| 6096 | ** information can be used to pass a limited amount of context from | 6132 | ** information can be used to pass a limited amount of context from |
| 6097 | ** one SQL function to another. Use the [sqlite3_result_subtype()] | 6133 | ** one SQL function to another. Use the [sqlite3_result_subtype()] |
| 6098 | ** routine to set the subtype for the return value of an SQL function. | 6134 | ** routine to set the subtype for the return value of an SQL function. |
| 6135 | ** | ||
| 6136 | ** Every [application-defined SQL function] that invoke this interface | ||
| 6137 | ** should include the [SQLITE_SUBTYPE] property in the text | ||
| 6138 | ** encoding argument when the function is [sqlite3_create_function|registered]. | ||
| 6139 | ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() | ||
| 6140 | ** might return zero instead of the upstream subtype in some corner cases. | ||
| 6099 | */ | 6141 | */ |
| 6100 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); | 6142 | SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); |
| 6101 | 6143 | ||
| @@ -6226,14 +6268,22 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); | |||
| 6226 | ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same | 6268 | ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same |
| 6227 | ** parameter)^, or | 6269 | ** parameter)^, or |
| 6228 | ** <li> ^(during the original sqlite3_set_auxdata() call when a memory | 6270 | ** <li> ^(during the original sqlite3_set_auxdata() call when a memory |
| 6229 | ** allocation error occurs.)^ </ul> | 6271 | ** allocation error occurs.)^ |
| 6272 | ** <li> ^(during the original sqlite3_set_auxdata() call if the function | ||
| 6273 | ** is evaluated during query planning instead of during query execution, | ||
| 6274 | ** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul> | ||
| 6230 | ** | 6275 | ** |
| 6231 | ** Note the last bullet in particular. The destructor X in | 6276 | ** Note the last two bullets in particular. The destructor X in |
| 6232 | ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the | 6277 | ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the |
| 6233 | ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() | 6278 | ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() |
| 6234 | ** should be called near the end of the function implementation and the | 6279 | ** should be called near the end of the function implementation and the |
| 6235 | ** function implementation should not make any use of P after | 6280 | ** function implementation should not make any use of P after |
| 6236 | ** sqlite3_set_auxdata() has been called. | 6281 | ** sqlite3_set_auxdata() has been called. Furthermore, a call to |
| 6282 | ** sqlite3_get_auxdata() that occurs immediately after a corresponding call | ||
| 6283 | ** to sqlite3_set_auxdata() might still return NULL if an out-of-memory | ||
| 6284 | ** condition occurred during the sqlite3_set_auxdata() call or if the | ||
| 6285 | ** function is being evaluated during query planning rather than during | ||
| 6286 | ** query execution. | ||
| 6237 | ** | 6287 | ** |
| 6238 | ** ^(In practice, auxiliary data is preserved between function calls for | 6288 | ** ^(In practice, auxiliary data is preserved between function calls for |
| 6239 | ** function parameters that are compile-time constants, including literal | 6289 | ** function parameters that are compile-time constants, including literal |
| @@ -6507,6 +6557,20 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); | |||
| 6507 | ** higher order bits are discarded. | 6557 | ** higher order bits are discarded. |
| 6508 | ** The number of subtype bytes preserved by SQLite might increase | 6558 | ** The number of subtype bytes preserved by SQLite might increase |
| 6509 | ** in future releases of SQLite. | 6559 | ** in future releases of SQLite. |
| 6560 | ** | ||
| 6561 | ** Every [application-defined SQL function] that invokes this interface | ||
| 6562 | ** should include the [SQLITE_RESULT_SUBTYPE] property in its | ||
| 6563 | ** text encoding argument when the SQL function is | ||
| 6564 | ** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] | ||
| 6565 | ** property is omitted from the function that invokes sqlite3_result_subtype(), | ||
| 6566 | ** then in some cases the sqlite3_result_subtype() might fail to set | ||
| 6567 | ** the result subtype. | ||
| 6568 | ** | ||
| 6569 | ** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any | ||
| 6570 | ** SQL function that invokes the sqlite3_result_subtype() interface | ||
| 6571 | ** and that does not have the SQLITE_RESULT_SUBTYPE property will raise | ||
| 6572 | ** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 | ||
| 6573 | ** by default. | ||
| 6510 | */ | 6574 | */ |
| 6511 | SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); | 6575 | SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); |
| 6512 | 6576 | ||
| @@ -7136,6 +7200,12 @@ SQLITE_API int sqlite3_autovacuum_pages( | |||
| 7136 | ** The exceptions defined in this paragraph might change in a future | 7200 | ** The exceptions defined in this paragraph might change in a future |
| 7137 | ** release of SQLite. | 7201 | ** release of SQLite. |
| 7138 | ** | 7202 | ** |
| 7203 | ** Whether the update hook is invoked before or after the | ||
| 7204 | ** corresponding change is currently unspecified and may differ | ||
| 7205 | ** depending on the type of change. Do not rely on the order of the | ||
| 7206 | ** hook call with regards to the final result of the operation which | ||
| 7207 | ** triggers the hook. | ||
| 7208 | ** | ||
| 7139 | ** The update hook implementation must not do anything that will modify | 7209 | ** The update hook implementation must not do anything that will modify |
| 7140 | ** the database connection that invoked the update hook. Any actions | 7210 | ** the database connection that invoked the update hook. Any actions |
| 7141 | ** to modify the database connection must be deferred until after the | 7211 | ** to modify the database connection must be deferred until after the |
| @@ -8307,9 +8377,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); | |||
| 8307 | ** | 8377 | ** |
| 8308 | ** ^(Some systems (for example, Windows 95) do not support the operation | 8378 | ** ^(Some systems (for example, Windows 95) do not support the operation |
| 8309 | ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() | 8379 | ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() |
| 8310 | ** will always return SQLITE_BUSY. The SQLite core only ever uses | 8380 | ** will always return SQLITE_BUSY. In most cases the SQLite core only uses |
| 8311 | ** sqlite3_mutex_try() as an optimization so this is acceptable | 8381 | ** sqlite3_mutex_try() as an optimization, so this is acceptable |
| 8312 | ** behavior.)^ | 8382 | ** behavior. The exceptions are unix builds that set the |
| 8383 | ** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working | ||
| 8384 | ** sqlite3_mutex_try() is required.)^ | ||
| 8313 | ** | 8385 | ** |
| 8314 | ** ^The sqlite3_mutex_leave() routine exits a mutex that was | 8386 | ** ^The sqlite3_mutex_leave() routine exits a mutex that was |
| 8315 | ** previously entered by the same thread. The behavior | 8387 | ** previously entered by the same thread. The behavior |
| @@ -8568,6 +8640,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8568 | #define SQLITE_TESTCTRL_ASSERT 12 | 8640 | #define SQLITE_TESTCTRL_ASSERT 12 |
| 8569 | #define SQLITE_TESTCTRL_ALWAYS 13 | 8641 | #define SQLITE_TESTCTRL_ALWAYS 13 |
| 8570 | #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ | 8642 | #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ |
| 8643 | #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 | ||
| 8571 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 | 8644 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 8572 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ | 8645 | #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ |
| 8573 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ | 8646 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ |
| @@ -8603,7 +8676,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8603 | ** The sqlite3_keyword_count() interface returns the number of distinct | 8676 | ** The sqlite3_keyword_count() interface returns the number of distinct |
| 8604 | ** keywords understood by SQLite. | 8677 | ** keywords understood by SQLite. |
| 8605 | ** | 8678 | ** |
| 8606 | ** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and | 8679 | ** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and |
| 8607 | ** makes *Z point to that keyword expressed as UTF8 and writes the number | 8680 | ** makes *Z point to that keyword expressed as UTF8 and writes the number |
| 8608 | ** of bytes in the keyword into *L. The string that *Z points to is not | 8681 | ** of bytes in the keyword into *L. The string that *Z points to is not |
| 8609 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns | 8682 | ** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns |
| @@ -10182,24 +10255,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); | |||
| 10182 | ** <li value="2"><p> | 10255 | ** <li value="2"><p> |
| 10183 | ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means | 10256 | ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means |
| 10184 | ** that the query planner does not need the rows returned in any particular | 10257 | ** that the query planner does not need the rows returned in any particular |
| 10185 | ** order, as long as rows with the same values in all "aOrderBy" columns | 10258 | ** order, as long as rows with the same values in all columns identified |
| 10186 | ** are adjacent.)^ ^(Furthermore, only a single row for each particular | 10259 | ** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows |
| 10187 | ** combination of values in the columns identified by the "aOrderBy" field | 10260 | ** contain the same values for all columns identified by "colUsed", all but |
| 10188 | ** needs to be returned.)^ ^It is always ok for two or more rows with the same | 10261 | ** one such row may optionally be omitted from the result.)^ |
| 10189 | ** values in all "aOrderBy" columns to be returned, as long as all such rows | 10262 | ** The virtual table is not required to omit rows that are duplicates |
| 10190 | ** are adjacent. ^The virtual table may, if it chooses, omit extra rows | 10263 | ** over the "colUsed" columns, but if the virtual table can do that without |
| 10191 | ** that have the same value for all columns identified by "aOrderBy". | 10264 | ** too much extra effort, it could potentially help the query to run faster. |
| 10192 | ** ^However omitting the extra rows is optional. | ||
| 10193 | ** This mode is used for a DISTINCT query. | 10265 | ** This mode is used for a DISTINCT query. |
| 10194 | ** <li value="3"><p> | 10266 | ** <li value="3"><p> |
| 10195 | ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means | 10267 | ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the |
| 10196 | ** that the query planner needs only distinct rows but it does need the | 10268 | ** virtual table must return rows in the order defined by "aOrderBy" as |
| 10197 | ** rows to be sorted.)^ ^The virtual table implementation is free to omit | 10269 | ** if the sqlite3_vtab_distinct() interface had returned 0. However if |
| 10198 | ** rows that are identical in all aOrderBy columns, if it wants to, but | 10270 | ** two or more rows in the result have the same values for all columns |
| 10199 | ** it is not required to omit any rows. This mode is used for queries | 10271 | ** identified by "colUsed", then all but one such row may optionally be |
| 10272 | ** omitted.)^ Like when the return value is 2, the virtual table | ||
| 10273 | ** is not required to omit rows that are duplicates over the "colUsed" | ||
| 10274 | ** columns, but if the virtual table can do that without | ||
| 10275 | ** too much extra effort, it could potentially help the query to run faster. | ||
| 10276 | ** This mode is used for queries | ||
| 10200 | ** that have both DISTINCT and ORDER BY clauses. | 10277 | ** that have both DISTINCT and ORDER BY clauses. |
| 10201 | ** </ol> | 10278 | ** </ol> |
| 10202 | ** | 10279 | ** |
| 10280 | ** <p>The following table summarizes the conditions under which the | ||
| 10281 | ** virtual table is allowed to set the "orderByConsumed" flag based on | ||
| 10282 | ** the value returned by sqlite3_vtab_distinct(). This table is a | ||
| 10283 | ** restatement of the previous four paragraphs: | ||
| 10284 | ** | ||
| 10285 | ** <table border=1 cellspacing=0 cellpadding=10 width="90%"> | ||
| 10286 | ** <tr> | ||
| 10287 | ** <td valign="top">sqlite3_vtab_distinct() return value | ||
| 10288 | ** <td valign="top">Rows are returned in aOrderBy order | ||
| 10289 | ** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent | ||
| 10290 | ** <td valign="top">Duplicates over all colUsed columns may be omitted | ||
| 10291 | ** <tr><td>0<td>yes<td>yes<td>no | ||
| 10292 | ** <tr><td>1<td>no<td>yes<td>no | ||
| 10293 | ** <tr><td>2<td>no<td>yes<td>yes | ||
| 10294 | ** <tr><td>3<td>yes<td>yes<td>yes | ||
| 10295 | ** </table> | ||
| 10296 | ** | ||
| 10203 | ** ^For the purposes of comparing virtual table output values to see if the | 10297 | ** ^For the purposes of comparing virtual table output values to see if the |
| 10204 | ** values are same value for sorting purposes, two NULL values are considered | 10298 | ** values are same value for sorting purposes, two NULL values are considered |
| 10205 | ** to be the same. In other words, the comparison operator is "IS" | 10299 | ** to be the same. In other words, the comparison operator is "IS" |
| @@ -12245,6 +12339,30 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c | |||
| 12245 | SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); | 12339 | SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); |
| 12246 | 12340 | ||
| 12247 | /* | 12341 | /* |
| 12342 | ** CAPI3REF: Add A Single Change To A Changegroup | ||
| 12343 | ** METHOD: sqlite3_changegroup | ||
| 12344 | ** | ||
| 12345 | ** This function adds the single change currently indicated by the iterator | ||
| 12346 | ** passed as the second argument to the changegroup object. The rules for | ||
| 12347 | ** adding the change are just as described for [sqlite3changegroup_add()]. | ||
| 12348 | ** | ||
| 12349 | ** If the change is successfully added to the changegroup, SQLITE_OK is | ||
| 12350 | ** returned. Otherwise, an SQLite error code is returned. | ||
| 12351 | ** | ||
| 12352 | ** The iterator must point to a valid entry when this function is called. | ||
| 12353 | ** If it does not, SQLITE_ERROR is returned and no change is added to the | ||
| 12354 | ** changegroup. Additionally, the iterator must not have been opened with | ||
| 12355 | ** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also | ||
| 12356 | ** returned. | ||
| 12357 | */ | ||
| 12358 | SQLITE_API int sqlite3changegroup_add_change( | ||
| 12359 | sqlite3_changegroup*, | ||
| 12360 | sqlite3_changeset_iter* | ||
| 12361 | ); | ||
| 12362 | |||
| 12363 | |||
| 12364 | |||
| 12365 | /* | ||
| 12248 | ** CAPI3REF: Obtain A Composite Changeset From A Changegroup | 12366 | ** CAPI3REF: Obtain A Composite Changeset From A Changegroup |
| 12249 | ** METHOD: sqlite3_changegroup | 12367 | ** METHOD: sqlite3_changegroup |
| 12250 | ** | 12368 | ** |
| @@ -13048,8 +13166,8 @@ struct Fts5PhraseIter { | |||
| 13048 | ** EXTENSION API FUNCTIONS | 13166 | ** EXTENSION API FUNCTIONS |
| 13049 | ** | 13167 | ** |
| 13050 | ** xUserData(pFts): | 13168 | ** xUserData(pFts): |
| 13051 | ** Return a copy of the context pointer the extension function was | 13169 | ** Return a copy of the pUserData pointer passed to the xCreateFunction() |
| 13052 | ** registered with. | 13170 | ** API when the extension function was registered. |
| 13053 | ** | 13171 | ** |
| 13054 | ** xColumnTotalSize(pFts, iCol, pnToken): | 13172 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 13055 | ** If parameter iCol is less than zero, set output variable *pnToken | 13173 | ** If parameter iCol is less than zero, set output variable *pnToken |
| @@ -13081,8 +13199,11 @@ struct Fts5PhraseIter { | |||
| 13081 | ** created with the "columnsize=0" option. | 13199 | ** created with the "columnsize=0" option. |
| 13082 | ** | 13200 | ** |
| 13083 | ** xColumnText: | 13201 | ** xColumnText: |
| 13084 | ** This function attempts to retrieve the text of column iCol of the | 13202 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 13085 | ** current document. If successful, (*pz) is set to point to a buffer | 13203 | ** number of columns in the table, SQLITE_RANGE is returned. |
| 13204 | ** | ||
| 13205 | ** Otherwise, this function attempts to retrieve the text of column iCol of | ||
| 13206 | ** the current document. If successful, (*pz) is set to point to a buffer | ||
| 13086 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes | 13207 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes |
| 13087 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, | 13208 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, |
| 13088 | ** if an error occurs, an SQLite error code is returned and the final values | 13209 | ** if an error occurs, an SQLite error code is returned and the final values |
| @@ -13092,8 +13213,10 @@ struct Fts5PhraseIter { | |||
| 13092 | ** Returns the number of phrases in the current query expression. | 13213 | ** Returns the number of phrases in the current query expression. |
| 13093 | ** | 13214 | ** |
| 13094 | ** xPhraseSize: | 13215 | ** xPhraseSize: |
| 13095 | ** Returns the number of tokens in phrase iPhrase of the query. Phrases | 13216 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 13096 | ** are numbered starting from zero. | 13217 | ** number of phrases in the current query, as returned by xPhraseCount, |
| 13218 | ** 0 is returned. Otherwise, this function returns the number of tokens in | ||
| 13219 | ** phrase iPhrase of the query. Phrases are numbered starting from zero. | ||
| 13097 | ** | 13220 | ** |
| 13098 | ** xInstCount: | 13221 | ** xInstCount: |
| 13099 | ** Set *pnInst to the total number of occurrences of all phrases within | 13222 | ** Set *pnInst to the total number of occurrences of all phrases within |
| @@ -13109,12 +13232,13 @@ struct Fts5PhraseIter { | |||
| 13109 | ** Query for the details of phrase match iIdx within the current row. | 13232 | ** Query for the details of phrase match iIdx within the current row. |
| 13110 | ** Phrase matches are numbered starting from zero, so the iIdx argument | 13233 | ** Phrase matches are numbered starting from zero, so the iIdx argument |
| 13111 | ** should be greater than or equal to zero and smaller than the value | 13234 | ** should be greater than or equal to zero and smaller than the value |
| 13112 | ** output by xInstCount(). | 13235 | ** output by xInstCount(). If iIdx is less than zero or greater than |
| 13236 | ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. | ||
| 13113 | ** | 13237 | ** |
| 13114 | ** Usually, output parameter *piPhrase is set to the phrase number, *piCol | 13238 | ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol |
| 13115 | ** to the column in which it occurs and *piOff the token offset of the | 13239 | ** to the column in which it occurs and *piOff the token offset of the |
| 13116 | ** first token of the phrase. Returns SQLITE_OK if successful, or an error | 13240 | ** first token of the phrase. SQLITE_OK is returned if successful, or an |
| 13117 | ** code (i.e. SQLITE_NOMEM) if an error occurs. | 13241 | ** error code (i.e. SQLITE_NOMEM) if an error occurs. |
| 13118 | ** | 13242 | ** |
| 13119 | ** This API can be quite slow if used with an FTS5 table created with the | 13243 | ** This API can be quite slow if used with an FTS5 table created with the |
| 13120 | ** "detail=none" or "detail=column" option. | 13244 | ** "detail=none" or "detail=column" option. |
| @@ -13140,6 +13264,10 @@ struct Fts5PhraseIter { | |||
| 13140 | ** Invoking Api.xUserData() returns a copy of the pointer passed as | 13264 | ** Invoking Api.xUserData() returns a copy of the pointer passed as |
| 13141 | ** the third argument to pUserData. | 13265 | ** the third argument to pUserData. |
| 13142 | ** | 13266 | ** |
| 13267 | ** If parameter iPhrase is less than zero, or greater than or equal to | ||
| 13268 | ** the number of phrases in the query, as returned by xPhraseCount(), | ||
| 13269 | ** this function returns SQLITE_RANGE. | ||
| 13270 | ** | ||
| 13143 | ** If the callback function returns any value other than SQLITE_OK, the | 13271 | ** If the callback function returns any value other than SQLITE_OK, the |
| 13144 | ** query is abandoned and the xQueryPhrase function returns immediately. | 13272 | ** query is abandoned and the xQueryPhrase function returns immediately. |
| 13145 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. | 13273 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. |
| @@ -13254,9 +13382,42 @@ struct Fts5PhraseIter { | |||
| 13254 | ** | 13382 | ** |
| 13255 | ** xPhraseNextColumn() | 13383 | ** xPhraseNextColumn() |
| 13256 | ** See xPhraseFirstColumn above. | 13384 | ** See xPhraseFirstColumn above. |
| 13385 | ** | ||
| 13386 | ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) | ||
| 13387 | ** This is used to access token iToken of phrase iPhrase of the current | ||
| 13388 | ** query. Before returning, output parameter *ppToken is set to point | ||
| 13389 | ** to a buffer containing the requested token, and *pnToken to the | ||
| 13390 | ** size of this buffer in bytes. | ||
| 13391 | ** | ||
| 13392 | ** If iPhrase or iToken are less than zero, or if iPhrase is greater than | ||
| 13393 | ** or equal to the number of phrases in the query as reported by | ||
| 13394 | ** xPhraseCount(), or if iToken is equal to or greater than the number of | ||
| 13395 | ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken | ||
| 13396 | are both zeroed. | ||
| 13397 | ** | ||
| 13398 | ** The output text is not a copy of the query text that specified the | ||
| 13399 | ** token. It is the output of the tokenizer module. For tokendata=1 | ||
| 13400 | ** tables, this includes any embedded 0x00 and trailing data. | ||
| 13401 | ** | ||
| 13402 | ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) | ||
| 13403 | ** This is used to access token iToken of phrase hit iIdx within the | ||
| 13404 | ** current row. If iIdx is less than zero or greater than or equal to the | ||
| 13405 | ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, | ||
| 13406 | ** output variable (*ppToken) is set to point to a buffer containing the | ||
| 13407 | ** matching document token, and (*pnToken) to the size of that buffer in | ||
| 13408 | ** bytes. This API is not available if the specified token matches a | ||
| 13409 | ** prefix query term. In that case both output variables are always set | ||
| 13410 | ** to 0. | ||
| 13411 | ** | ||
| 13412 | ** The output text is not a copy of the document text that was tokenized. | ||
| 13413 | ** It is the output of the tokenizer module. For tokendata=1 tables, this | ||
| 13414 | ** includes any embedded 0x00 and trailing data. | ||
| 13415 | ** | ||
| 13416 | ** This API can be quite slow if used with an FTS5 table created with the | ||
| 13417 | ** "detail=none" or "detail=column" option. | ||
| 13257 | */ | 13418 | */ |
| 13258 | struct Fts5ExtensionApi { | 13419 | struct Fts5ExtensionApi { |
| 13259 | int iVersion; /* Currently always set to 2 */ | 13420 | int iVersion; /* Currently always set to 3 */ |
| 13260 | 13421 | ||
| 13261 | void *(*xUserData)(Fts5Context*); | 13422 | void *(*xUserData)(Fts5Context*); |
| 13262 | 13423 | ||
| @@ -13291,6 +13452,13 @@ struct Fts5ExtensionApi { | |||
| 13291 | 13452 | ||
| 13292 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); | 13453 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); |
| 13293 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); | 13454 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); |
| 13455 | |||
| 13456 | /* Below this point are iVersion>=3 only */ | ||
| 13457 | int (*xQueryToken)(Fts5Context*, | ||
| 13458 | int iPhrase, int iToken, | ||
| 13459 | const char **ppToken, int *pnToken | ||
| 13460 | ); | ||
| 13461 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | ||
| 13294 | }; | 13462 | }; |
| 13295 | 13463 | ||
| 13296 | /* | 13464 | /* |
| @@ -13777,7 +13945,7 @@ struct fts5_api { | |||
| 13777 | ** max_page_count macro. | 13945 | ** max_page_count macro. |
| 13778 | */ | 13946 | */ |
| 13779 | #ifndef SQLITE_MAX_PAGE_COUNT | 13947 | #ifndef SQLITE_MAX_PAGE_COUNT |
| 13780 | # define SQLITE_MAX_PAGE_COUNT 1073741823 | 13948 | # define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */ |
| 13781 | #endif | 13949 | #endif |
| 13782 | 13950 | ||
| 13783 | /* | 13951 | /* |
| @@ -13917,6 +14085,19 @@ struct fts5_api { | |||
| 13917 | #endif | 14085 | #endif |
| 13918 | 14086 | ||
| 13919 | /* | 14087 | /* |
| 14088 | ** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly | ||
| 14089 | ** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0 | ||
| 14090 | */ | ||
| 14091 | #if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1 | ||
| 14092 | /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */ | ||
| 14093 | # undef SQLITE_DIRECT_OVERFLOW_READ | ||
| 14094 | #else | ||
| 14095 | /* In all other cases, enable */ | ||
| 14096 | # define SQLITE_DIRECT_OVERFLOW_READ 1 | ||
| 14097 | #endif | ||
| 14098 | |||
| 14099 | |||
| 14100 | /* | ||
| 13920 | ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. | 14101 | ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. |
| 13921 | ** 0 means mutexes are permanently disable and the library is never | 14102 | ** 0 means mutexes are permanently disable and the library is never |
| 13922 | ** threadsafe. 1 means the library is serialized which is the highest | 14103 | ** threadsafe. 1 means the library is serialized which is the highest |
| @@ -14184,6 +14365,8 @@ struct fts5_api { | |||
| 14184 | # define SQLITE_OMIT_ALTERTABLE | 14365 | # define SQLITE_OMIT_ALTERTABLE |
| 14185 | #endif | 14366 | #endif |
| 14186 | 14367 | ||
| 14368 | #define SQLITE_DIGIT_SEPARATOR '_' | ||
| 14369 | |||
| 14187 | /* | 14370 | /* |
| 14188 | ** Return true (non-zero) if the input is an integer that is too large | 14371 | ** Return true (non-zero) if the input is an integer that is too large |
| 14189 | ** to fit in 32-bits. This macro is used inside of various testcase() | 14372 | ** to fit in 32-bits. This macro is used inside of various testcase() |
| @@ -14476,8 +14659,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14476 | #define TK_TRUEFALSE 170 | 14659 | #define TK_TRUEFALSE 170 |
| 14477 | #define TK_ISNOT 171 | 14660 | #define TK_ISNOT 171 |
| 14478 | #define TK_FUNCTION 172 | 14661 | #define TK_FUNCTION 172 |
| 14479 | #define TK_UMINUS 173 | 14662 | #define TK_UPLUS 173 |
| 14480 | #define TK_UPLUS 174 | 14663 | #define TK_UMINUS 174 |
| 14481 | #define TK_TRUTH 175 | 14664 | #define TK_TRUTH 175 |
| 14482 | #define TK_REGISTER 176 | 14665 | #define TK_REGISTER 176 |
| 14483 | #define TK_VECTOR 177 | 14666 | #define TK_VECTOR 177 |
| @@ -14486,8 +14669,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); | |||
| 14486 | #define TK_ASTERISK 180 | 14669 | #define TK_ASTERISK 180 |
| 14487 | #define TK_SPAN 181 | 14670 | #define TK_SPAN 181 |
| 14488 | #define TK_ERROR 182 | 14671 | #define TK_ERROR 182 |
| 14489 | #define TK_SPACE 183 | 14672 | #define TK_QNUMBER 183 |
| 14490 | #define TK_ILLEGAL 184 | 14673 | #define TK_SPACE 184 |
| 14674 | #define TK_ILLEGAL 185 | ||
| 14491 | 14675 | ||
| 14492 | /************** End of parse.h ***********************************************/ | 14676 | /************** End of parse.h ***********************************************/ |
| 14493 | /************** Continuing where we left off in sqliteInt.h ******************/ | 14677 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| @@ -14749,7 +14933,7 @@ typedef INT16_TYPE LogEst; | |||
| 14749 | # define SQLITE_PTRSIZE __SIZEOF_POINTER__ | 14933 | # define SQLITE_PTRSIZE __SIZEOF_POINTER__ |
| 14750 | # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ | 14934 | # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 14751 | defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ | 14935 | defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ |
| 14752 | (defined(__APPLE__) && defined(__POWERPC__)) || \ | 14936 | (defined(__APPLE__) && defined(__ppc__)) || \ |
| 14753 | (defined(__TOS_AIX__) && !defined(__64BIT__)) | 14937 | (defined(__TOS_AIX__) && !defined(__64BIT__)) |
| 14754 | # define SQLITE_PTRSIZE 4 | 14938 | # define SQLITE_PTRSIZE 4 |
| 14755 | # else | 14939 | # else |
| @@ -14986,6 +15170,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace; | |||
| 14986 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing | 15170 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing |
| 14987 | ** 0x00020000 Transform DISTINCT into GROUP BY | 15171 | ** 0x00020000 Transform DISTINCT into GROUP BY |
| 14988 | ** 0x00040000 SELECT tree dump after all code has been generated | 15172 | ** 0x00040000 SELECT tree dump after all code has been generated |
| 15173 | ** 0x00080000 NOT NULL strength reduction | ||
| 14989 | */ | 15174 | */ |
| 14990 | 15175 | ||
| 14991 | /* | 15176 | /* |
| @@ -15016,7 +15201,7 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace; | |||
| 15016 | ** 0x00000010 Display sqlite3_index_info xBestIndex calls | 15201 | ** 0x00000010 Display sqlite3_index_info xBestIndex calls |
| 15017 | ** 0x00000020 Range an equality scan metrics | 15202 | ** 0x00000020 Range an equality scan metrics |
| 15018 | ** 0x00000040 IN operator decisions | 15203 | ** 0x00000040 IN operator decisions |
| 15019 | ** 0x00000080 WhereLoop cost adjustements | 15204 | ** 0x00000080 WhereLoop cost adjustments |
| 15020 | ** 0x00000100 | 15205 | ** 0x00000100 |
| 15021 | ** 0x00000200 Covering index decisions | 15206 | ** 0x00000200 Covering index decisions |
| 15022 | ** 0x00000400 OR optimization | 15207 | ** 0x00000400 OR optimization |
| @@ -15798,7 +15983,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); | |||
| 15798 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); | 15983 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); |
| 15799 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); | 15984 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); |
| 15800 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); | 15985 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); |
| 15801 | SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); | 15986 | SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*); |
| 15802 | SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); | 15987 | SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); |
| 15803 | SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); | 15988 | SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); |
| 15804 | 15989 | ||
| @@ -16165,6 +16350,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( | |||
| 16165 | sqlite3 *db, /* Database connection that is running the check */ | 16350 | sqlite3 *db, /* Database connection that is running the check */ |
| 16166 | Btree *p, /* The btree to be checked */ | 16351 | Btree *p, /* The btree to be checked */ |
| 16167 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ | 16352 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ |
| 16353 | sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */ | ||
| 16168 | int nRoot, /* Number of entries in aRoot[] */ | 16354 | int nRoot, /* Number of entries in aRoot[] */ |
| 16169 | int mxErr, /* Stop reporting errors after this many */ | 16355 | int mxErr, /* Stop reporting errors after this many */ |
| 16170 | int *pnErr, /* OUT: Write number of errors seen to this variable */ | 16356 | int *pnErr, /* OUT: Write number of errors seen to this variable */ |
| @@ -16385,6 +16571,7 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16385 | #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ | 16571 | #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ |
| 16386 | #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ | 16572 | #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ |
| 16387 | #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ | 16573 | #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ |
| 16574 | #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ | ||
| 16388 | 16575 | ||
| 16389 | /* Error message codes for OP_Halt */ | 16576 | /* Error message codes for OP_Halt */ |
| 16390 | #define P5_ConstraintNotNull 1 | 16577 | #define P5_ConstraintNotNull 1 |
| @@ -16434,12 +16621,12 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16434 | #define OP_Vacuum 5 | 16621 | #define OP_Vacuum 5 |
| 16435 | #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ | 16622 | #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ |
| 16436 | #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ | 16623 | #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ |
| 16437 | #define OP_Init 8 /* jump, synopsis: Start at P2 */ | 16624 | #define OP_Init 8 /* jump0, synopsis: Start at P2 */ |
| 16438 | #define OP_Goto 9 /* jump */ | 16625 | #define OP_Goto 9 /* jump */ |
| 16439 | #define OP_Gosub 10 /* jump */ | 16626 | #define OP_Gosub 10 /* jump */ |
| 16440 | #define OP_InitCoroutine 11 /* jump */ | 16627 | #define OP_InitCoroutine 11 /* jump0 */ |
| 16441 | #define OP_Yield 12 /* jump */ | 16628 | #define OP_Yield 12 /* jump0 */ |
| 16442 | #define OP_MustBeInt 13 /* jump */ | 16629 | #define OP_MustBeInt 13 /* jump0 */ |
| 16443 | #define OP_Jump 14 /* jump */ | 16630 | #define OP_Jump 14 /* jump */ |
| 16444 | #define OP_Once 15 /* jump */ | 16631 | #define OP_Once 15 /* jump */ |
| 16445 | #define OP_If 16 /* jump */ | 16632 | #define OP_If 16 /* jump */ |
| @@ -16447,22 +16634,22 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16447 | #define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ | 16634 | #define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ |
| 16448 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ | 16635 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| 16449 | #define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ | 16636 | #define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ |
| 16450 | #define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ | 16637 | #define OP_SeekLT 21 /* jump0, synopsis: key=r[P3@P4] */ |
| 16451 | #define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ | 16638 | #define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */ |
| 16452 | #define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ | 16639 | #define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */ |
| 16453 | #define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ | 16640 | #define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */ |
| 16454 | #define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ | 16641 | #define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ |
| 16455 | #define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ | 16642 | #define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ |
| 16456 | #define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ | 16643 | #define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ |
| 16457 | #define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ | 16644 | #define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ |
| 16458 | #define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ | 16645 | #define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ |
| 16459 | #define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ | 16646 | #define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */ |
| 16460 | #define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ | 16647 | #define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ |
| 16461 | #define OP_Last 32 /* jump */ | 16648 | #define OP_Last 32 /* jump0 */ |
| 16462 | #define OP_IfSmaller 33 /* jump */ | 16649 | #define OP_IfSizeBetween 33 /* jump */ |
| 16463 | #define OP_SorterSort 34 /* jump */ | 16650 | #define OP_SorterSort 34 /* jump */ |
| 16464 | #define OP_Sort 35 /* jump */ | 16651 | #define OP_Sort 35 /* jump */ |
| 16465 | #define OP_Rewind 36 /* jump */ | 16652 | #define OP_Rewind 36 /* jump0 */ |
| 16466 | #define OP_SorterNext 37 /* jump */ | 16653 | #define OP_SorterNext 37 /* jump */ |
| 16467 | #define OP_Prev 38 /* jump */ | 16654 | #define OP_Prev 38 /* jump */ |
| 16468 | #define OP_Next 39 /* jump */ | 16655 | #define OP_Next 39 /* jump */ |
| @@ -16474,7 +16661,7 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16474 | #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ | 16661 | #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ |
| 16475 | #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ | 16662 | #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 16476 | #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ | 16663 | #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 16477 | #define OP_Program 48 /* jump */ | 16664 | #define OP_Program 48 /* jump0 */ |
| 16478 | #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ | 16665 | #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 16479 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ | 16666 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 16480 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ | 16667 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| @@ -16504,7 +16691,7 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16504 | #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ | 16691 | #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */ |
| 16505 | #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ | 16692 | #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */ |
| 16506 | #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ | 16693 | #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */ |
| 16507 | #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */ | 16694 | #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1) */ |
| 16508 | #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ | 16695 | #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 16509 | #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ | 16696 | #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ |
| 16510 | #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ | 16697 | #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */ |
| @@ -16607,13 +16794,15 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16607 | #define OP_Pagecount 178 | 16794 | #define OP_Pagecount 178 |
| 16608 | #define OP_MaxPgcnt 179 | 16795 | #define OP_MaxPgcnt 179 |
| 16609 | #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ | 16796 | #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ |
| 16610 | #define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ | 16797 | #define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */ |
| 16611 | #define OP_Trace 182 | 16798 | #define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */ |
| 16612 | #define OP_CursorHint 183 | 16799 | #define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ |
| 16613 | #define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ | 16800 | #define OP_Trace 184 |
| 16614 | #define OP_Noop 185 | 16801 | #define OP_CursorHint 185 |
| 16615 | #define OP_Explain 186 | 16802 | #define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ |
| 16616 | #define OP_Abortable 187 | 16803 | #define OP_Noop 187 |
| 16804 | #define OP_Explain 188 | ||
| 16805 | #define OP_Abortable 189 | ||
| 16617 | 16806 | ||
| 16618 | /* Properties such as "out2" or "jump" that are specified in | 16807 | /* Properties such as "out2" or "jump" that are specified in |
| 16619 | ** comments following the "case" for each opcode in the vdbe.c | 16808 | ** comments following the "case" for each opcode in the vdbe.c |
| @@ -16626,14 +16815,15 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16626 | #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ | 16815 | #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ |
| 16627 | #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ | 16816 | #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ |
| 16628 | #define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ | 16817 | #define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ |
| 16818 | #define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */ | ||
| 16629 | #define OPFLG_INITIALIZER {\ | 16819 | #define OPFLG_INITIALIZER {\ |
| 16630 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ | 16820 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ |
| 16631 | /* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ | 16821 | /* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ |
| 16632 | /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\ | 16822 | /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ |
| 16633 | /* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\ | 16823 | /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ |
| 16634 | /* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\ | 16824 | /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ |
| 16635 | /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ | 16825 | /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ |
| 16636 | /* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ | 16826 | /* 48 */ 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ |
| 16637 | /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ | 16827 | /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ |
| 16638 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ | 16828 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ |
| 16639 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ | 16829 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ |
| @@ -16649,8 +16839,8 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 16649 | /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ | 16839 | /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ |
| 16650 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ | 16840 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 16651 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ | 16841 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ |
| 16652 | /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ | 16842 | /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ |
| 16653 | /* 184 */ 0x00, 0x00, 0x00, 0x00,} | 16843 | /* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} |
| 16654 | 16844 | ||
| 16655 | /* The resolve3P2Values() routine is able to run faster if it knows | 16845 | /* The resolve3P2Values() routine is able to run faster if it knows |
| 16656 | ** the value of the largest JUMP opcode. The smaller the maximum | 16846 | ** the value of the largest JUMP opcode. The smaller the maximum |
| @@ -16793,6 +16983,8 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); | |||
| 16793 | SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); | 16983 | SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); |
| 16794 | SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); | 16984 | SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); |
| 16795 | 16985 | ||
| 16986 | SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); | ||
| 16987 | |||
| 16796 | SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); | 16988 | SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); |
| 16797 | #ifdef SQLITE_ENABLE_BYTECODE_VTAB | 16989 | #ifdef SQLITE_ENABLE_BYTECODE_VTAB |
| 16798 | SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); | 16990 | SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); |
| @@ -17380,6 +17572,10 @@ struct FuncDefHash { | |||
| 17380 | }; | 17572 | }; |
| 17381 | #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) | 17573 | #define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) |
| 17382 | 17574 | ||
| 17575 | #if defined(SQLITE_USER_AUTHENTICATION) | ||
| 17576 | # warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \ | ||
| 17577 | See ext/userauth/user-auth.txt for details." | ||
| 17578 | #endif | ||
| 17383 | #ifdef SQLITE_USER_AUTHENTICATION | 17579 | #ifdef SQLITE_USER_AUTHENTICATION |
| 17384 | /* | 17580 | /* |
| 17385 | ** Information held in the "sqlite3" database connection object and used | 17581 | ** Information held in the "sqlite3" database connection object and used |
| @@ -17683,7 +17879,7 @@ struct sqlite3 { | |||
| 17683 | #define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ | 17879 | #define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ |
| 17684 | #define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ | 17880 | #define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ |
| 17685 | /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ | 17881 | /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ |
| 17686 | #define SQLITE_PushDown 0x00001000 /* The push-down optimization */ | 17882 | #define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */ |
| 17687 | #define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ | 17883 | #define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ |
| 17688 | #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ | 17884 | #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ |
| 17689 | #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ | 17885 | #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ |
| @@ -17811,14 +18007,15 @@ struct FuncDestructor { | |||
| 17811 | #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a | 18007 | #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a |
| 17812 | ** single query - might change over time */ | 18008 | ** single query - might change over time */ |
| 17813 | #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ | 18009 | #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ |
| 17814 | /* 0x8000 -- available for reuse */ | 18010 | #define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */ |
| 17815 | #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ | 18011 | #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ |
| 17816 | #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ | 18012 | #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ |
| 17817 | #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ | 18013 | #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ |
| 17818 | #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ | 18014 | /* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */ |
| 17819 | #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ | 18015 | #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ |
| 17820 | #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ | 18016 | #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ |
| 17821 | #define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ | 18017 | #define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ |
| 18018 | /* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */ | ||
| 17822 | #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ | 18019 | #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ |
| 17823 | 18020 | ||
| 17824 | /* Identifier numbers for each in-line function */ | 18021 | /* Identifier numbers for each in-line function */ |
| @@ -17910,10 +18107,11 @@ struct FuncDestructor { | |||
| 17910 | #define MFUNCTION(zName, nArg, xPtr, xFunc) \ | 18107 | #define MFUNCTION(zName, nArg, xPtr, xFunc) \ |
| 17911 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ | 18108 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ |
| 17912 | xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } | 18109 | xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } |
| 17913 | #define JFUNCTION(zName, nArg, iArg, xFunc) \ | 18110 | #define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \ |
| 17914 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ | 18111 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ |
| 17915 | SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ | 18112 | SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ |
| 17916 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } | 18113 | ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ |
| 18114 | SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} } | ||
| 17917 | #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ | 18115 | #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ |
| 17918 | {nArg, SQLITE_FUNC_BUILTIN|\ | 18116 | {nArg, SQLITE_FUNC_BUILTIN|\ |
| 17919 | SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ | 18117 | SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ |
| @@ -18254,8 +18452,7 @@ struct Table { | |||
| 18254 | #define TF_HasStored 0x00000040 /* Has one or more STORED columns */ | 18452 | #define TF_HasStored 0x00000040 /* Has one or more STORED columns */ |
| 18255 | #define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ | 18453 | #define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ |
| 18256 | #define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ | 18454 | #define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ |
| 18257 | #define TF_StatsUsed 0x00000100 /* Query planner decisions affected by | 18455 | #define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */ |
| 18258 | ** Index.aiRowLogEst[] values */ | ||
| 18259 | #define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ | 18456 | #define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ |
| 18260 | #define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ | 18457 | #define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ |
| 18261 | #define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ | 18458 | #define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ |
| @@ -18311,6 +18508,15 @@ struct Table { | |||
| 18311 | #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) | 18508 | #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) |
| 18312 | #define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) | 18509 | #define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) |
| 18313 | 18510 | ||
| 18511 | /* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is | ||
| 18512 | ** available. By default, this macro is false | ||
| 18513 | */ | ||
| 18514 | #ifndef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 18515 | # define ViewCanHaveRowid 0 | ||
| 18516 | #else | ||
| 18517 | # define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0) | ||
| 18518 | #endif | ||
| 18519 | |||
| 18314 | /* | 18520 | /* |
| 18315 | ** Each foreign key constraint is an instance of the following structure. | 18521 | ** Each foreign key constraint is an instance of the following structure. |
| 18316 | ** | 18522 | ** |
| @@ -18548,6 +18754,7 @@ struct Index { | |||
| 18548 | unsigned isCovering:1; /* True if this is a covering index */ | 18754 | unsigned isCovering:1; /* True if this is a covering index */ |
| 18549 | unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ | 18755 | unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ |
| 18550 | unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ | 18756 | unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ |
| 18757 | unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ | ||
| 18551 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ | 18758 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ |
| 18552 | unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ | 18759 | unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ |
| 18553 | unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ | 18760 | unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ |
| @@ -18661,6 +18868,7 @@ struct AggInfo { | |||
| 18661 | int iOBTab; /* Ephemeral table to implement ORDER BY */ | 18868 | int iOBTab; /* Ephemeral table to implement ORDER BY */ |
| 18662 | u8 bOBPayload; /* iOBTab has payload columns separate from key */ | 18869 | u8 bOBPayload; /* iOBTab has payload columns separate from key */ |
| 18663 | u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ | 18870 | u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ |
| 18871 | u8 bUseSubtype; /* Transfer subtype info through sorter */ | ||
| 18664 | } *aFunc; | 18872 | } *aFunc; |
| 18665 | int nFunc; /* Number of entries in aFunc[] */ | 18873 | int nFunc; /* Number of entries in aFunc[] */ |
| 18666 | u32 selId; /* Select to which this AggInfo belongs */ | 18874 | u32 selId; /* Select to which this AggInfo belongs */ |
| @@ -19044,10 +19252,12 @@ struct IdList { | |||
| 19044 | ** | 19252 | ** |
| 19045 | ** Union member validity: | 19253 | ** Union member validity: |
| 19046 | ** | 19254 | ** |
| 19047 | ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc | 19255 | ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc |
| 19048 | ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy | 19256 | ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy |
| 19049 | ** u2.pIBIndex fg.isIndexedBy && !fg.isCte | 19257 | ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy |
| 19050 | ** u2.pCteUse fg.isCte && !fg.isIndexedBy | 19258 | ** |
| 19259 | ** u2.pIBIndex fg.isIndexedBy && !fg.isCte | ||
| 19260 | ** u2.pCteUse fg.isCte && !fg.isIndexedBy | ||
| 19051 | */ | 19261 | */ |
| 19052 | struct SrcItem { | 19262 | struct SrcItem { |
| 19053 | Schema *pSchema; /* Schema to which this item is fixed */ | 19263 | Schema *pSchema; /* Schema to which this item is fixed */ |
| @@ -19075,6 +19285,7 @@ struct SrcItem { | |||
| 19075 | unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ | 19285 | unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ |
| 19076 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ | 19286 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ |
| 19077 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ | 19287 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ |
| 19288 | unsigned rowidUsed :1; /* The ROWID of this table is referenced */ | ||
| 19078 | } fg; | 19289 | } fg; |
| 19079 | int iCursor; /* The VDBE cursor number used to access this table */ | 19290 | int iCursor; /* The VDBE cursor number used to access this table */ |
| 19080 | union { | 19291 | union { |
| @@ -19085,6 +19296,7 @@ struct SrcItem { | |||
| 19085 | union { | 19296 | union { |
| 19086 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ | 19297 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ |
| 19087 | ExprList *pFuncArg; /* Arguments to table-valued-function */ | 19298 | ExprList *pFuncArg; /* Arguments to table-valued-function */ |
| 19299 | u32 nRow; /* Number of rows in a VALUES clause */ | ||
| 19088 | } u1; | 19300 | } u1; |
| 19089 | union { | 19301 | union { |
| 19090 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ | 19302 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ |
| @@ -19149,7 +19361,7 @@ struct SrcList { | |||
| 19149 | #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ | 19361 | #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ |
| 19150 | #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ | 19362 | #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ |
| 19151 | #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ | 19363 | #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ |
| 19152 | /* 0x2000 not currently used */ | 19364 | #define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */ |
| 19153 | #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ | 19365 | #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ |
| 19154 | /* 0x8000 not currently used */ | 19366 | /* 0x8000 not currently used */ |
| 19155 | 19367 | ||
| @@ -19194,6 +19406,7 @@ struct NameContext { | |||
| 19194 | int nRef; /* Number of names resolved by this context */ | 19406 | int nRef; /* Number of names resolved by this context */ |
| 19195 | int nNcErr; /* Number of errors encountered while resolving names */ | 19407 | int nNcErr; /* Number of errors encountered while resolving names */ |
| 19196 | int ncFlags; /* Zero or more NC_* flags defined below */ | 19408 | int ncFlags; /* Zero or more NC_* flags defined below */ |
| 19409 | u32 nNestedSelect; /* Number of nested selects using this NC */ | ||
| 19197 | Select *pWinSelect; /* SELECT statement for any window functions */ | 19410 | Select *pWinSelect; /* SELECT statement for any window functions */ |
| 19198 | }; | 19411 | }; |
| 19199 | 19412 | ||
| @@ -19227,6 +19440,7 @@ struct NameContext { | |||
| 19227 | #define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ | 19440 | #define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ |
| 19228 | #define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ | 19441 | #define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ |
| 19229 | #define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ | 19442 | #define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ |
| 19443 | #define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */ | ||
| 19230 | #define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ | 19444 | #define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ |
| 19231 | 19445 | ||
| 19232 | /* | 19446 | /* |
| @@ -19250,6 +19464,7 @@ struct Upsert { | |||
| 19250 | Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ | 19464 | Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ |
| 19251 | Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ | 19465 | Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ |
| 19252 | u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ | 19466 | u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ |
| 19467 | u8 isDup; /* True if 2nd or later with same pUpsertIdx */ | ||
| 19253 | /* Above this point is the parse tree for the ON CONFLICT clauses. | 19468 | /* Above this point is the parse tree for the ON CONFLICT clauses. |
| 19254 | ** The next group of fields stores intermediate data. */ | 19469 | ** The next group of fields stores intermediate data. */ |
| 19255 | void *pToFree; /* Free memory when deleting the Upsert object */ | 19470 | void *pToFree; /* Free memory when deleting the Upsert object */ |
| @@ -19339,11 +19554,12 @@ struct Select { | |||
| 19339 | #define SF_View 0x0200000 /* SELECT statement is a view */ | 19554 | #define SF_View 0x0200000 /* SELECT statement is a view */ |
| 19340 | #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ | 19555 | #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ |
| 19341 | #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ | 19556 | #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ |
| 19342 | #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ | 19557 | #define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ |
| 19343 | #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ | 19558 | #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ |
| 19344 | #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ | 19559 | #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ |
| 19345 | #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ | 19560 | #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ |
| 19346 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ | 19561 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ |
| 19562 | #define SF_Correlated 0x20000000 /* True if references the outer context */ | ||
| 19347 | 19563 | ||
| 19348 | /* True if S exists and has SF_NestedFrom */ | 19564 | /* True if S exists and has SF_NestedFrom */ |
| 19349 | #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) | 19565 | #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) |
| @@ -19583,6 +19799,7 @@ struct Parse { | |||
| 19583 | u8 disableLookaside; /* Number of times lookaside has been disabled */ | 19799 | u8 disableLookaside; /* Number of times lookaside has been disabled */ |
| 19584 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ | 19800 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ |
| 19585 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ | 19801 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ |
| 19802 | u8 bHasWith; /* True if statement contains WITH */ | ||
| 19586 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) | 19803 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 19587 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ | 19804 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ |
| 19588 | #endif | 19805 | #endif |
| @@ -19910,6 +20127,9 @@ struct sqlite3_str { | |||
| 19910 | ** | 20127 | ** |
| 19911 | ** 3. Make a (read-only) copy of a read-only RCStr string using | 20128 | ** 3. Make a (read-only) copy of a read-only RCStr string using |
| 19912 | ** sqlite3RCStrRef(). | 20129 | ** sqlite3RCStrRef(). |
| 20130 | ** | ||
| 20131 | ** "String" is in the name, but an RCStr object can also be used to hold | ||
| 20132 | ** binary data. | ||
| 19913 | */ | 20133 | */ |
| 19914 | struct RCStr { | 20134 | struct RCStr { |
| 19915 | u64 nRCRef; /* Number of references */ | 20135 | u64 nRCRef; /* Number of references */ |
| @@ -19968,6 +20188,9 @@ struct Sqlite3Config { | |||
| 19968 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ | 20188 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ |
| 19969 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ | 20189 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ |
| 19970 | u8 bUseLongDouble; /* Make use of long double */ | 20190 | u8 bUseLongDouble; /* Make use of long double */ |
| 20191 | #ifdef SQLITE_DEBUG | ||
| 20192 | u8 bJsonSelfcheck; /* Double-check JSON parsing */ | ||
| 20193 | #endif | ||
| 19971 | int mxStrlen; /* Maximum string length */ | 20194 | int mxStrlen; /* Maximum string length */ |
| 19972 | int neverCorrupt; /* Database is always well-formed */ | 20195 | int neverCorrupt; /* Database is always well-formed */ |
| 19973 | int szLookaside; /* Default lookaside buffer size */ | 20196 | int szLookaside; /* Default lookaside buffer size */ |
| @@ -20015,6 +20238,11 @@ struct Sqlite3Config { | |||
| 20015 | #ifndef SQLITE_UNTESTABLE | 20238 | #ifndef SQLITE_UNTESTABLE |
| 20016 | int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ | 20239 | int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ |
| 20017 | #endif | 20240 | #endif |
| 20241 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 20242 | u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW | ||
| 20243 | ** feature is disabled. 0 if rowids can | ||
| 20244 | ** occur in views. */ | ||
| 20245 | #endif | ||
| 20018 | int bLocaltimeFault; /* True to fail localtime() calls */ | 20246 | int bLocaltimeFault; /* True to fail localtime() calls */ |
| 20019 | int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ | 20247 | int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ |
| 20020 | int iOnceResetThreshold; /* When to reset OP_Once counters */ | 20248 | int iOnceResetThreshold; /* When to reset OP_Once counters */ |
| @@ -20251,6 +20479,9 @@ struct Window { | |||
| 20251 | ** due to the SQLITE_SUBTYPE flag */ | 20479 | ** due to the SQLITE_SUBTYPE flag */ |
| 20252 | }; | 20480 | }; |
| 20253 | 20481 | ||
| 20482 | SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow); | ||
| 20483 | SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal); | ||
| 20484 | |||
| 20254 | #ifndef SQLITE_OMIT_WINDOWFUNC | 20485 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 20255 | SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); | 20486 | SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); |
| 20256 | SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); | 20487 | SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); |
| @@ -20470,10 +20701,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); | |||
| 20470 | # define EXP754 (((u64)0x7ff)<<52) | 20701 | # define EXP754 (((u64)0x7ff)<<52) |
| 20471 | # define MAN754 ((((u64)1)<<52)-1) | 20702 | # define MAN754 ((((u64)1)<<52)-1) |
| 20472 | # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) | 20703 | # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) |
| 20704 | # define IsOvfl(X) (((X)&EXP754)==EXP754) | ||
| 20473 | SQLITE_PRIVATE int sqlite3IsNaN(double); | 20705 | SQLITE_PRIVATE int sqlite3IsNaN(double); |
| 20706 | SQLITE_PRIVATE int sqlite3IsOverflow(double); | ||
| 20474 | #else | 20707 | #else |
| 20475 | # define IsNaN(X) 0 | 20708 | # define IsNaN(X) 0 |
| 20476 | # define sqlite3IsNaN(X) 0 | 20709 | # define sqlite3IsNaN(X) 0 |
| 20710 | # define sqlite3IsOVerflow(X) 0 | ||
| 20477 | #endif | 20711 | #endif |
| 20478 | 20712 | ||
| 20479 | /* | 20713 | /* |
| @@ -20565,6 +20799,7 @@ SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); | |||
| 20565 | SQLITE_PRIVATE void sqlite3Dequote(char*); | 20799 | SQLITE_PRIVATE void sqlite3Dequote(char*); |
| 20566 | SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); | 20800 | SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); |
| 20567 | SQLITE_PRIVATE void sqlite3DequoteToken(Token*); | 20801 | SQLITE_PRIVATE void sqlite3DequoteToken(Token*); |
| 20802 | SQLITE_PRIVATE void sqlite3DequoteNumber(Parse*, Expr*); | ||
| 20568 | SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); | 20803 | SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); |
| 20569 | SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); | 20804 | SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); |
| 20570 | SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); | 20805 | SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); |
| @@ -20594,7 +20829,8 @@ SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); | |||
| 20594 | SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); | 20829 | SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); |
| 20595 | SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); | 20830 | SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); |
| 20596 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); | 20831 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); |
| 20597 | SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); | 20832 | SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*); |
| 20833 | SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse*, Expr*); | ||
| 20598 | SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); | 20834 | SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); |
| 20599 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); | 20835 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); |
| 20600 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); | 20836 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); |
| @@ -20603,6 +20839,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); | |||
| 20603 | SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); | 20839 | SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); |
| 20604 | SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); | 20840 | SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); |
| 20605 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); | 20841 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); |
| 20842 | SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); | ||
| 20606 | SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); | 20843 | SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); |
| 20607 | SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); | 20844 | SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); |
| 20608 | SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); | 20845 | SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); |
| @@ -20693,6 +20930,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); | |||
| 20693 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); | 20930 | SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); |
| 20694 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); | 20931 | SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); |
| 20695 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); | 20932 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); |
| 20933 | SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*); | ||
| 20696 | SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); | 20934 | SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); |
| 20697 | #ifndef SQLITE_OMIT_AUTOINCREMENT | 20935 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 20698 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); | 20936 | SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); |
| @@ -20729,6 +20967,7 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); | |||
| 20729 | SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, | 20967 | SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, |
| 20730 | Expr*,ExprList*,u32,Expr*); | 20968 | Expr*,ExprList*,u32,Expr*); |
| 20731 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); | 20969 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); |
| 20970 | SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); | ||
| 20732 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); | 20971 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); |
| 20733 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); | 20972 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); |
| 20734 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); | 20973 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); |
| @@ -20814,12 +21053,10 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); | |||
| 20814 | SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); | 21053 | SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); |
| 20815 | SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); | 21054 | SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); |
| 20816 | SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); | 21055 | SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); |
| 20817 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); | 21056 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); |
| 20818 | SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); | ||
| 20819 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); | 21057 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); |
| 20820 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); | 21058 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); |
| 20821 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); | 21059 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); |
| 20822 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); | ||
| 20823 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 21060 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 20824 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); | 21061 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 20825 | #endif | 21062 | #endif |
| @@ -20955,6 +21192,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); | |||
| 20955 | #endif | 21192 | #endif |
| 20956 | SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); | 21193 | SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); |
| 20957 | SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); | 21194 | SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); |
| 21195 | SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); | ||
| 20958 | SQLITE_PRIVATE LogEst sqlite3LogEst(u64); | 21196 | SQLITE_PRIVATE LogEst sqlite3LogEst(u64); |
| 20959 | SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); | 21197 | SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); |
| 20960 | SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); | 21198 | SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); |
| @@ -21003,7 +21241,9 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); | |||
| 21003 | SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); | 21241 | SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); |
| 21004 | SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); | 21242 | SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); |
| 21005 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); | 21243 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); |
| 21244 | #if !defined(SQLITE_OMIT_BLOB_LITERAL) | ||
| 21006 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); | 21245 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 21246 | #endif | ||
| 21007 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); | 21247 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 21008 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); | 21248 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 21009 | 21249 | ||
| @@ -21301,6 +21541,7 @@ SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); | |||
| 21301 | SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); | 21541 | SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); |
| 21302 | SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); | 21542 | SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); |
| 21303 | SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); | 21543 | SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); |
| 21544 | SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*); | ||
| 21304 | SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); | 21545 | SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); |
| 21305 | #else | 21546 | #else |
| 21306 | # define sqlite3CteNew(P,T,E,S) ((void*)0) | 21547 | # define sqlite3CteNew(P,T,E,S) ((void*)0) |
| @@ -21313,7 +21554,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); | |||
| 21313 | SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); | 21554 | SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); |
| 21314 | SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); | 21555 | SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); |
| 21315 | SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); | 21556 | SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); |
| 21316 | SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); | 21557 | SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*); |
| 21317 | SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); | 21558 | SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); |
| 21318 | SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); | 21559 | SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); |
| 21319 | SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); | 21560 | SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); |
| @@ -21703,6 +21944,9 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 21703 | "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), | 21944 | "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), |
| 21704 | # endif | 21945 | # endif |
| 21705 | #endif | 21946 | #endif |
| 21947 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 21948 | "ALLOW_ROWID_IN_VIEW", | ||
| 21949 | #endif | ||
| 21706 | #ifdef SQLITE_ALLOW_URI_AUTHORITY | 21950 | #ifdef SQLITE_ALLOW_URI_AUTHORITY |
| 21707 | "ALLOW_URI_AUTHORITY", | 21951 | "ALLOW_URI_AUTHORITY", |
| 21708 | #endif | 21952 | #endif |
| @@ -22678,6 +22922,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { | |||
| 22678 | 0, /* bSmallMalloc */ | 22922 | 0, /* bSmallMalloc */ |
| 22679 | 1, /* bExtraSchemaChecks */ | 22923 | 1, /* bExtraSchemaChecks */ |
| 22680 | sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ | 22924 | sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ |
| 22925 | #ifdef SQLITE_DEBUG | ||
| 22926 | 0, /* bJsonSelfcheck */ | ||
| 22927 | #endif | ||
| 22681 | 0x7ffffffe, /* mxStrlen */ | 22928 | 0x7ffffffe, /* mxStrlen */ |
| 22682 | 0, /* neverCorrupt */ | 22929 | 0, /* neverCorrupt */ |
| 22683 | SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ | 22930 | SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ |
| @@ -22720,6 +22967,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { | |||
| 22720 | #ifndef SQLITE_UNTESTABLE | 22967 | #ifndef SQLITE_UNTESTABLE |
| 22721 | 0, /* xTestCallback */ | 22968 | 0, /* xTestCallback */ |
| 22722 | #endif | 22969 | #endif |
| 22970 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 22971 | 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ | ||
| 22972 | #endif | ||
| 22723 | 0, /* bLocaltimeFault */ | 22973 | 0, /* bLocaltimeFault */ |
| 22724 | 0, /* xAltLocaltime */ | 22974 | 0, /* xAltLocaltime */ |
| 22725 | 0x7ffffffe, /* iOnceResetThreshold */ | 22975 | 0x7ffffffe, /* iOnceResetThreshold */ |
| @@ -23930,7 +24180,7 @@ SQLITE_API int sqlite3_db_status( | |||
| 23930 | case SQLITE_DBSTATUS_CACHE_MISS: | 24180 | case SQLITE_DBSTATUS_CACHE_MISS: |
| 23931 | case SQLITE_DBSTATUS_CACHE_WRITE:{ | 24181 | case SQLITE_DBSTATUS_CACHE_WRITE:{ |
| 23932 | int i; | 24182 | int i; |
| 23933 | int nRet = 0; | 24183 | u64 nRet = 0; |
| 23934 | assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); | 24184 | assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); |
| 23935 | assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); | 24185 | assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); |
| 23936 | 24186 | ||
| @@ -23943,7 +24193,7 @@ SQLITE_API int sqlite3_db_status( | |||
| 23943 | *pHighwater = 0; /* IMP: R-42420-56072 */ | 24193 | *pHighwater = 0; /* IMP: R-42420-56072 */ |
| 23944 | /* IMP: R-54100-20147 */ | 24194 | /* IMP: R-54100-20147 */ |
| 23945 | /* IMP: R-29431-39229 */ | 24195 | /* IMP: R-29431-39229 */ |
| 23946 | *pCurrent = nRet; | 24196 | *pCurrent = (int)nRet & 0x7fffffff; |
| 23947 | break; | 24197 | break; |
| 23948 | } | 24198 | } |
| 23949 | 24199 | ||
| @@ -24040,13 +24290,14 @@ struct DateTime { | |||
| 24040 | int tz; /* Timezone offset in minutes */ | 24290 | int tz; /* Timezone offset in minutes */ |
| 24041 | double s; /* Seconds */ | 24291 | double s; /* Seconds */ |
| 24042 | char validJD; /* True (1) if iJD is valid */ | 24292 | char validJD; /* True (1) if iJD is valid */ |
| 24043 | char rawS; /* Raw numeric value stored in s */ | ||
| 24044 | char validYMD; /* True (1) if Y,M,D are valid */ | 24293 | char validYMD; /* True (1) if Y,M,D are valid */ |
| 24045 | char validHMS; /* True (1) if h,m,s are valid */ | 24294 | char validHMS; /* True (1) if h,m,s are valid */ |
| 24046 | char validTZ; /* True (1) if tz is valid */ | 24295 | char nFloor; /* Days to implement "floor" */ |
| 24047 | char tzSet; /* Timezone was set explicitly */ | 24296 | unsigned rawS : 1; /* Raw numeric value stored in s */ |
| 24048 | char isError; /* An overflow has occurred */ | 24297 | unsigned isError : 1; /* An overflow has occurred */ |
| 24049 | char useSubsec; /* Display subsecond precision */ | 24298 | unsigned useSubsec : 1; /* Display subsecond precision */ |
| 24299 | unsigned isUtc : 1; /* Time is known to be UTC */ | ||
| 24300 | unsigned isLocal : 1; /* Time is known to be localtime */ | ||
| 24050 | }; | 24301 | }; |
| 24051 | 24302 | ||
| 24052 | 24303 | ||
| @@ -24144,6 +24395,8 @@ static int parseTimezone(const char *zDate, DateTime *p){ | |||
| 24144 | sgn = +1; | 24395 | sgn = +1; |
| 24145 | }else if( c=='Z' || c=='z' ){ | 24396 | }else if( c=='Z' || c=='z' ){ |
| 24146 | zDate++; | 24397 | zDate++; |
| 24398 | p->isLocal = 0; | ||
| 24399 | p->isUtc = 1; | ||
| 24147 | goto zulu_time; | 24400 | goto zulu_time; |
| 24148 | }else{ | 24401 | }else{ |
| 24149 | return c!=0; | 24402 | return c!=0; |
| @@ -24156,7 +24409,6 @@ static int parseTimezone(const char *zDate, DateTime *p){ | |||
| 24156 | p->tz = sgn*(nMn + nHr*60); | 24409 | p->tz = sgn*(nMn + nHr*60); |
| 24157 | zulu_time: | 24410 | zulu_time: |
| 24158 | while( sqlite3Isspace(*zDate) ){ zDate++; } | 24411 | while( sqlite3Isspace(*zDate) ){ zDate++; } |
| 24159 | p->tzSet = 1; | ||
| 24160 | return *zDate!=0; | 24412 | return *zDate!=0; |
| 24161 | } | 24413 | } |
| 24162 | 24414 | ||
| @@ -24200,7 +24452,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ | |||
| 24200 | p->m = m; | 24452 | p->m = m; |
| 24201 | p->s = s + ms; | 24453 | p->s = s + ms; |
| 24202 | if( parseTimezone(zDate, p) ) return 1; | 24454 | if( parseTimezone(zDate, p) ) return 1; |
| 24203 | p->validTZ = (p->tz!=0)?1:0; | ||
| 24204 | return 0; | 24455 | return 0; |
| 24205 | } | 24456 | } |
| 24206 | 24457 | ||
| @@ -24247,16 +24498,41 @@ static void computeJD(DateTime *p){ | |||
| 24247 | p->validJD = 1; | 24498 | p->validJD = 1; |
| 24248 | if( p->validHMS ){ | 24499 | if( p->validHMS ){ |
| 24249 | p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); | 24500 | p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); |
| 24250 | if( p->validTZ ){ | 24501 | if( p->tz ){ |
| 24251 | p->iJD -= p->tz*60000; | 24502 | p->iJD -= p->tz*60000; |
| 24252 | p->validYMD = 0; | 24503 | p->validYMD = 0; |
| 24253 | p->validHMS = 0; | 24504 | p->validHMS = 0; |
| 24254 | p->validTZ = 0; | 24505 | p->tz = 0; |
| 24506 | p->isUtc = 1; | ||
| 24507 | p->isLocal = 0; | ||
| 24255 | } | 24508 | } |
| 24256 | } | 24509 | } |
| 24257 | } | 24510 | } |
| 24258 | 24511 | ||
| 24259 | /* | 24512 | /* |
| 24513 | ** Given the YYYY-MM-DD information current in p, determine if there | ||
| 24514 | ** is day-of-month overflow and set nFloor to the number of days that | ||
| 24515 | ** would need to be subtracted from the date in order to bring the | ||
| 24516 | ** date back to the end of the month. | ||
| 24517 | */ | ||
| 24518 | static void computeFloor(DateTime *p){ | ||
| 24519 | assert( p->validYMD || p->isError ); | ||
| 24520 | assert( p->D>=0 && p->D<=31 ); | ||
| 24521 | assert( p->M>=0 && p->M<=12 ); | ||
| 24522 | if( p->D<=28 ){ | ||
| 24523 | p->nFloor = 0; | ||
| 24524 | }else if( (1<<p->M) & 0x15aa ){ | ||
| 24525 | p->nFloor = 0; | ||
| 24526 | }else if( p->M!=2 ){ | ||
| 24527 | p->nFloor = (p->D==31); | ||
| 24528 | }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){ | ||
| 24529 | p->nFloor = p->D - 28; | ||
| 24530 | }else{ | ||
| 24531 | p->nFloor = p->D - 29; | ||
| 24532 | } | ||
| 24533 | } | ||
| 24534 | |||
| 24535 | /* | ||
| 24260 | ** Parse dates of the form | 24536 | ** Parse dates of the form |
| 24261 | ** | 24537 | ** |
| 24262 | ** YYYY-MM-DD HH:MM:SS.FFF | 24538 | ** YYYY-MM-DD HH:MM:SS.FFF |
| @@ -24294,12 +24570,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ | |||
| 24294 | p->Y = neg ? -Y : Y; | 24570 | p->Y = neg ? -Y : Y; |
| 24295 | p->M = M; | 24571 | p->M = M; |
| 24296 | p->D = D; | 24572 | p->D = D; |
| 24297 | if( p->validTZ ){ | 24573 | computeFloor(p); |
| 24574 | if( p->tz ){ | ||
| 24298 | computeJD(p); | 24575 | computeJD(p); |
| 24299 | } | 24576 | } |
| 24300 | return 0; | 24577 | return 0; |
| 24301 | } | 24578 | } |
| 24302 | 24579 | ||
| 24580 | |||
| 24581 | static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */ | ||
| 24582 | |||
| 24303 | /* | 24583 | /* |
| 24304 | ** Set the time to the current time reported by the VFS. | 24584 | ** Set the time to the current time reported by the VFS. |
| 24305 | ** | 24585 | ** |
| @@ -24309,6 +24589,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ | |||
| 24309 | p->iJD = sqlite3StmtCurrentTime(context); | 24589 | p->iJD = sqlite3StmtCurrentTime(context); |
| 24310 | if( p->iJD>0 ){ | 24590 | if( p->iJD>0 ){ |
| 24311 | p->validJD = 1; | 24591 | p->validJD = 1; |
| 24592 | p->isUtc = 1; | ||
| 24593 | p->isLocal = 0; | ||
| 24594 | clearYMD_HMS_TZ(p); | ||
| 24312 | return 0; | 24595 | return 0; |
| 24313 | }else{ | 24596 | }else{ |
| 24314 | return 1; | 24597 | return 1; |
| @@ -24447,7 +24730,7 @@ static void computeYMD_HMS(DateTime *p){ | |||
| 24447 | static void clearYMD_HMS_TZ(DateTime *p){ | 24730 | static void clearYMD_HMS_TZ(DateTime *p){ |
| 24448 | p->validYMD = 0; | 24731 | p->validYMD = 0; |
| 24449 | p->validHMS = 0; | 24732 | p->validHMS = 0; |
| 24450 | p->validTZ = 0; | 24733 | p->tz = 0; |
| 24451 | } | 24734 | } |
| 24452 | 24735 | ||
| 24453 | #ifndef SQLITE_OMIT_LOCALTIME | 24736 | #ifndef SQLITE_OMIT_LOCALTIME |
| @@ -24579,7 +24862,7 @@ static int toLocaltime( | |||
| 24579 | p->validHMS = 1; | 24862 | p->validHMS = 1; |
| 24580 | p->validJD = 0; | 24863 | p->validJD = 0; |
| 24581 | p->rawS = 0; | 24864 | p->rawS = 0; |
| 24582 | p->validTZ = 0; | 24865 | p->tz = 0; |
| 24583 | p->isError = 0; | 24866 | p->isError = 0; |
| 24584 | return SQLITE_OK; | 24867 | return SQLITE_OK; |
| 24585 | } | 24868 | } |
| @@ -24599,12 +24882,12 @@ static const struct { | |||
| 24599 | float rLimit; /* Maximum NNN value for this transform */ | 24882 | float rLimit; /* Maximum NNN value for this transform */ |
| 24600 | float rXform; /* Constant used for this transform */ | 24883 | float rXform; /* Constant used for this transform */ |
| 24601 | } aXformType[] = { | 24884 | } aXformType[] = { |
| 24602 | { 6, "second", 4.6427e+14, 1.0 }, | 24885 | /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, |
| 24603 | { 6, "minute", 7.7379e+12, 60.0 }, | 24886 | /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, |
| 24604 | { 4, "hour", 1.2897e+11, 3600.0 }, | 24887 | /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, |
| 24605 | { 3, "day", 5373485.0, 86400.0 }, | 24888 | /* 3 */ { 3, "day", 5373485.0, 86400.0 }, |
| 24606 | { 5, "month", 176546.0, 2592000.0 }, | 24889 | /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 }, |
| 24607 | { 4, "year", 14713.0, 31536000.0 }, | 24890 | /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 }, |
| 24608 | }; | 24891 | }; |
| 24609 | 24892 | ||
| 24610 | /* | 24893 | /* |
| @@ -24636,14 +24919,20 @@ static void autoAdjustDate(DateTime *p){ | |||
| 24636 | ** NNN.NNNN seconds | 24919 | ** NNN.NNNN seconds |
| 24637 | ** NNN months | 24920 | ** NNN months |
| 24638 | ** NNN years | 24921 | ** NNN years |
| 24922 | ** +/-YYYY-MM-DD HH:MM:SS.SSS | ||
| 24923 | ** ceiling | ||
| 24924 | ** floor | ||
| 24639 | ** start of month | 24925 | ** start of month |
| 24640 | ** start of year | 24926 | ** start of year |
| 24641 | ** start of week | 24927 | ** start of week |
| 24642 | ** start of day | 24928 | ** start of day |
| 24643 | ** weekday N | 24929 | ** weekday N |
| 24644 | ** unixepoch | 24930 | ** unixepoch |
| 24931 | ** auto | ||
| 24645 | ** localtime | 24932 | ** localtime |
| 24646 | ** utc | 24933 | ** utc |
| 24934 | ** subsec | ||
| 24935 | ** subsecond | ||
| 24647 | ** | 24936 | ** |
| 24648 | ** Return 0 on success and 1 if there is any kind of error. If the error | 24937 | ** Return 0 on success and 1 if there is any kind of error. If the error |
| 24649 | ** is in a system call (i.e. localtime()), then an error message is written | 24938 | ** is in a system call (i.e. localtime()), then an error message is written |
| @@ -24674,6 +24963,37 @@ static int parseModifier( | |||
| 24674 | } | 24963 | } |
| 24675 | break; | 24964 | break; |
| 24676 | } | 24965 | } |
| 24966 | case 'c': { | ||
| 24967 | /* | ||
| 24968 | ** ceiling | ||
| 24969 | ** | ||
| 24970 | ** Resolve day-of-month overflow by rolling forward into the next | ||
| 24971 | ** month. As this is the default action, this modifier is really | ||
| 24972 | ** a no-op that is only included for symmetry. See "floor". | ||
| 24973 | */ | ||
| 24974 | if( sqlite3_stricmp(z, "ceiling")==0 ){ | ||
| 24975 | computeJD(p); | ||
| 24976 | clearYMD_HMS_TZ(p); | ||
| 24977 | rc = 0; | ||
| 24978 | p->nFloor = 0; | ||
| 24979 | } | ||
| 24980 | break; | ||
| 24981 | } | ||
| 24982 | case 'f': { | ||
| 24983 | /* | ||
| 24984 | ** floor | ||
| 24985 | ** | ||
| 24986 | ** Resolve day-of-month overflow by rolling back to the end of the | ||
| 24987 | ** previous month. | ||
| 24988 | */ | ||
| 24989 | if( sqlite3_stricmp(z, "floor")==0 ){ | ||
| 24990 | computeJD(p); | ||
| 24991 | p->iJD -= p->nFloor*86400000; | ||
| 24992 | clearYMD_HMS_TZ(p); | ||
| 24993 | rc = 0; | ||
| 24994 | } | ||
| 24995 | break; | ||
| 24996 | } | ||
| 24677 | case 'j': { | 24997 | case 'j': { |
| 24678 | /* | 24998 | /* |
| 24679 | ** julianday | 24999 | ** julianday |
| @@ -24700,7 +25020,9 @@ static int parseModifier( | |||
| 24700 | ** show local time. | 25020 | ** show local time. |
| 24701 | */ | 25021 | */ |
| 24702 | if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ | 25022 | if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ |
| 24703 | rc = toLocaltime(p, pCtx); | 25023 | rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx); |
| 25024 | p->isUtc = 0; | ||
| 25025 | p->isLocal = 1; | ||
| 24704 | } | 25026 | } |
| 24705 | break; | 25027 | break; |
| 24706 | } | 25028 | } |
| @@ -24725,7 +25047,7 @@ static int parseModifier( | |||
| 24725 | } | 25047 | } |
| 24726 | #ifndef SQLITE_OMIT_LOCALTIME | 25048 | #ifndef SQLITE_OMIT_LOCALTIME |
| 24727 | else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ | 25049 | else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ |
| 24728 | if( p->tzSet==0 ){ | 25050 | if( p->isUtc==0 ){ |
| 24729 | i64 iOrigJD; /* Original localtime */ | 25051 | i64 iOrigJD; /* Original localtime */ |
| 24730 | i64 iGuess; /* Guess at the corresponding utc time */ | 25052 | i64 iGuess; /* Guess at the corresponding utc time */ |
| 24731 | int cnt = 0; /* Safety to prevent infinite loop */ | 25053 | int cnt = 0; /* Safety to prevent infinite loop */ |
| @@ -24748,7 +25070,8 @@ static int parseModifier( | |||
| 24748 | memset(p, 0, sizeof(*p)); | 25070 | memset(p, 0, sizeof(*p)); |
| 24749 | p->iJD = iGuess; | 25071 | p->iJD = iGuess; |
| 24750 | p->validJD = 1; | 25072 | p->validJD = 1; |
| 24751 | p->tzSet = 1; | 25073 | p->isUtc = 1; |
| 25074 | p->isLocal = 0; | ||
| 24752 | } | 25075 | } |
| 24753 | rc = SQLITE_OK; | 25076 | rc = SQLITE_OK; |
| 24754 | } | 25077 | } |
| @@ -24768,7 +25091,7 @@ static int parseModifier( | |||
| 24768 | && r>=0.0 && r<7.0 && (n=(int)r)==r ){ | 25091 | && r>=0.0 && r<7.0 && (n=(int)r)==r ){ |
| 24769 | sqlite3_int64 Z; | 25092 | sqlite3_int64 Z; |
| 24770 | computeYMD_HMS(p); | 25093 | computeYMD_HMS(p); |
| 24771 | p->validTZ = 0; | 25094 | p->tz = 0; |
| 24772 | p->validJD = 0; | 25095 | p->validJD = 0; |
| 24773 | computeJD(p); | 25096 | computeJD(p); |
| 24774 | Z = ((p->iJD + 129600000)/86400000) % 7; | 25097 | Z = ((p->iJD + 129600000)/86400000) % 7; |
| @@ -24808,7 +25131,7 @@ static int parseModifier( | |||
| 24808 | p->h = p->m = 0; | 25131 | p->h = p->m = 0; |
| 24809 | p->s = 0.0; | 25132 | p->s = 0.0; |
| 24810 | p->rawS = 0; | 25133 | p->rawS = 0; |
| 24811 | p->validTZ = 0; | 25134 | p->tz = 0; |
| 24812 | p->validJD = 0; | 25135 | p->validJD = 0; |
| 24813 | if( sqlite3_stricmp(z,"month")==0 ){ | 25136 | if( sqlite3_stricmp(z,"month")==0 ){ |
| 24814 | p->D = 1; | 25137 | p->D = 1; |
| @@ -24879,6 +25202,7 @@ static int parseModifier( | |||
| 24879 | x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; | 25202 | x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; |
| 24880 | p->Y += x; | 25203 | p->Y += x; |
| 24881 | p->M -= x*12; | 25204 | p->M -= x*12; |
| 25205 | computeFloor(p); | ||
| 24882 | computeJD(p); | 25206 | computeJD(p); |
| 24883 | p->validHMS = 0; | 25207 | p->validHMS = 0; |
| 24884 | p->validYMD = 0; | 25208 | p->validYMD = 0; |
| @@ -24925,11 +25249,12 @@ static int parseModifier( | |||
| 24925 | z += n; | 25249 | z += n; |
| 24926 | while( sqlite3Isspace(*z) ) z++; | 25250 | while( sqlite3Isspace(*z) ) z++; |
| 24927 | n = sqlite3Strlen30(z); | 25251 | n = sqlite3Strlen30(z); |
| 24928 | if( n>10 || n<3 ) break; | 25252 | if( n<3 || n>10 ) break; |
| 24929 | if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; | 25253 | if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; |
| 24930 | computeJD(p); | 25254 | computeJD(p); |
| 24931 | assert( rc==1 ); | 25255 | assert( rc==1 ); |
| 24932 | rRounder = r<0 ? -0.5 : +0.5; | 25256 | rRounder = r<0 ? -0.5 : +0.5; |
| 25257 | p->nFloor = 0; | ||
| 24933 | for(i=0; i<ArraySize(aXformType); i++){ | 25258 | for(i=0; i<ArraySize(aXformType); i++){ |
| 24934 | if( aXformType[i].nName==n | 25259 | if( aXformType[i].nName==n |
| 24935 | && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 | 25260 | && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 |
| @@ -24937,21 +25262,24 @@ static int parseModifier( | |||
| 24937 | ){ | 25262 | ){ |
| 24938 | switch( i ){ | 25263 | switch( i ){ |
| 24939 | case 4: { /* Special processing to add months */ | 25264 | case 4: { /* Special processing to add months */ |
| 24940 | assert( strcmp(aXformType[i].zName,"month")==0 ); | 25265 | assert( strcmp(aXformType[4].zName,"month")==0 ); |
| 24941 | computeYMD_HMS(p); | 25266 | computeYMD_HMS(p); |
| 24942 | p->M += (int)r; | 25267 | p->M += (int)r; |
| 24943 | x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; | 25268 | x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; |
| 24944 | p->Y += x; | 25269 | p->Y += x; |
| 24945 | p->M -= x*12; | 25270 | p->M -= x*12; |
| 25271 | computeFloor(p); | ||
| 24946 | p->validJD = 0; | 25272 | p->validJD = 0; |
| 24947 | r -= (int)r; | 25273 | r -= (int)r; |
| 24948 | break; | 25274 | break; |
| 24949 | } | 25275 | } |
| 24950 | case 5: { /* Special processing to add years */ | 25276 | case 5: { /* Special processing to add years */ |
| 24951 | int y = (int)r; | 25277 | int y = (int)r; |
| 24952 | assert( strcmp(aXformType[i].zName,"year")==0 ); | 25278 | assert( strcmp(aXformType[5].zName,"year")==0 ); |
| 24953 | computeYMD_HMS(p); | 25279 | computeYMD_HMS(p); |
| 25280 | assert( p->M>=0 && p->M<=12 ); | ||
| 24954 | p->Y += y; | 25281 | p->Y += y; |
| 25282 | computeFloor(p); | ||
| 24955 | p->validJD = 0; | 25283 | p->validJD = 0; |
| 24956 | r -= (int)r; | 25284 | r -= (int)r; |
| 24957 | break; | 25285 | break; |
| @@ -25012,6 +25340,12 @@ static int isDate( | |||
| 25012 | } | 25340 | } |
| 25013 | computeJD(p); | 25341 | computeJD(p); |
| 25014 | if( p->isError || !validJulianDay(p->iJD) ) return 1; | 25342 | if( p->isError || !validJulianDay(p->iJD) ) return 1; |
| 25343 | if( argc==1 && p->validYMD && p->D>28 ){ | ||
| 25344 | /* Make sure a YYYY-MM-DD is normalized. | ||
| 25345 | ** Example: 2023-02-31 -> 2023-03-03 */ | ||
| 25346 | assert( p->validJD ); | ||
| 25347 | p->validYMD = 0; | ||
| 25348 | } | ||
| 25015 | return 0; | 25349 | return 0; |
| 25016 | } | 25350 | } |
| 25017 | 25351 | ||
| @@ -25200,21 +25534,82 @@ static void dateFunc( | |||
| 25200 | } | 25534 | } |
| 25201 | 25535 | ||
| 25202 | /* | 25536 | /* |
| 25537 | ** Compute the number of days after the most recent January 1. | ||
| 25538 | ** | ||
| 25539 | ** In other words, compute the zero-based day number for the | ||
| 25540 | ** current year: | ||
| 25541 | ** | ||
| 25542 | ** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ... | ||
| 25543 | ** Dec31 = 364 or 365. | ||
| 25544 | */ | ||
| 25545 | static int daysAfterJan01(DateTime *pDate){ | ||
| 25546 | DateTime jan01 = *pDate; | ||
| 25547 | assert( jan01.validYMD ); | ||
| 25548 | assert( jan01.validHMS ); | ||
| 25549 | assert( pDate->validJD ); | ||
| 25550 | jan01.validJD = 0; | ||
| 25551 | jan01.M = 1; | ||
| 25552 | jan01.D = 1; | ||
| 25553 | computeJD(&jan01); | ||
| 25554 | return (int)((pDate->iJD-jan01.iJD+43200000)/86400000); | ||
| 25555 | } | ||
| 25556 | |||
| 25557 | /* | ||
| 25558 | ** Return the number of days after the most recent Monday. | ||
| 25559 | ** | ||
| 25560 | ** In other words, return the day of the week according | ||
| 25561 | ** to this code: | ||
| 25562 | ** | ||
| 25563 | ** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday. | ||
| 25564 | */ | ||
| 25565 | static int daysAfterMonday(DateTime *pDate){ | ||
| 25566 | assert( pDate->validJD ); | ||
| 25567 | return (int)((pDate->iJD+43200000)/86400000) % 7; | ||
| 25568 | } | ||
| 25569 | |||
| 25570 | /* | ||
| 25571 | ** Return the number of days after the most recent Sunday. | ||
| 25572 | ** | ||
| 25573 | ** In other words, return the day of the week according | ||
| 25574 | ** to this code: | ||
| 25575 | ** | ||
| 25576 | ** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday | ||
| 25577 | */ | ||
| 25578 | static int daysAfterSunday(DateTime *pDate){ | ||
| 25579 | assert( pDate->validJD ); | ||
| 25580 | return (int)((pDate->iJD+129600000)/86400000) % 7; | ||
| 25581 | } | ||
| 25582 | |||
| 25583 | /* | ||
| 25203 | ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) | 25584 | ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) |
| 25204 | ** | 25585 | ** |
| 25205 | ** Return a string described by FORMAT. Conversions as follows: | 25586 | ** Return a string described by FORMAT. Conversions as follows: |
| 25206 | ** | 25587 | ** |
| 25207 | ** %d day of month | 25588 | ** %d day of month 01-31 |
| 25589 | ** %e day of month 1-31 | ||
| 25208 | ** %f ** fractional seconds SS.SSS | 25590 | ** %f ** fractional seconds SS.SSS |
| 25591 | ** %F ISO date. YYYY-MM-DD | ||
| 25592 | ** %G ISO year corresponding to %V 0000-9999. | ||
| 25593 | ** %g 2-digit ISO year corresponding to %V 00-99 | ||
| 25209 | ** %H hour 00-24 | 25594 | ** %H hour 00-24 |
| 25210 | ** %j day of year 000-366 | 25595 | ** %k hour 0-24 (leading zero converted to space) |
| 25596 | ** %I hour 01-12 | ||
| 25597 | ** %j day of year 001-366 | ||
| 25211 | ** %J ** julian day number | 25598 | ** %J ** julian day number |
| 25599 | ** %l hour 1-12 (leading zero converted to space) | ||
| 25212 | ** %m month 01-12 | 25600 | ** %m month 01-12 |
| 25213 | ** %M minute 00-59 | 25601 | ** %M minute 00-59 |
| 25602 | ** %p "am" or "pm" | ||
| 25603 | ** %P "AM" or "PM" | ||
| 25604 | ** %R time as HH:MM | ||
| 25214 | ** %s seconds since 1970-01-01 | 25605 | ** %s seconds since 1970-01-01 |
| 25215 | ** %S seconds 00-59 | 25606 | ** %S seconds 00-59 |
| 25216 | ** %w day of week 0-6 Sunday==0 | 25607 | ** %T time as HH:MM:SS |
| 25217 | ** %W week of year 00-53 | 25608 | ** %u day of week 1-7 Monday==1, Sunday==7 |
| 25609 | ** %w day of week 0-6 Sunday==0, Monday==1 | ||
| 25610 | ** %U week of year 00-53 (First Sunday is start of week 01) | ||
| 25611 | ** %V week of year 01-53 (First week containing Thursday is week 01) | ||
| 25612 | ** %W week of year 00-53 (First Monday is start of week 01) | ||
| 25218 | ** %Y year 0000-9999 | 25613 | ** %Y year 0000-9999 |
| 25219 | ** %% % | 25614 | ** %% % |
| 25220 | */ | 25615 | */ |
| @@ -25251,7 +25646,7 @@ static void strftimeFunc( | |||
| 25251 | sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); | 25646 | sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); |
| 25252 | break; | 25647 | break; |
| 25253 | } | 25648 | } |
| 25254 | case 'f': { | 25649 | case 'f': { /* Fractional seconds. (Non-standard) */ |
| 25255 | double s = x.s; | 25650 | double s = x.s; |
| 25256 | if( s>59.999 ) s = 59.999; | 25651 | if( s>59.999 ) s = 59.999; |
| 25257 | sqlite3_str_appendf(&sRes, "%06.3f", s); | 25652 | sqlite3_str_appendf(&sRes, "%06.3f", s); |
| @@ -25261,6 +25656,21 @@ static void strftimeFunc( | |||
| 25261 | sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); | 25656 | sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); |
| 25262 | break; | 25657 | break; |
| 25263 | } | 25658 | } |
| 25659 | case 'G': /* Fall thru */ | ||
| 25660 | case 'g': { | ||
| 25661 | DateTime y = x; | ||
| 25662 | assert( y.validJD ); | ||
| 25663 | /* Move y so that it is the Thursday in the same week as x */ | ||
| 25664 | y.iJD += (3 - daysAfterMonday(&x))*86400000; | ||
| 25665 | y.validYMD = 0; | ||
| 25666 | computeYMD(&y); | ||
| 25667 | if( cf=='g' ){ | ||
| 25668 | sqlite3_str_appendf(&sRes, "%02d", y.Y%100); | ||
| 25669 | }else{ | ||
| 25670 | sqlite3_str_appendf(&sRes, "%04d", y.Y); | ||
| 25671 | } | ||
| 25672 | break; | ||
| 25673 | } | ||
| 25264 | case 'H': | 25674 | case 'H': |
| 25265 | case 'k': { | 25675 | case 'k': { |
| 25266 | sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); | 25676 | sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); |
| @@ -25274,25 +25684,11 @@ static void strftimeFunc( | |||
| 25274 | sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); | 25684 | sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); |
| 25275 | break; | 25685 | break; |
| 25276 | } | 25686 | } |
| 25277 | case 'W': /* Fall thru */ | 25687 | case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ |
| 25278 | case 'j': { | 25688 | sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); |
| 25279 | int nDay; /* Number of days since 1st day of year */ | ||
| 25280 | DateTime y = x; | ||
| 25281 | y.validJD = 0; | ||
| 25282 | y.M = 1; | ||
| 25283 | y.D = 1; | ||
| 25284 | computeJD(&y); | ||
| 25285 | nDay = (int)((x.iJD-y.iJD+43200000)/86400000); | ||
| 25286 | if( cf=='W' ){ | ||
| 25287 | int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ | ||
| 25288 | wd = (int)(((x.iJD+43200000)/86400000)%7); | ||
| 25289 | sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); | ||
| 25290 | }else{ | ||
| 25291 | sqlite3_str_appendf(&sRes,"%03d",nDay+1); | ||
| 25292 | } | ||
| 25293 | break; | 25689 | break; |
| 25294 | } | 25690 | } |
| 25295 | case 'J': { | 25691 | case 'J': { /* Julian day number. (Non-standard) */ |
| 25296 | sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); | 25692 | sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); |
| 25297 | break; | 25693 | break; |
| 25298 | } | 25694 | } |
| @@ -25335,13 +25731,33 @@ static void strftimeFunc( | |||
| 25335 | sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); | 25731 | sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); |
| 25336 | break; | 25732 | break; |
| 25337 | } | 25733 | } |
| 25338 | case 'u': /* Fall thru */ | 25734 | case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ |
| 25339 | case 'w': { | 25735 | case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ |
| 25340 | char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; | 25736 | char c = (char)daysAfterSunday(&x) + '0'; |
| 25341 | if( c=='0' && cf=='u' ) c = '7'; | 25737 | if( c=='0' && cf=='u' ) c = '7'; |
| 25342 | sqlite3_str_appendchar(&sRes, 1, c); | 25738 | sqlite3_str_appendchar(&sRes, 1, c); |
| 25343 | break; | 25739 | break; |
| 25344 | } | 25740 | } |
| 25741 | case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ | ||
| 25742 | sqlite3_str_appendf(&sRes,"%02d", | ||
| 25743 | (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); | ||
| 25744 | break; | ||
| 25745 | } | ||
| 25746 | case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */ | ||
| 25747 | DateTime y = x; | ||
| 25748 | /* Adjust y so that is the Thursday in the same week as x */ | ||
| 25749 | assert( y.validJD ); | ||
| 25750 | y.iJD += (3 - daysAfterMonday(&x))*86400000; | ||
| 25751 | y.validYMD = 0; | ||
| 25752 | computeYMD(&y); | ||
| 25753 | sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); | ||
| 25754 | break; | ||
| 25755 | } | ||
| 25756 | case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ | ||
| 25757 | sqlite3_str_appendf(&sRes,"%02d", | ||
| 25758 | (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); | ||
| 25759 | break; | ||
| 25760 | } | ||
| 25345 | case 'Y': { | 25761 | case 'Y': { |
| 25346 | sqlite3_str_appendf(&sRes,"%04d",x.Y); | 25762 | sqlite3_str_appendf(&sRes,"%04d",x.Y); |
| 25347 | break; | 25763 | break; |
| @@ -25488,9 +25904,7 @@ static void timediffFunc( | |||
| 25488 | d1.iJD = d2.iJD - d1.iJD; | 25904 | d1.iJD = d2.iJD - d1.iJD; |
| 25489 | d1.iJD += (u64)1486995408 * (u64)100000; | 25905 | d1.iJD += (u64)1486995408 * (u64)100000; |
| 25490 | } | 25906 | } |
| 25491 | d1.validYMD = 0; | 25907 | clearYMD_HMS_TZ(&d1); |
| 25492 | d1.validHMS = 0; | ||
| 25493 | d1.validTZ = 0; | ||
| 25494 | computeYMD_HMS(&d1); | 25908 | computeYMD_HMS(&d1); |
| 25495 | sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); | 25909 | sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); |
| 25496 | sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", | 25910 | sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", |
| @@ -25559,6 +25973,36 @@ static void currentTimeFunc( | |||
| 25559 | } | 25973 | } |
| 25560 | #endif | 25974 | #endif |
| 25561 | 25975 | ||
| 25976 | #if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG) | ||
| 25977 | /* | ||
| 25978 | ** datedebug(...) | ||
| 25979 | ** | ||
| 25980 | ** This routine returns JSON that describes the internal DateTime object. | ||
| 25981 | ** Used for debugging and testing only. Subject to change. | ||
| 25982 | */ | ||
| 25983 | static void datedebugFunc( | ||
| 25984 | sqlite3_context *context, | ||
| 25985 | int argc, | ||
| 25986 | sqlite3_value **argv | ||
| 25987 | ){ | ||
| 25988 | DateTime x; | ||
| 25989 | if( isDate(context, argc, argv, &x)==0 ){ | ||
| 25990 | char *zJson; | ||
| 25991 | zJson = sqlite3_mprintf( | ||
| 25992 | "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d," | ||
| 25993 | "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d," | ||
| 25994 | "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d," | ||
| 25995 | "isUtc:%d,isLocal:%d}", | ||
| 25996 | x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz, | ||
| 25997 | x.s, x.validJD, x.validYMD, x.validHMS, | ||
| 25998 | x.nFloor, x.rawS, x.isError, x.useSubsec, | ||
| 25999 | x.isUtc, x.isLocal); | ||
| 26000 | sqlite3_result_text(context, zJson, -1, sqlite3_free); | ||
| 26001 | } | ||
| 26002 | } | ||
| 26003 | #endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */ | ||
| 26004 | |||
| 26005 | |||
| 25562 | /* | 26006 | /* |
| 25563 | ** This function registered all of the above C functions as SQL | 26007 | ** This function registered all of the above C functions as SQL |
| 25564 | ** functions. This should be the only routine in this file with | 26008 | ** functions. This should be the only routine in this file with |
| @@ -25574,6 +26018,9 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ | |||
| 25574 | PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), | 26018 | PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), |
| 25575 | PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), | 26019 | PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), |
| 25576 | PURE_DATE(timediff, 2, 0, 0, timediffFunc ), | 26020 | PURE_DATE(timediff, 2, 0, 0, timediffFunc ), |
| 26021 | #ifdef SQLITE_DEBUG | ||
| 26022 | PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ), | ||
| 26023 | #endif | ||
| 25577 | DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), | 26024 | DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), |
| 25578 | DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), | 26025 | DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), |
| 25579 | DFUNCTION(current_date, 0, 0, 0, cdateFunc ), | 26026 | DFUNCTION(current_date, 0, 0, 0, cdateFunc ), |
| @@ -29453,7 +29900,7 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ | |||
| 29453 | SQLITE_MEMORY_BARRIER; | 29900 | SQLITE_MEMORY_BARRIER; |
| 29454 | #elif defined(__GNUC__) | 29901 | #elif defined(__GNUC__) |
| 29455 | __sync_synchronize(); | 29902 | __sync_synchronize(); |
| 29456 | #elif MSVC_VERSION>=1300 | 29903 | #elif MSVC_VERSION>=1400 |
| 29457 | _ReadWriteBarrier(); | 29904 | _ReadWriteBarrier(); |
| 29458 | #elif defined(MemoryBarrier) | 29905 | #elif defined(MemoryBarrier) |
| 29459 | MemoryBarrier(); | 29906 | MemoryBarrier(); |
| @@ -29989,6 +30436,24 @@ static void sqlite3MallocAlarm(int nByte){ | |||
| 29989 | sqlite3_mutex_enter(mem0.mutex); | 30436 | sqlite3_mutex_enter(mem0.mutex); |
| 29990 | } | 30437 | } |
| 29991 | 30438 | ||
| 30439 | #ifdef SQLITE_DEBUG | ||
| 30440 | /* | ||
| 30441 | ** This routine is called whenever an out-of-memory condition is seen, | ||
| 30442 | ** It's only purpose to to serve as a breakpoint for gdb or similar | ||
| 30443 | ** code debuggers when working on out-of-memory conditions, for example | ||
| 30444 | ** caused by PRAGMA hard_heap_limit=N. | ||
| 30445 | */ | ||
| 30446 | static SQLITE_NOINLINE void test_oom_breakpoint(u64 n){ | ||
| 30447 | static u64 nOomFault = 0; | ||
| 30448 | nOomFault += n; | ||
| 30449 | /* The assert() is never reached in a human lifetime. It is here mostly | ||
| 30450 | ** to prevent code optimizers from optimizing out this function. */ | ||
| 30451 | assert( (nOomFault>>32) < 0xffffffff ); | ||
| 30452 | } | ||
| 30453 | #else | ||
| 30454 | # define test_oom_breakpoint(X) /* No-op for production builds */ | ||
| 30455 | #endif | ||
| 30456 | |||
| 29992 | /* | 30457 | /* |
| 29993 | ** Do a memory allocation with statistics and alarms. Assume the | 30458 | ** Do a memory allocation with statistics and alarms. Assume the |
| 29994 | ** lock is already held. | 30459 | ** lock is already held. |
| @@ -30015,6 +30480,7 @@ static void mallocWithAlarm(int n, void **pp){ | |||
| 30015 | if( mem0.hardLimit ){ | 30480 | if( mem0.hardLimit ){ |
| 30016 | nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); | 30481 | nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); |
| 30017 | if( nUsed >= mem0.hardLimit - nFull ){ | 30482 | if( nUsed >= mem0.hardLimit - nFull ){ |
| 30483 | test_oom_breakpoint(1); | ||
| 30018 | *pp = 0; | 30484 | *pp = 0; |
| 30019 | return; | 30485 | return; |
| 30020 | } | 30486 | } |
| @@ -30303,6 +30769,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ | |||
| 30303 | sqlite3MallocAlarm(nDiff); | 30769 | sqlite3MallocAlarm(nDiff); |
| 30304 | if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ | 30770 | if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ |
| 30305 | sqlite3_mutex_leave(mem0.mutex); | 30771 | sqlite3_mutex_leave(mem0.mutex); |
| 30772 | test_oom_breakpoint(1); | ||
| 30306 | return 0; | 30773 | return 0; |
| 30307 | } | 30774 | } |
| 30308 | } | 30775 | } |
| @@ -31169,6 +31636,7 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 31169 | if( xtype==etFLOAT ){ | 31636 | if( xtype==etFLOAT ){ |
| 31170 | iRound = -precision; | 31637 | iRound = -precision; |
| 31171 | }else if( xtype==etGENERIC ){ | 31638 | }else if( xtype==etGENERIC ){ |
| 31639 | if( precision==0 ) precision = 1; | ||
| 31172 | iRound = precision; | 31640 | iRound = precision; |
| 31173 | }else{ | 31641 | }else{ |
| 31174 | iRound = precision+1; | 31642 | iRound = precision+1; |
| @@ -31204,13 +31672,14 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 31204 | } | 31672 | } |
| 31205 | 31673 | ||
| 31206 | exp = s.iDP-1; | 31674 | exp = s.iDP-1; |
| 31207 | if( xtype==etGENERIC && precision>0 ) precision--; | ||
| 31208 | 31675 | ||
| 31209 | /* | 31676 | /* |
| 31210 | ** If the field type is etGENERIC, then convert to either etEXP | 31677 | ** If the field type is etGENERIC, then convert to either etEXP |
| 31211 | ** or etFLOAT, as appropriate. | 31678 | ** or etFLOAT, as appropriate. |
| 31212 | */ | 31679 | */ |
| 31213 | if( xtype==etGENERIC ){ | 31680 | if( xtype==etGENERIC ){ |
| 31681 | assert( precision>0 ); | ||
| 31682 | precision--; | ||
| 31214 | flag_rtz = !flag_alternateform; | 31683 | flag_rtz = !flag_alternateform; |
| 31215 | if( exp<-4 || exp>precision ){ | 31684 | if( exp<-4 || exp>precision ){ |
| 31216 | xtype = etEXP; | 31685 | xtype = etEXP; |
| @@ -31526,9 +31995,13 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 31526 | sqlite3_str_appendall(pAccum, pItem->zAlias); | 31995 | sqlite3_str_appendall(pAccum, pItem->zAlias); |
| 31527 | }else{ | 31996 | }else{ |
| 31528 | Select *pSel = pItem->pSelect; | 31997 | Select *pSel = pItem->pSelect; |
| 31529 | assert( pSel!=0 ); | 31998 | assert( pSel!=0 ); /* Because of tag-20240424-1 */ |
| 31530 | if( pSel->selFlags & SF_NestedFrom ){ | 31999 | if( pSel->selFlags & SF_NestedFrom ){ |
| 31531 | sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); | 32000 | sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); |
| 32001 | }else if( pSel->selFlags & SF_MultiValue ){ | ||
| 32002 | assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy ); | ||
| 32003 | sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE", | ||
| 32004 | pItem->u1.nRow); | ||
| 31532 | }else{ | 32005 | }else{ |
| 31533 | sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); | 32006 | sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); |
| 31534 | } | 32007 | } |
| @@ -32040,7 +32513,7 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ | |||
| 32040 | 32513 | ||
| 32041 | 32514 | ||
| 32042 | /***************************************************************************** | 32515 | /***************************************************************************** |
| 32043 | ** Reference counted string storage | 32516 | ** Reference counted string/blob storage |
| 32044 | *****************************************************************************/ | 32517 | *****************************************************************************/ |
| 32045 | 32518 | ||
| 32046 | /* | 32519 | /* |
| @@ -32305,8 +32778,10 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) | |||
| 32305 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; | 32778 | x.printfFlags |= SQLITE_PRINTF_INTERNAL; |
| 32306 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); | 32779 | sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); |
| 32307 | if( pItem->pTab ){ | 32780 | if( pItem->pTab ){ |
| 32308 | sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", | 32781 | sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", |
| 32309 | pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); | 32782 | pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, |
| 32783 | pItem->colUsed, | ||
| 32784 | pItem->fg.rowidUsed ? "+rowid" : ""); | ||
| 32310 | } | 32785 | } |
| 32311 | if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ | 32786 | if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ |
| 32312 | sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); | 32787 | sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); |
| @@ -32346,12 +32821,14 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) | |||
| 32346 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); | 32821 | sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); |
| 32347 | } | 32822 | } |
| 32348 | if( pItem->pSelect ){ | 32823 | if( pItem->pSelect ){ |
| 32824 | sqlite3TreeViewPush(&pView, i+1<pSrc->nSrc); | ||
| 32349 | if( pItem->pTab ){ | 32825 | if( pItem->pTab ){ |
| 32350 | Table *pTab = pItem->pTab; | 32826 | Table *pTab = pItem->pTab; |
| 32351 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); | 32827 | sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); |
| 32352 | } | 32828 | } |
| 32353 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); | 32829 | assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); |
| 32354 | sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); | 32830 | sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); |
| 32831 | sqlite3TreeViewPop(&pView); | ||
| 32355 | } | 32832 | } |
| 32356 | if( pItem->fg.isTabFunc ){ | 32833 | if( pItem->fg.isTabFunc ){ |
| 32357 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); | 32834 | sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); |
| @@ -32455,7 +32932,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m | |||
| 32455 | sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); | 32932 | sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); |
| 32456 | sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); | 32933 | sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); |
| 32457 | if( p->pLimit->pRight ){ | 32934 | if( p->pLimit->pRight ){ |
| 32458 | sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); | 32935 | sqlite3TreeViewItem(pView, "OFFSET", 0); |
| 32459 | sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); | 32936 | sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); |
| 32460 | sqlite3TreeViewPop(&pView); | 32937 | sqlite3TreeViewPop(&pView); |
| 32461 | } | 32938 | } |
| @@ -32892,7 +33369,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m | |||
| 32892 | assert( pExpr->x.pList->nExpr==2 ); | 33369 | assert( pExpr->x.pList->nExpr==2 ); |
| 32893 | pY = pExpr->x.pList->a[0].pExpr; | 33370 | pY = pExpr->x.pList->a[0].pExpr; |
| 32894 | pZ = pExpr->x.pList->a[1].pExpr; | 33371 | pZ = pExpr->x.pList->a[1].pExpr; |
| 32895 | sqlite3TreeViewLine(pView, "BETWEEN"); | 33372 | sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); |
| 32896 | sqlite3TreeViewExpr(pView, pX, 1); | 33373 | sqlite3TreeViewExpr(pView, pX, 1); |
| 32897 | sqlite3TreeViewExpr(pView, pY, 1); | 33374 | sqlite3TreeViewExpr(pView, pY, 1); |
| 32898 | sqlite3TreeViewExpr(pView, pZ, 0); | 33375 | sqlite3TreeViewExpr(pView, pZ, 0); |
| @@ -34027,7 +34504,38 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read( | |||
| 34027 | return c; | 34504 | return c; |
| 34028 | } | 34505 | } |
| 34029 | 34506 | ||
| 34030 | 34507 | /* | |
| 34508 | ** Read a single UTF8 character out of buffer z[], but reading no | ||
| 34509 | ** more than n characters from the buffer. z[] is not zero-terminated. | ||
| 34510 | ** | ||
| 34511 | ** Return the number of bytes used to construct the character. | ||
| 34512 | ** | ||
| 34513 | ** Invalid UTF8 might generate a strange result. No effort is made | ||
| 34514 | ** to detect invalid UTF8. | ||
| 34515 | ** | ||
| 34516 | ** At most 4 bytes will be read out of z[]. The return value will always | ||
| 34517 | ** be between 1 and 4. | ||
| 34518 | */ | ||
| 34519 | SQLITE_PRIVATE int sqlite3Utf8ReadLimited( | ||
| 34520 | const u8 *z, | ||
| 34521 | int n, | ||
| 34522 | u32 *piOut | ||
| 34523 | ){ | ||
| 34524 | u32 c; | ||
| 34525 | int i = 1; | ||
| 34526 | assert( n>0 ); | ||
| 34527 | c = z[0]; | ||
| 34528 | if( c>=0xc0 ){ | ||
| 34529 | c = sqlite3Utf8Trans1[c-0xc0]; | ||
| 34530 | if( n>4 ) n = 4; | ||
| 34531 | while( i<n && (z[i] & 0xc0)==0x80 ){ | ||
| 34532 | c = (c<<6) + (0x3f & z[i]); | ||
| 34533 | i++; | ||
| 34534 | } | ||
| 34535 | } | ||
| 34536 | *piOut = c; | ||
| 34537 | return i; | ||
| 34538 | } | ||
| 34031 | 34539 | ||
| 34032 | 34540 | ||
| 34033 | /* | 34541 | /* |
| @@ -34469,6 +34977,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){ | |||
| 34469 | } | 34977 | } |
| 34470 | #endif /* SQLITE_OMIT_FLOATING_POINT */ | 34978 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 34471 | 34979 | ||
| 34980 | #ifndef SQLITE_OMIT_FLOATING_POINT | ||
| 34981 | /* | ||
| 34982 | ** Return true if the floating point value is NaN or +Inf or -Inf. | ||
| 34983 | */ | ||
| 34984 | SQLITE_PRIVATE int sqlite3IsOverflow(double x){ | ||
| 34985 | int rc; /* The value return */ | ||
| 34986 | u64 y; | ||
| 34987 | memcpy(&y,&x,sizeof(y)); | ||
| 34988 | rc = IsOvfl(y); | ||
| 34989 | return rc; | ||
| 34990 | } | ||
| 34991 | #endif /* SQLITE_OMIT_FLOATING_POINT */ | ||
| 34992 | |||
| 34472 | /* | 34993 | /* |
| 34473 | ** Compute a string length that is limited to what can be stored in | 34994 | ** Compute a string length that is limited to what can be stored in |
| 34474 | ** lower 30 bits of a 32-bit signed integer. | 34995 | ** lower 30 bits of a 32-bit signed integer. |
| @@ -34542,7 +35063,7 @@ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ | |||
| 34542 | */ | 35063 | */ |
| 34543 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ | 35064 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ |
| 34544 | if( rc==SQLITE_IOERR_NOMEM ) return; | 35065 | if( rc==SQLITE_IOERR_NOMEM ) return; |
| 34545 | #ifdef SQLITE_USE_SEH | 35066 | #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) |
| 34546 | if( rc==SQLITE_IOERR_IN_PAGE ){ | 35067 | if( rc==SQLITE_IOERR_IN_PAGE ){ |
| 34547 | int ii; | 35068 | int ii; |
| 34548 | int iErr; | 35069 | int iErr; |
| @@ -34713,6 +35234,44 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ | |||
| 34713 | } | 35234 | } |
| 34714 | 35235 | ||
| 34715 | /* | 35236 | /* |
| 35237 | ** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken | ||
| 35238 | ** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those | ||
| 35239 | ** that contain '_' characters that must be removed before further processing. | ||
| 35240 | */ | ||
| 35241 | SQLITE_PRIVATE void sqlite3DequoteNumber(Parse *pParse, Expr *p){ | ||
| 35242 | assert( p!=0 || pParse->db->mallocFailed ); | ||
| 35243 | if( p ){ | ||
| 35244 | const char *pIn = p->u.zToken; | ||
| 35245 | char *pOut = p->u.zToken; | ||
| 35246 | int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X')); | ||
| 35247 | int iValue; | ||
| 35248 | assert( p->op==TK_QNUMBER ); | ||
| 35249 | p->op = TK_INTEGER; | ||
| 35250 | do { | ||
| 35251 | if( *pIn!=SQLITE_DIGIT_SEPARATOR ){ | ||
| 35252 | *pOut++ = *pIn; | ||
| 35253 | if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT; | ||
| 35254 | }else{ | ||
| 35255 | if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1]))) | ||
| 35256 | || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1]))) | ||
| 35257 | ){ | ||
| 35258 | sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken); | ||
| 35259 | } | ||
| 35260 | } | ||
| 35261 | }while( *pIn++ ); | ||
| 35262 | if( bHex ) p->op = TK_INTEGER; | ||
| 35263 | |||
| 35264 | /* tag-20240227-a: If after dequoting, the number is an integer that | ||
| 35265 | ** fits in 32 bits, then it must be converted into EP_IntValue. Other | ||
| 35266 | ** parts of the code expect this. See also tag-20240227-b. */ | ||
| 35267 | if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){ | ||
| 35268 | p->u.iValue = iValue; | ||
| 35269 | p->flags |= EP_IntValue; | ||
| 35270 | } | ||
| 35271 | } | ||
| 35272 | } | ||
| 35273 | |||
| 35274 | /* | ||
| 34716 | ** If the input token p is quoted, try to adjust the token to remove | 35275 | ** If the input token p is quoted, try to adjust the token to remove |
| 34717 | ** the quotes. This is not always possible: | 35276 | ** the quotes. This is not always possible: |
| 34718 | ** | 35277 | ** |
| @@ -35028,6 +35587,9 @@ do_atof_calc: | |||
| 35028 | u64 s2; | 35587 | u64 s2; |
| 35029 | rr[0] = (double)s; | 35588 | rr[0] = (double)s; |
| 35030 | s2 = (u64)rr[0]; | 35589 | s2 = (u64)rr[0]; |
| 35590 | #if defined(_MSC_VER) && _MSC_VER<1700 | ||
| 35591 | if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } | ||
| 35592 | #endif | ||
| 35031 | rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); | 35593 | rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); |
| 35032 | if( e>0 ){ | 35594 | if( e>0 ){ |
| 35033 | while( e>=100 ){ | 35595 | while( e>=100 ){ |
| @@ -35470,7 +36032,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou | |||
| 35470 | assert( p->n>0 ); | 36032 | assert( p->n>0 ); |
| 35471 | assert( p->n<sizeof(p->zBuf) ); | 36033 | assert( p->n<sizeof(p->zBuf) ); |
| 35472 | p->iDP = p->n + exp; | 36034 | p->iDP = p->n + exp; |
| 35473 | if( iRound<0 ){ | 36035 | if( iRound<=0 ){ |
| 35474 | iRound = p->iDP - iRound; | 36036 | iRound = p->iDP - iRound; |
| 35475 | if( iRound==0 && p->zBuf[i+1]>='5' ){ | 36037 | if( iRound==0 && p->zBuf[i+1]>='5' ){ |
| 35476 | iRound = 1; | 36038 | iRound = 1; |
| @@ -36648,7 +37210,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 36648 | /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), | 37210 | /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), |
| 36649 | /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), | 37211 | /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 36650 | /* 32 */ "Last" OpHelp(""), | 37212 | /* 32 */ "Last" OpHelp(""), |
| 36651 | /* 33 */ "IfSmaller" OpHelp(""), | 37213 | /* 33 */ "IfSizeBetween" OpHelp(""), |
| 36652 | /* 34 */ "SorterSort" OpHelp(""), | 37214 | /* 34 */ "SorterSort" OpHelp(""), |
| 36653 | /* 35 */ "Sort" OpHelp(""), | 37215 | /* 35 */ "Sort" OpHelp(""), |
| 36654 | /* 36 */ "Rewind" OpHelp(""), | 37216 | /* 36 */ "Rewind" OpHelp(""), |
| @@ -36693,7 +37255,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 36693 | /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), | 37255 | /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 36694 | /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), | 37256 | /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"), |
| 36695 | /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), | 37257 | /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| 36696 | /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), | 37258 | /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1)"), |
| 36697 | /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), | 37259 | /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 36698 | /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), | 37260 | /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), |
| 36699 | /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), | 37261 | /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"), |
| @@ -36796,13 +37358,15 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 36796 | /* 178 */ "Pagecount" OpHelp(""), | 37358 | /* 178 */ "Pagecount" OpHelp(""), |
| 36797 | /* 179 */ "MaxPgcnt" OpHelp(""), | 37359 | /* 179 */ "MaxPgcnt" OpHelp(""), |
| 36798 | /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), | 37360 | /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), |
| 36799 | /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), | 37361 | /* 181 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), |
| 36800 | /* 182 */ "Trace" OpHelp(""), | 37362 | /* 182 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), |
| 36801 | /* 183 */ "CursorHint" OpHelp(""), | 37363 | /* 183 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), |
| 36802 | /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), | 37364 | /* 184 */ "Trace" OpHelp(""), |
| 36803 | /* 185 */ "Noop" OpHelp(""), | 37365 | /* 185 */ "CursorHint" OpHelp(""), |
| 36804 | /* 186 */ "Explain" OpHelp(""), | 37366 | /* 186 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), |
| 36805 | /* 187 */ "Abortable" OpHelp(""), | 37367 | /* 187 */ "Noop" OpHelp(""), |
| 37368 | /* 188 */ "Explain" OpHelp(""), | ||
| 37369 | /* 189 */ "Abortable" OpHelp(""), | ||
| 36806 | }; | 37370 | }; |
| 36807 | return azName[i]; | 37371 | return azName[i]; |
| 36808 | } | 37372 | } |
| @@ -39089,8 +39653,12 @@ static int unixLogErrorAtLine( | |||
| 39089 | ** available, the error message will often be an empty string. Not a | 39653 | ** available, the error message will often be an empty string. Not a |
| 39090 | ** huge problem. Incorrectly concluding that the GNU version is available | 39654 | ** huge problem. Incorrectly concluding that the GNU version is available |
| 39091 | ** could lead to a segfault though. | 39655 | ** could lead to a segfault though. |
| 39656 | ** | ||
| 39657 | ** Forum post 3f13857fa4062301 reports that the Android SDK may use | ||
| 39658 | ** int-type return, depending on its version. | ||
| 39092 | */ | 39659 | */ |
| 39093 | #if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) | 39660 | #if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \ |
| 39661 | && !defined(ANDROID) && !defined(__ANDROID__) | ||
| 39094 | zErr = | 39662 | zErr = |
| 39095 | # endif | 39663 | # endif |
| 39096 | strerror_r(iErrno, aErr, sizeof(aErr)-1); | 39664 | strerror_r(iErrno, aErr, sizeof(aErr)-1); |
| @@ -41848,7 +42416,13 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ | |||
| 41848 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | 42416 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 41849 | case SQLITE_FCNTL_LOCK_TIMEOUT: { | 42417 | case SQLITE_FCNTL_LOCK_TIMEOUT: { |
| 41850 | int iOld = pFile->iBusyTimeout; | 42418 | int iOld = pFile->iBusyTimeout; |
| 42419 | #if SQLITE_ENABLE_SETLK_TIMEOUT==1 | ||
| 41851 | pFile->iBusyTimeout = *(int*)pArg; | 42420 | pFile->iBusyTimeout = *(int*)pArg; |
| 42421 | #elif SQLITE_ENABLE_SETLK_TIMEOUT==2 | ||
| 42422 | pFile->iBusyTimeout = !!(*(int*)pArg); | ||
| 42423 | #else | ||
| 42424 | # error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" | ||
| 42425 | #endif | ||
| 41852 | *(int*)pArg = iOld; | 42426 | *(int*)pArg = iOld; |
| 41853 | return SQLITE_OK; | 42427 | return SQLITE_OK; |
| 41854 | } | 42428 | } |
| @@ -42101,6 +42675,25 @@ static int unixGetpagesize(void){ | |||
| 42101 | ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and | 42675 | ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and |
| 42102 | ** unixMutexHeld() is true when reading or writing any other field | 42676 | ** unixMutexHeld() is true when reading or writing any other field |
| 42103 | ** in this structure. | 42677 | ** in this structure. |
| 42678 | ** | ||
| 42679 | ** aLock[SQLITE_SHM_NLOCK]: | ||
| 42680 | ** This array records the various locks held by clients on each of the | ||
| 42681 | ** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no | ||
| 42682 | ** locks are held by the process on this slot. If it is set to -1, then | ||
| 42683 | ** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] | ||
| 42684 | ** value is set to a positive value, then it is the number of shared | ||
| 42685 | ** locks currently held on the slot. | ||
| 42686 | ** | ||
| 42687 | ** aMutex[SQLITE_SHM_NLOCK]: | ||
| 42688 | ** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex | ||
| 42689 | ** pShmMutex is used to protect the aLock[] array and the right to | ||
| 42690 | ** call fcntl() on unixShmNode.hShm to obtain or release locks. | ||
| 42691 | ** | ||
| 42692 | ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array | ||
| 42693 | ** of mutexes - one for each locking slot. To read or write locking | ||
| 42694 | ** slot aLock[iSlot], the caller must hold the corresponding mutex | ||
| 42695 | ** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a | ||
| 42696 | ** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. | ||
| 42104 | */ | 42697 | */ |
| 42105 | struct unixShmNode { | 42698 | struct unixShmNode { |
| 42106 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ | 42699 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ |
| @@ -42114,10 +42707,11 @@ struct unixShmNode { | |||
| 42114 | char **apRegion; /* Array of mapped shared-memory regions */ | 42707 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 42115 | int nRef; /* Number of unixShm objects pointing to this */ | 42708 | int nRef; /* Number of unixShm objects pointing to this */ |
| 42116 | unixShm *pFirst; /* All unixShm objects pointing to this */ | 42709 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 42710 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 42711 | sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; | ||
| 42712 | #endif | ||
| 42117 | int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ | 42713 | int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ |
| 42118 | #ifdef SQLITE_DEBUG | 42714 | #ifdef SQLITE_DEBUG |
| 42119 | u8 exclMask; /* Mask of exclusive locks held */ | ||
| 42120 | u8 sharedMask; /* Mask of shared locks held */ | ||
| 42121 | u8 nextShmId; /* Next available unixShm.id value */ | 42715 | u8 nextShmId; /* Next available unixShm.id value */ |
| 42122 | #endif | 42716 | #endif |
| 42123 | }; | 42717 | }; |
| @@ -42200,16 +42794,35 @@ static int unixShmSystemLock( | |||
| 42200 | struct flock f; /* The posix advisory locking structure */ | 42794 | struct flock f; /* The posix advisory locking structure */ |
| 42201 | int rc = SQLITE_OK; /* Result code form fcntl() */ | 42795 | int rc = SQLITE_OK; /* Result code form fcntl() */ |
| 42202 | 42796 | ||
| 42203 | /* Access to the unixShmNode object is serialized by the caller */ | ||
| 42204 | pShmNode = pFile->pInode->pShmNode; | 42797 | pShmNode = pFile->pInode->pShmNode; |
| 42205 | assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); | 42798 | |
| 42206 | assert( pShmNode->nRef>0 || unixMutexHeld() ); | 42799 | /* Assert that the parameters are within expected range and that the |
| 42800 | ** correct mutex or mutexes are held. */ | ||
| 42801 | assert( pShmNode->nRef>=0 ); | ||
| 42802 | assert( (ofst==UNIX_SHM_DMS && n==1) | ||
| 42803 | || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) | ||
| 42804 | ); | ||
| 42805 | if( ofst==UNIX_SHM_DMS ){ | ||
| 42806 | assert( pShmNode->nRef>0 || unixMutexHeld() ); | ||
| 42807 | assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); | ||
| 42808 | }else{ | ||
| 42809 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 42810 | int ii; | ||
| 42811 | for(ii=ofst-UNIX_SHM_BASE; ii<ofst-UNIX_SHM_BASE+n; ii++){ | ||
| 42812 | assert( sqlite3_mutex_held(pShmNode->aMutex[ii]) ); | ||
| 42813 | } | ||
| 42814 | #else | ||
| 42815 | assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); | ||
| 42816 | assert( pShmNode->nRef>0 ); | ||
| 42817 | #endif | ||
| 42818 | } | ||
| 42207 | 42819 | ||
| 42208 | /* Shared locks never span more than one byte */ | 42820 | /* Shared locks never span more than one byte */ |
| 42209 | assert( n==1 || lockType!=F_RDLCK ); | 42821 | assert( n==1 || lockType!=F_RDLCK ); |
| 42210 | 42822 | ||
| 42211 | /* Locks are within range */ | 42823 | /* Locks are within range */ |
| 42212 | assert( n>=1 && n<=SQLITE_SHM_NLOCK ); | 42824 | assert( n>=1 && n<=SQLITE_SHM_NLOCK ); |
| 42825 | assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) ); | ||
| 42213 | 42826 | ||
| 42214 | if( pShmNode->hShm>=0 ){ | 42827 | if( pShmNode->hShm>=0 ){ |
| 42215 | int res; | 42828 | int res; |
| @@ -42220,7 +42833,7 @@ static int unixShmSystemLock( | |||
| 42220 | f.l_len = n; | 42833 | f.l_len = n; |
| 42221 | res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); | 42834 | res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); |
| 42222 | if( res==-1 ){ | 42835 | if( res==-1 ){ |
| 42223 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | 42836 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 |
| 42224 | rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); | 42837 | rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); |
| 42225 | #else | 42838 | #else |
| 42226 | rc = SQLITE_BUSY; | 42839 | rc = SQLITE_BUSY; |
| @@ -42228,39 +42841,28 @@ static int unixShmSystemLock( | |||
| 42228 | } | 42841 | } |
| 42229 | } | 42842 | } |
| 42230 | 42843 | ||
| 42231 | /* Update the global lock state and do debug tracing */ | 42844 | /* Do debug tracing */ |
| 42232 | #ifdef SQLITE_DEBUG | 42845 | #ifdef SQLITE_DEBUG |
| 42233 | { u16 mask; | ||
| 42234 | OSTRACE(("SHM-LOCK ")); | 42846 | OSTRACE(("SHM-LOCK ")); |
| 42235 | mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst); | ||
| 42236 | if( rc==SQLITE_OK ){ | 42847 | if( rc==SQLITE_OK ){ |
| 42237 | if( lockType==F_UNLCK ){ | 42848 | if( lockType==F_UNLCK ){ |
| 42238 | OSTRACE(("unlock %d ok", ofst)); | 42849 | OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); |
| 42239 | pShmNode->exclMask &= ~mask; | ||
| 42240 | pShmNode->sharedMask &= ~mask; | ||
| 42241 | }else if( lockType==F_RDLCK ){ | 42850 | }else if( lockType==F_RDLCK ){ |
| 42242 | OSTRACE(("read-lock %d ok", ofst)); | 42851 | OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); |
| 42243 | pShmNode->exclMask &= ~mask; | ||
| 42244 | pShmNode->sharedMask |= mask; | ||
| 42245 | }else{ | 42852 | }else{ |
| 42246 | assert( lockType==F_WRLCK ); | 42853 | assert( lockType==F_WRLCK ); |
| 42247 | OSTRACE(("write-lock %d ok", ofst)); | 42854 | OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); |
| 42248 | pShmNode->exclMask |= mask; | ||
| 42249 | pShmNode->sharedMask &= ~mask; | ||
| 42250 | } | 42855 | } |
| 42251 | }else{ | 42856 | }else{ |
| 42252 | if( lockType==F_UNLCK ){ | 42857 | if( lockType==F_UNLCK ){ |
| 42253 | OSTRACE(("unlock %d failed", ofst)); | 42858 | OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); |
| 42254 | }else if( lockType==F_RDLCK ){ | 42859 | }else if( lockType==F_RDLCK ){ |
| 42255 | OSTRACE(("read-lock failed")); | 42860 | OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); |
| 42256 | }else{ | 42861 | }else{ |
| 42257 | assert( lockType==F_WRLCK ); | 42862 | assert( lockType==F_WRLCK ); |
| 42258 | OSTRACE(("write-lock %d failed", ofst)); | 42863 | OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); |
| 42259 | } | 42864 | } |
| 42260 | } | 42865 | } |
| 42261 | OSTRACE((" - afterwards %03x,%03x\n", | ||
| 42262 | pShmNode->sharedMask, pShmNode->exclMask)); | ||
| 42263 | } | ||
| 42264 | #endif | 42866 | #endif |
| 42265 | 42867 | ||
| 42266 | return rc; | 42868 | return rc; |
| @@ -42297,6 +42899,11 @@ static void unixShmPurge(unixFile *pFd){ | |||
| 42297 | int i; | 42899 | int i; |
| 42298 | assert( p->pInode==pFd->pInode ); | 42900 | assert( p->pInode==pFd->pInode ); |
| 42299 | sqlite3_mutex_free(p->pShmMutex); | 42901 | sqlite3_mutex_free(p->pShmMutex); |
| 42902 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 42903 | for(i=0; i<SQLITE_SHM_NLOCK; i++){ | ||
| 42904 | sqlite3_mutex_free(p->aMutex[i]); | ||
| 42905 | } | ||
| 42906 | #endif | ||
| 42300 | for(i=0; i<p->nRegion; i+=nShmPerMap){ | 42907 | for(i=0; i<p->nRegion; i+=nShmPerMap){ |
| 42301 | if( p->hShm>=0 ){ | 42908 | if( p->hShm>=0 ){ |
| 42302 | osMunmap(p->apRegion[i], p->szRegion); | 42909 | osMunmap(p->apRegion[i], p->szRegion); |
| @@ -42356,7 +42963,20 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ | |||
| 42356 | pShmNode->isUnlocked = 1; | 42963 | pShmNode->isUnlocked = 1; |
| 42357 | rc = SQLITE_READONLY_CANTINIT; | 42964 | rc = SQLITE_READONLY_CANTINIT; |
| 42358 | }else{ | 42965 | }else{ |
| 42966 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 42967 | /* Do not use a blocking lock here. If the lock cannot be obtained | ||
| 42968 | ** immediately, it means some other connection is truncating the | ||
| 42969 | ** *-shm file. And after it has done so, it will not release its | ||
| 42970 | ** lock, but only downgrade it to a shared lock. So no point in | ||
| 42971 | ** blocking here. The call below to obtain the shared DMS lock may | ||
| 42972 | ** use a blocking lock. */ | ||
| 42973 | int iSaveTimeout = pDbFd->iBusyTimeout; | ||
| 42974 | pDbFd->iBusyTimeout = 0; | ||
| 42975 | #endif | ||
| 42359 | rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); | 42976 | rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); |
| 42977 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 42978 | pDbFd->iBusyTimeout = iSaveTimeout; | ||
| 42979 | #endif | ||
| 42360 | /* The first connection to attach must truncate the -shm file. We | 42980 | /* The first connection to attach must truncate the -shm file. We |
| 42361 | ** truncate to 3 bytes (an arbitrary small number, less than the | 42981 | ** truncate to 3 bytes (an arbitrary small number, less than the |
| 42362 | ** -shm header size) rather than 0 as a system debugging aid, to | 42982 | ** -shm header size) rather than 0 as a system debugging aid, to |
| @@ -42477,6 +43097,18 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ | |||
| 42477 | rc = SQLITE_NOMEM_BKPT; | 43097 | rc = SQLITE_NOMEM_BKPT; |
| 42478 | goto shm_open_err; | 43098 | goto shm_open_err; |
| 42479 | } | 43099 | } |
| 43100 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 43101 | { | ||
| 43102 | int ii; | ||
| 43103 | for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){ | ||
| 43104 | pShmNode->aMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); | ||
| 43105 | if( pShmNode->aMutex[ii]==0 ){ | ||
| 43106 | rc = SQLITE_NOMEM_BKPT; | ||
| 43107 | goto shm_open_err; | ||
| 43108 | } | ||
| 43109 | } | ||
| 43110 | } | ||
| 43111 | #endif | ||
| 42480 | } | 43112 | } |
| 42481 | 43113 | ||
| 42482 | if( pInode->bProcessLock==0 ){ | 43114 | if( pInode->bProcessLock==0 ){ |
| @@ -42698,9 +43330,11 @@ shmpage_out: | |||
| 42698 | */ | 43330 | */ |
| 42699 | #ifdef SQLITE_DEBUG | 43331 | #ifdef SQLITE_DEBUG |
| 42700 | static int assertLockingArrayOk(unixShmNode *pShmNode){ | 43332 | static int assertLockingArrayOk(unixShmNode *pShmNode){ |
| 43333 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 43334 | return 1; | ||
| 43335 | #else | ||
| 42701 | unixShm *pX; | 43336 | unixShm *pX; |
| 42702 | int aLock[SQLITE_SHM_NLOCK]; | 43337 | int aLock[SQLITE_SHM_NLOCK]; |
| 42703 | assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); | ||
| 42704 | 43338 | ||
| 42705 | memset(aLock, 0, sizeof(aLock)); | 43339 | memset(aLock, 0, sizeof(aLock)); |
| 42706 | for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ | 43340 | for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ |
| @@ -42718,13 +43352,14 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){ | |||
| 42718 | 43352 | ||
| 42719 | assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); | 43353 | assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); |
| 42720 | return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); | 43354 | return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); |
| 43355 | #endif | ||
| 42721 | } | 43356 | } |
| 42722 | #endif | 43357 | #endif |
| 42723 | 43358 | ||
| 42724 | /* | 43359 | /* |
| 42725 | ** Change the lock state for a shared-memory segment. | 43360 | ** Change the lock state for a shared-memory segment. |
| 42726 | ** | 43361 | ** |
| 42727 | ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little | 43362 | ** Note that the relationship between SHARED and EXCLUSIVE locks is a little |
| 42728 | ** different here than in posix. In xShmLock(), one can go from unlocked | 43363 | ** different here than in posix. In xShmLock(), one can go from unlocked |
| 42729 | ** to shared and back or from unlocked to exclusive and back. But one may | 43364 | ** to shared and back or from unlocked to exclusive and back. But one may |
| 42730 | ** not go from shared to exclusive or from exclusive to shared. | 43365 | ** not go from shared to exclusive or from exclusive to shared. |
| @@ -42739,7 +43374,7 @@ static int unixShmLock( | |||
| 42739 | unixShm *p; /* The shared memory being locked */ | 43374 | unixShm *p; /* The shared memory being locked */ |
| 42740 | unixShmNode *pShmNode; /* The underlying file iNode */ | 43375 | unixShmNode *pShmNode; /* The underlying file iNode */ |
| 42741 | int rc = SQLITE_OK; /* Result code */ | 43376 | int rc = SQLITE_OK; /* Result code */ |
| 42742 | u16 mask; /* Mask of locks to take or release */ | 43377 | u16 mask = (1<<(ofst+n)) - (1<<ofst); /* Mask of locks to take or release */ |
| 42743 | int *aLock; | 43378 | int *aLock; |
| 42744 | 43379 | ||
| 42745 | p = pDbFd->pShm; | 43380 | p = pDbFd->pShm; |
| @@ -42774,88 +43409,151 @@ static int unixShmLock( | |||
| 42774 | ** It is not permitted to block on the RECOVER lock. | 43409 | ** It is not permitted to block on the RECOVER lock. |
| 42775 | */ | 43410 | */ |
| 42776 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | 43411 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 42777 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( | 43412 | { |
| 42778 | (ofst!=2) /* not RECOVER */ | 43413 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 42779 | && (ofst!=1 || (p->exclMask|p->sharedMask)==0) | 43414 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 42780 | && (ofst!=0 || (p->exclMask|p->sharedMask)<3) | 43415 | (ofst!=2) /* not RECOVER */ |
| 42781 | && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst)) | 43416 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 42782 | )); | 43417 | && (ofst!=0 || lockMask<3) |
| 43418 | && (ofst<3 || lockMask<(1<<ofst)) | ||
| 43419 | )); | ||
| 43420 | } | ||
| 42783 | #endif | 43421 | #endif |
| 42784 | 43422 | ||
| 42785 | mask = (1<<(ofst+n)) - (1<<ofst); | 43423 | /* Check if there is any work to do. There are three cases: |
| 42786 | assert( n>1 || mask==(1<<ofst) ); | 43424 | ** |
| 42787 | sqlite3_mutex_enter(pShmNode->pShmMutex); | 43425 | ** a) An unlock operation where there are locks to unlock, |
| 42788 | assert( assertLockingArrayOk(pShmNode) ); | 43426 | ** b) An shared lock where the requested lock is not already held |
| 42789 | if( flags & SQLITE_SHM_UNLOCK ){ | 43427 | ** c) An exclusive lock where the requested lock is not already held |
| 42790 | if( (p->exclMask|p->sharedMask) & mask ){ | 43428 | ** |
| 42791 | int ii; | 43429 | ** The SQLite core never requests an exclusive lock that it already holds. |
| 42792 | int bUnlock = 1; | 43430 | ** This is assert()ed below. |
| 43431 | */ | ||
| 43432 | assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) | ||
| 43433 | || 0==(p->exclMask & mask) | ||
| 43434 | ); | ||
| 43435 | if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) | ||
| 43436 | || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) | ||
| 43437 | || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) | ||
| 43438 | ){ | ||
| 42793 | 43439 | ||
| 42794 | for(ii=ofst; ii<ofst+n; ii++){ | 43440 | /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if |
| 42795 | if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){ | 43441 | ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any |
| 42796 | bUnlock = 0; | 43442 | ** other thread is holding this mutex, then it is either holding or about |
| 42797 | } | 43443 | ** to hold a lock exclusive to the one being requested, and we may |
| 43444 | ** therefore return SQLITE_BUSY to the caller. | ||
| 43445 | ** | ||
| 43446 | ** Doing this prevents some deadlock scenarios. For example, thread 1 may | ||
| 43447 | ** be a checkpointer blocked waiting on the WRITER lock. And thread 2 | ||
| 43448 | ** may be a normal SQL client upgrading to a write transaction. In this | ||
| 43449 | ** case thread 2 does a non-blocking request for the WRITER lock. But - | ||
| 43450 | ** if it were to use sqlite3_mutex_enter() then it would effectively | ||
| 43451 | ** become a (doomed) blocking request, as thread 2 would block until thread | ||
| 43452 | ** 1 obtained WRITER and released the mutex. Since thread 2 already holds | ||
| 43453 | ** a lock on a read-locking slot at this point, this breaks the | ||
| 43454 | ** anti-deadlock rules (see above). */ | ||
| 43455 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 43456 | int iMutex; | ||
| 43457 | for(iMutex=ofst; iMutex<ofst+n; iMutex++){ | ||
| 43458 | if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){ | ||
| 43459 | rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]); | ||
| 43460 | if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; | ||
| 43461 | }else{ | ||
| 43462 | sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); | ||
| 42798 | } | 43463 | } |
| 43464 | } | ||
| 43465 | #else | ||
| 43466 | sqlite3_mutex_enter(pShmNode->pShmMutex); | ||
| 43467 | #endif | ||
| 42799 | 43468 | ||
| 42800 | if( bUnlock ){ | 43469 | if( ALWAYS(rc==SQLITE_OK) ){ |
| 42801 | rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); | 43470 | if( flags & SQLITE_SHM_UNLOCK ){ |
| 42802 | if( rc==SQLITE_OK ){ | 43471 | /* Case (a) - unlock. */ |
| 42803 | memset(&aLock[ofst], 0, sizeof(int)*n); | 43472 | int bUnlock = 1; |
| 43473 | assert( (p->exclMask & p->sharedMask)==0 ); | ||
| 43474 | assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); | ||
| 43475 | assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); | ||
| 43476 | |||
| 43477 | /* If this is a SHARED lock being unlocked, it is possible that other | ||
| 43478 | ** clients within this process are holding the same SHARED lock. In | ||
| 43479 | ** this case, set bUnlock to 0 so that the posix lock is not removed | ||
| 43480 | ** from the file-descriptor below. */ | ||
| 43481 | if( flags & SQLITE_SHM_SHARED ){ | ||
| 43482 | assert( n==1 ); | ||
| 43483 | assert( aLock[ofst]>=1 ); | ||
| 43484 | if( aLock[ofst]>1 ){ | ||
| 43485 | bUnlock = 0; | ||
| 43486 | aLock[ofst]--; | ||
| 43487 | p->sharedMask &= ~mask; | ||
| 43488 | } | ||
| 42804 | } | 43489 | } |
| 42805 | }else if( ALWAYS(p->sharedMask & (1<<ofst)) ){ | ||
| 42806 | assert( n==1 && aLock[ofst]>1 ); | ||
| 42807 | aLock[ofst]--; | ||
| 42808 | } | ||
| 42809 | 43490 | ||
| 42810 | /* Undo the local locks */ | 43491 | if( bUnlock ){ |
| 42811 | if( rc==SQLITE_OK ){ | 43492 | rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); |
| 42812 | p->exclMask &= ~mask; | 43493 | if( rc==SQLITE_OK ){ |
| 42813 | p->sharedMask &= ~mask; | 43494 | memset(&aLock[ofst], 0, sizeof(int)*n); |
| 42814 | } | 43495 | p->sharedMask &= ~mask; |
| 42815 | } | 43496 | p->exclMask &= ~mask; |
| 42816 | }else if( flags & SQLITE_SHM_SHARED ){ | 43497 | } |
| 42817 | assert( n==1 ); | 43498 | } |
| 42818 | assert( (p->exclMask & (1<<ofst))==0 ); | 43499 | }else if( flags & SQLITE_SHM_SHARED ){ |
| 42819 | if( (p->sharedMask & mask)==0 ){ | 43500 | /* Case (b) - a shared lock. */ |
| 42820 | if( aLock[ofst]<0 ){ | ||
| 42821 | rc = SQLITE_BUSY; | ||
| 42822 | }else if( aLock[ofst]==0 ){ | ||
| 42823 | rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); | ||
| 42824 | } | ||
| 42825 | 43501 | ||
| 42826 | /* Get the local shared locks */ | 43502 | if( aLock[ofst]<0 ){ |
| 42827 | if( rc==SQLITE_OK ){ | 43503 | /* An exclusive lock is held by some other connection. BUSY. */ |
| 42828 | p->sharedMask |= mask; | 43504 | rc = SQLITE_BUSY; |
| 42829 | aLock[ofst]++; | 43505 | }else if( aLock[ofst]==0 ){ |
| 42830 | } | 43506 | rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); |
| 42831 | } | 43507 | } |
| 42832 | }else{ | ||
| 42833 | /* Make sure no sibling connections hold locks that will block this | ||
| 42834 | ** lock. If any do, return SQLITE_BUSY right away. */ | ||
| 42835 | int ii; | ||
| 42836 | for(ii=ofst; ii<ofst+n; ii++){ | ||
| 42837 | assert( (p->sharedMask & mask)==0 ); | ||
| 42838 | if( ALWAYS((p->exclMask & (1<<ii))==0) && aLock[ii] ){ | ||
| 42839 | rc = SQLITE_BUSY; | ||
| 42840 | break; | ||
| 42841 | } | ||
| 42842 | } | ||
| 42843 | 43508 | ||
| 42844 | /* Get the exclusive locks at the system level. Then if successful | 43509 | /* Get the local shared locks */ |
| 42845 | ** also update the in-memory values. */ | 43510 | if( rc==SQLITE_OK ){ |
| 42846 | if( rc==SQLITE_OK ){ | 43511 | p->sharedMask |= mask; |
| 42847 | rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); | 43512 | aLock[ofst]++; |
| 42848 | if( rc==SQLITE_OK ){ | 43513 | } |
| 43514 | }else{ | ||
| 43515 | /* Case (c) - an exclusive lock. */ | ||
| 43516 | int ii; | ||
| 43517 | |||
| 43518 | assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ); | ||
| 42849 | assert( (p->sharedMask & mask)==0 ); | 43519 | assert( (p->sharedMask & mask)==0 ); |
| 42850 | p->exclMask |= mask; | 43520 | assert( (p->exclMask & mask)==0 ); |
| 43521 | |||
| 43522 | /* Make sure no sibling connections hold locks that will block this | ||
| 43523 | ** lock. If any do, return SQLITE_BUSY right away. */ | ||
| 42851 | for(ii=ofst; ii<ofst+n; ii++){ | 43524 | for(ii=ofst; ii<ofst+n; ii++){ |
| 42852 | aLock[ii] = -1; | 43525 | if( aLock[ii] ){ |
| 43526 | rc = SQLITE_BUSY; | ||
| 43527 | break; | ||
| 43528 | } | ||
| 43529 | } | ||
| 43530 | |||
| 43531 | /* Get the exclusive locks at the system level. Then if successful | ||
| 43532 | ** also update the in-memory values. */ | ||
| 43533 | if( rc==SQLITE_OK ){ | ||
| 43534 | rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); | ||
| 43535 | if( rc==SQLITE_OK ){ | ||
| 43536 | p->exclMask |= mask; | ||
| 43537 | for(ii=ofst; ii<ofst+n; ii++){ | ||
| 43538 | aLock[ii] = -1; | ||
| 43539 | } | ||
| 43540 | } | ||
| 42853 | } | 43541 | } |
| 42854 | } | 43542 | } |
| 43543 | assert( assertLockingArrayOk(pShmNode) ); | ||
| 43544 | } | ||
| 43545 | |||
| 43546 | /* Drop the mutexes acquired above. */ | ||
| 43547 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 43548 | leave_shmnode_mutexes: | ||
| 43549 | for(iMutex--; iMutex>=ofst; iMutex--){ | ||
| 43550 | sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); | ||
| 42855 | } | 43551 | } |
| 43552 | #else | ||
| 43553 | sqlite3_mutex_leave(pShmNode->pShmMutex); | ||
| 43554 | #endif | ||
| 42856 | } | 43555 | } |
| 42857 | assert( assertLockingArrayOk(pShmNode) ); | 43556 | |
| 42858 | sqlite3_mutex_leave(pShmNode->pShmMutex); | ||
| 42859 | OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", | 43557 | OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", |
| 42860 | p->id, osGetpid(0), p->sharedMask, p->exclMask)); | 43558 | p->id, osGetpid(0), p->sharedMask, p->exclMask)); |
| 42861 | return rc; | 43559 | return rc; |
| @@ -43105,11 +43803,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ | |||
| 43105 | 43803 | ||
| 43106 | #if SQLITE_MAX_MMAP_SIZE>0 | 43804 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 43107 | if( pFd->mmapSizeMax>0 ){ | 43805 | if( pFd->mmapSizeMax>0 ){ |
| 43806 | /* Ensure that there is always at least a 256 byte buffer of addressable | ||
| 43807 | ** memory following the returned page. If the database is corrupt, | ||
| 43808 | ** SQLite may overread the page slightly (in practice only a few bytes, | ||
| 43809 | ** but 256 is safe, round, number). */ | ||
| 43810 | const int nEofBuffer = 256; | ||
| 43108 | if( pFd->pMapRegion==0 ){ | 43811 | if( pFd->pMapRegion==0 ){ |
| 43109 | int rc = unixMapfile(pFd, -1); | 43812 | int rc = unixMapfile(pFd, -1); |
| 43110 | if( rc!=SQLITE_OK ) return rc; | 43813 | if( rc!=SQLITE_OK ) return rc; |
| 43111 | } | 43814 | } |
| 43112 | if( pFd->mmapSize >= iOff+nAmt ){ | 43815 | if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ |
| 43113 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; | 43816 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 43114 | pFd->nFetchOut++; | 43817 | pFd->nFetchOut++; |
| 43115 | } | 43818 | } |
| @@ -44053,12 +44756,19 @@ static int unixOpen( | |||
| 44053 | rc = SQLITE_READONLY_DIRECTORY; | 44756 | rc = SQLITE_READONLY_DIRECTORY; |
| 44054 | }else if( errno!=EISDIR && isReadWrite ){ | 44757 | }else if( errno!=EISDIR && isReadWrite ){ |
| 44055 | /* Failed to open the file for read/write access. Try read-only. */ | 44758 | /* Failed to open the file for read/write access. Try read-only. */ |
| 44759 | UnixUnusedFd *pReadonly = 0; | ||
| 44056 | flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | 44760 | flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 44057 | openFlags &= ~(O_RDWR|O_CREAT); | 44761 | openFlags &= ~(O_RDWR|O_CREAT); |
| 44058 | flags |= SQLITE_OPEN_READONLY; | 44762 | flags |= SQLITE_OPEN_READONLY; |
| 44059 | openFlags |= O_RDONLY; | 44763 | openFlags |= O_RDONLY; |
| 44060 | isReadonly = 1; | 44764 | isReadonly = 1; |
| 44061 | fd = robust_open(zName, openFlags, openMode); | 44765 | pReadonly = findReusableFd(zName, flags); |
| 44766 | if( pReadonly ){ | ||
| 44767 | fd = pReadonly->fd; | ||
| 44768 | sqlite3_free(pReadonly); | ||
| 44769 | }else{ | ||
| 44770 | fd = robust_open(zName, openFlags, openMode); | ||
| 44771 | } | ||
| 44062 | } | 44772 | } |
| 44063 | } | 44773 | } |
| 44064 | if( fd<0 ){ | 44774 | if( fd<0 ){ |
| @@ -50462,6 +51172,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ | |||
| 50462 | 51172 | ||
| 50463 | #if SQLITE_MAX_MMAP_SIZE>0 | 51173 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 50464 | if( pFd->mmapSizeMax>0 ){ | 51174 | if( pFd->mmapSizeMax>0 ){ |
| 51175 | /* Ensure that there is always at least a 256 byte buffer of addressable | ||
| 51176 | ** memory following the returned page. If the database is corrupt, | ||
| 51177 | ** SQLite may overread the page slightly (in practice only a few bytes, | ||
| 51178 | ** but 256 is safe, round, number). */ | ||
| 51179 | const int nEofBuffer = 256; | ||
| 50465 | if( pFd->pMapRegion==0 ){ | 51180 | if( pFd->pMapRegion==0 ){ |
| 50466 | int rc = winMapfile(pFd, -1); | 51181 | int rc = winMapfile(pFd, -1); |
| 50467 | if( rc!=SQLITE_OK ){ | 51182 | if( rc!=SQLITE_OK ){ |
| @@ -50470,7 +51185,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ | |||
| 50470 | return rc; | 51185 | return rc; |
| 50471 | } | 51186 | } |
| 50472 | } | 51187 | } |
| 50473 | if( pFd->mmapSize >= iOff+nAmt ){ | 51188 | if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ |
| 50474 | assert( pFd->pMapRegion!=0 ); | 51189 | assert( pFd->pMapRegion!=0 ); |
| 50475 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; | 51190 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 50476 | pFd->nFetchOut++; | 51191 | pFd->nFetchOut++; |
| @@ -52949,6 +53664,14 @@ SQLITE_API unsigned char *sqlite3_serialize( | |||
| 52949 | pOut = 0; | 53664 | pOut = 0; |
| 52950 | }else{ | 53665 | }else{ |
| 52951 | sz = sqlite3_column_int64(pStmt, 0)*szPage; | 53666 | sz = sqlite3_column_int64(pStmt, 0)*szPage; |
| 53667 | if( sz==0 ){ | ||
| 53668 | sqlite3_reset(pStmt); | ||
| 53669 | sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); | ||
| 53670 | rc = sqlite3_step(pStmt); | ||
| 53671 | if( rc==SQLITE_ROW ){ | ||
| 53672 | sz = sqlite3_column_int64(pStmt, 0)*szPage; | ||
| 53673 | } | ||
| 53674 | } | ||
| 52952 | if( piSize ) *piSize = sz; | 53675 | if( piSize ) *piSize = sz; |
| 52953 | if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ | 53676 | if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ |
| 52954 | pOut = 0; | 53677 | pOut = 0; |
| @@ -57073,7 +57796,7 @@ struct Pager { | |||
| 57073 | char *zJournal; /* Name of the journal file */ | 57796 | char *zJournal; /* Name of the journal file */ |
| 57074 | int (*xBusyHandler)(void*); /* Function to call when busy */ | 57797 | int (*xBusyHandler)(void*); /* Function to call when busy */ |
| 57075 | void *pBusyHandlerArg; /* Context argument for xBusyHandler */ | 57798 | void *pBusyHandlerArg; /* Context argument for xBusyHandler */ |
| 57076 | int aStat[4]; /* Total cache hits, misses, writes, spills */ | 57799 | u32 aStat[4]; /* Total cache hits, misses, writes, spills */ |
| 57077 | #ifdef SQLITE_TEST | 57800 | #ifdef SQLITE_TEST |
| 57078 | int nRead; /* Database pages read */ | 57801 | int nRead; /* Database pages read */ |
| 57079 | #endif | 57802 | #endif |
| @@ -57203,9 +57926,8 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ | |||
| 57203 | #ifndef SQLITE_OMIT_WAL | 57926 | #ifndef SQLITE_OMIT_WAL |
| 57204 | if( pPager->pWal ){ | 57927 | if( pPager->pWal ){ |
| 57205 | u32 iRead = 0; | 57928 | u32 iRead = 0; |
| 57206 | int rc; | 57929 | (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); |
| 57207 | rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); | 57930 | return iRead==0; |
| 57208 | return (rc==SQLITE_OK && iRead==0); | ||
| 57209 | } | 57931 | } |
| 57210 | #endif | 57932 | #endif |
| 57211 | return 1; | 57933 | return 1; |
| @@ -61447,10 +62169,13 @@ act_like_temp_file: | |||
| 61447 | */ | 62169 | */ |
| 61448 | SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ | 62170 | SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ |
| 61449 | Pager *pPager; | 62171 | Pager *pPager; |
| 62172 | const char *p; | ||
| 61450 | while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ | 62173 | while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ |
| 61451 | zName--; | 62174 | zName--; |
| 61452 | } | 62175 | } |
| 61453 | pPager = *(Pager**)(zName - 4 - sizeof(Pager*)); | 62176 | p = zName - 4 - sizeof(Pager*); |
| 62177 | assert( EIGHT_BYTE_ALIGNMENT(p) ); | ||
| 62178 | pPager = *(Pager**)p; | ||
| 61454 | return pPager->fd; | 62179 | return pPager->fd; |
| 61455 | } | 62180 | } |
| 61456 | 62181 | ||
| @@ -63214,11 +63939,11 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ | |||
| 63214 | a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; | 63939 | a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; |
| 63215 | a[4] = pPager->eState; | 63940 | a[4] = pPager->eState; |
| 63216 | a[5] = pPager->errCode; | 63941 | a[5] = pPager->errCode; |
| 63217 | a[6] = pPager->aStat[PAGER_STAT_HIT]; | 63942 | a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; |
| 63218 | a[7] = pPager->aStat[PAGER_STAT_MISS]; | 63943 | a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; |
| 63219 | a[8] = 0; /* Used to be pPager->nOvfl */ | 63944 | a[8] = 0; /* Used to be pPager->nOvfl */ |
| 63220 | a[9] = pPager->nRead; | 63945 | a[9] = pPager->nRead; |
| 63221 | a[10] = pPager->aStat[PAGER_STAT_WRITE]; | 63946 | a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; |
| 63222 | return a; | 63947 | return a; |
| 63223 | } | 63948 | } |
| 63224 | #endif | 63949 | #endif |
| @@ -63234,7 +63959,7 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ | |||
| 63234 | ** reset parameter is non-zero, the cache hit or miss count is zeroed before | 63959 | ** reset parameter is non-zero, the cache hit or miss count is zeroed before |
| 63235 | ** returning. | 63960 | ** returning. |
| 63236 | */ | 63961 | */ |
| 63237 | SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ | 63962 | SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ |
| 63238 | 63963 | ||
| 63239 | assert( eStat==SQLITE_DBSTATUS_CACHE_HIT | 63964 | assert( eStat==SQLITE_DBSTATUS_CACHE_HIT |
| 63240 | || eStat==SQLITE_DBSTATUS_CACHE_MISS | 63965 | || eStat==SQLITE_DBSTATUS_CACHE_MISS |
| @@ -63470,7 +64195,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ | |||
| 63470 | ** This will be either the rollback journal or the WAL file. | 64195 | ** This will be either the rollback journal or the WAL file. |
| 63471 | */ | 64196 | */ |
| 63472 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ | 64197 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ |
| 63473 | #if SQLITE_OMIT_WAL | 64198 | #ifdef SQLITE_OMIT_WAL |
| 63474 | return pPager->jfd; | 64199 | return pPager->jfd; |
| 63475 | #else | 64200 | #else |
| 63476 | return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; | 64201 | return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; |
| @@ -64174,7 +64899,7 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ | |||
| 64174 | } | 64899 | } |
| 64175 | #endif | 64900 | #endif |
| 64176 | 64901 | ||
| 64177 | #ifdef SQLITE_USE_SEH | 64902 | #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) |
| 64178 | SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ | 64903 | SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ |
| 64179 | return sqlite3WalSystemErrno(pPager->pWal); | 64904 | return sqlite3WalSystemErrno(pPager->pWal); |
| 64180 | } | 64905 | } |
| @@ -66190,6 +66915,19 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ | |||
| 66190 | } | 66915 | } |
| 66191 | 66916 | ||
| 66192 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | 66917 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 66918 | |||
| 66919 | |||
| 66920 | /* | ||
| 66921 | ** Attempt to enable blocking locks that block for nMs ms. Return 1 if | ||
| 66922 | ** blocking locks are successfully enabled, or 0 otherwise. | ||
| 66923 | */ | ||
| 66924 | static int walEnableBlockingMs(Wal *pWal, int nMs){ | ||
| 66925 | int rc = sqlite3OsFileControl( | ||
| 66926 | pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs | ||
| 66927 | ); | ||
| 66928 | return (rc==SQLITE_OK); | ||
| 66929 | } | ||
| 66930 | |||
| 66193 | /* | 66931 | /* |
| 66194 | ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) | 66932 | ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) |
| 66195 | ** they are supported by the VFS, and (b) the database handle is configured | 66933 | ** they are supported by the VFS, and (b) the database handle is configured |
| @@ -66201,11 +66939,7 @@ static int walEnableBlocking(Wal *pWal){ | |||
| 66201 | if( pWal->db ){ | 66939 | if( pWal->db ){ |
| 66202 | int tmout = pWal->db->busyTimeout; | 66940 | int tmout = pWal->db->busyTimeout; |
| 66203 | if( tmout ){ | 66941 | if( tmout ){ |
| 66204 | int rc; | 66942 | res = walEnableBlockingMs(pWal, tmout); |
| 66205 | rc = sqlite3OsFileControl( | ||
| 66206 | pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout | ||
| 66207 | ); | ||
| 66208 | res = (rc==SQLITE_OK); | ||
| 66209 | } | 66943 | } |
| 66210 | } | 66944 | } |
| 66211 | return res; | 66945 | return res; |
| @@ -66254,20 +66988,10 @@ SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ | |||
| 66254 | pWal->db = db; | 66988 | pWal->db = db; |
| 66255 | } | 66989 | } |
| 66256 | 66990 | ||
| 66257 | /* | ||
| 66258 | ** Take an exclusive WRITE lock. Blocking if so configured. | ||
| 66259 | */ | ||
| 66260 | static int walLockWriter(Wal *pWal){ | ||
| 66261 | int rc; | ||
| 66262 | walEnableBlocking(pWal); | ||
| 66263 | rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); | ||
| 66264 | walDisableBlocking(pWal); | ||
| 66265 | return rc; | ||
| 66266 | } | ||
| 66267 | #else | 66991 | #else |
| 66268 | # define walEnableBlocking(x) 0 | 66992 | # define walEnableBlocking(x) 0 |
| 66269 | # define walDisableBlocking(x) | 66993 | # define walDisableBlocking(x) |
| 66270 | # define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) | 66994 | # define walEnableBlockingMs(pWal, ms) 0 |
| 66271 | # define sqlite3WalDb(pWal, db) | 66995 | # define sqlite3WalDb(pWal, db) |
| 66272 | #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ | 66996 | #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ |
| 66273 | 66997 | ||
| @@ -66868,7 +67592,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ | |||
| 66868 | } | 67592 | } |
| 66869 | }else{ | 67593 | }else{ |
| 66870 | int bWriteLock = pWal->writeLock; | 67594 | int bWriteLock = pWal->writeLock; |
| 66871 | if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){ | 67595 | if( bWriteLock |
| 67596 | || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) | ||
| 67597 | ){ | ||
| 66872 | pWal->writeLock = 1; | 67598 | pWal->writeLock = 1; |
| 66873 | if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ | 67599 | if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ |
| 66874 | badHdr = walIndexTryHdr(pWal, pChanged); | 67600 | badHdr = walIndexTryHdr(pWal, pChanged); |
| @@ -66876,7 +67602,8 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ | |||
| 66876 | /* If the wal-index header is still malformed even while holding | 67602 | /* If the wal-index header is still malformed even while holding |
| 66877 | ** a WRITE lock, it can only mean that the header is corrupted and | 67603 | ** a WRITE lock, it can only mean that the header is corrupted and |
| 66878 | ** needs to be reconstructed. So run recovery to do exactly that. | 67604 | ** needs to be reconstructed. So run recovery to do exactly that. |
| 66879 | */ | 67605 | ** Disable blocking locks first. */ |
| 67606 | walDisableBlocking(pWal); | ||
| 66880 | rc = walIndexRecover(pWal); | 67607 | rc = walIndexRecover(pWal); |
| 66881 | *pChanged = 1; | 67608 | *pChanged = 1; |
| 66882 | } | 67609 | } |
| @@ -67087,6 +67814,37 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ | |||
| 67087 | } | 67814 | } |
| 67088 | 67815 | ||
| 67089 | /* | 67816 | /* |
| 67817 | ** The final argument passed to walTryBeginRead() is of type (int*). The | ||
| 67818 | ** caller should invoke walTryBeginRead as follows: | ||
| 67819 | ** | ||
| 67820 | ** int cnt = 0; | ||
| 67821 | ** do { | ||
| 67822 | ** rc = walTryBeginRead(..., &cnt); | ||
| 67823 | ** }while( rc==WAL_RETRY ); | ||
| 67824 | ** | ||
| 67825 | ** The final value of "cnt" is of no use to the caller. It is used by | ||
| 67826 | ** the implementation of walTryBeginRead() as follows: | ||
| 67827 | ** | ||
| 67828 | ** + Each time walTryBeginRead() is called, it is incremented. Once | ||
| 67829 | ** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() | ||
| 67830 | ** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() | ||
| 67831 | ** returns SQLITE_PROTOCOL. | ||
| 67832 | ** | ||
| 67833 | ** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed | ||
| 67834 | ** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS | ||
| 67835 | ** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case | ||
| 67836 | ** the next invocation of walTryBeginRead() may omit an expected call to | ||
| 67837 | ** sqlite3OsSleep(). There has already been a delay when the previous call | ||
| 67838 | ** waited on a lock. | ||
| 67839 | */ | ||
| 67840 | #define WAL_RETRY_PROTOCOL_LIMIT 100 | ||
| 67841 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 67842 | # define WAL_RETRY_BLOCKED_MASK 0x10000000 | ||
| 67843 | #else | ||
| 67844 | # define WAL_RETRY_BLOCKED_MASK 0 | ||
| 67845 | #endif | ||
| 67846 | |||
| 67847 | /* | ||
| 67090 | ** Attempt to start a read transaction. This might fail due to a race or | 67848 | ** Attempt to start a read transaction. This might fail due to a race or |
| 67091 | ** other transient condition. When that happens, it returns WAL_RETRY to | 67849 | ** other transient condition. When that happens, it returns WAL_RETRY to |
| 67092 | ** indicate to the caller that it is safe to retry immediately. | 67850 | ** indicate to the caller that it is safe to retry immediately. |
| @@ -67136,13 +67894,16 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ | |||
| 67136 | ** so it takes care to hold an exclusive lock on the corresponding | 67894 | ** so it takes care to hold an exclusive lock on the corresponding |
| 67137 | ** WAL_READ_LOCK() while changing values. | 67895 | ** WAL_READ_LOCK() while changing values. |
| 67138 | */ | 67896 | */ |
| 67139 | static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | 67897 | static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ |
| 67140 | volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ | 67898 | volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ |
| 67141 | u32 mxReadMark; /* Largest aReadMark[] value */ | 67899 | u32 mxReadMark; /* Largest aReadMark[] value */ |
| 67142 | int mxI; /* Index of largest aReadMark[] value */ | 67900 | int mxI; /* Index of largest aReadMark[] value */ |
| 67143 | int i; /* Loop counter */ | 67901 | int i; /* Loop counter */ |
| 67144 | int rc = SQLITE_OK; /* Return code */ | 67902 | int rc = SQLITE_OK; /* Return code */ |
| 67145 | u32 mxFrame; /* Wal frame to lock to */ | 67903 | u32 mxFrame; /* Wal frame to lock to */ |
| 67904 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 67905 | int nBlockTmout = 0; | ||
| 67906 | #endif | ||
| 67146 | 67907 | ||
| 67147 | assert( pWal->readLock<0 ); /* Not currently locked */ | 67908 | assert( pWal->readLock<0 ); /* Not currently locked */ |
| 67148 | 67909 | ||
| @@ -67166,14 +67927,34 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 67166 | ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. | 67927 | ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. |
| 67167 | ** The total delay time before giving up is less than 10 seconds. | 67928 | ** The total delay time before giving up is less than 10 seconds. |
| 67168 | */ | 67929 | */ |
| 67169 | if( cnt>5 ){ | 67930 | (*pCnt)++; |
| 67931 | if( *pCnt>5 ){ | ||
| 67170 | int nDelay = 1; /* Pause time in microseconds */ | 67932 | int nDelay = 1; /* Pause time in microseconds */ |
| 67171 | if( cnt>100 ){ | 67933 | int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); |
| 67934 | if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ | ||
| 67172 | VVA_ONLY( pWal->lockError = 1; ) | 67935 | VVA_ONLY( pWal->lockError = 1; ) |
| 67173 | return SQLITE_PROTOCOL; | 67936 | return SQLITE_PROTOCOL; |
| 67174 | } | 67937 | } |
| 67175 | if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; | 67938 | if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; |
| 67939 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 67940 | /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor | ||
| 67941 | ** to block for locks for approximately nDelay us. This affects three | ||
| 67942 | ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if | ||
| 67943 | ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the | ||
| 67944 | ** first attempted read fails, and (c) the shared lock taken on the | ||
| 67945 | ** read-mark. | ||
| 67946 | ** | ||
| 67947 | ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, | ||
| 67948 | ** then sleep for the minimum of 1us. The previous call already provided | ||
| 67949 | ** an extra delay while it was blocking on the lock. | ||
| 67950 | */ | ||
| 67951 | nBlockTmout = (nDelay+998) / 1000; | ||
| 67952 | if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ | ||
| 67953 | if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; | ||
| 67954 | } | ||
| 67955 | #endif | ||
| 67176 | sqlite3OsSleep(pWal->pVfs, nDelay); | 67956 | sqlite3OsSleep(pWal->pVfs, nDelay); |
| 67957 | *pCnt &= ~WAL_RETRY_BLOCKED_MASK; | ||
| 67177 | } | 67958 | } |
| 67178 | 67959 | ||
| 67179 | if( !useWal ){ | 67960 | if( !useWal ){ |
| @@ -67181,6 +67962,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 67181 | if( pWal->bShmUnreliable==0 ){ | 67962 | if( pWal->bShmUnreliable==0 ){ |
| 67182 | rc = walIndexReadHdr(pWal, pChanged); | 67963 | rc = walIndexReadHdr(pWal, pChanged); |
| 67183 | } | 67964 | } |
| 67965 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT | ||
| 67966 | walDisableBlocking(pWal); | ||
| 67967 | if( rc==SQLITE_BUSY_TIMEOUT ){ | ||
| 67968 | rc = SQLITE_BUSY; | ||
| 67969 | *pCnt |= WAL_RETRY_BLOCKED_MASK; | ||
| 67970 | } | ||
| 67971 | #endif | ||
| 67184 | if( rc==SQLITE_BUSY ){ | 67972 | if( rc==SQLITE_BUSY ){ |
| 67185 | /* If there is not a recovery running in another thread or process | 67973 | /* If there is not a recovery running in another thread or process |
| 67186 | ** then convert BUSY errors to WAL_RETRY. If recovery is known to | 67974 | ** then convert BUSY errors to WAL_RETRY. If recovery is known to |
| @@ -67295,9 +68083,19 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 67295 | return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; | 68083 | return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; |
| 67296 | } | 68084 | } |
| 67297 | 68085 | ||
| 68086 | (void)walEnableBlockingMs(pWal, nBlockTmout); | ||
| 67298 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); | 68087 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 68088 | walDisableBlocking(pWal); | ||
| 67299 | if( rc ){ | 68089 | if( rc ){ |
| 67300 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; | 68090 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 68091 | if( rc==SQLITE_BUSY_TIMEOUT ){ | ||
| 68092 | *pCnt |= WAL_RETRY_BLOCKED_MASK; | ||
| 68093 | } | ||
| 68094 | #else | ||
| 68095 | assert( rc!=SQLITE_BUSY_TIMEOUT ); | ||
| 68096 | #endif | ||
| 68097 | assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); | ||
| 68098 | return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; | ||
| 67301 | } | 68099 | } |
| 67302 | /* Now that the read-lock has been obtained, check that neither the | 68100 | /* Now that the read-lock has been obtained, check that neither the |
| 67303 | ** value in the aReadMark[] array or the contents of the wal-index | 68101 | ** value in the aReadMark[] array or the contents of the wal-index |
| @@ -67485,7 +68283,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ | |||
| 67485 | #endif | 68283 | #endif |
| 67486 | 68284 | ||
| 67487 | do{ | 68285 | do{ |
| 67488 | rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); | 68286 | rc = walTryBeginRead(pWal, pChanged, 0, &cnt); |
| 67489 | }while( rc==WAL_RETRY ); | 68287 | }while( rc==WAL_RETRY ); |
| 67490 | testcase( (rc&0xff)==SQLITE_BUSY ); | 68288 | testcase( (rc&0xff)==SQLITE_BUSY ); |
| 67491 | testcase( (rc&0xff)==SQLITE_IOERR ); | 68289 | testcase( (rc&0xff)==SQLITE_IOERR ); |
| @@ -67666,6 +68464,7 @@ static int walFindFrame( | |||
| 67666 | iRead = iFrame; | 68464 | iRead = iFrame; |
| 67667 | } | 68465 | } |
| 67668 | if( (nCollide--)==0 ){ | 68466 | if( (nCollide--)==0 ){ |
| 68467 | *piRead = 0; | ||
| 67669 | return SQLITE_CORRUPT_BKPT; | 68468 | return SQLITE_CORRUPT_BKPT; |
| 67670 | } | 68469 | } |
| 67671 | iKey = walNextHash(iKey); | 68470 | iKey = walNextHash(iKey); |
| @@ -67969,7 +68768,7 @@ static int walRestartLog(Wal *pWal){ | |||
| 67969 | cnt = 0; | 68768 | cnt = 0; |
| 67970 | do{ | 68769 | do{ |
| 67971 | int notUsed; | 68770 | int notUsed; |
| 67972 | rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); | 68771 | rc = walTryBeginRead(pWal, ¬Used, 1, &cnt); |
| 67973 | }while( rc==WAL_RETRY ); | 68772 | }while( rc==WAL_RETRY ); |
| 67974 | assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ | 68773 | assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ |
| 67975 | testcase( (rc&0xff)==SQLITE_IOERR ); | 68774 | testcase( (rc&0xff)==SQLITE_IOERR ); |
| @@ -68390,10 +69189,9 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( | |||
| 68390 | if( pWal->readOnly ) return SQLITE_READONLY; | 69189 | if( pWal->readOnly ) return SQLITE_READONLY; |
| 68391 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); | 69190 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 68392 | 69191 | ||
| 68393 | /* Enable blocking locks, if possible. If blocking locks are successfully | 69192 | /* Enable blocking locks, if possible. */ |
| 68394 | ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */ | ||
| 68395 | sqlite3WalDb(pWal, db); | 69193 | sqlite3WalDb(pWal, db); |
| 68396 | (void)walEnableBlocking(pWal); | 69194 | if( xBusy2 ) (void)walEnableBlocking(pWal); |
| 68397 | 69195 | ||
| 68398 | /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive | 69196 | /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive |
| 68399 | ** "checkpoint" lock on the database file. | 69197 | ** "checkpoint" lock on the database file. |
| @@ -68434,9 +69232,14 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( | |||
| 68434 | /* Read the wal-index header. */ | 69232 | /* Read the wal-index header. */ |
| 68435 | SEH_TRY { | 69233 | SEH_TRY { |
| 68436 | if( rc==SQLITE_OK ){ | 69234 | if( rc==SQLITE_OK ){ |
| 69235 | /* For a passive checkpoint, do not re-enable blocking locks after | ||
| 69236 | ** reading the wal-index header. A passive checkpoint should not block | ||
| 69237 | ** or invoke the busy handler. The only lock such a checkpoint may | ||
| 69238 | ** attempt to obtain is a lock on a read-slot, and it should give up | ||
| 69239 | ** immediately and do a partial checkpoint if it cannot obtain it. */ | ||
| 68437 | walDisableBlocking(pWal); | 69240 | walDisableBlocking(pWal); |
| 68438 | rc = walIndexReadHdr(pWal, &isChanged); | 69241 | rc = walIndexReadHdr(pWal, &isChanged); |
| 68439 | (void)walEnableBlocking(pWal); | 69242 | if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); |
| 68440 | if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ | 69243 | if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ |
| 68441 | sqlite3OsUnfetch(pWal->pDbFd, 0, 0); | 69244 | sqlite3OsUnfetch(pWal->pDbFd, 0, 0); |
| 68442 | } | 69245 | } |
| @@ -68773,7 +69576,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ | |||
| 68773 | ** 22 1 Min embedded payload fraction (must be 32) | 69576 | ** 22 1 Min embedded payload fraction (must be 32) |
| 68774 | ** 23 1 Min leaf payload fraction (must be 32) | 69577 | ** 23 1 Min leaf payload fraction (must be 32) |
| 68775 | ** 24 4 File change counter | 69578 | ** 24 4 File change counter |
| 68776 | ** 28 4 Reserved for future use | 69579 | ** 28 4 The size of the database in pages |
| 68777 | ** 32 4 First freelist page | 69580 | ** 32 4 First freelist page |
| 68778 | ** 36 4 Number of freelist pages in the file | 69581 | ** 36 4 Number of freelist pages in the file |
| 68779 | ** 40 60 15 4-byte meta values passed to higher layers | 69582 | ** 40 60 15 4-byte meta values passed to higher layers |
| @@ -69416,6 +70219,7 @@ struct IntegrityCk { | |||
| 69416 | StrAccum errMsg; /* Accumulate the error message text here */ | 70219 | StrAccum errMsg; /* Accumulate the error message text here */ |
| 69417 | u32 *heap; /* Min-heap used for analyzing cell coverage */ | 70220 | u32 *heap; /* Min-heap used for analyzing cell coverage */ |
| 69418 | sqlite3 *db; /* Database connection running the check */ | 70221 | sqlite3 *db; /* Database connection running the check */ |
| 70222 | i64 nRow; /* Number of rows visited in current tree */ | ||
| 69419 | }; | 70223 | }; |
| 69420 | 70224 | ||
| 69421 | /* | 70225 | /* |
| @@ -69890,8 +70694,47 @@ int corruptPageError(int lineno, MemPage *p){ | |||
| 69890 | # define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) | 70694 | # define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) |
| 69891 | #endif | 70695 | #endif |
| 69892 | 70696 | ||
| 70697 | /* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled | ||
| 70698 | ** or if the lock tracking is disabled. This is always the value for | ||
| 70699 | ** release builds. | ||
| 70700 | */ | ||
| 70701 | #define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/ | ||
| 70702 | |||
| 69893 | #ifndef SQLITE_OMIT_SHARED_CACHE | 70703 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 69894 | 70704 | ||
| 70705 | #if 0 | ||
| 70706 | /* ^---- Change to 1 and recompile to enable shared-lock tracing | ||
| 70707 | ** for debugging purposes. | ||
| 70708 | ** | ||
| 70709 | ** Print all shared-cache locks on a BtShared. Debugging use only. | ||
| 70710 | */ | ||
| 70711 | static void sharedLockTrace( | ||
| 70712 | BtShared *pBt, | ||
| 70713 | const char *zMsg, | ||
| 70714 | int iRoot, | ||
| 70715 | int eLockType | ||
| 70716 | ){ | ||
| 70717 | BtLock *pLock; | ||
| 70718 | if( iRoot>0 ){ | ||
| 70719 | printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W"); | ||
| 70720 | }else{ | ||
| 70721 | printf("%s-%p:", zMsg, pBt); | ||
| 70722 | } | ||
| 70723 | for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ | ||
| 70724 | printf(" %p/%u%s", pLock->pBtree, pLock->iTable, | ||
| 70725 | pLock->eLock==READ_LOCK ? "R" : "W"); | ||
| 70726 | while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){ | ||
| 70727 | pLock = pLock->pNext; | ||
| 70728 | printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W"); | ||
| 70729 | } | ||
| 70730 | } | ||
| 70731 | printf("\n"); | ||
| 70732 | fflush(stdout); | ||
| 70733 | } | ||
| 70734 | #undef SHARED_LOCK_TRACE | ||
| 70735 | #define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE) | ||
| 70736 | #endif /* Shared-lock tracing */ | ||
| 70737 | |||
| 69895 | #ifdef SQLITE_DEBUG | 70738 | #ifdef SQLITE_DEBUG |
| 69896 | /* | 70739 | /* |
| 69897 | **** This function is only used as part of an assert() statement. *** | 70740 | **** This function is only used as part of an assert() statement. *** |
| @@ -69968,6 +70811,8 @@ static int hasSharedCacheTableLock( | |||
| 69968 | iTab = iRoot; | 70811 | iTab = iRoot; |
| 69969 | } | 70812 | } |
| 69970 | 70813 | ||
| 70814 | SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType); | ||
| 70815 | |||
| 69971 | /* Search for the required lock. Either a write-lock on root-page iTab, a | 70816 | /* Search for the required lock. Either a write-lock on root-page iTab, a |
| 69972 | ** write-lock on the schema table, or (if the client is reading) a | 70817 | ** write-lock on the schema table, or (if the client is reading) a |
| 69973 | ** read-lock on iTab will suffice. Return 1 if any of these are found. */ | 70818 | ** read-lock on iTab will suffice. Return 1 if any of these are found. */ |
| @@ -70101,6 +70946,8 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ | |||
| 70101 | BtLock *pLock = 0; | 70946 | BtLock *pLock = 0; |
| 70102 | BtLock *pIter; | 70947 | BtLock *pIter; |
| 70103 | 70948 | ||
| 70949 | SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock); | ||
| 70950 | |||
| 70104 | assert( sqlite3BtreeHoldsMutex(p) ); | 70951 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 70105 | assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); | 70952 | assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); |
| 70106 | assert( p->db!=0 ); | 70953 | assert( p->db!=0 ); |
| @@ -70168,6 +71015,8 @@ static void clearAllSharedCacheTableLocks(Btree *p){ | |||
| 70168 | assert( p->sharable || 0==*ppIter ); | 71015 | assert( p->sharable || 0==*ppIter ); |
| 70169 | assert( p->inTrans>0 ); | 71016 | assert( p->inTrans>0 ); |
| 70170 | 71017 | ||
| 71018 | SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0); | ||
| 71019 | |||
| 70171 | while( *ppIter ){ | 71020 | while( *ppIter ){ |
| 70172 | BtLock *pLock = *ppIter; | 71021 | BtLock *pLock = *ppIter; |
| 70173 | assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); | 71022 | assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); |
| @@ -70206,6 +71055,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){ | |||
| 70206 | */ | 71055 | */ |
| 70207 | static void downgradeAllSharedCacheTableLocks(Btree *p){ | 71056 | static void downgradeAllSharedCacheTableLocks(Btree *p){ |
| 70208 | BtShared *pBt = p->pBt; | 71057 | BtShared *pBt = p->pBt; |
| 71058 | |||
| 71059 | SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0); | ||
| 71060 | |||
| 70209 | if( pBt->pWriter==p ){ | 71061 | if( pBt->pWriter==p ){ |
| 70210 | BtLock *pLock; | 71062 | BtLock *pLock; |
| 70211 | pBt->pWriter = 0; | 71063 | pBt->pWriter = 0; |
| @@ -74819,9 +75671,12 @@ static int accessPayload( | |||
| 74819 | if( pCur->aOverflow==0 | 75671 | if( pCur->aOverflow==0 |
| 74820 | || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) | 75672 | || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) |
| 74821 | ){ | 75673 | ){ |
| 74822 | Pgno *aNew = (Pgno*)sqlite3Realloc( | 75674 | Pgno *aNew; |
| 74823 | pCur->aOverflow, nOvfl*2*sizeof(Pgno) | 75675 | if( sqlite3FaultSim(413) ){ |
| 74824 | ); | 75676 | aNew = 0; |
| 75677 | }else{ | ||
| 75678 | aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno)); | ||
| 75679 | } | ||
| 74825 | if( aNew==0 ){ | 75680 | if( aNew==0 ){ |
| 74826 | return SQLITE_NOMEM_BKPT; | 75681 | return SQLITE_NOMEM_BKPT; |
| 74827 | }else{ | 75682 | }else{ |
| @@ -74831,6 +75686,12 @@ static int accessPayload( | |||
| 74831 | memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); | 75686 | memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); |
| 74832 | pCur->curFlags |= BTCF_ValidOvfl; | 75687 | pCur->curFlags |= BTCF_ValidOvfl; |
| 74833 | }else{ | 75688 | }else{ |
| 75689 | /* Sanity check the validity of the overflow page cache */ | ||
| 75690 | assert( pCur->aOverflow[0]==nextPage | ||
| 75691 | || pCur->aOverflow[0]==0 | ||
| 75692 | || CORRUPT_DB ); | ||
| 75693 | assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 ); | ||
| 75694 | |||
| 74834 | /* If the overflow page-list cache has been allocated and the | 75695 | /* If the overflow page-list cache has been allocated and the |
| 74835 | ** entry for the first required overflow page is valid, skip | 75696 | ** entry for the first required overflow page is valid, skip |
| 74836 | ** directly to it. | 75697 | ** directly to it. |
| @@ -74900,7 +75761,6 @@ static int accessPayload( | |||
| 74900 | assert( aWrite>=pBufStart ); /* due to (6) */ | 75761 | assert( aWrite>=pBufStart ); /* due to (6) */ |
| 74901 | memcpy(aSave, aWrite, 4); | 75762 | memcpy(aSave, aWrite, 4); |
| 74902 | rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); | 75763 | rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); |
| 74903 | if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; | ||
| 74904 | nextPage = get4byte(aWrite); | 75764 | nextPage = get4byte(aWrite); |
| 74905 | memcpy(aWrite, aSave, 4); | 75765 | memcpy(aWrite, aSave, 4); |
| 74906 | }else | 75766 | }else |
| @@ -75313,6 +76173,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ | |||
| 75313 | return rc; | 76173 | return rc; |
| 75314 | } | 76174 | } |
| 75315 | 76175 | ||
| 76176 | #ifdef SQLITE_DEBUG | ||
| 76177 | /* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that | ||
| 76178 | ** this flags are true for a consistent database. | ||
| 76179 | ** | ||
| 76180 | ** This routine is is called from within assert() statements only. | ||
| 76181 | ** It is an internal verification routine and does not appear in production | ||
| 76182 | ** builds. | ||
| 76183 | */ | ||
| 76184 | static int cursorIsAtLastEntry(BtCursor *pCur){ | ||
| 76185 | int ii; | ||
| 76186 | for(ii=0; ii<pCur->iPage; ii++){ | ||
| 76187 | if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0; | ||
| 76188 | } | ||
| 76189 | return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0; | ||
| 76190 | } | ||
| 76191 | #endif | ||
| 76192 | |||
| 75316 | /* Move the cursor to the last entry in the table. Return SQLITE_OK | 76193 | /* Move the cursor to the last entry in the table. Return SQLITE_OK |
| 75317 | ** on success. Set *pRes to 0 if the cursor actually points to something | 76194 | ** on success. Set *pRes to 0 if the cursor actually points to something |
| 75318 | ** or set *pRes to 1 if the table is empty. | 76195 | ** or set *pRes to 1 if the table is empty. |
| @@ -75341,18 +76218,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ | |||
| 75341 | 76218 | ||
| 75342 | /* If the cursor already points to the last entry, this is a no-op. */ | 76219 | /* If the cursor already points to the last entry, this is a no-op. */ |
| 75343 | if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ | 76220 | if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ |
| 75344 | #ifdef SQLITE_DEBUG | 76221 | assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); |
| 75345 | /* This block serves to assert() that the cursor really does point | ||
| 75346 | ** to the last entry in the b-tree. */ | ||
| 75347 | int ii; | ||
| 75348 | for(ii=0; ii<pCur->iPage; ii++){ | ||
| 75349 | assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); | ||
| 75350 | } | ||
| 75351 | assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB ); | ||
| 75352 | testcase( pCur->ix!=pCur->pPage->nCell-1 ); | ||
| 75353 | /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */ | ||
| 75354 | assert( pCur->pPage->leaf ); | ||
| 75355 | #endif | ||
| 75356 | *pRes = 0; | 76222 | *pRes = 0; |
| 75357 | return SQLITE_OK; | 76223 | return SQLITE_OK; |
| 75358 | } | 76224 | } |
| @@ -75405,6 +76271,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( | |||
| 75405 | } | 76271 | } |
| 75406 | if( pCur->info.nKey<intKey ){ | 76272 | if( pCur->info.nKey<intKey ){ |
| 75407 | if( (pCur->curFlags & BTCF_AtLast)!=0 ){ | 76273 | if( (pCur->curFlags & BTCF_AtLast)!=0 ){ |
| 76274 | assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); | ||
| 75408 | *pRes = -1; | 76275 | *pRes = -1; |
| 75409 | return SQLITE_OK; | 76276 | return SQLITE_OK; |
| 75410 | } | 76277 | } |
| @@ -75871,10 +76738,10 @@ SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ | |||
| 75871 | assert( cursorOwnsBtShared(pCur) ); | 76738 | assert( cursorOwnsBtShared(pCur) ); |
| 75872 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); | 76739 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 75873 | 76740 | ||
| 75874 | /* Currently this interface is only called by the OP_IfSmaller | 76741 | /* Currently this interface is only called by the OP_IfSizeBetween |
| 75875 | ** opcode, and it that case the cursor will always be valid and | 76742 | ** opcode and the OP_Count opcode with P3=1. In either case, |
| 75876 | ** will always point to a leaf node. */ | 76743 | ** the cursor will always be valid unless the btree is empty. */ |
| 75877 | if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; | 76744 | if( pCur->eState!=CURSOR_VALID ) return 0; |
| 75878 | if( NEVER(pCur->pPage->leaf==0) ) return -1; | 76745 | if( NEVER(pCur->pPage->leaf==0) ) return -1; |
| 75879 | 76746 | ||
| 75880 | n = pCur->pPage->nCell; | 76747 | n = pCur->pPage->nCell; |
| @@ -76020,7 +76887,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ | |||
| 76020 | } | 76887 | } |
| 76021 | 76888 | ||
| 76022 | pPage = pCur->pPage; | 76889 | pPage = pCur->pPage; |
| 76023 | assert( pPage->isInit ); | 76890 | if( sqlite3FaultSim(412) ) pPage->isInit = 0; |
| 76891 | if( !pPage->isInit ){ | ||
| 76892 | return SQLITE_CORRUPT_BKPT; | ||
| 76893 | } | ||
| 76024 | if( !pPage->leaf ){ | 76894 | if( !pPage->leaf ){ |
| 76025 | int idx = pCur->ix; | 76895 | int idx = pCur->ix; |
| 76026 | rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); | 76896 | rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); |
| @@ -76693,7 +77563,10 @@ static int fillInCell( | |||
| 76693 | n = nHeader + nPayload; | 77563 | n = nHeader + nPayload; |
| 76694 | testcase( n==3 ); | 77564 | testcase( n==3 ); |
| 76695 | testcase( n==4 ); | 77565 | testcase( n==4 ); |
| 76696 | if( n<4 ) n = 4; | 77566 | if( n<4 ){ |
| 77567 | n = 4; | ||
| 77568 | pPayload[nPayload] = 0; | ||
| 77569 | } | ||
| 76697 | *pnSize = n; | 77570 | *pnSize = n; |
| 76698 | assert( nSrc<=nPayload ); | 77571 | assert( nSrc<=nPayload ); |
| 76699 | testcase( nSrc<nPayload ); | 77572 | testcase( nSrc<nPayload ); |
| @@ -77999,7 +78872,7 @@ static int balance_nonroot( | |||
| 77999 | ** table-interior, index-leaf, or index-interior). | 78872 | ** table-interior, index-leaf, or index-interior). |
| 78000 | */ | 78873 | */ |
| 78001 | if( pOld->aData[0]!=apOld[0]->aData[0] ){ | 78874 | if( pOld->aData[0]!=apOld[0]->aData[0] ){ |
| 78002 | rc = SQLITE_CORRUPT_BKPT; | 78875 | rc = SQLITE_CORRUPT_PAGE(pOld); |
| 78003 | goto balance_cleanup; | 78876 | goto balance_cleanup; |
| 78004 | } | 78877 | } |
| 78005 | 78878 | ||
| @@ -78023,7 +78896,7 @@ static int balance_nonroot( | |||
| 78023 | memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); | 78896 | memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); |
| 78024 | if( pOld->nOverflow>0 ){ | 78897 | if( pOld->nOverflow>0 ){ |
| 78025 | if( NEVER(limit<pOld->aiOvfl[0]) ){ | 78898 | if( NEVER(limit<pOld->aiOvfl[0]) ){ |
| 78026 | rc = SQLITE_CORRUPT_BKPT; | 78899 | rc = SQLITE_CORRUPT_PAGE(pOld); |
| 78027 | goto balance_cleanup; | 78900 | goto balance_cleanup; |
| 78028 | } | 78901 | } |
| 78029 | limit = pOld->aiOvfl[0]; | 78902 | limit = pOld->aiOvfl[0]; |
| @@ -78666,7 +79539,7 @@ static int anotherValidCursor(BtCursor *pCur){ | |||
| 78666 | && pOther->eState==CURSOR_VALID | 79539 | && pOther->eState==CURSOR_VALID |
| 78667 | && pOther->pPage==pCur->pPage | 79540 | && pOther->pPage==pCur->pPage |
| 78668 | ){ | 79541 | ){ |
| 78669 | return SQLITE_CORRUPT_BKPT; | 79542 | return SQLITE_CORRUPT_PAGE(pCur->pPage); |
| 78670 | } | 79543 | } |
| 78671 | } | 79544 | } |
| 78672 | return SQLITE_OK; | 79545 | return SQLITE_OK; |
| @@ -78726,7 +79599,7 @@ static int balance(BtCursor *pCur){ | |||
| 78726 | /* The page being written is not a root page, and there is currently | 79599 | /* The page being written is not a root page, and there is currently |
| 78727 | ** more than one reference to it. This only happens if the page is one | 79600 | ** more than one reference to it. This only happens if the page is one |
| 78728 | ** of its own ancestor pages. Corruption. */ | 79601 | ** of its own ancestor pages. Corruption. */ |
| 78729 | rc = SQLITE_CORRUPT_BKPT; | 79602 | rc = SQLITE_CORRUPT_PAGE(pPage); |
| 78730 | }else{ | 79603 | }else{ |
| 78731 | MemPage * const pParent = pCur->apPage[iPage-1]; | 79604 | MemPage * const pParent = pCur->apPage[iPage-1]; |
| 78732 | int const iIdx = pCur->aiIdx[iPage-1]; | 79605 | int const iIdx = pCur->aiIdx[iPage-1]; |
| @@ -78890,7 +79763,7 @@ static SQLITE_NOINLINE int btreeOverwriteOverflowCell( | |||
| 78890 | rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); | 79763 | rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); |
| 78891 | if( rc ) return rc; | 79764 | if( rc ) return rc; |
| 78892 | if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ | 79765 | if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ |
| 78893 | rc = SQLITE_CORRUPT_BKPT; | 79766 | rc = SQLITE_CORRUPT_PAGE(pPage); |
| 78894 | }else{ | 79767 | }else{ |
| 78895 | if( iOffset+ovflPageSize<(u32)nTotal ){ | 79768 | if( iOffset+ovflPageSize<(u32)nTotal ){ |
| 78896 | ovflPgno = get4byte(pPage->aData); | 79769 | ovflPgno = get4byte(pPage->aData); |
| @@ -78918,7 +79791,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ | |||
| 78918 | if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd | 79791 | if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd |
| 78919 | || pCur->info.pPayload < pPage->aData + pPage->cellOffset | 79792 | || pCur->info.pPayload < pPage->aData + pPage->cellOffset |
| 78920 | ){ | 79793 | ){ |
| 78921 | return SQLITE_CORRUPT_BKPT; | 79794 | return SQLITE_CORRUPT_PAGE(pPage); |
| 78922 | } | 79795 | } |
| 78923 | if( pCur->info.nLocal==nTotal ){ | 79796 | if( pCur->info.nLocal==nTotal ){ |
| 78924 | /* The entire cell is local */ | 79797 | /* The entire cell is local */ |
| @@ -78999,7 +79872,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 78999 | ** Which can only happen if the SQLITE_NoSchemaError flag was set when | 79872 | ** Which can only happen if the SQLITE_NoSchemaError flag was set when |
| 79000 | ** the schema was loaded. This cannot be asserted though, as a user might | 79873 | ** the schema was loaded. This cannot be asserted though, as a user might |
| 79001 | ** set the flag, load the schema, and then unset the flag. */ | 79874 | ** set the flag, load the schema, and then unset the flag. */ |
| 79002 | return SQLITE_CORRUPT_BKPT; | 79875 | return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); |
| 79003 | } | 79876 | } |
| 79004 | } | 79877 | } |
| 79005 | 79878 | ||
| @@ -79122,7 +79995,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79122 | if( pPage->nFree<0 ){ | 79995 | if( pPage->nFree<0 ){ |
| 79123 | if( NEVER(pCur->eState>CURSOR_INVALID) ){ | 79996 | if( NEVER(pCur->eState>CURSOR_INVALID) ){ |
| 79124 | /* ^^^^^--- due to the moveToRoot() call above */ | 79997 | /* ^^^^^--- due to the moveToRoot() call above */ |
| 79125 | rc = SQLITE_CORRUPT_BKPT; | 79998 | rc = SQLITE_CORRUPT_PAGE(pPage); |
| 79126 | }else{ | 79999 | }else{ |
| 79127 | rc = btreeComputeFreeSpace(pPage); | 80000 | rc = btreeComputeFreeSpace(pPage); |
| 79128 | } | 80001 | } |
| @@ -79139,7 +80012,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79139 | if( flags & BTREE_PREFORMAT ){ | 80012 | if( flags & BTREE_PREFORMAT ){ |
| 79140 | rc = SQLITE_OK; | 80013 | rc = SQLITE_OK; |
| 79141 | szNew = p->pBt->nPreformatSize; | 80014 | szNew = p->pBt->nPreformatSize; |
| 79142 | if( szNew<4 ) szNew = 4; | 80015 | if( szNew<4 ){ |
| 80016 | szNew = 4; | ||
| 80017 | newCell[3] = 0; | ||
| 80018 | } | ||
| 79143 | if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ | 80019 | if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ |
| 79144 | CellInfo info; | 80020 | CellInfo info; |
| 79145 | pPage->xParseCell(pPage, newCell, &info); | 80021 | pPage->xParseCell(pPage, newCell, &info); |
| @@ -79161,7 +80037,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79161 | CellInfo info; | 80037 | CellInfo info; |
| 79162 | assert( idx>=0 ); | 80038 | assert( idx>=0 ); |
| 79163 | if( idx>=pPage->nCell ){ | 80039 | if( idx>=pPage->nCell ){ |
| 79164 | return SQLITE_CORRUPT_BKPT; | 80040 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79165 | } | 80041 | } |
| 79166 | rc = sqlite3PagerWrite(pPage->pDbPage); | 80042 | rc = sqlite3PagerWrite(pPage->pDbPage); |
| 79167 | if( rc ){ | 80043 | if( rc ){ |
| @@ -79188,10 +80064,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79188 | ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ | 80064 | ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ |
| 79189 | assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ | 80065 | assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ |
| 79190 | if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ | 80066 | if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ |
| 79191 | return SQLITE_CORRUPT_BKPT; | 80067 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79192 | } | 80068 | } |
| 79193 | if( oldCell+szNew > pPage->aDataEnd ){ | 80069 | if( oldCell+szNew > pPage->aDataEnd ){ |
| 79194 | return SQLITE_CORRUPT_BKPT; | 80070 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79195 | } | 80071 | } |
| 79196 | memcpy(oldCell, newCell, szNew); | 80072 | memcpy(oldCell, newCell, szNew); |
| 79197 | return SQLITE_OK; | 80073 | return SQLITE_OK; |
| @@ -79201,7 +80077,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79201 | }else if( loc<0 && pPage->nCell>0 ){ | 80077 | }else if( loc<0 && pPage->nCell>0 ){ |
| 79202 | assert( pPage->leaf ); | 80078 | assert( pPage->leaf ); |
| 79203 | idx = ++pCur->ix; | 80079 | idx = ++pCur->ix; |
| 79204 | pCur->curFlags &= ~BTCF_ValidNKey; | 80080 | pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 79205 | }else{ | 80081 | }else{ |
| 79206 | assert( pPage->leaf ); | 80082 | assert( pPage->leaf ); |
| 79207 | } | 80083 | } |
| @@ -79231,7 +80107,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 79231 | */ | 80107 | */ |
| 79232 | if( pPage->nOverflow ){ | 80108 | if( pPage->nOverflow ){ |
| 79233 | assert( rc==SQLITE_OK ); | 80109 | assert( rc==SQLITE_OK ); |
| 79234 | pCur->curFlags &= ~(BTCF_ValidNKey); | 80110 | pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 79235 | rc = balance(pCur); | 80111 | rc = balance(pCur); |
| 79236 | 80112 | ||
| 79237 | /* Must make sure nOverflow is reset to zero even if the balance() | 80113 | /* Must make sure nOverflow is reset to zero even if the balance() |
| @@ -79293,7 +80169,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 | |||
| 79293 | nIn = pSrc->info.nLocal; | 80169 | nIn = pSrc->info.nLocal; |
| 79294 | aIn = pSrc->info.pPayload; | 80170 | aIn = pSrc->info.pPayload; |
| 79295 | if( aIn+nIn>pSrc->pPage->aDataEnd ){ | 80171 | if( aIn+nIn>pSrc->pPage->aDataEnd ){ |
| 79296 | return SQLITE_CORRUPT_BKPT; | 80172 | return SQLITE_CORRUPT_PAGE(pSrc->pPage); |
| 79297 | } | 80173 | } |
| 79298 | nRem = pSrc->info.nPayload; | 80174 | nRem = pSrc->info.nPayload; |
| 79299 | if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ | 80175 | if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ |
| @@ -79318,7 +80194,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 | |||
| 79318 | 80194 | ||
| 79319 | if( nRem>nIn ){ | 80195 | if( nRem>nIn ){ |
| 79320 | if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ | 80196 | if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ |
| 79321 | return SQLITE_CORRUPT_BKPT; | 80197 | return SQLITE_CORRUPT_PAGE(pSrc->pPage); |
| 79322 | } | 80198 | } |
| 79323 | ovflIn = get4byte(&pSrc->info.pPayload[nIn]); | 80199 | ovflIn = get4byte(&pSrc->info.pPayload[nIn]); |
| 79324 | } | 80200 | } |
| @@ -79414,7 +80290,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ | |||
| 79414 | assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); | 80290 | assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); |
| 79415 | if( rc || pCur->eState!=CURSOR_VALID ) return rc; | 80291 | if( rc || pCur->eState!=CURSOR_VALID ) return rc; |
| 79416 | }else{ | 80292 | }else{ |
| 79417 | return SQLITE_CORRUPT_BKPT; | 80293 | return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); |
| 79418 | } | 80294 | } |
| 79419 | } | 80295 | } |
| 79420 | assert( pCur->eState==CURSOR_VALID ); | 80296 | assert( pCur->eState==CURSOR_VALID ); |
| @@ -79423,14 +80299,14 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ | |||
| 79423 | iCellIdx = pCur->ix; | 80299 | iCellIdx = pCur->ix; |
| 79424 | pPage = pCur->pPage; | 80300 | pPage = pCur->pPage; |
| 79425 | if( pPage->nCell<=iCellIdx ){ | 80301 | if( pPage->nCell<=iCellIdx ){ |
| 79426 | return SQLITE_CORRUPT_BKPT; | 80302 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79427 | } | 80303 | } |
| 79428 | pCell = findCell(pPage, iCellIdx); | 80304 | pCell = findCell(pPage, iCellIdx); |
| 79429 | if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ | 80305 | if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ |
| 79430 | return SQLITE_CORRUPT_BKPT; | 80306 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79431 | } | 80307 | } |
| 79432 | if( pCell<&pPage->aCellIdx[pPage->nCell] ){ | 80308 | if( pCell<&pPage->aCellIdx[pPage->nCell] ){ |
| 79433 | return SQLITE_CORRUPT_BKPT; | 80309 | return SQLITE_CORRUPT_PAGE(pPage); |
| 79434 | } | 80310 | } |
| 79435 | 80311 | ||
| 79436 | /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must | 80312 | /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must |
| @@ -79521,7 +80397,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ | |||
| 79521 | n = pCur->pPage->pgno; | 80397 | n = pCur->pPage->pgno; |
| 79522 | } | 80398 | } |
| 79523 | pCell = findCell(pLeaf, pLeaf->nCell-1); | 80399 | pCell = findCell(pLeaf, pLeaf->nCell-1); |
| 79524 | if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; | 80400 | if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_PAGE(pLeaf); |
| 79525 | nCell = pLeaf->xCellSize(pLeaf, pCell); | 80401 | nCell = pLeaf->xCellSize(pLeaf, pCell); |
| 79526 | assert( MX_CELL_SIZE(pBt) >= nCell ); | 80402 | assert( MX_CELL_SIZE(pBt) >= nCell ); |
| 79527 | pTmp = pBt->pTmpSpace; | 80403 | pTmp = pBt->pTmpSpace; |
| @@ -79637,7 +80513,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ | |||
| 79637 | */ | 80513 | */ |
| 79638 | sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); | 80514 | sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); |
| 79639 | if( pgnoRoot>btreePagecount(pBt) ){ | 80515 | if( pgnoRoot>btreePagecount(pBt) ){ |
| 79640 | return SQLITE_CORRUPT_BKPT; | 80516 | return SQLITE_CORRUPT_PGNO(pgnoRoot); |
| 79641 | } | 80517 | } |
| 79642 | pgnoRoot++; | 80518 | pgnoRoot++; |
| 79643 | 80519 | ||
| @@ -79685,7 +80561,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ | |||
| 79685 | } | 80561 | } |
| 79686 | rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); | 80562 | rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); |
| 79687 | if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ | 80563 | if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ |
| 79688 | rc = SQLITE_CORRUPT_BKPT; | 80564 | rc = SQLITE_CORRUPT_PGNO(pgnoRoot); |
| 79689 | } | 80565 | } |
| 79690 | if( rc!=SQLITE_OK ){ | 80566 | if( rc!=SQLITE_OK ){ |
| 79691 | releasePage(pRoot); | 80567 | releasePage(pRoot); |
| @@ -79775,14 +80651,14 @@ static int clearDatabasePage( | |||
| 79775 | 80651 | ||
| 79776 | assert( sqlite3_mutex_held(pBt->mutex) ); | 80652 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 79777 | if( pgno>btreePagecount(pBt) ){ | 80653 | if( pgno>btreePagecount(pBt) ){ |
| 79778 | return SQLITE_CORRUPT_BKPT; | 80654 | return SQLITE_CORRUPT_PGNO(pgno); |
| 79779 | } | 80655 | } |
| 79780 | rc = getAndInitPage(pBt, pgno, &pPage, 0); | 80656 | rc = getAndInitPage(pBt, pgno, &pPage, 0); |
| 79781 | if( rc ) return rc; | 80657 | if( rc ) return rc; |
| 79782 | if( (pBt->openFlags & BTREE_SINGLE)==0 | 80658 | if( (pBt->openFlags & BTREE_SINGLE)==0 |
| 79783 | && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) | 80659 | && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) |
| 79784 | ){ | 80660 | ){ |
| 79785 | rc = SQLITE_CORRUPT_BKPT; | 80661 | rc = SQLITE_CORRUPT_PAGE(pPage); |
| 79786 | goto cleardatabasepage_out; | 80662 | goto cleardatabasepage_out; |
| 79787 | } | 80663 | } |
| 79788 | hdr = pPage->hdrOffset; | 80664 | hdr = pPage->hdrOffset; |
| @@ -79886,7 +80762,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ | |||
| 79886 | assert( p->inTrans==TRANS_WRITE ); | 80762 | assert( p->inTrans==TRANS_WRITE ); |
| 79887 | assert( iTable>=2 ); | 80763 | assert( iTable>=2 ); |
| 79888 | if( iTable>btreePagecount(pBt) ){ | 80764 | if( iTable>btreePagecount(pBt) ){ |
| 79889 | return SQLITE_CORRUPT_BKPT; | 80765 | return SQLITE_CORRUPT_PGNO(iTable); |
| 79890 | } | 80766 | } |
| 79891 | 80767 | ||
| 79892 | rc = sqlite3BtreeClearTable(p, iTable, 0); | 80768 | rc = sqlite3BtreeClearTable(p, iTable, 0); |
| @@ -80480,6 +81356,9 @@ static int checkTreePage( | |||
| 80480 | ** number of cells on the page. */ | 81356 | ** number of cells on the page. */ |
| 80481 | nCell = get2byte(&data[hdr+3]); | 81357 | nCell = get2byte(&data[hdr+3]); |
| 80482 | assert( pPage->nCell==nCell ); | 81358 | assert( pPage->nCell==nCell ); |
| 81359 | if( pPage->leaf || pPage->intKey==0 ){ | ||
| 81360 | pCheck->nRow += nCell; | ||
| 81361 | } | ||
| 80483 | 81362 | ||
| 80484 | /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page | 81363 | /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page |
| 80485 | ** immediately follows the b-tree page header. */ | 81364 | ** immediately follows the b-tree page header. */ |
| @@ -80591,6 +81470,7 @@ static int checkTreePage( | |||
| 80591 | btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); | 81470 | btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); |
| 80592 | } | 81471 | } |
| 80593 | } | 81472 | } |
| 81473 | assert( heap!=0 ); | ||
| 80594 | /* Add the freeblocks to the min-heap | 81474 | /* Add the freeblocks to the min-heap |
| 80595 | ** | 81475 | ** |
| 80596 | ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header | 81476 | ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header |
| @@ -80690,6 +81570,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( | |||
| 80690 | sqlite3 *db, /* Database connection that is running the check */ | 81570 | sqlite3 *db, /* Database connection that is running the check */ |
| 80691 | Btree *p, /* The btree to be checked */ | 81571 | Btree *p, /* The btree to be checked */ |
| 80692 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ | 81572 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ |
| 81573 | Mem *aCnt, /* Memory cells to write counts for each tree to */ | ||
| 80693 | int nRoot, /* Number of entries in aRoot[] */ | 81574 | int nRoot, /* Number of entries in aRoot[] */ |
| 80694 | int mxErr, /* Stop reporting errors after this many */ | 81575 | int mxErr, /* Stop reporting errors after this many */ |
| 80695 | int *pnErr, /* OUT: Write number of errors seen to this variable */ | 81576 | int *pnErr, /* OUT: Write number of errors seen to this variable */ |
| @@ -80703,7 +81584,9 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( | |||
| 80703 | int bPartial = 0; /* True if not checking all btrees */ | 81584 | int bPartial = 0; /* True if not checking all btrees */ |
| 80704 | int bCkFreelist = 1; /* True to scan the freelist */ | 81585 | int bCkFreelist = 1; /* True to scan the freelist */ |
| 80705 | VVA_ONLY( int nRef ); | 81586 | VVA_ONLY( int nRef ); |
| 81587 | |||
| 80706 | assert( nRoot>0 ); | 81588 | assert( nRoot>0 ); |
| 81589 | assert( aCnt!=0 ); | ||
| 80707 | 81590 | ||
| 80708 | /* aRoot[0]==0 means this is a partial check */ | 81591 | /* aRoot[0]==0 means this is a partial check */ |
| 80709 | if( aRoot[0]==0 ){ | 81592 | if( aRoot[0]==0 ){ |
| @@ -80776,15 +81659,18 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( | |||
| 80776 | testcase( pBt->db->flags & SQLITE_CellSizeCk ); | 81659 | testcase( pBt->db->flags & SQLITE_CellSizeCk ); |
| 80777 | pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; | 81660 | pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; |
| 80778 | for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ | 81661 | for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ |
| 80779 | i64 notUsed; | 81662 | sCheck.nRow = 0; |
| 80780 | if( aRoot[i]==0 ) continue; | 81663 | if( aRoot[i] ){ |
| 81664 | i64 notUsed; | ||
| 80781 | #ifndef SQLITE_OMIT_AUTOVACUUM | 81665 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 80782 | if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ | 81666 | if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ |
| 80783 | checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); | 81667 | checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); |
| 80784 | } | 81668 | } |
| 80785 | #endif | 81669 | #endif |
| 80786 | sCheck.v0 = aRoot[i]; | 81670 | sCheck.v0 = aRoot[i]; |
| 80787 | checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); | 81671 | checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); |
| 81672 | } | ||
| 81673 | sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); | ||
| 80788 | } | 81674 | } |
| 80789 | pBt->db->flags = savedDbFlags; | 81675 | pBt->db->flags = savedDbFlags; |
| 80790 | 81676 | ||
| @@ -82839,6 +83725,13 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ | |||
| 82839 | } | 83725 | } |
| 82840 | } | 83726 | } |
| 82841 | 83727 | ||
| 83728 | /* | ||
| 83729 | ** Set the iIdx'th entry of array aMem[] to contain integer value val. | ||
| 83730 | */ | ||
| 83731 | SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val){ | ||
| 83732 | sqlite3VdbeMemSetInt64(&aMem[iIdx], val); | ||
| 83733 | } | ||
| 83734 | |||
| 82842 | /* A no-op destructor */ | 83735 | /* A no-op destructor */ |
| 82843 | SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } | 83736 | SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } |
| 82844 | 83737 | ||
| @@ -83411,7 +84304,7 @@ static int valueFromFunction( | |||
| 83411 | #endif | 84304 | #endif |
| 83412 | assert( pFunc ); | 84305 | assert( pFunc ); |
| 83413 | if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 | 84306 | if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 |
| 83414 | || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) | 84307 | || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0 |
| 83415 | ){ | 84308 | ){ |
| 83416 | return SQLITE_OK; | 84309 | return SQLITE_OK; |
| 83417 | } | 84310 | } |
| @@ -83527,14 +84420,20 @@ static int valueFromExpr( | |||
| 83527 | } | 84420 | } |
| 83528 | 84421 | ||
| 83529 | /* Handle negative integers in a single step. This is needed in the | 84422 | /* Handle negative integers in a single step. This is needed in the |
| 83530 | ** case when the value is -9223372036854775808. | 84423 | ** case when the value is -9223372036854775808. Except - do not do this |
| 83531 | */ | 84424 | ** for hexadecimal literals. */ |
| 83532 | if( op==TK_UMINUS | 84425 | if( op==TK_UMINUS ){ |
| 83533 | && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ | 84426 | Expr *pLeft = pExpr->pLeft; |
| 83534 | pExpr = pExpr->pLeft; | 84427 | if( (pLeft->op==TK_INTEGER || pLeft->op==TK_FLOAT) ){ |
| 83535 | op = pExpr->op; | 84428 | if( ExprHasProperty(pLeft, EP_IntValue) |
| 83536 | negInt = -1; | 84429 | || pLeft->u.zToken[0]!='0' || (pLeft->u.zToken[1] & ~0x20)!='X' |
| 83537 | zNeg = "-"; | 84430 | ){ |
| 84431 | pExpr = pLeft; | ||
| 84432 | op = pExpr->op; | ||
| 84433 | negInt = -1; | ||
| 84434 | zNeg = "-"; | ||
| 84435 | } | ||
| 84436 | } | ||
| 83538 | } | 84437 | } |
| 83539 | 84438 | ||
| 83540 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ | 84439 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| @@ -83543,12 +84442,26 @@ static int valueFromExpr( | |||
| 83543 | if( ExprHasProperty(pExpr, EP_IntValue) ){ | 84442 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 83544 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); | 84443 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 83545 | }else{ | 84444 | }else{ |
| 83546 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); | 84445 | i64 iVal; |
| 83547 | if( zVal==0 ) goto no_mem; | 84446 | if( op==TK_INTEGER && 0==sqlite3DecOrHexToI64(pExpr->u.zToken, &iVal) ){ |
| 83548 | sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); | 84447 | sqlite3VdbeMemSetInt64(pVal, iVal*negInt); |
| 84448 | }else{ | ||
| 84449 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); | ||
| 84450 | if( zVal==0 ) goto no_mem; | ||
| 84451 | sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); | ||
| 84452 | } | ||
| 83549 | } | 84453 | } |
| 83550 | if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ | 84454 | if( affinity==SQLITE_AFF_BLOB ){ |
| 83551 | sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); | 84455 | if( op==TK_FLOAT ){ |
| 84456 | assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); | ||
| 84457 | sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8); | ||
| 84458 | pVal->flags = MEM_Real; | ||
| 84459 | }else if( op==TK_INTEGER ){ | ||
| 84460 | /* This case is required by -9223372036854775808 and other strings | ||
| 84461 | ** that look like integers but cannot be handled by the | ||
| 84462 | ** sqlite3DecOrHexToI64() call above. */ | ||
| 84463 | sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); | ||
| 84464 | } | ||
| 83552 | }else{ | 84465 | }else{ |
| 83553 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); | 84466 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 83554 | } | 84467 | } |
| @@ -83818,17 +84731,17 @@ SQLITE_PRIVATE int sqlite3Stat4Column( | |||
| 83818 | sqlite3_value **ppVal /* OUT: Extracted value */ | 84731 | sqlite3_value **ppVal /* OUT: Extracted value */ |
| 83819 | ){ | 84732 | ){ |
| 83820 | u32 t = 0; /* a column type code */ | 84733 | u32 t = 0; /* a column type code */ |
| 83821 | int nHdr; /* Size of the header in the record */ | 84734 | u32 nHdr; /* Size of the header in the record */ |
| 83822 | int iHdr; /* Next unread header byte */ | 84735 | u32 iHdr; /* Next unread header byte */ |
| 83823 | int iField; /* Next unread data byte */ | 84736 | i64 iField; /* Next unread data byte */ |
| 83824 | int szField = 0; /* Size of the current data field */ | 84737 | u32 szField = 0; /* Size of the current data field */ |
| 83825 | int i; /* Column index */ | 84738 | int i; /* Column index */ |
| 83826 | u8 *a = (u8*)pRec; /* Typecast byte array */ | 84739 | u8 *a = (u8*)pRec; /* Typecast byte array */ |
| 83827 | Mem *pMem = *ppVal; /* Write result into this Mem object */ | 84740 | Mem *pMem = *ppVal; /* Write result into this Mem object */ |
| 83828 | 84741 | ||
| 83829 | assert( iCol>0 ); | 84742 | assert( iCol>0 ); |
| 83830 | iHdr = getVarint32(a, nHdr); | 84743 | iHdr = getVarint32(a, nHdr); |
| 83831 | if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; | 84744 | if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; |
| 83832 | iField = nHdr; | 84745 | iField = nHdr; |
| 83833 | for(i=0; i<=iCol; i++){ | 84746 | for(i=0; i<=iCol; i++){ |
| 83834 | iHdr += getVarint32(&a[iHdr], t); | 84747 | iHdr += getVarint32(&a[iHdr], t); |
| @@ -84135,10 +85048,11 @@ static int growOpArray(Vdbe *v, int nOp){ | |||
| 84135 | ** sqlite3CantopenError(lineno) | 85048 | ** sqlite3CantopenError(lineno) |
| 84136 | */ | 85049 | */ |
| 84137 | static void test_addop_breakpoint(int pc, Op *pOp){ | 85050 | static void test_addop_breakpoint(int pc, Op *pOp){ |
| 84138 | static int n = 0; | 85051 | static u64 n = 0; |
| 84139 | (void)pc; | 85052 | (void)pc; |
| 84140 | (void)pOp; | 85053 | (void)pOp; |
| 84141 | n++; | 85054 | n++; |
| 85055 | if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ | ||
| 84142 | } | 85056 | } |
| 84143 | #endif | 85057 | #endif |
| 84144 | 85058 | ||
| @@ -84862,6 +85776,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ | |||
| 84862 | assert( aLabel!=0 ); /* True because of tag-20230419-1 */ | 85776 | assert( aLabel!=0 ); /* True because of tag-20230419-1 */ |
| 84863 | pOp->p2 = aLabel[ADDR(pOp->p2)]; | 85777 | pOp->p2 = aLabel[ADDR(pOp->p2)]; |
| 84864 | } | 85778 | } |
| 85779 | |||
| 85780 | /* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes | ||
| 85781 | ** might */ | ||
| 85782 | assert( pOp->p2>0 | ||
| 85783 | || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 ); | ||
| 85784 | |||
| 85785 | /* Jumps never go off the end of the bytecode array */ | ||
| 85786 | assert( pOp->p2<p->nOp | ||
| 85787 | || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 ); | ||
| 84865 | break; | 85788 | break; |
| 84866 | } | 85789 | } |
| 84867 | } | 85790 | } |
| @@ -85323,6 +86246,10 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ | |||
| 85323 | if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); | 86246 | if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); |
| 85324 | break; | 86247 | break; |
| 85325 | } | 86248 | } |
| 86249 | case P4_TABLEREF: { | ||
| 86250 | if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); | ||
| 86251 | break; | ||
| 86252 | } | ||
| 85326 | } | 86253 | } |
| 85327 | } | 86254 | } |
| 85328 | 86255 | ||
| @@ -85450,7 +86377,7 @@ static void SQLITE_NOINLINE vdbeChangeP4Full( | |||
| 85450 | int n | 86377 | int n |
| 85451 | ){ | 86378 | ){ |
| 85452 | if( pOp->p4type ){ | 86379 | if( pOp->p4type ){ |
| 85453 | freeP4(p->db, pOp->p4type, pOp->p4.p); | 86380 | assert( pOp->p4type > P4_FREE_IF_LE ); |
| 85454 | pOp->p4type = 0; | 86381 | pOp->p4type = 0; |
| 85455 | pOp->p4.p = 0; | 86382 | pOp->p4.p = 0; |
| 85456 | } | 86383 | } |
| @@ -87265,7 +88192,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ | |||
| 87265 | 88192 | ||
| 87266 | /* Check for immediate foreign key violations. */ | 88193 | /* Check for immediate foreign key violations. */ |
| 87267 | if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ | 88194 | if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ |
| 87268 | sqlite3VdbeCheckFk(p, 0); | 88195 | (void)sqlite3VdbeCheckFk(p, 0); |
| 87269 | } | 88196 | } |
| 87270 | 88197 | ||
| 87271 | /* If the auto-commit flag is set and this is the only active writer | 88198 | /* If the auto-commit flag is set and this is the only active writer |
| @@ -87979,6 +88906,23 @@ static void serialGet( | |||
| 87979 | pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; | 88906 | pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; |
| 87980 | } | 88907 | } |
| 87981 | } | 88908 | } |
| 88909 | static int serialGet7( | ||
| 88910 | const unsigned char *buf, /* Buffer to deserialize from */ | ||
| 88911 | Mem *pMem /* Memory cell to write value into */ | ||
| 88912 | ){ | ||
| 88913 | u64 x = FOUR_BYTE_UINT(buf); | ||
| 88914 | u32 y = FOUR_BYTE_UINT(buf+4); | ||
| 88915 | x = (x<<32) + y; | ||
| 88916 | assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); | ||
| 88917 | swapMixedEndianFloat(x); | ||
| 88918 | memcpy(&pMem->u.r, &x, sizeof(x)); | ||
| 88919 | if( IsNaN(x) ){ | ||
| 88920 | pMem->flags = MEM_Null; | ||
| 88921 | return 1; | ||
| 88922 | } | ||
| 88923 | pMem->flags = MEM_Real; | ||
| 88924 | return 0; | ||
| 88925 | } | ||
| 87982 | SQLITE_PRIVATE void sqlite3VdbeSerialGet( | 88926 | SQLITE_PRIVATE void sqlite3VdbeSerialGet( |
| 87983 | const unsigned char *buf, /* Buffer to deserialize from */ | 88927 | const unsigned char *buf, /* Buffer to deserialize from */ |
| 87984 | u32 serial_type, /* Serial type to deserialize */ | 88928 | u32 serial_type, /* Serial type to deserialize */ |
| @@ -88418,17 +89362,15 @@ SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ | |||
| 88418 | return (x<r) ? -1 : (x>r); | 89362 | return (x<r) ? -1 : (x>r); |
| 88419 | }else{ | 89363 | }else{ |
| 88420 | i64 y; | 89364 | i64 y; |
| 88421 | double s; | ||
| 88422 | if( r<-9223372036854775808.0 ) return +1; | 89365 | if( r<-9223372036854775808.0 ) return +1; |
| 88423 | if( r>=9223372036854775808.0 ) return -1; | 89366 | if( r>=9223372036854775808.0 ) return -1; |
| 88424 | y = (i64)r; | 89367 | y = (i64)r; |
| 88425 | if( i<y ) return -1; | 89368 | if( i<y ) return -1; |
| 88426 | if( i>y ) return +1; | 89369 | if( i>y ) return +1; |
| 88427 | s = (double)i; | 89370 | testcase( doubleLt(((double)i),r) ); |
| 88428 | testcase( doubleLt(s,r) ); | 89371 | testcase( doubleLt(r,((double)i)) ); |
| 88429 | testcase( doubleLt(r,s) ); | 89372 | testcase( doubleEq(r,((double)i)) ); |
| 88430 | testcase( doubleEq(r,s) ); | 89373 | return (((double)i)<r) ? -1 : (((double)i)>r); |
| 88431 | return (s<r) ? -1 : (s>r); | ||
| 88432 | } | 89374 | } |
| 88433 | } | 89375 | } |
| 88434 | 89376 | ||
| @@ -88658,7 +89600,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 88658 | }else if( serial_type==0 ){ | 89600 | }else if( serial_type==0 ){ |
| 88659 | rc = -1; | 89601 | rc = -1; |
| 88660 | }else if( serial_type==7 ){ | 89602 | }else if( serial_type==7 ){ |
| 88661 | sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); | 89603 | serialGet7(&aKey1[d1], &mem1); |
| 88662 | rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); | 89604 | rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); |
| 88663 | }else{ | 89605 | }else{ |
| 88664 | i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); | 89606 | i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); |
| @@ -88683,14 +89625,18 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 88683 | }else if( serial_type==0 ){ | 89625 | }else if( serial_type==0 ){ |
| 88684 | rc = -1; | 89626 | rc = -1; |
| 88685 | }else{ | 89627 | }else{ |
| 88686 | sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); | ||
| 88687 | if( serial_type==7 ){ | 89628 | if( serial_type==7 ){ |
| 88688 | if( mem1.u.r<pRhs->u.r ){ | 89629 | if( serialGet7(&aKey1[d1], &mem1) ){ |
| 89630 | rc = -1; /* mem1 is a NaN */ | ||
| 89631 | }else if( mem1.u.r<pRhs->u.r ){ | ||
| 88689 | rc = -1; | 89632 | rc = -1; |
| 88690 | }else if( mem1.u.r>pRhs->u.r ){ | 89633 | }else if( mem1.u.r>pRhs->u.r ){ |
| 88691 | rc = +1; | 89634 | rc = +1; |
| 89635 | }else{ | ||
| 89636 | assert( rc==0 ); | ||
| 88692 | } | 89637 | } |
| 88693 | }else{ | 89638 | }else{ |
| 89639 | sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); | ||
| 88694 | rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); | 89640 | rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); |
| 88695 | } | 89641 | } |
| 88696 | } | 89642 | } |
| @@ -88760,7 +89706,14 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 88760 | /* RHS is null */ | 89706 | /* RHS is null */ |
| 88761 | else{ | 89707 | else{ |
| 88762 | serial_type = aKey1[idx1]; | 89708 | serial_type = aKey1[idx1]; |
| 88763 | rc = (serial_type!=0 && serial_type!=10); | 89709 | if( serial_type==0 |
| 89710 | || serial_type==10 | ||
| 89711 | || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) | ||
| 89712 | ){ | ||
| 89713 | assert( rc==0 ); | ||
| 89714 | }else{ | ||
| 89715 | rc = 1; | ||
| 89716 | } | ||
| 88764 | } | 89717 | } |
| 88765 | 89718 | ||
| 88766 | if( rc!=0 ){ | 89719 | if( rc!=0 ){ |
| @@ -89220,7 +90173,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff | |||
| 89220 | assert( iVar>0 ); | 90173 | assert( iVar>0 ); |
| 89221 | if( v ){ | 90174 | if( v ){ |
| 89222 | Mem *pMem = &v->aVar[iVar-1]; | 90175 | Mem *pMem = &v->aVar[iVar-1]; |
| 89223 | assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); | 90176 | assert( (v->db->flags & SQLITE_EnableQPSG)==0 |
| 90177 | || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); | ||
| 89224 | if( 0==(pMem->flags & MEM_Null) ){ | 90178 | if( 0==(pMem->flags & MEM_Null) ){ |
| 89225 | sqlite3_value *pRet = sqlite3ValueNew(v->db); | 90179 | sqlite3_value *pRet = sqlite3ValueNew(v->db); |
| 89226 | if( pRet ){ | 90180 | if( pRet ){ |
| @@ -89240,7 +90194,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff | |||
| 89240 | */ | 90194 | */ |
| 89241 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ | 90195 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ |
| 89242 | assert( iVar>0 ); | 90196 | assert( iVar>0 ); |
| 89243 | assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); | 90197 | assert( (v->db->flags & SQLITE_EnableQPSG)==0 |
| 90198 | || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); | ||
| 89244 | if( iVar>=32 ){ | 90199 | if( iVar>=32 ){ |
| 89245 | v->expmask |= 0x80000000; | 90200 | v->expmask |= 0x80000000; |
| 89246 | }else{ | 90201 | }else{ |
| @@ -89573,7 +90528,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ | |||
| 89573 | int rc = SQLITE_OK; | 90528 | int rc = SQLITE_OK; |
| 89574 | Vdbe *p = (Vdbe*)pStmt; | 90529 | Vdbe *p = (Vdbe*)pStmt; |
| 89575 | #if SQLITE_THREADSAFE | 90530 | #if SQLITE_THREADSAFE |
| 89576 | sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; | 90531 | sqlite3_mutex *mutex; |
| 90532 | #endif | ||
| 90533 | #ifdef SQLITE_ENABLE_API_ARMOR | ||
| 90534 | if( pStmt==0 ){ | ||
| 90535 | return SQLITE_MISUSE_BKPT; | ||
| 90536 | } | ||
| 90537 | #endif | ||
| 90538 | #if SQLITE_THREADSAFE | ||
| 90539 | mutex = p->db->mutex; | ||
| 89577 | #endif | 90540 | #endif |
| 89578 | sqlite3_mutex_enter(mutex); | 90541 | sqlite3_mutex_enter(mutex); |
| 89579 | for(i=0; i<p->nVar; i++){ | 90542 | for(i=0; i<p->nVar; i++){ |
| @@ -89952,6 +90915,18 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubt | |||
| 89952 | #ifdef SQLITE_ENABLE_API_ARMOR | 90915 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 89953 | if( pCtx==0 ) return; | 90916 | if( pCtx==0 ) return; |
| 89954 | #endif | 90917 | #endif |
| 90918 | #if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0 | ||
| 90919 | if( pCtx->pFunc!=0 | ||
| 90920 | && (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0 | ||
| 90921 | ){ | ||
| 90922 | char zErr[200]; | ||
| 90923 | sqlite3_snprintf(sizeof(zErr), zErr, | ||
| 90924 | "misuse of sqlite3_result_subtype() by %s()", | ||
| 90925 | pCtx->pFunc->zName); | ||
| 90926 | sqlite3_result_error(pCtx, zErr, -1); | ||
| 90927 | return; | ||
| 90928 | } | ||
| 90929 | #endif /* SQLITE_STRICT_SUBTYPE */ | ||
| 89955 | pOut = pCtx->pOut; | 90930 | pOut = pCtx->pOut; |
| 89956 | assert( sqlite3_mutex_held(pOut->db->mutex) ); | 90931 | assert( sqlite3_mutex_held(pOut->db->mutex) ); |
| 89957 | pOut->eSubtype = eSubtype & 0xff; | 90932 | pOut->eSubtype = eSubtype & 0xff; |
| @@ -90351,9 +91326,8 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ | |||
| 90351 | SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ | 91326 | SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ |
| 90352 | #ifdef SQLITE_ENABLE_API_ARMOR | 91327 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 90353 | if( p==0 ) return 0; | 91328 | if( p==0 ) return 0; |
| 90354 | #else | ||
| 90355 | assert( p && p->pFunc ); | ||
| 90356 | #endif | 91329 | #endif |
| 91330 | assert( p && p->pFunc ); | ||
| 90357 | return p->pFunc->pUserData; | 91331 | return p->pFunc->pUserData; |
| 90358 | } | 91332 | } |
| 90359 | 91333 | ||
| @@ -91806,7 +92780,6 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( | |||
| 91806 | } | 92780 | } |
| 91807 | if( flags & SQLITE_SCANSTAT_COMPLEX ){ | 92781 | if( flags & SQLITE_SCANSTAT_COMPLEX ){ |
| 91808 | idx = iScan; | 92782 | idx = iScan; |
| 91809 | pScan = &p->aScan[idx]; | ||
| 91810 | }else{ | 92783 | }else{ |
| 91811 | /* If the COMPLEX flag is clear, then this function must ignore any | 92784 | /* If the COMPLEX flag is clear, then this function must ignore any |
| 91812 | ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ | 92785 | ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ |
| @@ -91819,6 +92792,8 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( | |||
| 91819 | } | 92792 | } |
| 91820 | } | 92793 | } |
| 91821 | if( idx>=p->nScan ) return 1; | 92794 | if( idx>=p->nScan ) return 1; |
| 92795 | assert( pScan==0 || pScan==&p->aScan[idx] ); | ||
| 92796 | pScan = &p->aScan[idx]; | ||
| 91822 | 92797 | ||
| 91823 | switch( iScanStatusOp ){ | 92798 | switch( iScanStatusOp ){ |
| 91824 | case SQLITE_SCANSTAT_NLOOP: { | 92799 | case SQLITE_SCANSTAT_NLOOP: { |
| @@ -92270,11 +93245,12 @@ SQLITE_API int sqlite3_found_count = 0; | |||
| 92270 | ** sqlite3CantopenError(lineno) | 93245 | ** sqlite3CantopenError(lineno) |
| 92271 | */ | 93246 | */ |
| 92272 | static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ | 93247 | static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ |
| 92273 | static int n = 0; | 93248 | static u64 n = 0; |
| 92274 | (void)pc; | 93249 | (void)pc; |
| 92275 | (void)pOp; | 93250 | (void)pOp; |
| 92276 | (void)v; | 93251 | (void)v; |
| 92277 | n++; | 93252 | n++; |
| 93253 | if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ | ||
| 92278 | } | 93254 | } |
| 92279 | #endif | 93255 | #endif |
| 92280 | 93256 | ||
| @@ -93266,7 +94242,7 @@ case OP_Return: { /* in1 */ | |||
| 93266 | ** | 94242 | ** |
| 93267 | ** See also: EndCoroutine | 94243 | ** See also: EndCoroutine |
| 93268 | */ | 94244 | */ |
| 93269 | case OP_InitCoroutine: { /* jump */ | 94245 | case OP_InitCoroutine: { /* jump0 */ |
| 93270 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); | 94246 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 93271 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); | 94247 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 93272 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); | 94248 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| @@ -93289,7 +94265,9 @@ jump_to_p2: | |||
| 93289 | ** | 94265 | ** |
| 93290 | ** The instruction at the address in register P1 is a Yield. | 94266 | ** The instruction at the address in register P1 is a Yield. |
| 93291 | ** Jump to the P2 parameter of that Yield. | 94267 | ** Jump to the P2 parameter of that Yield. |
| 93292 | ** After the jump, register P1 becomes undefined. | 94268 | ** After the jump, the value register P1 is left with a value |
| 94269 | ** such that subsequent OP_Yields go back to the this same | ||
| 94270 | ** OP_EndCoroutine instruction. | ||
| 93293 | ** | 94271 | ** |
| 93294 | ** See also: InitCoroutine | 94272 | ** See also: InitCoroutine |
| 93295 | */ | 94273 | */ |
| @@ -93301,8 +94279,8 @@ case OP_EndCoroutine: { /* in1 */ | |||
| 93301 | pCaller = &aOp[pIn1->u.i]; | 94279 | pCaller = &aOp[pIn1->u.i]; |
| 93302 | assert( pCaller->opcode==OP_Yield ); | 94280 | assert( pCaller->opcode==OP_Yield ); |
| 93303 | assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); | 94281 | assert( pCaller->p2>=0 && pCaller->p2<p->nOp ); |
| 94282 | pIn1->u.i = (int)(pOp - p->aOp) - 1; | ||
| 93304 | pOp = &aOp[pCaller->p2 - 1]; | 94283 | pOp = &aOp[pCaller->p2 - 1]; |
| 93305 | pIn1->flags = MEM_Undefined; | ||
| 93306 | break; | 94284 | break; |
| 93307 | } | 94285 | } |
| 93308 | 94286 | ||
| @@ -93319,7 +94297,7 @@ case OP_EndCoroutine: { /* in1 */ | |||
| 93319 | ** | 94297 | ** |
| 93320 | ** See also: InitCoroutine | 94298 | ** See also: InitCoroutine |
| 93321 | */ | 94299 | */ |
| 93322 | case OP_Yield: { /* in1, jump */ | 94300 | case OP_Yield: { /* in1, jump0 */ |
| 93323 | int pcDest; | 94301 | int pcDest; |
| 93324 | pIn1 = &aMem[pOp->p1]; | 94302 | pIn1 = &aMem[pOp->p1]; |
| 93325 | assert( VdbeMemDynamic(pIn1)==0 ); | 94303 | assert( VdbeMemDynamic(pIn1)==0 ); |
| @@ -93649,19 +94627,15 @@ case OP_Blob: { /* out2 */ | |||
| 93649 | break; | 94627 | break; |
| 93650 | } | 94628 | } |
| 93651 | 94629 | ||
| 93652 | /* Opcode: Variable P1 P2 * P4 * | 94630 | /* Opcode: Variable P1 P2 * * * |
| 93653 | ** Synopsis: r[P2]=parameter(P1,P4) | 94631 | ** Synopsis: r[P2]=parameter(P1) |
| 93654 | ** | 94632 | ** |
| 93655 | ** Transfer the values of bound parameter P1 into register P2 | 94633 | ** Transfer the values of bound parameter P1 into register P2 |
| 93656 | ** | ||
| 93657 | ** If the parameter is named, then its name appears in P4. | ||
| 93658 | ** The P4 value is used by sqlite3_bind_parameter_name(). | ||
| 93659 | */ | 94634 | */ |
| 93660 | case OP_Variable: { /* out2 */ | 94635 | case OP_Variable: { /* out2 */ |
| 93661 | Mem *pVar; /* Value being transferred */ | 94636 | Mem *pVar; /* Value being transferred */ |
| 93662 | 94637 | ||
| 93663 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); | 94638 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 93664 | assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); | ||
| 93665 | pVar = &p->aVar[pOp->p1 - 1]; | 94639 | pVar = &p->aVar[pOp->p1 - 1]; |
| 93666 | if( sqlite3VdbeMemTooBig(pVar) ){ | 94640 | if( sqlite3VdbeMemTooBig(pVar) ){ |
| 93667 | goto too_big; | 94641 | goto too_big; |
| @@ -94171,7 +95145,7 @@ case OP_AddImm: { /* in1 */ | |||
| 94171 | pIn1 = &aMem[pOp->p1]; | 95145 | pIn1 = &aMem[pOp->p1]; |
| 94172 | memAboutToChange(p, pIn1); | 95146 | memAboutToChange(p, pIn1); |
| 94173 | sqlite3VdbeMemIntegerify(pIn1); | 95147 | sqlite3VdbeMemIntegerify(pIn1); |
| 94174 | pIn1->u.i += pOp->p2; | 95148 | *(u64*)&pIn1->u.i += (u64)pOp->p2; |
| 94175 | break; | 95149 | break; |
| 94176 | } | 95150 | } |
| 94177 | 95151 | ||
| @@ -94182,7 +95156,7 @@ case OP_AddImm: { /* in1 */ | |||
| 94182 | ** without data loss, then jump immediately to P2, or if P2==0 | 95156 | ** without data loss, then jump immediately to P2, or if P2==0 |
| 94183 | ** raise an SQLITE_MISMATCH exception. | 95157 | ** raise an SQLITE_MISMATCH exception. |
| 94184 | */ | 95158 | */ |
| 94185 | case OP_MustBeInt: { /* jump, in1 */ | 95159 | case OP_MustBeInt: { /* jump0, in1 */ |
| 94186 | pIn1 = &aMem[pOp->p1]; | 95160 | pIn1 = &aMem[pOp->p1]; |
| 94187 | if( (pIn1->flags & MEM_Int)==0 ){ | 95161 | if( (pIn1->flags & MEM_Int)==0 ){ |
| 94188 | applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); | 95162 | applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); |
| @@ -94223,7 +95197,7 @@ case OP_RealAffinity: { /* in1 */ | |||
| 94223 | } | 95197 | } |
| 94224 | #endif | 95198 | #endif |
| 94225 | 95199 | ||
| 94226 | #ifndef SQLITE_OMIT_CAST | 95200 | #if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE) |
| 94227 | /* Opcode: Cast P1 P2 * * * | 95201 | /* Opcode: Cast P1 P2 * * * |
| 94228 | ** Synopsis: affinity(r[P1]) | 95202 | ** Synopsis: affinity(r[P1]) |
| 94229 | ** | 95203 | ** |
| @@ -94438,7 +95412,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 94438 | } | 95412 | } |
| 94439 | } | 95413 | } |
| 94440 | }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ | 95414 | }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ |
| 94441 | if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | 95415 | if( (flags1 & MEM_Str)!=0 ){ |
| 95416 | pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); | ||
| 95417 | }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | ||
| 94442 | testcase( pIn1->flags & MEM_Int ); | 95418 | testcase( pIn1->flags & MEM_Int ); |
| 94443 | testcase( pIn1->flags & MEM_Real ); | 95419 | testcase( pIn1->flags & MEM_Real ); |
| 94444 | testcase( pIn1->flags & MEM_IntReal ); | 95420 | testcase( pIn1->flags & MEM_IntReal ); |
| @@ -94447,7 +95423,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 94447 | flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); | 95423 | flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); |
| 94448 | if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; | 95424 | if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; |
| 94449 | } | 95425 | } |
| 94450 | if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | 95426 | if( (flags3 & MEM_Str)!=0 ){ |
| 95427 | pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); | ||
| 95428 | }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | ||
| 94451 | testcase( pIn3->flags & MEM_Int ); | 95429 | testcase( pIn3->flags & MEM_Int ); |
| 94452 | testcase( pIn3->flags & MEM_Real ); | 95430 | testcase( pIn3->flags & MEM_Real ); |
| 94453 | testcase( pIn3->flags & MEM_IntReal ); | 95431 | testcase( pIn3->flags & MEM_IntReal ); |
| @@ -95791,11 +96769,16 @@ case OP_MakeRecord: { | |||
| 95791 | switch( len ){ | 96769 | switch( len ){ |
| 95792 | default: zPayload[7] = (u8)(v&0xff); v >>= 8; | 96770 | default: zPayload[7] = (u8)(v&0xff); v >>= 8; |
| 95793 | zPayload[6] = (u8)(v&0xff); v >>= 8; | 96771 | zPayload[6] = (u8)(v&0xff); v >>= 8; |
| 96772 | /* no break */ deliberate_fall_through | ||
| 95794 | case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; | 96773 | case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; |
| 95795 | zPayload[4] = (u8)(v&0xff); v >>= 8; | 96774 | zPayload[4] = (u8)(v&0xff); v >>= 8; |
| 96775 | /* no break */ deliberate_fall_through | ||
| 95796 | case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; | 96776 | case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; |
| 96777 | /* no break */ deliberate_fall_through | ||
| 95797 | case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; | 96778 | case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; |
| 96779 | /* no break */ deliberate_fall_through | ||
| 95798 | case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; | 96780 | case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; |
| 96781 | /* no break */ deliberate_fall_through | ||
| 95799 | case 1: zPayload[0] = (u8)(v&0xff); | 96782 | case 1: zPayload[0] = (u8)(v&0xff); |
| 95800 | } | 96783 | } |
| 95801 | zPayload += len; | 96784 | zPayload += len; |
| @@ -96714,7 +97697,8 @@ case OP_SequenceTest: { | |||
| 96714 | ** is the only cursor opcode that works with a pseudo-table. | 97697 | ** is the only cursor opcode that works with a pseudo-table. |
| 96715 | ** | 97698 | ** |
| 96716 | ** P3 is the number of fields in the records that will be stored by | 97699 | ** P3 is the number of fields in the records that will be stored by |
| 96717 | ** the pseudo-table. | 97700 | ** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor |
| 97701 | ** will return NULL for every column. | ||
| 96718 | */ | 97702 | */ |
| 96719 | case OP_OpenPseudo: { | 97703 | case OP_OpenPseudo: { |
| 96720 | VdbeCursor *pCx; | 97704 | VdbeCursor *pCx; |
| @@ -96857,10 +97841,10 @@ case OP_ColumnsUsed: { | |||
| 96857 | ** | 97841 | ** |
| 96858 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt | 97842 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 96859 | */ | 97843 | */ |
| 96860 | case OP_SeekLT: /* jump, in3, group, ncycle */ | 97844 | case OP_SeekLT: /* jump0, in3, group, ncycle */ |
| 96861 | case OP_SeekLE: /* jump, in3, group, ncycle */ | 97845 | case OP_SeekLE: /* jump0, in3, group, ncycle */ |
| 96862 | case OP_SeekGE: /* jump, in3, group, ncycle */ | 97846 | case OP_SeekGE: /* jump0, in3, group, ncycle */ |
| 96863 | case OP_SeekGT: { /* jump, in3, group, ncycle */ | 97847 | case OP_SeekGT: { /* jump0, in3, group, ncycle */ |
| 96864 | int res; /* Comparison result */ | 97848 | int res; /* Comparison result */ |
| 96865 | int oc; /* Opcode */ | 97849 | int oc; /* Opcode */ |
| 96866 | VdbeCursor *pC; /* The cursor to seek */ | 97850 | VdbeCursor *pC; /* The cursor to seek */ |
| @@ -97527,7 +98511,7 @@ case OP_Found: { /* jump, in3, ncycle */ | |||
| 97527 | ** | 98511 | ** |
| 97528 | ** See also: Found, NotFound, NoConflict, SeekRowid | 98512 | ** See also: Found, NotFound, NoConflict, SeekRowid |
| 97529 | */ | 98513 | */ |
| 97530 | case OP_SeekRowid: { /* jump, in3, ncycle */ | 98514 | case OP_SeekRowid: { /* jump0, in3, ncycle */ |
| 97531 | VdbeCursor *pC; | 98515 | VdbeCursor *pC; |
| 97532 | BtCursor *pCrsr; | 98516 | BtCursor *pCrsr; |
| 97533 | int res; | 98517 | int res; |
| @@ -98286,7 +99270,7 @@ case OP_NullRow: { | |||
| 98286 | ** configured to use Prev, not Next. | 99270 | ** configured to use Prev, not Next. |
| 98287 | */ | 99271 | */ |
| 98288 | case OP_SeekEnd: /* ncycle */ | 99272 | case OP_SeekEnd: /* ncycle */ |
| 98289 | case OP_Last: { /* jump, ncycle */ | 99273 | case OP_Last: { /* jump0, ncycle */ |
| 98290 | VdbeCursor *pC; | 99274 | VdbeCursor *pC; |
| 98291 | BtCursor *pCrsr; | 99275 | BtCursor *pCrsr; |
| 98292 | int res; | 99276 | int res; |
| @@ -98320,28 +99304,38 @@ case OP_Last: { /* jump, ncycle */ | |||
| 98320 | break; | 99304 | break; |
| 98321 | } | 99305 | } |
| 98322 | 99306 | ||
| 98323 | /* Opcode: IfSmaller P1 P2 P3 * * | 99307 | /* Opcode: IfSizeBetween P1 P2 P3 P4 * |
| 98324 | ** | 99308 | ** |
| 98325 | ** Estimate the number of rows in the table P1. Jump to P2 if that | 99309 | ** Let N be the approximate number of rows in the table or index |
| 98326 | ** estimate is less than approximately 2**(0.1*P3). | 99310 | ** with cursor P1 and let X be 10*log2(N) if N is positive or -1 |
| 99311 | ** if N is zero. | ||
| 99312 | ** | ||
| 99313 | ** Jump to P2 if X is in between P3 and P4, inclusive. | ||
| 98327 | */ | 99314 | */ |
| 98328 | case OP_IfSmaller: { /* jump */ | 99315 | case OP_IfSizeBetween: { /* jump */ |
| 98329 | VdbeCursor *pC; | 99316 | VdbeCursor *pC; |
| 98330 | BtCursor *pCrsr; | 99317 | BtCursor *pCrsr; |
| 98331 | int res; | 99318 | int res; |
| 98332 | i64 sz; | 99319 | i64 sz; |
| 98333 | 99320 | ||
| 98334 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 99321 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 99322 | assert( pOp->p4type==P4_INT32 ); | ||
| 99323 | assert( pOp->p3>=-1 && pOp->p3<=640*2 ); | ||
| 99324 | assert( pOp->p4.i>=-1 && pOp->p4.i<=640*2 ); | ||
| 98335 | pC = p->apCsr[pOp->p1]; | 99325 | pC = p->apCsr[pOp->p1]; |
| 98336 | assert( pC!=0 ); | 99326 | assert( pC!=0 ); |
| 98337 | pCrsr = pC->uc.pCursor; | 99327 | pCrsr = pC->uc.pCursor; |
| 98338 | assert( pCrsr ); | 99328 | assert( pCrsr ); |
| 98339 | rc = sqlite3BtreeFirst(pCrsr, &res); | 99329 | rc = sqlite3BtreeFirst(pCrsr, &res); |
| 98340 | if( rc ) goto abort_due_to_error; | 99330 | if( rc ) goto abort_due_to_error; |
| 98341 | if( res==0 ){ | 99331 | if( res!=0 ){ |
| 99332 | sz = -1; /* -Infinity encoding */ | ||
| 99333 | }else{ | ||
| 98342 | sz = sqlite3BtreeRowCountEst(pCrsr); | 99334 | sz = sqlite3BtreeRowCountEst(pCrsr); |
| 98343 | if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1; | 99335 | assert( sz>0 ); |
| 99336 | sz = sqlite3LogEst((u64)sz); | ||
| 98344 | } | 99337 | } |
| 99338 | res = sz>=pOp->p3 && sz<=pOp->p4.i; | ||
| 98345 | VdbeBranchTaken(res!=0,2); | 99339 | VdbeBranchTaken(res!=0,2); |
| 98346 | if( res ) goto jump_to_p2; | 99340 | if( res ) goto jump_to_p2; |
| 98347 | break; | 99341 | break; |
| @@ -98394,7 +99388,7 @@ case OP_Sort: { /* jump ncycle */ | |||
| 98394 | ** from the beginning toward the end. In other words, the cursor is | 99388 | ** from the beginning toward the end. In other words, the cursor is |
| 98395 | ** configured to use Next, not Prev. | 99389 | ** configured to use Next, not Prev. |
| 98396 | */ | 99390 | */ |
| 98397 | case OP_Rewind: { /* jump, ncycle */ | 99391 | case OP_Rewind: { /* jump0, ncycle */ |
| 98398 | VdbeCursor *pC; | 99392 | VdbeCursor *pC; |
| 98399 | BtCursor *pCrsr; | 99393 | BtCursor *pCrsr; |
| 98400 | int res; | 99394 | int res; |
| @@ -99041,11 +100035,18 @@ case OP_CreateBtree: { /* out2 */ | |||
| 99041 | break; | 100035 | break; |
| 99042 | } | 100036 | } |
| 99043 | 100037 | ||
| 99044 | /* Opcode: SqlExec * * * P4 * | 100038 | /* Opcode: SqlExec P1 P2 * P4 * |
| 99045 | ** | 100039 | ** |
| 99046 | ** Run the SQL statement or statements specified in the P4 string. | 100040 | ** Run the SQL statement or statements specified in the P4 string. |
| 99047 | ** Disable Auth and Trace callbacks while those statements are running if | 100041 | ** |
| 99048 | ** P1 is true. | 100042 | ** The P1 parameter is a bitmask of options: |
| 100043 | ** | ||
| 100044 | ** 0x0001 Disable Auth and Trace callbacks while the statements | ||
| 100045 | ** in P4 are running. | ||
| 100046 | ** | ||
| 100047 | ** 0x0002 Set db->nAnalysisLimit to P2 while the statements in | ||
| 100048 | ** P4 are running. | ||
| 100049 | ** | ||
| 99049 | */ | 100050 | */ |
| 99050 | case OP_SqlExec: { | 100051 | case OP_SqlExec: { |
| 99051 | char *zErr; | 100052 | char *zErr; |
| @@ -99053,6 +100054,7 @@ case OP_SqlExec: { | |||
| 99053 | sqlite3_xauth xAuth; | 100054 | sqlite3_xauth xAuth; |
| 99054 | #endif | 100055 | #endif |
| 99055 | u8 mTrace; | 100056 | u8 mTrace; |
| 100057 | int savedAnalysisLimit; | ||
| 99056 | 100058 | ||
| 99057 | sqlite3VdbeIncrWriteCounter(p, 0); | 100059 | sqlite3VdbeIncrWriteCounter(p, 0); |
| 99058 | db->nSqlExec++; | 100060 | db->nSqlExec++; |
| @@ -99061,18 +100063,23 @@ case OP_SqlExec: { | |||
| 99061 | xAuth = db->xAuth; | 100063 | xAuth = db->xAuth; |
| 99062 | #endif | 100064 | #endif |
| 99063 | mTrace = db->mTrace; | 100065 | mTrace = db->mTrace; |
| 99064 | if( pOp->p1 ){ | 100066 | savedAnalysisLimit = db->nAnalysisLimit; |
| 100067 | if( pOp->p1 & 0x0001 ){ | ||
| 99065 | #ifndef SQLITE_OMIT_AUTHORIZATION | 100068 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 99066 | db->xAuth = 0; | 100069 | db->xAuth = 0; |
| 99067 | #endif | 100070 | #endif |
| 99068 | db->mTrace = 0; | 100071 | db->mTrace = 0; |
| 99069 | } | 100072 | } |
| 100073 | if( pOp->p1 & 0x0002 ){ | ||
| 100074 | db->nAnalysisLimit = pOp->p2; | ||
| 100075 | } | ||
| 99070 | rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); | 100076 | rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); |
| 99071 | db->nSqlExec--; | 100077 | db->nSqlExec--; |
| 99072 | #ifndef SQLITE_OMIT_AUTHORIZATION | 100078 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 99073 | db->xAuth = xAuth; | 100079 | db->xAuth = xAuth; |
| 99074 | #endif | 100080 | #endif |
| 99075 | db->mTrace = mTrace; | 100081 | db->mTrace = mTrace; |
| 100082 | db->nAnalysisLimit = savedAnalysisLimit; | ||
| 99076 | if( zErr || rc ){ | 100083 | if( zErr || rc ){ |
| 99077 | sqlite3VdbeError(p, "%s", zErr); | 100084 | sqlite3VdbeError(p, "%s", zErr); |
| 99078 | sqlite3_free(zErr); | 100085 | sqlite3_free(zErr); |
| @@ -99224,11 +100231,11 @@ case OP_DropTrigger: { | |||
| 99224 | /* Opcode: IntegrityCk P1 P2 P3 P4 P5 | 100231 | /* Opcode: IntegrityCk P1 P2 P3 P4 P5 |
| 99225 | ** | 100232 | ** |
| 99226 | ** Do an analysis of the currently open database. Store in | 100233 | ** Do an analysis of the currently open database. Store in |
| 99227 | ** register P1 the text of an error message describing any problems. | 100234 | ** register (P1+1) the text of an error message describing any problems. |
| 99228 | ** If no problems are found, store a NULL in register P1. | 100235 | ** If no problems are found, store a NULL in register (P1+1). |
| 99229 | ** | 100236 | ** |
| 99230 | ** The register P3 contains one less than the maximum number of allowed errors. | 100237 | ** The register (P1) contains one less than the maximum number of allowed |
| 99231 | ** At most reg(P3) errors will be reported. | 100238 | ** errors. At most reg(P1) errors will be reported. |
| 99232 | ** In other words, the analysis stops as soon as reg(P1) errors are | 100239 | ** In other words, the analysis stops as soon as reg(P1) errors are |
| 99233 | ** seen. Reg(P1) is updated with the number of errors remaining. | 100240 | ** seen. Reg(P1) is updated with the number of errors remaining. |
| 99234 | ** | 100241 | ** |
| @@ -99248,19 +100255,21 @@ case OP_IntegrityCk: { | |||
| 99248 | Mem *pnErr; /* Register keeping track of errors remaining */ | 100255 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 99249 | 100256 | ||
| 99250 | assert( p->bIsReader ); | 100257 | assert( p->bIsReader ); |
| 100258 | assert( pOp->p4type==P4_INTARRAY ); | ||
| 99251 | nRoot = pOp->p2; | 100259 | nRoot = pOp->p2; |
| 99252 | aRoot = pOp->p4.ai; | 100260 | aRoot = pOp->p4.ai; |
| 99253 | assert( nRoot>0 ); | 100261 | assert( nRoot>0 ); |
| 100262 | assert( aRoot!=0 ); | ||
| 99254 | assert( aRoot[0]==(Pgno)nRoot ); | 100263 | assert( aRoot[0]==(Pgno)nRoot ); |
| 99255 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | 100264 | assert( pOp->p1>0 && (pOp->p1+1)<=(p->nMem+1 - p->nCursor) ); |
| 99256 | pnErr = &aMem[pOp->p3]; | 100265 | pnErr = &aMem[pOp->p1]; |
| 99257 | assert( (pnErr->flags & MEM_Int)!=0 ); | 100266 | assert( (pnErr->flags & MEM_Int)!=0 ); |
| 99258 | assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); | 100267 | assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 99259 | pIn1 = &aMem[pOp->p1]; | 100268 | pIn1 = &aMem[pOp->p1+1]; |
| 99260 | assert( pOp->p5<db->nDb ); | 100269 | assert( pOp->p5<db->nDb ); |
| 99261 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); | 100270 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); |
| 99262 | rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, | 100271 | rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], |
| 99263 | (int)pnErr->u.i+1, &nErr, &z); | 100272 | &aMem[pOp->p3], nRoot, (int)pnErr->u.i+1, &nErr, &z); |
| 99264 | sqlite3VdbeMemSetNull(pIn1); | 100273 | sqlite3VdbeMemSetNull(pIn1); |
| 99265 | if( nErr==0 ){ | 100274 | if( nErr==0 ){ |
| 99266 | assert( z==0 ); | 100275 | assert( z==0 ); |
| @@ -99387,7 +100396,9 @@ case OP_RowSetTest: { /* jump, in1, in3 */ | |||
| 99387 | ** P1 contains the address of the memory cell that contains the first memory | 100396 | ** P1 contains the address of the memory cell that contains the first memory |
| 99388 | ** cell in an array of values used as arguments to the sub-program. P2 | 100397 | ** cell in an array of values used as arguments to the sub-program. P2 |
| 99389 | ** contains the address to jump to if the sub-program throws an IGNORE | 100398 | ** contains the address to jump to if the sub-program throws an IGNORE |
| 99390 | ** exception using the RAISE() function. Register P3 contains the address | 100399 | ** exception using the RAISE() function. P2 might be zero, if there is |
| 100400 | ** no possibility that an IGNORE exception will be raised. | ||
| 100401 | ** Register P3 contains the address | ||
| 99391 | ** of a memory cell in this (the parent) VM that is used to allocate the | 100402 | ** of a memory cell in this (the parent) VM that is used to allocate the |
| 99392 | ** memory required by the sub-vdbe at runtime. | 100403 | ** memory required by the sub-vdbe at runtime. |
| 99393 | ** | 100404 | ** |
| @@ -99395,7 +100406,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ | |||
| 99395 | ** | 100406 | ** |
| 99396 | ** If P5 is non-zero, then recursive program invocation is enabled. | 100407 | ** If P5 is non-zero, then recursive program invocation is enabled. |
| 99397 | */ | 100408 | */ |
| 99398 | case OP_Program: { /* jump */ | 100409 | case OP_Program: { /* jump0 */ |
| 99399 | int nMem; /* Number of memory registers for sub-program */ | 100410 | int nMem; /* Number of memory registers for sub-program */ |
| 99400 | int nByte; /* Bytes of runtime space required for sub-program */ | 100411 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 99401 | Mem *pRt; /* Register to allocate runtime space */ | 100412 | Mem *pRt; /* Register to allocate runtime space */ |
| @@ -100317,24 +101328,23 @@ case OP_VCheck: { /* out2 */ | |||
| 100317 | 101328 | ||
| 100318 | pOut = &aMem[pOp->p2]; | 101329 | pOut = &aMem[pOp->p2]; |
| 100319 | sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ | 101330 | sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ |
| 100320 | assert( pOp->p4type==P4_TABLE ); | 101331 | assert( pOp->p4type==P4_TABLEREF ); |
| 100321 | pTab = pOp->p4.pTab; | 101332 | pTab = pOp->p4.pTab; |
| 100322 | assert( pTab!=0 ); | 101333 | assert( pTab!=0 ); |
| 101334 | assert( pTab->nTabRef>0 ); | ||
| 100323 | assert( IsVirtual(pTab) ); | 101335 | assert( IsVirtual(pTab) ); |
| 100324 | assert( pTab->u.vtab.p!=0 ); | 101336 | if( pTab->u.vtab.p==0 ) break; |
| 100325 | pVtab = pTab->u.vtab.p->pVtab; | 101337 | pVtab = pTab->u.vtab.p->pVtab; |
| 100326 | assert( pVtab!=0 ); | 101338 | assert( pVtab!=0 ); |
| 100327 | pModule = pVtab->pModule; | 101339 | pModule = pVtab->pModule; |
| 100328 | assert( pModule!=0 ); | 101340 | assert( pModule!=0 ); |
| 100329 | assert( pModule->iVersion>=4 ); | 101341 | assert( pModule->iVersion>=4 ); |
| 100330 | assert( pModule->xIntegrity!=0 ); | 101342 | assert( pModule->xIntegrity!=0 ); |
| 100331 | pTab->nTabRef++; | ||
| 100332 | sqlite3VtabLock(pTab->u.vtab.p); | 101343 | sqlite3VtabLock(pTab->u.vtab.p); |
| 100333 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); | 101344 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 100334 | rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, | 101345 | rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, |
| 100335 | pOp->p3, &zErr); | 101346 | pOp->p3, &zErr); |
| 100336 | sqlite3VtabUnlock(pTab->u.vtab.p); | 101347 | sqlite3VtabUnlock(pTab->u.vtab.p); |
| 100337 | sqlite3DeleteTable(db, pTab); | ||
| 100338 | if( rc ){ | 101348 | if( rc ){ |
| 100339 | sqlite3_free(zErr); | 101349 | sqlite3_free(zErr); |
| 100340 | goto abort_due_to_error; | 101350 | goto abort_due_to_error; |
| @@ -100459,6 +101469,7 @@ case OP_VColumn: { /* ncycle */ | |||
| 100459 | const sqlite3_module *pModule; | 101469 | const sqlite3_module *pModule; |
| 100460 | Mem *pDest; | 101470 | Mem *pDest; |
| 100461 | sqlite3_context sContext; | 101471 | sqlite3_context sContext; |
| 101472 | FuncDef nullFunc; | ||
| 100462 | 101473 | ||
| 100463 | VdbeCursor *pCur = p->apCsr[pOp->p1]; | 101474 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 100464 | assert( pCur!=0 ); | 101475 | assert( pCur!=0 ); |
| @@ -100476,6 +101487,9 @@ case OP_VColumn: { /* ncycle */ | |||
| 100476 | memset(&sContext, 0, sizeof(sContext)); | 101487 | memset(&sContext, 0, sizeof(sContext)); |
| 100477 | sContext.pOut = pDest; | 101488 | sContext.pOut = pDest; |
| 100478 | sContext.enc = encoding; | 101489 | sContext.enc = encoding; |
| 101490 | nullFunc.pUserData = 0; | ||
| 101491 | nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; | ||
| 101492 | sContext.pFunc = &nullFunc; | ||
| 100479 | assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); | 101493 | assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); |
| 100480 | if( pOp->p5 & OPFLAG_NOCHNG ){ | 101494 | if( pOp->p5 & OPFLAG_NOCHNG ){ |
| 100481 | sqlite3VdbeMemSetNull(pDest); | 101495 | sqlite3VdbeMemSetNull(pDest); |
| @@ -100808,6 +101822,42 @@ case OP_ClrSubtype: { /* in1 */ | |||
| 100808 | break; | 101822 | break; |
| 100809 | } | 101823 | } |
| 100810 | 101824 | ||
| 101825 | /* Opcode: GetSubtype P1 P2 * * * | ||
| 101826 | ** Synopsis: r[P2] = r[P1].subtype | ||
| 101827 | ** | ||
| 101828 | ** Extract the subtype value from register P1 and write that subtype | ||
| 101829 | ** into register P2. If P1 has no subtype, then P1 gets a NULL. | ||
| 101830 | */ | ||
| 101831 | case OP_GetSubtype: { /* in1 out2 */ | ||
| 101832 | pIn1 = &aMem[pOp->p1]; | ||
| 101833 | pOut = &aMem[pOp->p2]; | ||
| 101834 | if( pIn1->flags & MEM_Subtype ){ | ||
| 101835 | sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); | ||
| 101836 | }else{ | ||
| 101837 | sqlite3VdbeMemSetNull(pOut); | ||
| 101838 | } | ||
| 101839 | break; | ||
| 101840 | } | ||
| 101841 | |||
| 101842 | /* Opcode: SetSubtype P1 P2 * * * | ||
| 101843 | ** Synopsis: r[P2].subtype = r[P1] | ||
| 101844 | ** | ||
| 101845 | ** Set the subtype value of register P2 to the integer from register P1. | ||
| 101846 | ** If P1 is NULL, clear the subtype from p2. | ||
| 101847 | */ | ||
| 101848 | case OP_SetSubtype: { /* in1 out2 */ | ||
| 101849 | pIn1 = &aMem[pOp->p1]; | ||
| 101850 | pOut = &aMem[pOp->p2]; | ||
| 101851 | if( pIn1->flags & MEM_Null ){ | ||
| 101852 | pOut->flags &= ~MEM_Subtype; | ||
| 101853 | }else{ | ||
| 101854 | assert( pIn1->flags & MEM_Int ); | ||
| 101855 | pOut->flags |= MEM_Subtype; | ||
| 101856 | pOut->eSubtype = (u8)(pIn1->u.i & 0xff); | ||
| 101857 | } | ||
| 101858 | break; | ||
| 101859 | } | ||
| 101860 | |||
| 100811 | /* Opcode: FilterAdd P1 * P3 P4 * | 101861 | /* Opcode: FilterAdd P1 * P3 P4 * |
| 100812 | ** Synopsis: filter(P1) += key(P3@P4) | 101862 | ** Synopsis: filter(P1) += key(P3@P4) |
| 100813 | ** | 101863 | ** |
| @@ -100905,7 +101955,7 @@ case OP_Filter: { /* jump */ | |||
| 100905 | ** error is encountered. | 101955 | ** error is encountered. |
| 100906 | */ | 101956 | */ |
| 100907 | case OP_Trace: | 101957 | case OP_Trace: |
| 100908 | case OP_Init: { /* jump */ | 101958 | case OP_Init: { /* jump0 */ |
| 100909 | int i; | 101959 | int i; |
| 100910 | #ifndef SQLITE_OMIT_TRACE | 101960 | #ifndef SQLITE_OMIT_TRACE |
| 100911 | char *zTrace; | 101961 | char *zTrace; |
| @@ -104806,10 +105856,10 @@ static int bytecodevtabColumn( | |||
| 104806 | 105856 | ||
| 104807 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | 105857 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 104808 | case 9: /* nexec */ | 105858 | case 9: /* nexec */ |
| 104809 | sqlite3_result_int(ctx, pOp->nExec); | 105859 | sqlite3_result_int64(ctx, pOp->nExec); |
| 104810 | break; | 105860 | break; |
| 104811 | case 10: /* ncycle */ | 105861 | case 10: /* ncycle */ |
| 104812 | sqlite3_result_int(ctx, pOp->nCycle); | 105862 | sqlite3_result_int64(ctx, pOp->nCycle); |
| 104813 | break; | 105863 | break; |
| 104814 | #else | 105864 | #else |
| 104815 | case 9: /* nexec */ | 105865 | case 9: /* nexec */ |
| @@ -105753,6 +106803,8 @@ static void resolveAlias( | |||
| 105753 | assert( iCol>=0 && iCol<pEList->nExpr ); | 106803 | assert( iCol>=0 && iCol<pEList->nExpr ); |
| 105754 | pOrig = pEList->a[iCol].pExpr; | 106804 | pOrig = pEList->a[iCol].pExpr; |
| 105755 | assert( pOrig!=0 ); | 106805 | assert( pOrig!=0 ); |
| 106806 | assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); | ||
| 106807 | if( pExpr->pAggInfo ) return; | ||
| 105756 | db = pParse->db; | 106808 | db = pParse->db; |
| 105757 | pDup = sqlite3ExprDup(db, pOrig, 0); | 106809 | pDup = sqlite3ExprDup(db, pOrig, 0); |
| 105758 | if( db->mallocFailed ){ | 106810 | if( db->mallocFailed ){ |
| @@ -105856,6 +106908,7 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ | |||
| 105856 | assert( ExprUseYTab(pExpr) ); | 106908 | assert( ExprUseYTab(pExpr) ); |
| 105857 | pExTab = pExpr->y.pTab; | 106909 | pExTab = pExpr->y.pTab; |
| 105858 | assert( pExTab!=0 ); | 106910 | assert( pExTab!=0 ); |
| 106911 | assert( n < pExTab->nCol ); | ||
| 105859 | if( (pExTab->tabFlags & TF_HasGenerated)!=0 | 106912 | if( (pExTab->tabFlags & TF_HasGenerated)!=0 |
| 105860 | && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 | 106913 | && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 |
| 105861 | ){ | 106914 | ){ |
| @@ -105899,7 +106952,7 @@ static void extendFJMatch( | |||
| 105899 | static SQLITE_NOINLINE int isValidSchemaTableName( | 106952 | static SQLITE_NOINLINE int isValidSchemaTableName( |
| 105900 | const char *zTab, /* Name as it appears in the SQL */ | 106953 | const char *zTab, /* Name as it appears in the SQL */ |
| 105901 | Table *pTab, /* The schema table we are trying to match */ | 106954 | Table *pTab, /* The schema table we are trying to match */ |
| 105902 | Schema *pSchema /* non-NULL if a database qualifier is present */ | 106955 | const char *zDb /* non-NULL if a database qualifier is present */ |
| 105903 | ){ | 106956 | ){ |
| 105904 | const char *zLegacy; | 106957 | const char *zLegacy; |
| 105905 | assert( pTab!=0 ); | 106958 | assert( pTab!=0 ); |
| @@ -105910,7 +106963,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName( | |||
| 105910 | if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ | 106963 | if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ |
| 105911 | return 1; | 106964 | return 1; |
| 105912 | } | 106965 | } |
| 105913 | if( pSchema==0 ) return 0; | 106966 | if( zDb==0 ) return 0; |
| 105914 | if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; | 106967 | if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; |
| 105915 | if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; | 106968 | if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; |
| 105916 | }else{ | 106969 | }else{ |
| @@ -105950,7 +107003,7 @@ static int lookupName( | |||
| 105950 | Parse *pParse, /* The parsing context */ | 107003 | Parse *pParse, /* The parsing context */ |
| 105951 | const char *zDb, /* Name of the database containing table, or NULL */ | 107004 | const char *zDb, /* Name of the database containing table, or NULL */ |
| 105952 | const char *zTab, /* Name of table containing column, or NULL */ | 107005 | const char *zTab, /* Name of table containing column, or NULL */ |
| 105953 | const char *zCol, /* Name of the column. */ | 107006 | const Expr *pRight, /* Name of the column. */ |
| 105954 | NameContext *pNC, /* The name context used to resolve the name */ | 107007 | NameContext *pNC, /* The name context used to resolve the name */ |
| 105955 | Expr *pExpr /* Make this EXPR node point to the selected column */ | 107008 | Expr *pExpr /* Make this EXPR node point to the selected column */ |
| 105956 | ){ | 107009 | ){ |
| @@ -105967,6 +107020,7 @@ static int lookupName( | |||
| 105967 | Table *pTab = 0; /* Table holding the row */ | 107020 | Table *pTab = 0; /* Table holding the row */ |
| 105968 | Column *pCol; /* A column of pTab */ | 107021 | Column *pCol; /* A column of pTab */ |
| 105969 | ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ | 107022 | ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ |
| 107023 | const char *zCol = pRight->u.zToken; | ||
| 105970 | 107024 | ||
| 105971 | assert( pNC ); /* the name context cannot be NULL. */ | 107025 | assert( pNC ); /* the name context cannot be NULL. */ |
| 105972 | assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ | 107026 | assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ |
| @@ -106092,7 +107146,7 @@ static int lookupName( | |||
| 106092 | } | 107146 | } |
| 106093 | }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ | 107147 | }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ |
| 106094 | if( pTab->tnum!=1 ) continue; | 107148 | if( pTab->tnum!=1 ) continue; |
| 106095 | if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; | 107149 | if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue; |
| 106096 | } | 107150 | } |
| 106097 | assert( ExprUseYTab(pExpr) ); | 107151 | assert( ExprUseYTab(pExpr) ); |
| 106098 | if( IN_RENAME_OBJECT && pItem->zAlias ){ | 107152 | if( IN_RENAME_OBJECT && pItem->zAlias ){ |
| @@ -106139,8 +107193,37 @@ static int lookupName( | |||
| 106139 | } | 107193 | } |
| 106140 | } | 107194 | } |
| 106141 | if( 0==cnt && VisibleRowid(pTab) ){ | 107195 | if( 0==cnt && VisibleRowid(pTab) ){ |
| 107196 | /* pTab is a potential ROWID match. Keep track of it and match | ||
| 107197 | ** the ROWID later if that seems appropriate. (Search for "cntTab" | ||
| 107198 | ** to find related code.) Only allow a ROWID match if there is | ||
| 107199 | ** a single ROWID match candidate. | ||
| 107200 | */ | ||
| 107201 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 107202 | /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match | ||
| 107203 | ** if there is a single VIEW candidate or if there is a single | ||
| 107204 | ** non-VIEW candidate plus multiple VIEW candidates. In other | ||
| 107205 | ** words non-VIEW candidate terms take precedence over VIEWs. | ||
| 107206 | */ | ||
| 107207 | if( cntTab==0 | ||
| 107208 | || (cntTab==1 | ||
| 107209 | && ALWAYS(pMatch!=0) | ||
| 107210 | && ALWAYS(pMatch->pTab!=0) | ||
| 107211 | && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 | ||
| 107212 | && (pTab->tabFlags & TF_Ephemeral)==0) | ||
| 107213 | ){ | ||
| 107214 | cntTab = 1; | ||
| 107215 | pMatch = pItem; | ||
| 107216 | }else{ | ||
| 107217 | cntTab++; | ||
| 107218 | } | ||
| 107219 | #else | ||
| 107220 | /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is | ||
| 107221 | ** simpler since we require exactly one candidate, which will | ||
| 107222 | ** always be a non-VIEW | ||
| 107223 | */ | ||
| 106142 | cntTab++; | 107224 | cntTab++; |
| 106143 | pMatch = pItem; | 107225 | pMatch = pItem; |
| 107226 | #endif | ||
| 106144 | } | 107227 | } |
| 106145 | } | 107228 | } |
| 106146 | if( pMatch ){ | 107229 | if( pMatch ){ |
| @@ -106169,7 +107252,8 @@ static int lookupName( | |||
| 106169 | if( pParse->bReturning ){ | 107252 | if( pParse->bReturning ){ |
| 106170 | if( (pNC->ncFlags & NC_UBaseReg)!=0 | 107253 | if( (pNC->ncFlags & NC_UBaseReg)!=0 |
| 106171 | && ALWAYS(zTab==0 | 107254 | && ALWAYS(zTab==0 |
| 106172 | || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) | 107255 | || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0 |
| 107256 | || isValidSchemaTableName(zTab, pParse->pTriggerTab, 0)) | ||
| 106173 | ){ | 107257 | ){ |
| 106174 | pExpr->iTable = op!=TK_DELETE; | 107258 | pExpr->iTable = op!=TK_DELETE; |
| 106175 | pTab = pParse->pTriggerTab; | 107259 | pTab = pParse->pTriggerTab; |
| @@ -106266,13 +107350,18 @@ static int lookupName( | |||
| 106266 | ** Perhaps the name is a reference to the ROWID | 107350 | ** Perhaps the name is a reference to the ROWID |
| 106267 | */ | 107351 | */ |
| 106268 | if( cnt==0 | 107352 | if( cnt==0 |
| 106269 | && cntTab==1 | 107353 | && cntTab>=1 |
| 106270 | && pMatch | 107354 | && pMatch |
| 106271 | && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 | 107355 | && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 |
| 106272 | && sqlite3IsRowid(zCol) | 107356 | && sqlite3IsRowid(zCol) |
| 106273 | && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) | 107357 | && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) |
| 106274 | ){ | 107358 | ){ |
| 106275 | cnt = 1; | 107359 | cnt = cntTab; |
| 107360 | #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 | ||
| 107361 | if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){ | ||
| 107362 | eNewExprOp = TK_NULL; | ||
| 107363 | } | ||
| 107364 | #endif | ||
| 106276 | if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; | 107365 | if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; |
| 106277 | pExpr->affExpr = SQLITE_AFF_INTEGER; | 107366 | pExpr->affExpr = SQLITE_AFF_INTEGER; |
| 106278 | } | 107367 | } |
| @@ -106426,12 +107515,17 @@ static int lookupName( | |||
| 106426 | sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); | 107515 | sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); |
| 106427 | }else if( zTab ){ | 107516 | }else if( zTab ){ |
| 106428 | sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); | 107517 | sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); |
| 107518 | }else if( cnt==0 && ExprHasProperty(pRight,EP_DblQuoted) ){ | ||
| 107519 | sqlite3ErrorMsg(pParse, "%s: \"%s\" - should this be a" | ||
| 107520 | " string literal in single-quotes?", | ||
| 107521 | zErr, zCol); | ||
| 106429 | }else{ | 107522 | }else{ |
| 106430 | sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); | 107523 | sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); |
| 106431 | } | 107524 | } |
| 106432 | sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); | 107525 | sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); |
| 106433 | pParse->checkSchema = 1; | 107526 | pParse->checkSchema = 1; |
| 106434 | pTopNC->nNcErr++; | 107527 | pTopNC->nNcErr++; |
| 107528 | eNewExprOp = TK_NULL; | ||
| 106435 | } | 107529 | } |
| 106436 | assert( pFJMatch==0 ); | 107530 | assert( pFJMatch==0 ); |
| 106437 | 107531 | ||
| @@ -106458,8 +107552,12 @@ static int lookupName( | |||
| 106458 | ** If a generated column is referenced, set bits for every column | 107552 | ** If a generated column is referenced, set bits for every column |
| 106459 | ** of the table. | 107553 | ** of the table. |
| 106460 | */ | 107554 | */ |
| 106461 | if( pExpr->iColumn>=0 && pMatch!=0 ){ | 107555 | if( pMatch ){ |
| 106462 | pMatch->colUsed |= sqlite3ExprColUsed(pExpr); | 107556 | if( pExpr->iColumn>=0 ){ |
| 107557 | pMatch->colUsed |= sqlite3ExprColUsed(pExpr); | ||
| 107558 | }else{ | ||
| 107559 | pMatch->fg.rowidUsed = 1; | ||
| 107560 | } | ||
| 106463 | } | 107561 | } |
| 106464 | 107562 | ||
| 106465 | pExpr->op = eNewExprOp; | 107563 | pExpr->op = eNewExprOp; |
| @@ -106636,6 +107734,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106636 | ** resolved. This prevents "column" from being counted as having been | 107734 | ** resolved. This prevents "column" from being counted as having been |
| 106637 | ** referenced, which might prevent a SELECT from being erroneously | 107735 | ** referenced, which might prevent a SELECT from being erroneously |
| 106638 | ** marked as correlated. | 107736 | ** marked as correlated. |
| 107737 | ** | ||
| 107738 | ** 2024-03-28: Beware of aggregates. A bare column of aggregated table | ||
| 107739 | ** can still evaluate to NULL even though it is marked as NOT NULL. | ||
| 107740 | ** Example: | ||
| 107741 | ** | ||
| 107742 | ** CREATE TABLE t1(a INT NOT NULL); | ||
| 107743 | ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1; | ||
| 107744 | ** | ||
| 107745 | ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized | ||
| 107746 | ** here because at the time this case is hit, we do not yet know whether | ||
| 107747 | ** or not t1 is being aggregated. We have to assume the worst and omit | ||
| 107748 | ** the optimization. The only time it is safe to apply this optimization | ||
| 107749 | ** is within the WHERE clause. | ||
| 106639 | */ | 107750 | */ |
| 106640 | case TK_NOTNULL: | 107751 | case TK_NOTNULL: |
| 106641 | case TK_ISNULL: { | 107752 | case TK_ISNULL: { |
| @@ -106646,19 +107757,36 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106646 | anRef[i] = p->nRef; | 107757 | anRef[i] = p->nRef; |
| 106647 | } | 107758 | } |
| 106648 | sqlite3WalkExpr(pWalker, pExpr->pLeft); | 107759 | sqlite3WalkExpr(pWalker, pExpr->pLeft); |
| 106649 | if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ | 107760 | if( IN_RENAME_OBJECT ) return WRC_Prune; |
| 106650 | testcase( ExprHasProperty(pExpr, EP_OuterON) ); | 107761 | if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ |
| 106651 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 107762 | /* The expression can be NULL. So the optimization does not apply */ |
| 106652 | pExpr->u.iValue = (pExpr->op==TK_NOTNULL); | 107763 | return WRC_Prune; |
| 106653 | pExpr->flags |= EP_IntValue; | 107764 | } |
| 106654 | pExpr->op = TK_INTEGER; | ||
| 106655 | 107765 | ||
| 106656 | for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ | 107766 | for(i=0, p=pNC; p; p=p->pNext, i++){ |
| 106657 | p->nRef = anRef[i]; | 107767 | if( (p->ncFlags & NC_Where)==0 ){ |
| 107768 | return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */ | ||
| 106658 | } | 107769 | } |
| 106659 | sqlite3ExprDelete(pParse->db, pExpr->pLeft); | ||
| 106660 | pExpr->pLeft = 0; | ||
| 106661 | } | 107770 | } |
| 107771 | testcase( ExprHasProperty(pExpr, EP_OuterON) ); | ||
| 107772 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | ||
| 107773 | #if TREETRACE_ENABLED | ||
| 107774 | if( sqlite3TreeTrace & 0x80000 ){ | ||
| 107775 | sqlite3DebugPrintf( | ||
| 107776 | "NOT NULL strength reduction converts the following to %d:\n", | ||
| 107777 | pExpr->op==TK_NOTNULL | ||
| 107778 | ); | ||
| 107779 | sqlite3ShowExpr(pExpr); | ||
| 107780 | } | ||
| 107781 | #endif /* TREETRACE_ENABLED */ | ||
| 107782 | pExpr->u.iValue = (pExpr->op==TK_NOTNULL); | ||
| 107783 | pExpr->flags |= EP_IntValue; | ||
| 107784 | pExpr->op = TK_INTEGER; | ||
| 107785 | for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ | ||
| 107786 | p->nRef = anRef[i]; | ||
| 107787 | } | ||
| 107788 | sqlite3ExprDelete(pParse->db, pExpr->pLeft); | ||
| 107789 | pExpr->pLeft = 0; | ||
| 106662 | return WRC_Prune; | 107790 | return WRC_Prune; |
| 106663 | } | 107791 | } |
| 106664 | 107792 | ||
| @@ -106672,7 +107800,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106672 | */ | 107800 | */ |
| 106673 | case TK_ID: | 107801 | case TK_ID: |
| 106674 | case TK_DOT: { | 107802 | case TK_DOT: { |
| 106675 | const char *zColumn; | ||
| 106676 | const char *zTable; | 107803 | const char *zTable; |
| 106677 | const char *zDb; | 107804 | const char *zDb; |
| 106678 | Expr *pRight; | 107805 | Expr *pRight; |
| @@ -106681,7 +107808,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106681 | zDb = 0; | 107808 | zDb = 0; |
| 106682 | zTable = 0; | 107809 | zTable = 0; |
| 106683 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 107810 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 106684 | zColumn = pExpr->u.zToken; | 107811 | pRight = pExpr; |
| 106685 | }else{ | 107812 | }else{ |
| 106686 | Expr *pLeft = pExpr->pLeft; | 107813 | Expr *pLeft = pExpr->pLeft; |
| 106687 | testcase( pNC->ncFlags & NC_IdxExpr ); | 107814 | testcase( pNC->ncFlags & NC_IdxExpr ); |
| @@ -106700,14 +107827,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106700 | } | 107827 | } |
| 106701 | assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); | 107828 | assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); |
| 106702 | zTable = pLeft->u.zToken; | 107829 | zTable = pLeft->u.zToken; |
| 106703 | zColumn = pRight->u.zToken; | ||
| 106704 | assert( ExprUseYTab(pExpr) ); | 107830 | assert( ExprUseYTab(pExpr) ); |
| 106705 | if( IN_RENAME_OBJECT ){ | 107831 | if( IN_RENAME_OBJECT ){ |
| 106706 | sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); | 107832 | sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); |
| 106707 | sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); | 107833 | sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); |
| 106708 | } | 107834 | } |
| 106709 | } | 107835 | } |
| 106710 | return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); | 107836 | return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); |
| 106711 | } | 107837 | } |
| 106712 | 107838 | ||
| 106713 | /* Resolve function names | 107839 | /* Resolve function names |
| @@ -106883,11 +108009,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106883 | #endif | 108009 | #endif |
| 106884 | } | 108010 | } |
| 106885 | } | 108011 | } |
| 106886 | #ifndef SQLITE_OMIT_WINDOWFUNC | 108012 | else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){ |
| 106887 | else if( ExprHasProperty(pExpr, EP_WinFunc) ){ | ||
| 106888 | is_agg = 1; | 108013 | is_agg = 1; |
| 106889 | } | 108014 | } |
| 106890 | #endif | ||
| 106891 | sqlite3WalkExprList(pWalker, pList); | 108015 | sqlite3WalkExprList(pWalker, pList); |
| 106892 | if( is_agg ){ | 108016 | if( is_agg ){ |
| 106893 | if( pExpr->pLeft ){ | 108017 | if( pExpr->pLeft ){ |
| @@ -106923,11 +108047,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106923 | while( pNC2 | 108047 | while( pNC2 |
| 106924 | && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 | 108048 | && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 |
| 106925 | ){ | 108049 | ){ |
| 106926 | pExpr->op2++; | 108050 | pExpr->op2 += (1 + pNC2->nNestedSelect); |
| 106927 | pNC2 = pNC2->pNext; | 108051 | pNC2 = pNC2->pNext; |
| 106928 | } | 108052 | } |
| 106929 | assert( pDef!=0 || IN_RENAME_OBJECT ); | 108053 | assert( pDef!=0 || IN_RENAME_OBJECT ); |
| 106930 | if( pNC2 && pDef ){ | 108054 | if( pNC2 && pDef ){ |
| 108055 | pExpr->op2 += pNC2->nNestedSelect; | ||
| 106931 | assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); | 108056 | assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); |
| 106932 | assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); | 108057 | assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); |
| 106933 | testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); | 108058 | testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); |
| @@ -106956,6 +108081,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106956 | testcase( pNC->ncFlags & NC_PartIdx ); | 108081 | testcase( pNC->ncFlags & NC_PartIdx ); |
| 106957 | testcase( pNC->ncFlags & NC_IdxExpr ); | 108082 | testcase( pNC->ncFlags & NC_IdxExpr ); |
| 106958 | testcase( pNC->ncFlags & NC_GenCol ); | 108083 | testcase( pNC->ncFlags & NC_GenCol ); |
| 108084 | assert( pExpr->x.pSelect ); | ||
| 106959 | if( pNC->ncFlags & NC_SelfRef ){ | 108085 | if( pNC->ncFlags & NC_SelfRef ){ |
| 106960 | notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); | 108086 | notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); |
| 106961 | }else{ | 108087 | }else{ |
| @@ -106964,6 +108090,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 106964 | assert( pNC->nRef>=nRef ); | 108090 | assert( pNC->nRef>=nRef ); |
| 106965 | if( nRef!=pNC->nRef ){ | 108091 | if( nRef!=pNC->nRef ){ |
| 106966 | ExprSetProperty(pExpr, EP_VarSelect); | 108092 | ExprSetProperty(pExpr, EP_VarSelect); |
| 108093 | pExpr->x.pSelect->selFlags |= SF_Correlated; | ||
| 106967 | } | 108094 | } |
| 106968 | pNC->ncFlags |= NC_Subquery; | 108095 | pNC->ncFlags |= NC_Subquery; |
| 106969 | } | 108096 | } |
| @@ -107486,8 +108613,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 107486 | 108613 | ||
| 107487 | /* Recursively resolve names in all subqueries in the FROM clause | 108614 | /* Recursively resolve names in all subqueries in the FROM clause |
| 107488 | */ | 108615 | */ |
| 108616 | if( pOuterNC ) pOuterNC->nNestedSelect++; | ||
| 107489 | for(i=0; i<p->pSrc->nSrc; i++){ | 108617 | for(i=0; i<p->pSrc->nSrc; i++){ |
| 107490 | SrcItem *pItem = &p->pSrc->a[i]; | 108618 | SrcItem *pItem = &p->pSrc->a[i]; |
| 108619 | assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/ | ||
| 107491 | if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ | 108620 | if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ |
| 107492 | int nRef = pOuterNC ? pOuterNC->nRef : 0; | 108621 | int nRef = pOuterNC ? pOuterNC->nRef : 0; |
| 107493 | const char *zSavedContext = pParse->zAuthContext; | 108622 | const char *zSavedContext = pParse->zAuthContext; |
| @@ -107510,6 +108639,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 107510 | } | 108639 | } |
| 107511 | } | 108640 | } |
| 107512 | } | 108641 | } |
| 108642 | if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ | ||
| 108643 | pOuterNC->nNestedSelect--; | ||
| 108644 | } | ||
| 107513 | 108645 | ||
| 107514 | /* Set up the local name-context to pass to sqlite3ResolveExprNames() to | 108646 | /* Set up the local name-context to pass to sqlite3ResolveExprNames() to |
| 107515 | ** resolve the result-set expression list. | 108647 | ** resolve the result-set expression list. |
| @@ -107553,7 +108685,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ | |||
| 107553 | } | 108685 | } |
| 107554 | if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; | 108686 | if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; |
| 107555 | } | 108687 | } |
| 108688 | sNC.ncFlags |= NC_Where; | ||
| 107556 | if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; | 108689 | if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; |
| 108690 | sNC.ncFlags &= ~NC_Where; | ||
| 107557 | 108691 | ||
| 107558 | /* Resolve names in table-valued-function arguments */ | 108692 | /* Resolve names in table-valued-function arguments */ |
| 107559 | for(i=0; i<p->pSrc->nSrc; i++){ | 108693 | for(i=0; i<p->pSrc->nSrc; i++){ |
| @@ -107744,6 +108878,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( | |||
| 107744 | ** Resolve all names for all expression in an expression list. This is | 108878 | ** Resolve all names for all expression in an expression list. This is |
| 107745 | ** just like sqlite3ResolveExprNames() except that it works for an expression | 108879 | ** just like sqlite3ResolveExprNames() except that it works for an expression |
| 107746 | ** list rather than a single expression. | 108880 | ** list rather than a single expression. |
| 108881 | ** | ||
| 108882 | ** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a | ||
| 108883 | ** failure. | ||
| 107747 | */ | 108884 | */ |
| 107748 | SQLITE_PRIVATE int sqlite3ResolveExprListNames( | 108885 | SQLITE_PRIVATE int sqlite3ResolveExprListNames( |
| 107749 | NameContext *pNC, /* Namespace to resolve expressions in. */ | 108886 | NameContext *pNC, /* Namespace to resolve expressions in. */ |
| @@ -107752,7 +108889,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( | |||
| 107752 | int i; | 108889 | int i; |
| 107753 | int savedHasAgg = 0; | 108890 | int savedHasAgg = 0; |
| 107754 | Walker w; | 108891 | Walker w; |
| 107755 | if( pList==0 ) return WRC_Continue; | 108892 | if( pList==0 ) return SQLITE_OK; |
| 107756 | w.pParse = pNC->pParse; | 108893 | w.pParse = pNC->pParse; |
| 107757 | w.xExprCallback = resolveExprStep; | 108894 | w.xExprCallback = resolveExprStep; |
| 107758 | w.xSelectCallback = resolveSelectStep; | 108895 | w.xSelectCallback = resolveSelectStep; |
| @@ -107766,7 +108903,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( | |||
| 107766 | #if SQLITE_MAX_EXPR_DEPTH>0 | 108903 | #if SQLITE_MAX_EXPR_DEPTH>0 |
| 107767 | w.pParse->nHeight += pExpr->nHeight; | 108904 | w.pParse->nHeight += pExpr->nHeight; |
| 107768 | if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ | 108905 | if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ |
| 107769 | return WRC_Abort; | 108906 | return SQLITE_ERROR; |
| 107770 | } | 108907 | } |
| 107771 | #endif | 108908 | #endif |
| 107772 | sqlite3WalkExprNN(&w, pExpr); | 108909 | sqlite3WalkExprNN(&w, pExpr); |
| @@ -107783,10 +108920,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( | |||
| 107783 | (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); | 108920 | (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); |
| 107784 | pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); | 108921 | pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); |
| 107785 | } | 108922 | } |
| 107786 | if( w.pParse->nErr>0 ) return WRC_Abort; | 108923 | if( w.pParse->nErr>0 ) return SQLITE_ERROR; |
| 107787 | } | 108924 | } |
| 107788 | pNC->ncFlags |= savedHasAgg; | 108925 | pNC->ncFlags |= savedHasAgg; |
| 107789 | return WRC_Continue; | 108926 | return SQLITE_OK; |
| 107790 | } | 108927 | } |
| 107791 | 108928 | ||
| 107792 | /* | 108929 | /* |
| @@ -108092,9 +109229,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ | |||
| 108092 | assert( pExpr->x.pList->nExpr>0 ); | 109229 | assert( pExpr->x.pList->nExpr>0 ); |
| 108093 | assert( pExpr->op==TK_FUNCTION ); | 109230 | assert( pExpr->op==TK_FUNCTION ); |
| 108094 | pExpr = pExpr->x.pList->a[0].pExpr; | 109231 | pExpr = pExpr->x.pList->a[0].pExpr; |
| 108095 | }else{ | 109232 | }else if( pExpr->op==TK_COLLATE ){ |
| 108096 | assert( pExpr->op==TK_COLLATE ); | ||
| 108097 | pExpr = pExpr->pLeft; | 109233 | pExpr = pExpr->pLeft; |
| 109234 | }else{ | ||
| 109235 | break; | ||
| 108098 | } | 109236 | } |
| 108099 | } | 109237 | } |
| 108100 | return pExpr; | 109238 | return pExpr; |
| @@ -108788,11 +109926,12 @@ SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ | |||
| 108788 | ** appear to be quoted. If the quotes were of the form "..." (double-quotes) | 109926 | ** appear to be quoted. If the quotes were of the form "..." (double-quotes) |
| 108789 | ** then the EP_DblQuoted flag is set on the expression node. | 109927 | ** then the EP_DblQuoted flag is set on the expression node. |
| 108790 | ** | 109928 | ** |
| 108791 | ** Special case: If op==TK_INTEGER and pToken points to a string that | 109929 | ** Special case (tag-20240227-a): If op==TK_INTEGER and pToken points to |
| 108792 | ** can be translated into a 32-bit integer, then the token is not | 109930 | ** a string that can be translated into a 32-bit integer, then the token is |
| 108793 | ** stored in u.zToken. Instead, the integer values is written | 109931 | ** not stored in u.zToken. Instead, the integer values is written |
| 108794 | ** into u.iValue and the EP_IntValue flag is set. No extra storage | 109932 | ** into u.iValue and the EP_IntValue flag is set. No extra storage |
| 108795 | ** is allocated to hold the integer text and the dequote flag is ignored. | 109933 | ** is allocated to hold the integer text and the dequote flag is ignored. |
| 109934 | ** See also tag-20240227-b. | ||
| 108796 | */ | 109935 | */ |
| 108797 | SQLITE_PRIVATE Expr *sqlite3ExprAlloc( | 109936 | SQLITE_PRIVATE Expr *sqlite3ExprAlloc( |
| 108798 | sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ | 109937 | sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ |
| @@ -108808,7 +109947,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( | |||
| 108808 | if( pToken ){ | 109947 | if( pToken ){ |
| 108809 | if( op!=TK_INTEGER || pToken->z==0 | 109948 | if( op!=TK_INTEGER || pToken->z==0 |
| 108810 | || sqlite3GetInt32(pToken->z, &iValue)==0 ){ | 109949 | || sqlite3GetInt32(pToken->z, &iValue)==0 ){ |
| 108811 | nExtra = pToken->n+1; | 109950 | nExtra = pToken->n+1; /* tag-20240227-a */ |
| 108812 | assert( iValue>=0 ); | 109951 | assert( iValue>=0 ); |
| 108813 | } | 109952 | } |
| 108814 | } | 109953 | } |
| @@ -109097,9 +110236,7 @@ SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( | |||
| 109097 | assert( ExprUseXList(pExpr) ); | 110236 | assert( ExprUseXList(pExpr) ); |
| 109098 | if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ | 110237 | if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ |
| 109099 | /* Ignore ORDER BY on zero-argument aggregates */ | 110238 | /* Ignore ORDER BY on zero-argument aggregates */ |
| 109100 | sqlite3ParserAddCleanup(pParse, | 110239 | sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); |
| 109101 | (void(*)(sqlite3*,void*))sqlite3ExprListDelete, | ||
| 109102 | pOrderBy); | ||
| 109103 | return; | 110240 | return; |
| 109104 | } | 110241 | } |
| 109105 | if( IsWindowFunc(pExpr) ){ | 110242 | if( IsWindowFunc(pExpr) ){ |
| @@ -109242,6 +110379,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n | |||
| 109242 | static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | 110379 | static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ |
| 109243 | assert( p!=0 ); | 110380 | assert( p!=0 ); |
| 109244 | assert( db!=0 ); | 110381 | assert( db!=0 ); |
| 110382 | exprDeleteRestart: | ||
| 109245 | assert( !ExprUseUValue(p) || p->u.iValue>=0 ); | 110383 | assert( !ExprUseUValue(p) || p->u.iValue>=0 ); |
| 109246 | assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); | 110384 | assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); |
| 109247 | assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); | 110385 | assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); |
| @@ -109257,7 +110395,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | |||
| 109257 | if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ | 110395 | if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ |
| 109258 | /* The Expr.x union is never used at the same time as Expr.pRight */ | 110396 | /* The Expr.x union is never used at the same time as Expr.pRight */ |
| 109259 | assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); | 110397 | assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); |
| 109260 | if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); | ||
| 109261 | if( p->pRight ){ | 110398 | if( p->pRight ){ |
| 109262 | assert( !ExprHasProperty(p, EP_WinFunc) ); | 110399 | assert( !ExprHasProperty(p, EP_WinFunc) ); |
| 109263 | sqlite3ExprDeleteNN(db, p->pRight); | 110400 | sqlite3ExprDeleteNN(db, p->pRight); |
| @@ -109272,6 +110409,19 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | |||
| 109272 | } | 110409 | } |
| 109273 | #endif | 110410 | #endif |
| 109274 | } | 110411 | } |
| 110412 | if( p->pLeft && p->op!=TK_SELECT_COLUMN ){ | ||
| 110413 | Expr *pLeft = p->pLeft; | ||
| 110414 | if( !ExprHasProperty(p, EP_Static) | ||
| 110415 | && !ExprHasProperty(pLeft, EP_Static) | ||
| 110416 | ){ | ||
| 110417 | /* Avoid unnecessary recursion on unary operators */ | ||
| 110418 | sqlite3DbNNFreeNN(db, p); | ||
| 110419 | p = pLeft; | ||
| 110420 | goto exprDeleteRestart; | ||
| 110421 | }else{ | ||
| 110422 | sqlite3ExprDeleteNN(db, pLeft); | ||
| 110423 | } | ||
| 110424 | } | ||
| 109275 | } | 110425 | } |
| 109276 | if( !ExprHasProperty(p, EP_Static) ){ | 110426 | if( !ExprHasProperty(p, EP_Static) ){ |
| 109277 | sqlite3DbNNFreeNN(db, p); | 110427 | sqlite3DbNNFreeNN(db, p); |
| @@ -109280,6 +110430,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | |||
| 109280 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ | 110430 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| 109281 | if( p ) sqlite3ExprDeleteNN(db, p); | 110431 | if( p ) sqlite3ExprDeleteNN(db, p); |
| 109282 | } | 110432 | } |
| 110433 | SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ | ||
| 110434 | if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); | ||
| 110435 | } | ||
| 109283 | 110436 | ||
| 109284 | /* | 110437 | /* |
| 109285 | ** Clear both elements of an OnOrUsing object | 110438 | ** Clear both elements of an OnOrUsing object |
| @@ -109301,13 +110454,11 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ | |||
| 109301 | ** | 110454 | ** |
| 109302 | ** The pExpr might be deleted immediately on an OOM error. | 110455 | ** The pExpr might be deleted immediately on an OOM error. |
| 109303 | ** | 110456 | ** |
| 109304 | ** The deferred delete is (currently) implemented by adding the | 110457 | ** Return 0 if the delete was successfully deferred. Return non-zero |
| 109305 | ** pExpr to the pParse->pConstExpr list with a register number of 0. | 110458 | ** if the delete happened immediately because of an OOM. |
| 109306 | */ | 110459 | */ |
| 109307 | SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ | 110460 | SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ |
| 109308 | sqlite3ParserAddCleanup(pParse, | 110461 | return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); |
| 109309 | (void(*)(sqlite3*,void*))sqlite3ExprDelete, | ||
| 109310 | pExpr); | ||
| 109311 | } | 110462 | } |
| 109312 | 110463 | ||
| 109313 | /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the | 110464 | /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the |
| @@ -109743,17 +110894,19 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla | |||
| 109743 | pNewItem->iCursor = pOldItem->iCursor; | 110894 | pNewItem->iCursor = pOldItem->iCursor; |
| 109744 | pNewItem->addrFillSub = pOldItem->addrFillSub; | 110895 | pNewItem->addrFillSub = pOldItem->addrFillSub; |
| 109745 | pNewItem->regReturn = pOldItem->regReturn; | 110896 | pNewItem->regReturn = pOldItem->regReturn; |
| 110897 | pNewItem->regResult = pOldItem->regResult; | ||
| 109746 | if( pNewItem->fg.isIndexedBy ){ | 110898 | if( pNewItem->fg.isIndexedBy ){ |
| 109747 | pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); | 110899 | pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); |
| 110900 | }else if( pNewItem->fg.isTabFunc ){ | ||
| 110901 | pNewItem->u1.pFuncArg = | ||
| 110902 | sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); | ||
| 110903 | }else{ | ||
| 110904 | pNewItem->u1.nRow = pOldItem->u1.nRow; | ||
| 109748 | } | 110905 | } |
| 109749 | pNewItem->u2 = pOldItem->u2; | 110906 | pNewItem->u2 = pOldItem->u2; |
| 109750 | if( pNewItem->fg.isCte ){ | 110907 | if( pNewItem->fg.isCte ){ |
| 109751 | pNewItem->u2.pCteUse->nUse++; | 110908 | pNewItem->u2.pCteUse->nUse++; |
| 109752 | } | 110909 | } |
| 109753 | if( pNewItem->fg.isTabFunc ){ | ||
| 109754 | pNewItem->u1.pFuncArg = | ||
| 109755 | sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); | ||
| 109756 | } | ||
| 109757 | pTab = pNewItem->pTab = pOldItem->pTab; | 110910 | pTab = pNewItem->pTab = pOldItem->pTab; |
| 109758 | if( pTab ){ | 110911 | if( pTab ){ |
| 109759 | pTab->nTabRef++; | 110912 | pTab->nTabRef++; |
| @@ -110113,6 +111266,9 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ | |||
| 110113 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ | 111266 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ |
| 110114 | if( pList ) exprListDeleteNN(db, pList); | 111267 | if( pList ) exprListDeleteNN(db, pList); |
| 110115 | } | 111268 | } |
| 111269 | SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ | ||
| 111270 | if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); | ||
| 111271 | } | ||
| 110116 | 111272 | ||
| 110117 | /* | 111273 | /* |
| 110118 | ** Return the bitwise-OR of all Expr.flags fields in the given | 111274 | ** Return the bitwise-OR of all Expr.flags fields in the given |
| @@ -110216,6 +111372,54 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ | |||
| 110216 | return pExpr; | 111372 | return pExpr; |
| 110217 | } | 111373 | } |
| 110218 | 111374 | ||
| 111375 | /* | ||
| 111376 | ** pExpr is a TK_FUNCTION node. Try to determine whether or not the | ||
| 111377 | ** function is a constant function. A function is constant if all of | ||
| 111378 | ** the following are true: | ||
| 111379 | ** | ||
| 111380 | ** (1) It is a scalar function (not an aggregate or window function) | ||
| 111381 | ** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG | ||
| 111382 | ** property. | ||
| 111383 | ** (3) All of its arguments are constants | ||
| 111384 | ** | ||
| 111385 | ** This routine sets pWalker->eCode to 0 if pExpr is not a constant. | ||
| 111386 | ** It makes no changes to pWalker->eCode if pExpr is constant. In | ||
| 111387 | ** every case, it returns WRC_Abort. | ||
| 111388 | ** | ||
| 111389 | ** Called as a service subroutine from exprNodeIsConstant(). | ||
| 111390 | */ | ||
| 111391 | static SQLITE_NOINLINE int exprNodeIsConstantFunction( | ||
| 111392 | Walker *pWalker, | ||
| 111393 | Expr *pExpr | ||
| 111394 | ){ | ||
| 111395 | int n; /* Number of arguments */ | ||
| 111396 | ExprList *pList; /* List of arguments */ | ||
| 111397 | FuncDef *pDef; /* The function */ | ||
| 111398 | sqlite3 *db; /* The database */ | ||
| 111399 | |||
| 111400 | assert( pExpr->op==TK_FUNCTION ); | ||
| 111401 | if( ExprHasProperty(pExpr, EP_TokenOnly) | ||
| 111402 | || (pList = pExpr->x.pList)==0 | ||
| 111403 | ){; | ||
| 111404 | n = 0; | ||
| 111405 | }else{ | ||
| 111406 | n = pList->nExpr; | ||
| 111407 | sqlite3WalkExprList(pWalker, pList); | ||
| 111408 | if( pWalker->eCode==0 ) return WRC_Abort; | ||
| 111409 | } | ||
| 111410 | db = pWalker->pParse->db; | ||
| 111411 | pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); | ||
| 111412 | if( pDef==0 | ||
| 111413 | || pDef->xFinalize!=0 | ||
| 111414 | || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 | ||
| 111415 | || ExprHasProperty(pExpr, EP_WinFunc) | ||
| 111416 | ){ | ||
| 111417 | pWalker->eCode = 0; | ||
| 111418 | return WRC_Abort; | ||
| 111419 | } | ||
| 111420 | return WRC_Prune; | ||
| 111421 | } | ||
| 111422 | |||
| 110219 | 111423 | ||
| 110220 | /* | 111424 | /* |
| 110221 | ** These routines are Walker callbacks used to check expressions to | 111425 | ** These routines are Walker callbacks used to check expressions to |
| @@ -110244,6 +111448,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ | |||
| 110244 | ** malformed schema error. | 111448 | ** malformed schema error. |
| 110245 | */ | 111449 | */ |
| 110246 | static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ | 111450 | static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ |
| 111451 | assert( pWalker->eCode>0 ); | ||
| 110247 | 111452 | ||
| 110248 | /* If pWalker->eCode is 2 then any term of the expression that comes from | 111453 | /* If pWalker->eCode is 2 then any term of the expression that comes from |
| 110249 | ** the ON or USING clauses of an outer join disqualifies the expression | 111454 | ** the ON or USING clauses of an outer join disqualifies the expression |
| @@ -110263,6 +111468,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ | |||
| 110263 | ){ | 111468 | ){ |
| 110264 | if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); | 111469 | if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); |
| 110265 | return WRC_Continue; | 111470 | return WRC_Continue; |
| 111471 | }else if( pWalker->pParse ){ | ||
| 111472 | return exprNodeIsConstantFunction(pWalker, pExpr); | ||
| 110266 | }else{ | 111473 | }else{ |
| 110267 | pWalker->eCode = 0; | 111474 | pWalker->eCode = 0; |
| 110268 | return WRC_Abort; | 111475 | return WRC_Abort; |
| @@ -110291,9 +111498,11 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ | |||
| 110291 | case TK_IF_NULL_ROW: | 111498 | case TK_IF_NULL_ROW: |
| 110292 | case TK_REGISTER: | 111499 | case TK_REGISTER: |
| 110293 | case TK_DOT: | 111500 | case TK_DOT: |
| 111501 | case TK_RAISE: | ||
| 110294 | testcase( pExpr->op==TK_REGISTER ); | 111502 | testcase( pExpr->op==TK_REGISTER ); |
| 110295 | testcase( pExpr->op==TK_IF_NULL_ROW ); | 111503 | testcase( pExpr->op==TK_IF_NULL_ROW ); |
| 110296 | testcase( pExpr->op==TK_DOT ); | 111504 | testcase( pExpr->op==TK_DOT ); |
| 111505 | testcase( pExpr->op==TK_RAISE ); | ||
| 110297 | pWalker->eCode = 0; | 111506 | pWalker->eCode = 0; |
| 110298 | return WRC_Abort; | 111507 | return WRC_Abort; |
| 110299 | case TK_VARIABLE: | 111508 | case TK_VARIABLE: |
| @@ -110315,15 +111524,15 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ | |||
| 110315 | return WRC_Continue; | 111524 | return WRC_Continue; |
| 110316 | } | 111525 | } |
| 110317 | } | 111526 | } |
| 110318 | static int exprIsConst(Expr *p, int initFlag, int iCur){ | 111527 | static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ |
| 110319 | Walker w; | 111528 | Walker w; |
| 110320 | w.eCode = initFlag; | 111529 | w.eCode = initFlag; |
| 111530 | w.pParse = pParse; | ||
| 110321 | w.xExprCallback = exprNodeIsConstant; | 111531 | w.xExprCallback = exprNodeIsConstant; |
| 110322 | w.xSelectCallback = sqlite3SelectWalkFail; | 111532 | w.xSelectCallback = sqlite3SelectWalkFail; |
| 110323 | #ifdef SQLITE_DEBUG | 111533 | #ifdef SQLITE_DEBUG |
| 110324 | w.xSelectCallback2 = sqlite3SelectWalkAssert2; | 111534 | w.xSelectCallback2 = sqlite3SelectWalkAssert2; |
| 110325 | #endif | 111535 | #endif |
| 110326 | w.u.iCur = iCur; | ||
| 110327 | sqlite3WalkExpr(&w, p); | 111536 | sqlite3WalkExpr(&w, p); |
| 110328 | return w.eCode; | 111537 | return w.eCode; |
| 110329 | } | 111538 | } |
| @@ -110335,9 +111544,15 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ | |||
| 110335 | ** For the purposes of this function, a double-quoted string (ex: "abc") | 111544 | ** For the purposes of this function, a double-quoted string (ex: "abc") |
| 110336 | ** is considered a variable but a single-quoted string (ex: 'abc') is | 111545 | ** is considered a variable but a single-quoted string (ex: 'abc') is |
| 110337 | ** a constant. | 111546 | ** a constant. |
| 111547 | ** | ||
| 111548 | ** The pParse parameter may be NULL. But if it is NULL, there is no way | ||
| 111549 | ** to determine if function calls are constant or not, and hence all | ||
| 111550 | ** function calls will be considered to be non-constant. If pParse is | ||
| 111551 | ** not NULL, then a function call might be constant, depending on the | ||
| 111552 | ** function and on its parameters. | ||
| 110338 | */ | 111553 | */ |
| 110339 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ | 111554 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ |
| 110340 | return exprIsConst(p, 1, 0); | 111555 | return exprIsConst(pParse, p, 1); |
| 110341 | } | 111556 | } |
| 110342 | 111557 | ||
| 110343 | /* | 111558 | /* |
| @@ -110353,8 +111568,24 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ | |||
| 110353 | ** can be added to the pParse->pConstExpr list and evaluated once when | 111568 | ** can be added to the pParse->pConstExpr list and evaluated once when |
| 110354 | ** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). | 111569 | ** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). |
| 110355 | */ | 111570 | */ |
| 110356 | SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ | 111571 | static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){ |
| 110357 | return exprIsConst(p, 2, 0); | 111572 | return exprIsConst(pParse, p, 2); |
| 111573 | } | ||
| 111574 | |||
| 111575 | /* | ||
| 111576 | ** This routine examines sub-SELECT statements as an expression is being | ||
| 111577 | ** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered | ||
| 111578 | ** constant as long as they are uncorrelated - meaning that they do not | ||
| 111579 | ** contain any terms from outer contexts. | ||
| 111580 | */ | ||
| 111581 | static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){ | ||
| 111582 | assert( pSelect!=0 ); | ||
| 111583 | assert( pWalker->eCode==3 || pWalker->eCode==0 ); | ||
| 111584 | if( (pSelect->selFlags & SF_Correlated)!=0 ){ | ||
| 111585 | pWalker->eCode = 0; | ||
| 111586 | return WRC_Abort; | ||
| 111587 | } | ||
| 111588 | return WRC_Prune; | ||
| 110358 | } | 111589 | } |
| 110359 | 111590 | ||
| 110360 | /* | 111591 | /* |
| @@ -110362,9 +111593,26 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ | |||
| 110362 | ** for any single row of the table with cursor iCur. In other words, the | 111593 | ** for any single row of the table with cursor iCur. In other words, the |
| 110363 | ** expression must not refer to any non-deterministic function nor any | 111594 | ** expression must not refer to any non-deterministic function nor any |
| 110364 | ** table other than iCur. | 111595 | ** table other than iCur. |
| 111596 | ** | ||
| 111597 | ** Consider uncorrelated subqueries to be constants if the bAllowSubq | ||
| 111598 | ** parameter is true. | ||
| 110365 | */ | 111599 | */ |
| 110366 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ | 111600 | static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ |
| 110367 | return exprIsConst(p, 3, iCur); | 111601 | Walker w; |
| 111602 | w.eCode = 3; | ||
| 111603 | w.pParse = 0; | ||
| 111604 | w.xExprCallback = exprNodeIsConstant; | ||
| 111605 | if( bAllowSubq ){ | ||
| 111606 | w.xSelectCallback = exprSelectWalkTableConstant; | ||
| 111607 | }else{ | ||
| 111608 | w.xSelectCallback = sqlite3SelectWalkFail; | ||
| 111609 | #ifdef SQLITE_DEBUG | ||
| 111610 | w.xSelectCallback2 = sqlite3SelectWalkAssert2; | ||
| 111611 | #endif | ||
| 111612 | } | ||
| 111613 | w.u.iCur = iCur; | ||
| 111614 | sqlite3WalkExpr(&w, p); | ||
| 111615 | return w.eCode; | ||
| 110368 | } | 111616 | } |
| 110369 | 111617 | ||
| 110370 | /* | 111618 | /* |
| @@ -110382,7 +111630,10 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ | |||
| 110382 | ** | 111630 | ** |
| 110383 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. | 111631 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. |
| 110384 | ** | 111632 | ** |
| 110385 | ** (2) pExpr cannot use subqueries or non-deterministic functions. | 111633 | ** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is |
| 111634 | ** true and the subquery is non-correlated | ||
| 111635 | ** | ||
| 111636 | ** (2b) pExpr cannot use non-deterministic functions. | ||
| 110386 | ** | 111637 | ** |
| 110387 | ** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. | 111638 | ** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. |
| 110388 | ** (Is there some way to relax this constraint?) | 111639 | ** (Is there some way to relax this constraint?) |
| @@ -110411,7 +111662,8 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ | |||
| 110411 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( | 111662 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( |
| 110412 | Expr *pExpr, /* The constraint */ | 111663 | Expr *pExpr, /* The constraint */ |
| 110413 | const SrcList *pSrcList, /* Complete FROM clause */ | 111664 | const SrcList *pSrcList, /* Complete FROM clause */ |
| 110414 | int iSrc /* Which element of pSrcList to use */ | 111665 | int iSrc, /* Which element of pSrcList to use */ |
| 111666 | int bAllowSubq /* Allow non-correlated subqueries */ | ||
| 110415 | ){ | 111667 | ){ |
| 110416 | const SrcItem *pSrc = &pSrcList->a[iSrc]; | 111668 | const SrcItem *pSrc = &pSrcList->a[iSrc]; |
| 110417 | if( pSrc->fg.jointype & JT_LTORJ ){ | 111669 | if( pSrc->fg.jointype & JT_LTORJ ){ |
| @@ -110436,7 +111688,8 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( | |||
| 110436 | } | 111688 | } |
| 110437 | } | 111689 | } |
| 110438 | } | 111690 | } |
| 110439 | return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ | 111691 | /* Rules (1), (2a), and (2b) handled by the following: */ |
| 111692 | return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq); | ||
| 110440 | } | 111693 | } |
| 110441 | 111694 | ||
| 110442 | 111695 | ||
| @@ -110521,7 +111774,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprLi | |||
| 110521 | */ | 111774 | */ |
| 110522 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ | 111775 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ |
| 110523 | assert( isInit==0 || isInit==1 ); | 111776 | assert( isInit==0 || isInit==1 ); |
| 110524 | return exprIsConst(p, 4+isInit, 0); | 111777 | return exprIsConst(0, p, 4+isInit); |
| 110525 | } | 111778 | } |
| 110526 | 111779 | ||
| 110527 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 111780 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| @@ -110611,10 +111864,14 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ | |||
| 110611 | return 0; | 111864 | return 0; |
| 110612 | case TK_COLUMN: | 111865 | case TK_COLUMN: |
| 110613 | assert( ExprUseYTab(p) ); | 111866 | assert( ExprUseYTab(p) ); |
| 110614 | return ExprHasProperty(p, EP_CanBeNull) || | 111867 | return ExprHasProperty(p, EP_CanBeNull) |
| 110615 | p->y.pTab==0 || /* Reference to column of index on expression */ | 111868 | || NEVER(p->y.pTab==0) /* Reference to column of index on expr */ |
| 110616 | (p->iColumn>=0 | 111869 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW |
| 111870 | || (p->iColumn==XN_ROWID && IsView(p->y.pTab)) | ||
| 111871 | #endif | ||
| 111872 | || (p->iColumn>=0 | ||
| 110617 | && p->y.pTab->aCol!=0 /* Possible due to prior error */ | 111873 | && p->y.pTab->aCol!=0 /* Possible due to prior error */ |
| 111874 | && ALWAYS(p->iColumn<p->y.pTab->nCol) | ||
| 110618 | && p->y.pTab->aCol[p->iColumn].notNull==0); | 111875 | && p->y.pTab->aCol[p->iColumn].notNull==0); |
| 110619 | default: | 111876 | default: |
| 110620 | return 1; | 111877 | return 1; |
| @@ -110765,13 +112022,13 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ | |||
| 110765 | ** The argument is an IN operator with a list (not a subquery) on the | 112022 | ** The argument is an IN operator with a list (not a subquery) on the |
| 110766 | ** right-hand side. Return TRUE if that list is constant. | 112023 | ** right-hand side. Return TRUE if that list is constant. |
| 110767 | */ | 112024 | */ |
| 110768 | static int sqlite3InRhsIsConstant(Expr *pIn){ | 112025 | static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){ |
| 110769 | Expr *pLHS; | 112026 | Expr *pLHS; |
| 110770 | int res; | 112027 | int res; |
| 110771 | assert( !ExprHasProperty(pIn, EP_xIsSelect) ); | 112028 | assert( !ExprHasProperty(pIn, EP_xIsSelect) ); |
| 110772 | pLHS = pIn->pLeft; | 112029 | pLHS = pIn->pLeft; |
| 110773 | pIn->pLeft = 0; | 112030 | pIn->pLeft = 0; |
| 110774 | res = sqlite3ExprIsConstant(pIn); | 112031 | res = sqlite3ExprIsConstant(pParse, pIn); |
| 110775 | pIn->pLeft = pLHS; | 112032 | pIn->pLeft = pLHS; |
| 110776 | return res; | 112033 | return res; |
| 110777 | } | 112034 | } |
| @@ -111040,7 +112297,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( | |||
| 111040 | if( eType==0 | 112297 | if( eType==0 |
| 111041 | && (inFlags & IN_INDEX_NOOP_OK) | 112298 | && (inFlags & IN_INDEX_NOOP_OK) |
| 111042 | && ExprUseXList(pX) | 112299 | && ExprUseXList(pX) |
| 111043 | && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) | 112300 | && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2) |
| 111044 | ){ | 112301 | ){ |
| 111045 | pParse->nTab--; /* Back out the allocation of the unused cursor */ | 112302 | pParse->nTab--; /* Back out the allocation of the unused cursor */ |
| 111046 | iTab = -1; /* Cursor is not allocated */ | 112303 | iTab = -1; /* Cursor is not allocated */ |
| @@ -111323,7 +112580,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 111323 | ** this code only executes once. Because for a non-constant | 112580 | ** this code only executes once. Because for a non-constant |
| 111324 | ** expression we need to rerun this code each time. | 112581 | ** expression we need to rerun this code each time. |
| 111325 | */ | 112582 | */ |
| 111326 | if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ | 112583 | if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){ |
| 111327 | sqlite3VdbeChangeToNoop(v, addrOnce-1); | 112584 | sqlite3VdbeChangeToNoop(v, addrOnce-1); |
| 111328 | sqlite3VdbeChangeToNoop(v, addrOnce); | 112585 | sqlite3VdbeChangeToNoop(v, addrOnce); |
| 111329 | ExprClearProperty(pExpr, EP_Subrtn); | 112586 | ExprClearProperty(pExpr, EP_Subrtn); |
| @@ -112487,12 +113744,6 @@ expr_code_doover: | |||
| 112487 | assert( pExpr->u.zToken!=0 ); | 113744 | assert( pExpr->u.zToken!=0 ); |
| 112488 | assert( pExpr->u.zToken[0]!=0 ); | 113745 | assert( pExpr->u.zToken[0]!=0 ); |
| 112489 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); | 113746 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 112490 | if( pExpr->u.zToken[1]!=0 ){ | ||
| 112491 | const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); | ||
| 112492 | assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); | ||
| 112493 | pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ | ||
| 112494 | sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); | ||
| 112495 | } | ||
| 112496 | return target; | 113747 | return target; |
| 112497 | } | 113748 | } |
| 112498 | case TK_REGISTER: { | 113749 | case TK_REGISTER: { |
| @@ -112666,7 +113917,9 @@ expr_code_doover: | |||
| 112666 | } | 113917 | } |
| 112667 | #endif | 113918 | #endif |
| 112668 | 113919 | ||
| 112669 | if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ | 113920 | if( ConstFactorOk(pParse) |
| 113921 | && sqlite3ExprIsConstantNotJoin(pParse,pExpr) | ||
| 113922 | ){ | ||
| 112670 | /* SQL functions can be expensive. So try to avoid running them | 113923 | /* SQL functions can be expensive. So try to avoid running them |
| 112671 | ** multiple times if we know they always give the same result */ | 113924 | ** multiple times if we know they always give the same result */ |
| 112672 | return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); | 113925 | return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); |
| @@ -112697,7 +113950,7 @@ expr_code_doover: | |||
| 112697 | } | 113950 | } |
| 112698 | 113951 | ||
| 112699 | for(i=0; i<nFarg; i++){ | 113952 | for(i=0; i<nFarg; i++){ |
| 112700 | if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ | 113953 | if( i<32 && sqlite3ExprIsConstant(pParse, pFarg->a[i].pExpr) ){ |
| 112701 | testcase( i==31 ); | 113954 | testcase( i==31 ); |
| 112702 | constMask |= MASKBIT32(i); | 113955 | constMask |= MASKBIT32(i); |
| 112703 | } | 113956 | } |
| @@ -112839,8 +114092,9 @@ expr_code_doover: | |||
| 112839 | if( !ExprHasProperty(pExpr, EP_Collate) ){ | 114092 | if( !ExprHasProperty(pExpr, EP_Collate) ){ |
| 112840 | /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called | 114093 | /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called |
| 112841 | ** "SOFT-COLLATE" that is added to constraints that are pushed down | 114094 | ** "SOFT-COLLATE" that is added to constraints that are pushed down |
| 112842 | ** from outer queries into sub-queries by the push-down optimization. | 114095 | ** from outer queries into sub-queries by the WHERE-clause push-down |
| 112843 | ** Clear subtypes as subtypes may not cross a subquery boundary. | 114096 | ** optimization. Clear subtypes as subtypes may not cross a subquery |
| 114097 | ** boundary. | ||
| 112844 | */ | 114098 | */ |
| 112845 | assert( pExpr->pLeft ); | 114099 | assert( pExpr->pLeft ); |
| 112846 | sqlite3ExprCode(pParse, pExpr->pLeft, target); | 114100 | sqlite3ExprCode(pParse, pExpr->pLeft, target); |
| @@ -113164,7 +114418,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ | |||
| 113164 | if( ConstFactorOk(pParse) | 114418 | if( ConstFactorOk(pParse) |
| 113165 | && ALWAYS(pExpr!=0) | 114419 | && ALWAYS(pExpr!=0) |
| 113166 | && pExpr->op!=TK_REGISTER | 114420 | && pExpr->op!=TK_REGISTER |
| 113167 | && sqlite3ExprIsConstantNotJoin(pExpr) | 114421 | && sqlite3ExprIsConstantNotJoin(pParse, pExpr) |
| 113168 | ){ | 114422 | ){ |
| 113169 | *pReg = 0; | 114423 | *pReg = 0; |
| 113170 | r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); | 114424 | r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); |
| @@ -113196,8 +114450,10 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ | |||
| 113196 | inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); | 114450 | inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); |
| 113197 | if( inReg!=target ){ | 114451 | if( inReg!=target ){ |
| 113198 | u8 op; | 114452 | u8 op; |
| 113199 | if( ALWAYS(pExpr) | 114453 | Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); |
| 113200 | && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) | 114454 | testcase( pX!=pExpr ); |
| 114455 | if( ALWAYS(pX) | ||
| 114456 | && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) | ||
| 113201 | ){ | 114457 | ){ |
| 113202 | op = OP_Copy; | 114458 | op = OP_Copy; |
| 113203 | }else{ | 114459 | }else{ |
| @@ -113226,7 +114482,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ | |||
| 113226 | ** might choose to code the expression at initialization time. | 114482 | ** might choose to code the expression at initialization time. |
| 113227 | */ | 114483 | */ |
| 113228 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ | 114484 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ |
| 113229 | if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ | 114485 | if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ |
| 113230 | sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); | 114486 | sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); |
| 113231 | }else{ | 114487 | }else{ |
| 113232 | sqlite3ExprCodeCopy(pParse, pExpr, target); | 114488 | sqlite3ExprCodeCopy(pParse, pExpr, target); |
| @@ -113285,7 +114541,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( | |||
| 113285 | sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); | 114541 | sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); |
| 113286 | } | 114542 | } |
| 113287 | }else if( (flags & SQLITE_ECEL_FACTOR)!=0 | 114543 | }else if( (flags & SQLITE_ECEL_FACTOR)!=0 |
| 113288 | && sqlite3ExprIsConstantNotJoin(pExpr) | 114544 | && sqlite3ExprIsConstantNotJoin(pParse,pExpr) |
| 113289 | ){ | 114545 | ){ |
| 113290 | sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); | 114546 | sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); |
| 113291 | }else{ | 114547 | }else{ |
| @@ -113917,8 +115173,8 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB | |||
| 113917 | */ | 115173 | */ |
| 113918 | SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ | 115174 | SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ |
| 113919 | return sqlite3ExprCompare(0, | 115175 | return sqlite3ExprCompare(0, |
| 113920 | sqlite3ExprSkipCollateAndLikely(pA), | 115176 | sqlite3ExprSkipCollate(pA), |
| 113921 | sqlite3ExprSkipCollateAndLikely(pB), | 115177 | sqlite3ExprSkipCollate(pB), |
| 113922 | iTab); | 115178 | iTab); |
| 113923 | } | 115179 | } |
| 113924 | 115180 | ||
| @@ -114436,9 +115692,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ | |||
| 114436 | && pAggInfo->aCol[iAgg].pCExpr==pExpr | 115692 | && pAggInfo->aCol[iAgg].pCExpr==pExpr |
| 114437 | ){ | 115693 | ){ |
| 114438 | pExpr = sqlite3ExprDup(db, pExpr, 0); | 115694 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 114439 | if( pExpr ){ | 115695 | if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ |
| 114440 | pAggInfo->aCol[iAgg].pCExpr = pExpr; | 115696 | pAggInfo->aCol[iAgg].pCExpr = pExpr; |
| 114441 | sqlite3ExprDeferredDelete(pParse, pExpr); | ||
| 114442 | } | 115697 | } |
| 114443 | } | 115698 | } |
| 114444 | }else{ | 115699 | }else{ |
| @@ -114447,9 +115702,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ | |||
| 114447 | && pAggInfo->aFunc[iAgg].pFExpr==pExpr | 115702 | && pAggInfo->aFunc[iAgg].pFExpr==pExpr |
| 114448 | ){ | 115703 | ){ |
| 114449 | pExpr = sqlite3ExprDup(db, pExpr, 0); | 115704 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 114450 | if( pExpr ){ | 115705 | if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ |
| 114451 | pAggInfo->aFunc[iAgg].pFExpr = pExpr; | 115706 | pAggInfo->aFunc[iAgg].pFExpr = pExpr; |
| 114452 | sqlite3ExprDeferredDelete(pParse, pExpr); | ||
| 114453 | } | 115707 | } |
| 114454 | } | 115708 | } |
| 114455 | } | 115709 | } |
| @@ -114643,13 +115897,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ | |||
| 114643 | case TK_AGG_FUNCTION: { | 115897 | case TK_AGG_FUNCTION: { |
| 114644 | if( (pNC->ncFlags & NC_InAggFunc)==0 | 115898 | if( (pNC->ncFlags & NC_InAggFunc)==0 |
| 114645 | && pWalker->walkerDepth==pExpr->op2 | 115899 | && pWalker->walkerDepth==pExpr->op2 |
| 115900 | && pExpr->pAggInfo==0 | ||
| 114646 | ){ | 115901 | ){ |
| 114647 | /* Check to see if pExpr is a duplicate of another aggregate | 115902 | /* Check to see if pExpr is a duplicate of another aggregate |
| 114648 | ** function that is already in the pAggInfo structure | 115903 | ** function that is already in the pAggInfo structure |
| 114649 | */ | 115904 | */ |
| 114650 | struct AggInfo_func *pItem = pAggInfo->aFunc; | 115905 | struct AggInfo_func *pItem = pAggInfo->aFunc; |
| 114651 | for(i=0; i<pAggInfo->nFunc; i++, pItem++){ | 115906 | for(i=0; i<pAggInfo->nFunc; i++, pItem++){ |
| 114652 | if( pItem->pFExpr==pExpr ) break; | 115907 | if( NEVER(pItem->pFExpr==pExpr) ) break; |
| 114653 | if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ | 115908 | if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ |
| 114654 | break; | 115909 | break; |
| 114655 | } | 115910 | } |
| @@ -114692,6 +115947,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ | |||
| 114692 | }else{ | 115947 | }else{ |
| 114693 | pItem->bOBPayload = 1; | 115948 | pItem->bOBPayload = 1; |
| 114694 | } | 115949 | } |
| 115950 | pItem->bUseSubtype = | ||
| 115951 | (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; | ||
| 114695 | }else{ | 115952 | }else{ |
| 114696 | pItem->iOBTab = -1; | 115953 | pItem->iOBTab = -1; |
| 114697 | } | 115954 | } |
| @@ -116205,7 +117462,7 @@ static int renameResolveTrigger(Parse *pParse){ | |||
| 116205 | /* ALWAYS() because if the table of the trigger does not exist, the | 117462 | /* ALWAYS() because if the table of the trigger does not exist, the |
| 116206 | ** error would have been hit before this point */ | 117463 | ** error would have been hit before this point */ |
| 116207 | if( ALWAYS(pParse->pTriggerTab) ){ | 117464 | if( ALWAYS(pParse->pTriggerTab) ){ |
| 116208 | rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); | 117465 | rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; |
| 116209 | } | 117466 | } |
| 116210 | 117467 | ||
| 116211 | /* Resolve symbols in WHEN clause */ | 117468 | /* Resolve symbols in WHEN clause */ |
| @@ -117147,7 +118404,12 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T | |||
| 117147 | if( i==pTab->iPKey ){ | 118404 | if( i==pTab->iPKey ){ |
| 117148 | sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); | 118405 | sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); |
| 117149 | }else{ | 118406 | }else{ |
| 118407 | char aff = pTab->aCol[i].affinity; | ||
| 118408 | if( aff==SQLITE_AFF_REAL ){ | ||
| 118409 | pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; | ||
| 118410 | } | ||
| 117150 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); | 118411 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); |
| 118412 | pTab->aCol[i].affinity = aff; | ||
| 117151 | } | 118413 | } |
| 117152 | nField++; | 118414 | nField++; |
| 117153 | } | 118415 | } |
| @@ -117458,9 +118720,9 @@ static void openStatTable( | |||
| 117458 | typedef struct StatAccum StatAccum; | 118720 | typedef struct StatAccum StatAccum; |
| 117459 | typedef struct StatSample StatSample; | 118721 | typedef struct StatSample StatSample; |
| 117460 | struct StatSample { | 118722 | struct StatSample { |
| 117461 | tRowcnt *anEq; /* sqlite_stat4.nEq */ | ||
| 117462 | tRowcnt *anDLt; /* sqlite_stat4.nDLt */ | 118723 | tRowcnt *anDLt; /* sqlite_stat4.nDLt */ |
| 117463 | #ifdef SQLITE_ENABLE_STAT4 | 118724 | #ifdef SQLITE_ENABLE_STAT4 |
| 118725 | tRowcnt *anEq; /* sqlite_stat4.nEq */ | ||
| 117464 | tRowcnt *anLt; /* sqlite_stat4.nLt */ | 118726 | tRowcnt *anLt; /* sqlite_stat4.nLt */ |
| 117465 | union { | 118727 | union { |
| 117466 | i64 iRowid; /* Rowid in main table of the key */ | 118728 | i64 iRowid; /* Rowid in main table of the key */ |
| @@ -117618,9 +118880,9 @@ static void statInit( | |||
| 117618 | 118880 | ||
| 117619 | /* Allocate the space required for the StatAccum object */ | 118881 | /* Allocate the space required for the StatAccum object */ |
| 117620 | n = sizeof(*p) | 118882 | n = sizeof(*p) |
| 117621 | + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ | 118883 | + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ |
| 117622 | + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ | ||
| 117623 | #ifdef SQLITE_ENABLE_STAT4 | 118884 | #ifdef SQLITE_ENABLE_STAT4 |
| 118885 | n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ | ||
| 117624 | if( mxSample ){ | 118886 | if( mxSample ){ |
| 117625 | n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ | 118887 | n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ |
| 117626 | + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ | 118888 | + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ |
| @@ -117641,9 +118903,9 @@ static void statInit( | |||
| 117641 | p->nKeyCol = nKeyCol; | 118903 | p->nKeyCol = nKeyCol; |
| 117642 | p->nSkipAhead = 0; | 118904 | p->nSkipAhead = 0; |
| 117643 | p->current.anDLt = (tRowcnt*)&p[1]; | 118905 | p->current.anDLt = (tRowcnt*)&p[1]; |
| 117644 | p->current.anEq = &p->current.anDLt[nColUp]; | ||
| 117645 | 118906 | ||
| 117646 | #ifdef SQLITE_ENABLE_STAT4 | 118907 | #ifdef SQLITE_ENABLE_STAT4 |
| 118908 | p->current.anEq = &p->current.anDLt[nColUp]; | ||
| 117647 | p->mxSample = p->nLimit==0 ? mxSample : 0; | 118909 | p->mxSample = p->nLimit==0 ? mxSample : 0; |
| 117648 | if( mxSample ){ | 118910 | if( mxSample ){ |
| 117649 | u8 *pSpace; /* Allocated space not yet assigned */ | 118911 | u8 *pSpace; /* Allocated space not yet assigned */ |
| @@ -117910,7 +119172,9 @@ static void statPush( | |||
| 117910 | 119172 | ||
| 117911 | if( p->nRow==0 ){ | 119173 | if( p->nRow==0 ){ |
| 117912 | /* This is the first call to this function. Do initialization. */ | 119174 | /* This is the first call to this function. Do initialization. */ |
| 119175 | #ifdef SQLITE_ENABLE_STAT4 | ||
| 117913 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; | 119176 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 119177 | #endif | ||
| 117914 | }else{ | 119178 | }else{ |
| 117915 | /* Second and subsequent calls get processed here */ | 119179 | /* Second and subsequent calls get processed here */ |
| 117916 | #ifdef SQLITE_ENABLE_STAT4 | 119180 | #ifdef SQLITE_ENABLE_STAT4 |
| @@ -117919,15 +119183,17 @@ static void statPush( | |||
| 117919 | 119183 | ||
| 117920 | /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply | 119184 | /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply |
| 117921 | ** to the current row of the index. */ | 119185 | ** to the current row of the index. */ |
| 119186 | #ifdef SQLITE_ENABLE_STAT4 | ||
| 117922 | for(i=0; i<iChng; i++){ | 119187 | for(i=0; i<iChng; i++){ |
| 117923 | p->current.anEq[i]++; | 119188 | p->current.anEq[i]++; |
| 117924 | } | 119189 | } |
| 119190 | #endif | ||
| 117925 | for(i=iChng; i<p->nCol; i++){ | 119191 | for(i=iChng; i<p->nCol; i++){ |
| 117926 | p->current.anDLt[i]++; | 119192 | p->current.anDLt[i]++; |
| 117927 | #ifdef SQLITE_ENABLE_STAT4 | 119193 | #ifdef SQLITE_ENABLE_STAT4 |
| 117928 | if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; | 119194 | if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; |
| 117929 | #endif | ||
| 117930 | p->current.anEq[i] = 1; | 119195 | p->current.anEq[i] = 1; |
| 119196 | #endif | ||
| 117931 | } | 119197 | } |
| 117932 | } | 119198 | } |
| 117933 | 119199 | ||
| @@ -118061,7 +119327,9 @@ static void statGet( | |||
| 118061 | u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; | 119327 | u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 118062 | if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; | 119328 | if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; |
| 118063 | sqlite3_str_appendf(&sStat, " %llu", iVal); | 119329 | sqlite3_str_appendf(&sStat, " %llu", iVal); |
| 118064 | assert( p->current.anEq[i] ); | 119330 | #ifdef SQLITE_ENABLE_STAT4 |
| 119331 | assert( p->current.anEq[i] || p->nRow==0 ); | ||
| 119332 | #endif | ||
| 118065 | } | 119333 | } |
| 118066 | sqlite3ResultStrAccum(context, &sStat); | 119334 | sqlite3ResultStrAccum(context, &sStat); |
| 118067 | } | 119335 | } |
| @@ -118245,7 +119513,7 @@ static void analyzeOneTable( | |||
| 118245 | 119513 | ||
| 118246 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 119514 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 118247 | int nCol; /* Number of columns in pIdx. "N" */ | 119515 | int nCol; /* Number of columns in pIdx. "N" */ |
| 118248 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ | 119516 | int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */ |
| 118249 | int addrNextRow; /* Address of "next_row:" */ | 119517 | int addrNextRow; /* Address of "next_row:" */ |
| 118250 | const char *zIdxName; /* Name of the index */ | 119518 | const char *zIdxName; /* Name of the index */ |
| 118251 | int nColTest; /* Number of columns to test for changes */ | 119519 | int nColTest; /* Number of columns to test for changes */ |
| @@ -118269,9 +119537,14 @@ static void analyzeOneTable( | |||
| 118269 | /* | 119537 | /* |
| 118270 | ** Pseudo-code for loop that calls stat_push(): | 119538 | ** Pseudo-code for loop that calls stat_push(): |
| 118271 | ** | 119539 | ** |
| 118272 | ** Rewind csr | ||
| 118273 | ** if eof(csr) goto end_of_scan; | ||
| 118274 | ** regChng = 0 | 119540 | ** regChng = 0 |
| 119541 | ** Rewind csr | ||
| 119542 | ** if eof(csr){ | ||
| 119543 | ** stat_init() with count = 0; | ||
| 119544 | ** goto end_of_scan; | ||
| 119545 | ** } | ||
| 119546 | ** count() | ||
| 119547 | ** stat_init() | ||
| 118275 | ** goto chng_addr_0; | 119548 | ** goto chng_addr_0; |
| 118276 | ** | 119549 | ** |
| 118277 | ** next_row: | 119550 | ** next_row: |
| @@ -118310,41 +119583,36 @@ static void analyzeOneTable( | |||
| 118310 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); | 119583 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 118311 | VdbeComment((v, "%s", pIdx->zName)); | 119584 | VdbeComment((v, "%s", pIdx->zName)); |
| 118312 | 119585 | ||
| 118313 | /* Invoke the stat_init() function. The arguments are: | 119586 | /* Implementation of the following: |
| 118314 | ** | 119587 | ** |
| 119588 | ** regChng = 0 | ||
| 119589 | ** Rewind csr | ||
| 119590 | ** if eof(csr){ | ||
| 119591 | ** stat_init() with count = 0; | ||
| 119592 | ** goto end_of_scan; | ||
| 119593 | ** } | ||
| 119594 | ** count() | ||
| 119595 | ** stat_init() | ||
| 119596 | ** goto chng_addr_0; | ||
| 119597 | */ | ||
| 119598 | assert( regTemp2==regStat+4 ); | ||
| 119599 | sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); | ||
| 119600 | |||
| 119601 | /* Arguments to stat_init(): | ||
| 118315 | ** (1) the number of columns in the index including the rowid | 119602 | ** (1) the number of columns in the index including the rowid |
| 118316 | ** (or for a WITHOUT ROWID table, the number of PK columns), | 119603 | ** (or for a WITHOUT ROWID table, the number of PK columns), |
| 118317 | ** (2) the number of columns in the key without the rowid/pk | 119604 | ** (2) the number of columns in the key without the rowid/pk |
| 118318 | ** (3) estimated number of rows in the index, | 119605 | ** (3) estimated number of rows in the index. */ |
| 118319 | */ | ||
| 118320 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); | 119606 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); |
| 118321 | assert( regRowid==regStat+2 ); | 119607 | assert( regRowid==regStat+2 ); |
| 118322 | sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); | 119608 | sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); |
| 118323 | #ifdef SQLITE_ENABLE_STAT4 | 119609 | sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, |
| 118324 | if( OptimizationEnabled(db, SQLITE_Stat4) ){ | 119610 | OptimizationDisabled(db, SQLITE_Stat4)); |
| 118325 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp); | ||
| 118326 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); | ||
| 118327 | VdbeCoverage(v); | ||
| 118328 | }else | ||
| 118329 | #endif | ||
| 118330 | { | ||
| 118331 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); | ||
| 118332 | VdbeCoverage(v); | ||
| 118333 | sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1); | ||
| 118334 | } | ||
| 118335 | assert( regTemp2==regStat+4 ); | ||
| 118336 | sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); | ||
| 118337 | sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, | 119611 | sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, |
| 118338 | &statInitFuncdef, 0); | 119612 | &statInitFuncdef, 0); |
| 119613 | addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); | ||
| 119614 | VdbeCoverage(v); | ||
| 118339 | 119615 | ||
| 118340 | /* Implementation of the following: | ||
| 118341 | ** | ||
| 118342 | ** Rewind csr | ||
| 118343 | ** if eof(csr) goto end_of_scan; | ||
| 118344 | ** regChng = 0 | ||
| 118345 | ** goto next_push_0; | ||
| 118346 | ** | ||
| 118347 | */ | ||
| 118348 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); | 119616 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 118349 | addrNextRow = sqlite3VdbeCurrentAddr(v); | 119617 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 118350 | 119618 | ||
| @@ -118451,6 +119719,12 @@ static void analyzeOneTable( | |||
| 118451 | } | 119719 | } |
| 118452 | 119720 | ||
| 118453 | /* Add the entry to the stat1 table. */ | 119721 | /* Add the entry to the stat1 table. */ |
| 119722 | if( pIdx->pPartIdxWhere ){ | ||
| 119723 | /* Partial indexes might get a zero-entry in sqlite_stat1. But | ||
| 119724 | ** an empty table is omitted from sqlite_stat1. */ | ||
| 119725 | sqlite3VdbeJumpHere(v, addrGotoEnd); | ||
| 119726 | addrGotoEnd = 0; | ||
| 119727 | } | ||
| 118454 | callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); | 119728 | callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); |
| 118455 | assert( "BBB"[0]==SQLITE_AFF_TEXT ); | 119729 | assert( "BBB"[0]==SQLITE_AFF_TEXT ); |
| 118456 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); | 119730 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); |
| @@ -118474,6 +119748,13 @@ static void analyzeOneTable( | |||
| 118474 | int addrIsNull; | 119748 | int addrIsNull; |
| 118475 | u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; | 119749 | u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; |
| 118476 | 119750 | ||
| 119751 | /* No STAT4 data is generated if the number of rows is zero */ | ||
| 119752 | if( addrGotoEnd==0 ){ | ||
| 119753 | sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER); | ||
| 119754 | addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); | ||
| 119755 | VdbeCoverage(v); | ||
| 119756 | } | ||
| 119757 | |||
| 118477 | if( doOnce ){ | 119758 | if( doOnce ){ |
| 118478 | int mxCol = nCol; | 119759 | int mxCol = nCol; |
| 118479 | Index *pX; | 119760 | Index *pX; |
| @@ -118526,7 +119807,7 @@ static void analyzeOneTable( | |||
| 118526 | #endif /* SQLITE_ENABLE_STAT4 */ | 119807 | #endif /* SQLITE_ENABLE_STAT4 */ |
| 118527 | 119808 | ||
| 118528 | /* End of analysis */ | 119809 | /* End of analysis */ |
| 118529 | sqlite3VdbeJumpHere(v, addrRewind); | 119810 | if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd); |
| 118530 | } | 119811 | } |
| 118531 | 119812 | ||
| 118532 | 119813 | ||
| @@ -118750,6 +120031,16 @@ static void decodeIntArray( | |||
| 118750 | while( z[0]!=0 && z[0]!=' ' ) z++; | 120031 | while( z[0]!=0 && z[0]!=' ' ) z++; |
| 118751 | while( z[0]==' ' ) z++; | 120032 | while( z[0]==' ' ) z++; |
| 118752 | } | 120033 | } |
| 120034 | |||
| 120035 | /* Set the bLowQual flag if the peak number of rows obtained | ||
| 120036 | ** from a full equality match is so large that a full table scan | ||
| 120037 | ** seems likely to be faster than using the index. | ||
| 120038 | */ | ||
| 120039 | if( aLog[0] > 66 /* Index has more than 100 rows */ | ||
| 120040 | && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ | ||
| 120041 | ){ | ||
| 120042 | pIndex->bLowQual = 1; | ||
| 120043 | } | ||
| 118753 | } | 120044 | } |
| 118754 | } | 120045 | } |
| 118755 | 120046 | ||
| @@ -120265,7 +121556,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ | |||
| 120265 | } | 121556 | } |
| 120266 | sqlite3VdbeAddOp0(v, OP_Halt); | 121557 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 120267 | 121558 | ||
| 120268 | #if SQLITE_USER_AUTHENTICATION | 121559 | #if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE) |
| 120269 | if( pParse->nTableLock>0 && db->init.busy==0 ){ | 121560 | if( pParse->nTableLock>0 && db->init.busy==0 ){ |
| 120270 | sqlite3UserAuthInit(db); | 121561 | sqlite3UserAuthInit(db); |
| 120271 | if( db->auth.authLevel<UAUTH_User ){ | 121562 | if( db->auth.authLevel<UAUTH_User ){ |
| @@ -120796,7 +122087,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr( | |||
| 120796 | */ | 122087 | */ |
| 120797 | SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ | 122088 | SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ |
| 120798 | if( pCol->iDflt==0 ) return 0; | 122089 | if( pCol->iDflt==0 ) return 0; |
| 120799 | if( NEVER(!IsOrdinaryTable(pTab)) ) return 0; | 122090 | if( !IsOrdinaryTable(pTab) ) return 0; |
| 120800 | if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; | 122091 | if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; |
| 120801 | if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0; | 122092 | if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0; |
| 120802 | return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; | 122093 | return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; |
| @@ -120949,6 +122240,9 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ | |||
| 120949 | if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; | 122240 | if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; |
| 120950 | deleteTable(db, pTable); | 122241 | deleteTable(db, pTable); |
| 120951 | } | 122242 | } |
| 122243 | SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ | ||
| 122244 | sqlite3DeleteTable(db, (Table*)pTable); | ||
| 122245 | } | ||
| 120952 | 122246 | ||
| 120953 | 122247 | ||
| 120954 | /* | 122248 | /* |
| @@ -121486,7 +122780,8 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ | |||
| 121486 | /* | 122780 | /* |
| 121487 | ** Clean up the data structures associated with the RETURNING clause. | 122781 | ** Clean up the data structures associated with the RETURNING clause. |
| 121488 | */ | 122782 | */ |
| 121489 | static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ | 122783 | static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ |
| 122784 | Returning *pRet = (Returning*)pArg; | ||
| 121490 | Hash *pHash; | 122785 | Hash *pHash; |
| 121491 | pHash = &(db->aDb[1].pSchema->trigHash); | 122786 | pHash = &(db->aDb[1].pSchema->trigHash); |
| 121492 | sqlite3HashInsert(pHash, pRet->zName, 0); | 122787 | sqlite3HashInsert(pHash, pRet->zName, 0); |
| @@ -121528,8 +122823,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ | |||
| 121528 | pParse->u1.pReturning = pRet; | 122823 | pParse->u1.pReturning = pRet; |
| 121529 | pRet->pParse = pParse; | 122824 | pRet->pParse = pParse; |
| 121530 | pRet->pReturnEL = pList; | 122825 | pRet->pReturnEL = pList; |
| 121531 | sqlite3ParserAddCleanup(pParse, | 122826 | sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); |
| 121532 | (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); | ||
| 121533 | testcase( pParse->earlyCleanup ); | 122827 | testcase( pParse->earlyCleanup ); |
| 121534 | if( db->mallocFailed ) return; | 122828 | if( db->mallocFailed ) return; |
| 121535 | sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, | 122829 | sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, |
| @@ -121728,7 +123022,8 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ | |||
| 121728 | 123022 | ||
| 121729 | assert( zIn!=0 ); | 123023 | assert( zIn!=0 ); |
| 121730 | while( zIn[0] ){ | 123024 | while( zIn[0] ){ |
| 121731 | h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; | 123025 | u8 x = *(u8*)zIn; |
| 123026 | h = (h<<8) + sqlite3UpperToLower[x]; | ||
| 121732 | zIn++; | 123027 | zIn++; |
| 121733 | if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ | 123028 | if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ |
| 121734 | aff = SQLITE_AFF_TEXT; | 123029 | aff = SQLITE_AFF_TEXT; |
| @@ -122900,20 +124195,20 @@ SQLITE_PRIVATE void sqlite3EndTable( | |||
| 122900 | int regRowid; /* Rowid of the next row to insert */ | 124195 | int regRowid; /* Rowid of the next row to insert */ |
| 122901 | int addrInsLoop; /* Top of the loop for inserting rows */ | 124196 | int addrInsLoop; /* Top of the loop for inserting rows */ |
| 122902 | Table *pSelTab; /* A table that describes the SELECT results */ | 124197 | Table *pSelTab; /* A table that describes the SELECT results */ |
| 124198 | int iCsr; /* Write cursor on the new table */ | ||
| 122903 | 124199 | ||
| 122904 | if( IN_SPECIAL_PARSE ){ | 124200 | if( IN_SPECIAL_PARSE ){ |
| 122905 | pParse->rc = SQLITE_ERROR; | 124201 | pParse->rc = SQLITE_ERROR; |
| 122906 | pParse->nErr++; | 124202 | pParse->nErr++; |
| 122907 | return; | 124203 | return; |
| 122908 | } | 124204 | } |
| 124205 | iCsr = pParse->nTab++; | ||
| 122909 | regYield = ++pParse->nMem; | 124206 | regYield = ++pParse->nMem; |
| 122910 | regRec = ++pParse->nMem; | 124207 | regRec = ++pParse->nMem; |
| 122911 | regRowid = ++pParse->nMem; | 124208 | regRowid = ++pParse->nMem; |
| 122912 | assert(pParse->nTab==1); | ||
| 122913 | sqlite3MayAbort(pParse); | 124209 | sqlite3MayAbort(pParse); |
| 122914 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); | 124210 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb); |
| 122915 | sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); | 124211 | sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); |
| 122916 | pParse->nTab = 2; | ||
| 122917 | addrTop = sqlite3VdbeCurrentAddr(v) + 1; | 124212 | addrTop = sqlite3VdbeCurrentAddr(v) + 1; |
| 122918 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); | 124213 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); |
| 122919 | if( pParse->nErr ) return; | 124214 | if( pParse->nErr ) return; |
| @@ -122934,11 +124229,11 @@ SQLITE_PRIVATE void sqlite3EndTable( | |||
| 122934 | VdbeCoverage(v); | 124229 | VdbeCoverage(v); |
| 122935 | sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); | 124230 | sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); |
| 122936 | sqlite3TableAffinity(v, p, 0); | 124231 | sqlite3TableAffinity(v, p, 0); |
| 122937 | sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); | 124232 | sqlite3VdbeAddOp2(v, OP_NewRowid, iCsr, regRowid); |
| 122938 | sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); | 124233 | sqlite3VdbeAddOp3(v, OP_Insert, iCsr, regRec, regRowid); |
| 122939 | sqlite3VdbeGoto(v, addrInsLoop); | 124234 | sqlite3VdbeGoto(v, addrInsLoop); |
| 122940 | sqlite3VdbeJumpHere(v, addrInsLoop); | 124235 | sqlite3VdbeJumpHere(v, addrInsLoop); |
| 122941 | sqlite3VdbeAddOp1(v, OP_Close, 1); | 124236 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); |
| 122942 | } | 124237 | } |
| 122943 | 124238 | ||
| 122944 | /* Compute the complete text of the CREATE statement */ | 124239 | /* Compute the complete text of the CREATE statement */ |
| @@ -122995,13 +124290,10 @@ SQLITE_PRIVATE void sqlite3EndTable( | |||
| 122995 | /* Test for cycles in generated columns and illegal expressions | 124290 | /* Test for cycles in generated columns and illegal expressions |
| 122996 | ** in CHECK constraints and in DEFAULT clauses. */ | 124291 | ** in CHECK constraints and in DEFAULT clauses. */ |
| 122997 | if( p->tabFlags & TF_HasGenerated ){ | 124292 | if( p->tabFlags & TF_HasGenerated ){ |
| 122998 | sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, | 124293 | sqlite3VdbeAddOp4(v, OP_SqlExec, 0x0001, 0, 0, |
| 122999 | sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", | 124294 | sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", |
| 123000 | db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); | 124295 | db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); |
| 123001 | } | 124296 | } |
| 123002 | sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, | ||
| 123003 | sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", | ||
| 123004 | db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); | ||
| 123005 | } | 124297 | } |
| 123006 | 124298 | ||
| 123007 | /* Add the table to the in-memory representation of the database. | 124299 | /* Add the table to the in-memory representation of the database. |
| @@ -123078,9 +124370,12 @@ SQLITE_PRIVATE void sqlite3CreateView( | |||
| 123078 | ** on a view, even though views do not have rowids. The following flag | 124370 | ** on a view, even though views do not have rowids. The following flag |
| 123079 | ** setting fixes this problem. But the fix can be disabled by compiling | 124371 | ** setting fixes this problem. But the fix can be disabled by compiling |
| 123080 | ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that | 124372 | ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that |
| 123081 | ** depend upon the old buggy behavior. */ | 124373 | ** depend upon the old buggy behavior. The ability can also be toggled |
| 123082 | #ifndef SQLITE_ALLOW_ROWID_IN_VIEW | 124374 | ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ |
| 123083 | p->tabFlags |= TF_NoVisibleRowid; | 124375 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW |
| 124376 | p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */ | ||
| 124377 | #else | ||
| 124378 | p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */ | ||
| 123084 | #endif | 124379 | #endif |
| 123085 | 124380 | ||
| 123086 | sqlite3TwoPartName(pParse, pName1, pName2, &pName); | 124381 | sqlite3TwoPartName(pParse, pName1, pName2, &pName); |
| @@ -123136,8 +124431,9 @@ create_view_fail: | |||
| 123136 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) | 124431 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) |
| 123137 | /* | 124432 | /* |
| 123138 | ** The Table structure pTable is really a VIEW. Fill in the names of | 124433 | ** The Table structure pTable is really a VIEW. Fill in the names of |
| 123139 | ** the columns of the view in the pTable structure. Return the number | 124434 | ** the columns of the view in the pTable structure. Return non-zero if |
| 123140 | ** of errors. If an error is seen leave an error message in pParse->zErrMsg. | 124435 | ** there are errors. If an error is seen an error message is left |
| 124436 | ** in pParse->zErrMsg. | ||
| 123141 | */ | 124437 | */ |
| 123142 | static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ | 124438 | static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ |
| 123143 | Table *pSelTab; /* A fake table from which we get the result set */ | 124439 | Table *pSelTab; /* A fake table from which we get the result set */ |
| @@ -123260,7 +124556,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ | |||
| 123260 | sqlite3DeleteColumnNames(db, pTable); | 124556 | sqlite3DeleteColumnNames(db, pTable); |
| 123261 | } | 124557 | } |
| 123262 | #endif /* SQLITE_OMIT_VIEW */ | 124558 | #endif /* SQLITE_OMIT_VIEW */ |
| 123263 | return nErr; | 124559 | return nErr + pParse->nErr; |
| 123264 | } | 124560 | } |
| 123265 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | 124561 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ |
| 123266 | assert( pTable!=0 ); | 124562 | assert( pTable!=0 ); |
| @@ -125593,7 +126889,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ | |||
| 125593 | if( iDb<0 ) return; | 126889 | if( iDb<0 ) return; |
| 125594 | z = sqlite3NameFromToken(db, pObjName); | 126890 | z = sqlite3NameFromToken(db, pObjName); |
| 125595 | if( z==0 ) return; | 126891 | if( z==0 ) return; |
| 125596 | zDb = db->aDb[iDb].zDbSName; | 126892 | zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; |
| 125597 | pTab = sqlite3FindTable(db, z, zDb); | 126893 | pTab = sqlite3FindTable(db, z, zDb); |
| 125598 | if( pTab ){ | 126894 | if( pTab ){ |
| 125599 | reindexTable(pParse, pTab, 0); | 126895 | reindexTable(pParse, pTab, 0); |
| @@ -125603,6 +126899,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ | |||
| 125603 | pIndex = sqlite3FindIndex(db, z, zDb); | 126899 | pIndex = sqlite3FindIndex(db, z, zDb); |
| 125604 | sqlite3DbFree(db, z); | 126900 | sqlite3DbFree(db, z); |
| 125605 | if( pIndex ){ | 126901 | if( pIndex ){ |
| 126902 | iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); | ||
| 125606 | sqlite3BeginWriteOperation(pParse, 0, iDb); | 126903 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 125607 | sqlite3RefillIndex(pParse, pIndex, -1); | 126904 | sqlite3RefillIndex(pParse, pIndex, -1); |
| 125608 | return; | 126905 | return; |
| @@ -125768,6 +127065,9 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ | |||
| 125768 | sqlite3DbFree(db, pWith); | 127065 | sqlite3DbFree(db, pWith); |
| 125769 | } | 127066 | } |
| 125770 | } | 127067 | } |
| 127068 | SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ | ||
| 127069 | sqlite3WithDelete(db, (With*)pWith); | ||
| 127070 | } | ||
| 125771 | #endif /* !defined(SQLITE_OMIT_CTE) */ | 127071 | #endif /* !defined(SQLITE_OMIT_CTE) */ |
| 125772 | 127072 | ||
| 125773 | /************** End of build.c ***********************************************/ | 127073 | /************** End of build.c ***********************************************/ |
| @@ -128449,13 +129749,13 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ | |||
| 128449 | double r1, r2; | 129749 | double r1, r2; |
| 128450 | const char *zVal; | 129750 | const char *zVal; |
| 128451 | r1 = sqlite3_value_double(pValue); | 129751 | r1 = sqlite3_value_double(pValue); |
| 128452 | sqlite3_str_appendf(pStr, "%!.15g", r1); | 129752 | sqlite3_str_appendf(pStr, "%!0.15g", r1); |
| 128453 | zVal = sqlite3_str_value(pStr); | 129753 | zVal = sqlite3_str_value(pStr); |
| 128454 | if( zVal ){ | 129754 | if( zVal ){ |
| 128455 | sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); | 129755 | sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); |
| 128456 | if( r1!=r2 ){ | 129756 | if( r1!=r2 ){ |
| 128457 | sqlite3_str_reset(pStr); | 129757 | sqlite3_str_reset(pStr); |
| 128458 | sqlite3_str_appendf(pStr, "%!.20e", r1); | 129758 | sqlite3_str_appendf(pStr, "%!0.20e", r1); |
| 128459 | } | 129759 | } |
| 128460 | } | 129760 | } |
| 128461 | break; | 129761 | break; |
| @@ -128757,7 +130057,7 @@ static void replaceFunc( | |||
| 128757 | } | 130057 | } |
| 128758 | if( zPattern[0]==0 ){ | 130058 | if( zPattern[0]==0 ){ |
| 128759 | assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); | 130059 | assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); |
| 128760 | sqlite3_result_value(context, argv[0]); | 130060 | sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT); |
| 128761 | return; | 130061 | return; |
| 128762 | } | 130062 | } |
| 128763 | nPattern = sqlite3_value_bytes(argv[1]); | 130063 | nPattern = sqlite3_value_bytes(argv[1]); |
| @@ -129240,7 +130540,7 @@ static void sumFinalize(sqlite3_context *context){ | |||
| 129240 | if( p->approx ){ | 130540 | if( p->approx ){ |
| 129241 | if( p->ovrfl ){ | 130541 | if( p->ovrfl ){ |
| 129242 | sqlite3_result_error(context,"integer overflow",-1); | 130542 | sqlite3_result_error(context,"integer overflow",-1); |
| 129243 | }else if( !sqlite3IsNaN(p->rErr) ){ | 130543 | }else if( !sqlite3IsOverflow(p->rErr) ){ |
| 129244 | sqlite3_result_double(context, p->rSum+p->rErr); | 130544 | sqlite3_result_double(context, p->rSum+p->rErr); |
| 129245 | }else{ | 130545 | }else{ |
| 129246 | sqlite3_result_double(context, p->rSum); | 130546 | sqlite3_result_double(context, p->rSum); |
| @@ -129257,7 +130557,7 @@ static void avgFinalize(sqlite3_context *context){ | |||
| 129257 | double r; | 130557 | double r; |
| 129258 | if( p->approx ){ | 130558 | if( p->approx ){ |
| 129259 | r = p->rSum; | 130559 | r = p->rSum; |
| 129260 | if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; | 130560 | if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; |
| 129261 | }else{ | 130561 | }else{ |
| 129262 | r = (double)(p->iSum); | 130562 | r = (double)(p->iSum); |
| 129263 | } | 130563 | } |
| @@ -129271,7 +130571,7 @@ static void totalFinalize(sqlite3_context *context){ | |||
| 129271 | if( p ){ | 130571 | if( p ){ |
| 129272 | if( p->approx ){ | 130572 | if( p->approx ){ |
| 129273 | r = p->rSum; | 130573 | r = p->rSum; |
| 129274 | if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; | 130574 | if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; |
| 129275 | }else{ | 130575 | }else{ |
| 129276 | r = (double)(p->iSum); | 130576 | r = (double)(p->iSum); |
| 129277 | } | 130577 | } |
| @@ -129554,6 +130854,8 @@ static void groupConcatValue(sqlite3_context *context){ | |||
| 129554 | sqlite3_result_error_toobig(context); | 130854 | sqlite3_result_error_toobig(context); |
| 129555 | }else if( pAccum->accError==SQLITE_NOMEM ){ | 130855 | }else if( pAccum->accError==SQLITE_NOMEM ){ |
| 129556 | sqlite3_result_error_nomem(context); | 130856 | sqlite3_result_error_nomem(context); |
| 130857 | }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ | ||
| 130858 | sqlite3_result_text(context, "", 1, SQLITE_STATIC); | ||
| 129557 | }else{ | 130859 | }else{ |
| 129558 | const char *zText = sqlite3_str_value(pAccum); | 130860 | const char *zText = sqlite3_str_value(pAccum); |
| 129559 | sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); | 130861 | sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); |
| @@ -132168,6 +133470,196 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ | |||
| 132168 | # define autoIncStep(A,B,C) | 133470 | # define autoIncStep(A,B,C) |
| 132169 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ | 133471 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 132170 | 133472 | ||
| 133473 | /* | ||
| 133474 | ** If argument pVal is a Select object returned by an sqlite3MultiValues() | ||
| 133475 | ** that was able to use the co-routine optimization, finish coding the | ||
| 133476 | ** co-routine. | ||
| 133477 | */ | ||
| 133478 | SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ | ||
| 133479 | if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ | ||
| 133480 | SrcItem *pItem = &pVal->pSrc->a[0]; | ||
| 133481 | sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn); | ||
| 133482 | sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1); | ||
| 133483 | } | ||
| 133484 | } | ||
| 133485 | |||
| 133486 | /* | ||
| 133487 | ** Return true if all expressions in the expression-list passed as the | ||
| 133488 | ** only argument are constant. | ||
| 133489 | */ | ||
| 133490 | static int exprListIsConstant(Parse *pParse, ExprList *pRow){ | ||
| 133491 | int ii; | ||
| 133492 | for(ii=0; ii<pRow->nExpr; ii++){ | ||
| 133493 | if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; | ||
| 133494 | } | ||
| 133495 | return 1; | ||
| 133496 | } | ||
| 133497 | |||
| 133498 | /* | ||
| 133499 | ** Return true if all expressions in the expression-list passed as the | ||
| 133500 | ** only argument are both constant and have no affinity. | ||
| 133501 | */ | ||
| 133502 | static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ | ||
| 133503 | int ii; | ||
| 133504 | if( exprListIsConstant(pParse,pRow)==0 ) return 0; | ||
| 133505 | for(ii=0; ii<pRow->nExpr; ii++){ | ||
| 133506 | Expr *pExpr = pRow->a[ii].pExpr; | ||
| 133507 | assert( pExpr->op!=TK_RAISE ); | ||
| 133508 | assert( pExpr->affExpr==0 ); | ||
| 133509 | if( 0!=sqlite3ExprAffinity(pExpr) ) return 0; | ||
| 133510 | } | ||
| 133511 | return 1; | ||
| 133512 | |||
| 133513 | } | ||
| 133514 | |||
| 133515 | /* | ||
| 133516 | ** This function is called by the parser for the second and subsequent | ||
| 133517 | ** rows of a multi-row VALUES clause. Argument pLeft is the part of | ||
| 133518 | ** the VALUES clause already parsed, argument pRow is the vector of values | ||
| 133519 | ** for the new row. The Select object returned represents the complete | ||
| 133520 | ** VALUES clause, including the new row. | ||
| 133521 | ** | ||
| 133522 | ** There are two ways in which this may be achieved - by incremental | ||
| 133523 | ** coding of a co-routine (the "co-routine" method) or by returning a | ||
| 133524 | ** Select object equivalent to the following (the "UNION ALL" method): | ||
| 133525 | ** | ||
| 133526 | ** "pLeft UNION ALL SELECT pRow" | ||
| 133527 | ** | ||
| 133528 | ** If the VALUES clause contains a lot of rows, this compound Select | ||
| 133529 | ** object may consume a lot of memory. | ||
| 133530 | ** | ||
| 133531 | ** When the co-routine method is used, each row that will be returned | ||
| 133532 | ** by the VALUES clause is coded into part of a co-routine as it is | ||
| 133533 | ** passed to this function. The returned Select object is equivalent to: | ||
| 133534 | ** | ||
| 133535 | ** SELECT * FROM ( | ||
| 133536 | ** Select object to read co-routine | ||
| 133537 | ** ) | ||
| 133538 | ** | ||
| 133539 | ** The co-routine method is used in most cases. Exceptions are: | ||
| 133540 | ** | ||
| 133541 | ** a) If the current statement has a WITH clause. This is to avoid | ||
| 133542 | ** statements like: | ||
| 133543 | ** | ||
| 133544 | ** WITH cte AS ( VALUES('x'), ('y') ... ) | ||
| 133545 | ** SELECT * FROM cte AS a, cte AS b; | ||
| 133546 | ** | ||
| 133547 | ** This will not work, as the co-routine uses a hard-coded register | ||
| 133548 | ** for its OP_Yield instructions, and so it is not possible for two | ||
| 133549 | ** cursors to iterate through it concurrently. | ||
| 133550 | ** | ||
| 133551 | ** b) The schema is currently being parsed (i.e. the VALUES clause is part | ||
| 133552 | ** of a schema item like a VIEW or TRIGGER). In this case there is no VM | ||
| 133553 | ** being generated when parsing is taking place, and so generating | ||
| 133554 | ** a co-routine is not possible. | ||
| 133555 | ** | ||
| 133556 | ** c) There are non-constant expressions in the VALUES clause (e.g. | ||
| 133557 | ** the VALUES clause is part of a correlated sub-query). | ||
| 133558 | ** | ||
| 133559 | ** d) One or more of the values in the first row of the VALUES clause | ||
| 133560 | ** has an affinity (i.e. is a CAST expression). This causes problems | ||
| 133561 | ** because the complex rules SQLite uses (see function | ||
| 133562 | ** sqlite3SubqueryColumnTypes() in select.c) to determine the effective | ||
| 133563 | ** affinity of such a column for all rows require access to all values in | ||
| 133564 | ** the column simultaneously. | ||
| 133565 | */ | ||
| 133566 | SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ | ||
| 133567 | |||
| 133568 | if( pParse->bHasWith /* condition (a) above */ | ||
| 133569 | || pParse->db->init.busy /* condition (b) above */ | ||
| 133570 | || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ | ||
| 133571 | || (pLeft->pSrc->nSrc==0 && | ||
| 133572 | exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ | ||
| 133573 | || IN_SPECIAL_PARSE | ||
| 133574 | ){ | ||
| 133575 | /* The co-routine method cannot be used. Fall back to UNION ALL. */ | ||
| 133576 | Select *pSelect = 0; | ||
| 133577 | int f = SF_Values | SF_MultiValue; | ||
| 133578 | if( pLeft->pSrc->nSrc ){ | ||
| 133579 | sqlite3MultiValuesEnd(pParse, pLeft); | ||
| 133580 | f = SF_Values; | ||
| 133581 | }else if( pLeft->pPrior ){ | ||
| 133582 | /* In this case set the SF_MultiValue flag only if it was set on pLeft */ | ||
| 133583 | f = (f & pLeft->selFlags); | ||
| 133584 | } | ||
| 133585 | pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); | ||
| 133586 | pLeft->selFlags &= ~SF_MultiValue; | ||
| 133587 | if( pSelect ){ | ||
| 133588 | pSelect->op = TK_ALL; | ||
| 133589 | pSelect->pPrior = pLeft; | ||
| 133590 | pLeft = pSelect; | ||
| 133591 | } | ||
| 133592 | }else{ | ||
| 133593 | SrcItem *p = 0; /* SrcItem that reads from co-routine */ | ||
| 133594 | |||
| 133595 | if( pLeft->pSrc->nSrc==0 ){ | ||
| 133596 | /* Co-routine has not yet been started and the special Select object | ||
| 133597 | ** that accesses the co-routine has not yet been created. This block | ||
| 133598 | ** does both those things. */ | ||
| 133599 | Vdbe *v = sqlite3GetVdbe(pParse); | ||
| 133600 | Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0); | ||
| 133601 | |||
| 133602 | /* Ensure the database schema has been read. This is to ensure we have | ||
| 133603 | ** the correct text encoding. */ | ||
| 133604 | if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ | ||
| 133605 | sqlite3ReadSchema(pParse); | ||
| 133606 | } | ||
| 133607 | |||
| 133608 | if( pRet ){ | ||
| 133609 | SelectDest dest; | ||
| 133610 | pRet->pSrc->nSrc = 1; | ||
| 133611 | pRet->pPrior = pLeft->pPrior; | ||
| 133612 | pRet->op = pLeft->op; | ||
| 133613 | if( pRet->pPrior ) pRet->selFlags |= SF_Values; | ||
| 133614 | pLeft->pPrior = 0; | ||
| 133615 | pLeft->op = TK_SELECT; | ||
| 133616 | assert( pLeft->pNext==0 ); | ||
| 133617 | assert( pRet->pNext==0 ); | ||
| 133618 | p = &pRet->pSrc->a[0]; | ||
| 133619 | p->pSelect = pLeft; | ||
| 133620 | p->fg.viaCoroutine = 1; | ||
| 133621 | p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; | ||
| 133622 | p->regReturn = ++pParse->nMem; | ||
| 133623 | p->iCursor = -1; | ||
| 133624 | p->u1.nRow = 2; | ||
| 133625 | sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub); | ||
| 133626 | sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn); | ||
| 133627 | |||
| 133628 | /* Allocate registers for the output of the co-routine. Do so so | ||
| 133629 | ** that there are two unused registers immediately before those | ||
| 133630 | ** used by the co-routine. This allows the code in sqlite3Insert() | ||
| 133631 | ** to use these registers directly, instead of copying the output | ||
| 133632 | ** of the co-routine to a separate array for processing. */ | ||
| 133633 | dest.iSdst = pParse->nMem + 3; | ||
| 133634 | dest.nSdst = pLeft->pEList->nExpr; | ||
| 133635 | pParse->nMem += 2 + dest.nSdst; | ||
| 133636 | |||
| 133637 | pLeft->selFlags |= SF_MultiValue; | ||
| 133638 | sqlite3Select(pParse, pLeft, &dest); | ||
| 133639 | p->regResult = dest.iSdst; | ||
| 133640 | assert( pParse->nErr || dest.iSdst>0 ); | ||
| 133641 | pLeft = pRet; | ||
| 133642 | } | ||
| 133643 | }else{ | ||
| 133644 | p = &pLeft->pSrc->a[0]; | ||
| 133645 | assert( !p->fg.isTabFunc && !p->fg.isIndexedBy ); | ||
| 133646 | p->u1.nRow++; | ||
| 133647 | } | ||
| 133648 | |||
| 133649 | if( pParse->nErr==0 ){ | ||
| 133650 | assert( p!=0 ); | ||
| 133651 | if( p->pSelect->pEList->nExpr!=pRow->nExpr ){ | ||
| 133652 | sqlite3SelectWrongNumTermsError(pParse, p->pSelect); | ||
| 133653 | }else{ | ||
| 133654 | sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0); | ||
| 133655 | sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn); | ||
| 133656 | } | ||
| 133657 | } | ||
| 133658 | sqlite3ExprListDelete(pParse->db, pRow); | ||
| 133659 | } | ||
| 133660 | |||
| 133661 | return pLeft; | ||
| 133662 | } | ||
| 132171 | 133663 | ||
| 132172 | /* Forward declaration */ | 133664 | /* Forward declaration */ |
| 132173 | static int xferOptimization( | 133665 | static int xferOptimization( |
| @@ -132504,25 +133996,40 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 132504 | if( pSelect ){ | 133996 | if( pSelect ){ |
| 132505 | /* Data is coming from a SELECT or from a multi-row VALUES clause. | 133997 | /* Data is coming from a SELECT or from a multi-row VALUES clause. |
| 132506 | ** Generate a co-routine to run the SELECT. */ | 133998 | ** Generate a co-routine to run the SELECT. */ |
| 132507 | int regYield; /* Register holding co-routine entry-point */ | ||
| 132508 | int addrTop; /* Top of the co-routine */ | ||
| 132509 | int rc; /* Result code */ | 133999 | int rc; /* Result code */ |
| 132510 | 134000 | ||
| 132511 | regYield = ++pParse->nMem; | 134001 | if( pSelect->pSrc->nSrc==1 |
| 132512 | addrTop = sqlite3VdbeCurrentAddr(v) + 1; | 134002 | && pSelect->pSrc->a[0].fg.viaCoroutine |
| 132513 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); | 134003 | && pSelect->pPrior==0 |
| 132514 | sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); | 134004 | ){ |
| 132515 | dest.iSdst = bIdListInOrder ? regData : 0; | 134005 | SrcItem *pItem = &pSelect->pSrc->a[0]; |
| 132516 | dest.nSdst = pTab->nCol; | 134006 | dest.iSDParm = pItem->regReturn; |
| 132517 | rc = sqlite3Select(pParse, pSelect, &dest); | 134007 | regFromSelect = pItem->regResult; |
| 132518 | regFromSelect = dest.iSdst; | 134008 | nColumn = pItem->pSelect->pEList->nExpr; |
| 132519 | assert( db->pParse==pParse ); | 134009 | ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); |
| 132520 | if( rc || pParse->nErr ) goto insert_cleanup; | 134010 | if( bIdListInOrder && nColumn==pTab->nCol ){ |
| 132521 | assert( db->mallocFailed==0 ); | 134011 | regData = regFromSelect; |
| 132522 | sqlite3VdbeEndCoroutine(v, regYield); | 134012 | regRowid = regData - 1; |
| 132523 | sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ | 134013 | regIns = regRowid - (IsVirtual(pTab) ? 1 : 0); |
| 132524 | assert( pSelect->pEList ); | 134014 | } |
| 132525 | nColumn = pSelect->pEList->nExpr; | 134015 | }else{ |
| 134016 | int addrTop; /* Top of the co-routine */ | ||
| 134017 | int regYield = ++pParse->nMem; | ||
| 134018 | addrTop = sqlite3VdbeCurrentAddr(v) + 1; | ||
| 134019 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); | ||
| 134020 | sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); | ||
| 134021 | dest.iSdst = bIdListInOrder ? regData : 0; | ||
| 134022 | dest.nSdst = pTab->nCol; | ||
| 134023 | rc = sqlite3Select(pParse, pSelect, &dest); | ||
| 134024 | regFromSelect = dest.iSdst; | ||
| 134025 | assert( db->pParse==pParse ); | ||
| 134026 | if( rc || pParse->nErr ) goto insert_cleanup; | ||
| 134027 | assert( db->mallocFailed==0 ); | ||
| 134028 | sqlite3VdbeEndCoroutine(v, regYield); | ||
| 134029 | sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ | ||
| 134030 | assert( pSelect->pEList ); | ||
| 134031 | nColumn = pSelect->pEList->nExpr; | ||
| 134032 | } | ||
| 132526 | 134033 | ||
| 132527 | /* Set useTempTable to TRUE if the result of the SELECT statement | 134034 | /* Set useTempTable to TRUE if the result of the SELECT statement |
| 132528 | ** should be written into a temporary table (template 4). Set to | 134035 | ** should be written into a temporary table (template 4). Set to |
| @@ -132677,7 +134184,7 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 132677 | pNx->iDataCur = iDataCur; | 134184 | pNx->iDataCur = iDataCur; |
| 132678 | pNx->iIdxCur = iIdxCur; | 134185 | pNx->iIdxCur = iIdxCur; |
| 132679 | if( pNx->pUpsertTarget ){ | 134186 | if( pNx->pUpsertTarget ){ |
| 132680 | if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){ | 134187 | if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){ |
| 132681 | goto insert_cleanup; | 134188 | goto insert_cleanup; |
| 132682 | } | 134189 | } |
| 132683 | } | 134190 | } |
| @@ -134569,7 +136076,10 @@ static int xferOptimization( | |||
| 134569 | } | 136076 | } |
| 134570 | } | 136077 | } |
| 134571 | #ifndef SQLITE_OMIT_CHECK | 136078 | #ifndef SQLITE_OMIT_CHECK |
| 134572 | if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ | 136079 | if( pDest->pCheck |
| 136080 | && (db->mDbFlags & DBFLAG_Vacuum)==0 | ||
| 136081 | && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) | ||
| 136082 | ){ | ||
| 134573 | return 0; /* Tables have different CHECK constraints. Ticket #2252 */ | 136083 | return 0; /* Tables have different CHECK constraints. Ticket #2252 */ |
| 134574 | } | 136084 | } |
| 134575 | #endif | 136085 | #endif |
| @@ -137245,6 +138755,34 @@ static const PragmaName aPragmaName[] = { | |||
| 137245 | /************** Continuing where we left off in pragma.c *********************/ | 138755 | /************** Continuing where we left off in pragma.c *********************/ |
| 137246 | 138756 | ||
| 137247 | /* | 138757 | /* |
| 138758 | ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands | ||
| 138759 | ** will be run with an analysis_limit set to the lessor of the value of | ||
| 138760 | ** the following macro or to the actual analysis_limit if it is non-zero, | ||
| 138761 | ** in order to prevent PRAGMA optimize from running for too long. | ||
| 138762 | ** | ||
| 138763 | ** The value of 2000 is chosen emperically so that the worst-case run-time | ||
| 138764 | ** for PRAGMA optimize does not exceed 100 milliseconds against a variety | ||
| 138765 | ** of test databases on a RaspberryPI-4 compiled using -Os and without | ||
| 138766 | ** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of | ||
| 138767 | ** this paragraph, "worst-case" means that ANALYZE ends up being | ||
| 138768 | ** run on every table in the database. The worst case typically only | ||
| 138769 | ** happens if PRAGMA optimize is run on a database file for which ANALYZE | ||
| 138770 | ** has not been previously run and the 0x10000 flag is included so that | ||
| 138771 | ** all tables are analyzed. The usual case for PRAGMA optimize is that | ||
| 138772 | ** no ANALYZE commands will be run at all, or if any ANALYZE happens it | ||
| 138773 | ** will be against a single table, so that expected timing for PRAGMA | ||
| 138774 | ** optimize on a PI-4 is more like 1 millisecond or less with the 0x10000 | ||
| 138775 | ** flag or less than 100 microseconds without the 0x10000 flag. | ||
| 138776 | ** | ||
| 138777 | ** An analysis limit of 2000 is almost always sufficient for the query | ||
| 138778 | ** planner to fully characterize an index. The additional accuracy from | ||
| 138779 | ** a larger analysis is not usually helpful. | ||
| 138780 | */ | ||
| 138781 | #ifndef SQLITE_DEFAULT_OPTIMIZE_LIMIT | ||
| 138782 | # define SQLITE_DEFAULT_OPTIMIZE_LIMIT 2000 | ||
| 138783 | #endif | ||
| 138784 | |||
| 138785 | /* | ||
| 137248 | ** Interpret the given string as a safety level. Return 0 for OFF, | 138786 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 137249 | ** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or | 138787 | ** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or |
| 137250 | ** unrecognized string argument. The FULL and EXTRA option is disallowed | 138788 | ** unrecognized string argument. The FULL and EXTRA option is disallowed |
| @@ -138889,7 +140427,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138889 | /* Set the maximum error count */ | 140427 | /* Set the maximum error count */ |
| 138890 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; | 140428 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; |
| 138891 | if( zRight ){ | 140429 | if( zRight ){ |
| 138892 | if( sqlite3GetInt32(zRight, &mxErr) ){ | 140430 | if( sqlite3GetInt32(pValue->z, &mxErr) ){ |
| 138893 | if( mxErr<=0 ){ | 140431 | if( mxErr<=0 ){ |
| 138894 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; | 140432 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; |
| 138895 | } | 140433 | } |
| @@ -138906,7 +140444,6 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138906 | Hash *pTbls; /* Set of all tables in the schema */ | 140444 | Hash *pTbls; /* Set of all tables in the schema */ |
| 138907 | int *aRoot; /* Array of root page numbers of all btrees */ | 140445 | int *aRoot; /* Array of root page numbers of all btrees */ |
| 138908 | int cnt = 0; /* Number of entries in aRoot[] */ | 140446 | int cnt = 0; /* Number of entries in aRoot[] */ |
| 138909 | int mxIdx = 0; /* Maximum number of indexes for any table */ | ||
| 138910 | 140447 | ||
| 138911 | if( OMIT_TEMPDB && i==1 ) continue; | 140448 | if( OMIT_TEMPDB && i==1 ) continue; |
| 138912 | if( iDb>=0 && i!=iDb ) continue; | 140449 | if( iDb>=0 && i!=iDb ) continue; |
| @@ -138928,7 +140465,6 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138928 | if( pObjTab && pObjTab!=pTab ) continue; | 140465 | if( pObjTab && pObjTab!=pTab ) continue; |
| 138929 | if( HasRowid(pTab) ) cnt++; | 140466 | if( HasRowid(pTab) ) cnt++; |
| 138930 | for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } | 140467 | for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } |
| 138931 | if( nIdx>mxIdx ) mxIdx = nIdx; | ||
| 138932 | } | 140468 | } |
| 138933 | if( cnt==0 ) continue; | 140469 | if( cnt==0 ) continue; |
| 138934 | if( pObjTab ) cnt++; | 140470 | if( pObjTab ) cnt++; |
| @@ -138948,11 +140484,11 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138948 | aRoot[0] = cnt; | 140484 | aRoot[0] = cnt; |
| 138949 | 140485 | ||
| 138950 | /* Make sure sufficient number of registers have been allocated */ | 140486 | /* Make sure sufficient number of registers have been allocated */ |
| 138951 | sqlite3TouchRegister(pParse, 8+mxIdx); | 140487 | sqlite3TouchRegister(pParse, 8+cnt); |
| 138952 | sqlite3ClearTempRegCache(pParse); | 140488 | sqlite3ClearTempRegCache(pParse); |
| 138953 | 140489 | ||
| 138954 | /* Do the b-tree integrity checks */ | 140490 | /* Do the b-tree integrity checks */ |
| 138955 | sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); | 140491 | sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); |
| 138956 | sqlite3VdbeChangeP5(v, (u8)i); | 140492 | sqlite3VdbeChangeP5(v, (u8)i); |
| 138957 | addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); | 140493 | addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); |
| 138958 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, | 140494 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| @@ -138962,6 +140498,36 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138962 | integrityCheckResultRow(v); | 140498 | integrityCheckResultRow(v); |
| 138963 | sqlite3VdbeJumpHere(v, addr); | 140499 | sqlite3VdbeJumpHere(v, addr); |
| 138964 | 140500 | ||
| 140501 | /* Check that the indexes all have the right number of rows */ | ||
| 140502 | cnt = pObjTab ? 1 : 0; | ||
| 140503 | sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); | ||
| 140504 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | ||
| 140505 | int iTab = 0; | ||
| 140506 | Table *pTab = sqliteHashData(x); | ||
| 140507 | Index *pIdx; | ||
| 140508 | if( pObjTab && pObjTab!=pTab ) continue; | ||
| 140509 | if( HasRowid(pTab) ){ | ||
| 140510 | iTab = cnt++; | ||
| 140511 | }else{ | ||
| 140512 | iTab = cnt; | ||
| 140513 | for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){ | ||
| 140514 | if( IsPrimaryKeyIndex(pIdx) ) break; | ||
| 140515 | iTab++; | ||
| 140516 | } | ||
| 140517 | } | ||
| 140518 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | ||
| 140519 | if( pIdx->pPartIdxWhere==0 ){ | ||
| 140520 | addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+cnt, 0, 8+iTab); | ||
| 140521 | VdbeCoverageNeverNull(v); | ||
| 140522 | sqlite3VdbeLoadString(v, 4, pIdx->zName); | ||
| 140523 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); | ||
| 140524 | integrityCheckResultRow(v); | ||
| 140525 | sqlite3VdbeJumpHere(v, addr); | ||
| 140526 | } | ||
| 140527 | cnt++; | ||
| 140528 | } | ||
| 140529 | } | ||
| 140530 | |||
| 138965 | /* Make sure all the indices are constructed correctly. | 140531 | /* Make sure all the indices are constructed correctly. |
| 138966 | */ | 140532 | */ |
| 138967 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | 140533 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
| @@ -138976,30 +140542,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 138976 | int mxCol; /* Maximum non-virtual column number */ | 140542 | int mxCol; /* Maximum non-virtual column number */ |
| 138977 | 140543 | ||
| 138978 | if( pObjTab && pObjTab!=pTab ) continue; | 140544 | if( pObjTab && pObjTab!=pTab ) continue; |
| 138979 | if( !IsOrdinaryTable(pTab) ){ | 140545 | if( !IsOrdinaryTable(pTab) ) continue; |
| 138980 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
| 138981 | sqlite3_vtab *pVTab; | ||
| 138982 | int a1; | ||
| 138983 | if( !IsVirtual(pTab) ) continue; | ||
| 138984 | if( pTab->nCol<=0 ){ | ||
| 138985 | const char *zMod = pTab->u.vtab.azArg[0]; | ||
| 138986 | if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; | ||
| 138987 | } | ||
| 138988 | sqlite3ViewGetColumnNames(pParse, pTab); | ||
| 138989 | if( pTab->u.vtab.p==0 ) continue; | ||
| 138990 | pVTab = pTab->u.vtab.p->pVtab; | ||
| 138991 | if( NEVER(pVTab==0) ) continue; | ||
| 138992 | if( NEVER(pVTab->pModule==0) ) continue; | ||
| 138993 | if( pVTab->pModule->iVersion<4 ) continue; | ||
| 138994 | if( pVTab->pModule->xIntegrity==0 ) continue; | ||
| 138995 | sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); | ||
| 138996 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); | ||
| 138997 | a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); | ||
| 138998 | integrityCheckResultRow(v); | ||
| 138999 | sqlite3VdbeJumpHere(v, a1); | ||
| 139000 | #endif | ||
| 139001 | continue; | ||
| 139002 | } | ||
| 139003 | if( isQuick || HasRowid(pTab) ){ | 140546 | if( isQuick || HasRowid(pTab) ){ |
| 139004 | pPk = 0; | 140547 | pPk = 0; |
| 139005 | r2 = 0; | 140548 | r2 = 0; |
| @@ -139134,6 +140677,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139134 | ** is REAL, we have to load the actual data using OP_Column | 140677 | ** is REAL, we have to load the actual data using OP_Column |
| 139135 | ** to reliably determine if the value is a NULL. */ | 140678 | ** to reliably determine if the value is a NULL. */ |
| 139136 | sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); | 140679 | sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); |
| 140680 | sqlite3ColumnDefault(v, pTab, j, 3); | ||
| 139137 | jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); | 140681 | jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); |
| 139138 | VdbeCoverage(v); | 140682 | VdbeCoverage(v); |
| 139139 | } | 140683 | } |
| @@ -139307,23 +140851,43 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139307 | } | 140851 | } |
| 139308 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); | 140852 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 139309 | sqlite3VdbeJumpHere(v, loopTop-1); | 140853 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 139310 | if( !isQuick ){ | 140854 | if( pPk ){ |
| 139311 | sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); | 140855 | assert( !isQuick ); |
| 139312 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | 140856 | sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); |
| 139313 | if( pPk==pIdx ) continue; | ||
| 139314 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); | ||
| 139315 | addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); | ||
| 139316 | sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); | ||
| 139317 | sqlite3VdbeLoadString(v, 4, pIdx->zName); | ||
| 139318 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); | ||
| 139319 | integrityCheckResultRow(v); | ||
| 139320 | sqlite3VdbeJumpHere(v, addr); | ||
| 139321 | } | ||
| 139322 | if( pPk ){ | ||
| 139323 | sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); | ||
| 139324 | } | ||
| 139325 | } | 140857 | } |
| 139326 | } | 140858 | } |
| 140859 | |||
| 140860 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
| 140861 | /* Second pass to invoke the xIntegrity method on all virtual | ||
| 140862 | ** tables. | ||
| 140863 | */ | ||
| 140864 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | ||
| 140865 | Table *pTab = sqliteHashData(x); | ||
| 140866 | sqlite3_vtab *pVTab; | ||
| 140867 | int a1; | ||
| 140868 | if( pObjTab && pObjTab!=pTab ) continue; | ||
| 140869 | if( IsOrdinaryTable(pTab) ) continue; | ||
| 140870 | if( !IsVirtual(pTab) ) continue; | ||
| 140871 | if( pTab->nCol<=0 ){ | ||
| 140872 | const char *zMod = pTab->u.vtab.azArg[0]; | ||
| 140873 | if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; | ||
| 140874 | } | ||
| 140875 | sqlite3ViewGetColumnNames(pParse, pTab); | ||
| 140876 | if( pTab->u.vtab.p==0 ) continue; | ||
| 140877 | pVTab = pTab->u.vtab.p->pVtab; | ||
| 140878 | if( NEVER(pVTab==0) ) continue; | ||
| 140879 | if( NEVER(pVTab->pModule==0) ) continue; | ||
| 140880 | if( pVTab->pModule->iVersion<4 ) continue; | ||
| 140881 | if( pVTab->pModule->xIntegrity==0 ) continue; | ||
| 140882 | sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); | ||
| 140883 | pTab->nTabRef++; | ||
| 140884 | sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); | ||
| 140885 | a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); | ||
| 140886 | integrityCheckResultRow(v); | ||
| 140887 | sqlite3VdbeJumpHere(v, a1); | ||
| 140888 | continue; | ||
| 140889 | } | ||
| 140890 | #endif | ||
| 139327 | } | 140891 | } |
| 139328 | { | 140892 | { |
| 139329 | static const int iLn = VDBE_OFFSET_LINENO(2); | 140893 | static const int iLn = VDBE_OFFSET_LINENO(2); |
| @@ -139587,44 +141151,63 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139587 | ** | 141151 | ** |
| 139588 | ** The optional argument is a bitmask of optimizations to perform: | 141152 | ** The optional argument is a bitmask of optimizations to perform: |
| 139589 | ** | 141153 | ** |
| 139590 | ** 0x0001 Debugging mode. Do not actually perform any optimizations | 141154 | ** 0x00001 Debugging mode. Do not actually perform any optimizations |
| 139591 | ** but instead return one line of text for each optimization | 141155 | ** but instead return one line of text for each optimization |
| 139592 | ** that would have been done. Off by default. | 141156 | ** that would have been done. Off by default. |
| 139593 | ** | 141157 | ** |
| 139594 | ** 0x0002 Run ANALYZE on tables that might benefit. On by default. | 141158 | ** 0x00002 Run ANALYZE on tables that might benefit. On by default. |
| 139595 | ** See below for additional information. | 141159 | ** See below for additional information. |
| 139596 | ** | 141160 | ** |
| 139597 | ** 0x0004 (Not yet implemented) Record usage and performance | 141161 | ** 0x00010 Run all ANALYZE operations using an analysis_limit that |
| 139598 | ** information from the current session in the | 141162 | ** is the lessor of the current analysis_limit and the |
| 139599 | ** database file so that it will be available to "optimize" | 141163 | ** SQLITE_DEFAULT_OPTIMIZE_LIMIT compile-time option. |
| 139600 | ** pragmas run by future database connections. | 141164 | ** The default value of SQLITE_DEFAULT_OPTIMIZE_LIMIT is |
| 141165 | ** currently (2024-02-19) set to 2000, which is such that | ||
| 141166 | ** the worst case run-time for PRAGMA optimize on a 100MB | ||
| 141167 | ** database will usually be less than 100 milliseconds on | ||
| 141168 | ** a RaspberryPI-4 class machine. On by default. | ||
| 139601 | ** | 141169 | ** |
| 139602 | ** 0x0008 (Not yet implemented) Create indexes that might have | 141170 | ** 0x10000 Look at tables to see if they need to be reanalyzed |
| 139603 | ** been helpful to recent queries | 141171 | ** due to growth or shrinkage even if they have not been |
| 141172 | ** queried during the current connection. Off by default. | ||
| 139604 | ** | 141173 | ** |
| 139605 | ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all | 141174 | ** The default MASK is and always shall be 0x0fffe. In the current |
| 139606 | ** of the optimizations listed above except Debug Mode, including new | 141175 | ** implementation, the default mask only covers the 0x00002 optimization, |
| 139607 | ** optimizations that have not yet been invented. If new optimizations are | 141176 | ** though additional optimizations that are covered by 0x0fffe might be |
| 139608 | ** ever added that should be off by default, those off-by-default | 141177 | ** added in the future. Optimizations that are off by default and must |
| 139609 | ** optimizations will have bitmasks of 0x10000 or larger. | 141178 | ** be explicitly requested have masks of 0x10000 or greater. |
| 139610 | ** | 141179 | ** |
| 139611 | ** DETERMINATION OF WHEN TO RUN ANALYZE | 141180 | ** DETERMINATION OF WHEN TO RUN ANALYZE |
| 139612 | ** | 141181 | ** |
| 139613 | ** In the current implementation, a table is analyzed if only if all of | 141182 | ** In the current implementation, a table is analyzed if only if all of |
| 139614 | ** the following are true: | 141183 | ** the following are true: |
| 139615 | ** | 141184 | ** |
| 139616 | ** (1) MASK bit 0x02 is set. | 141185 | ** (1) MASK bit 0x00002 is set. |
| 141186 | ** | ||
| 141187 | ** (2) The table is an ordinary table, not a virtual table or view. | ||
| 139617 | ** | 141188 | ** |
| 139618 | ** (2) The query planner used sqlite_stat1-style statistics for one or | 141189 | ** (3) The table name does not begin with "sqlite_". |
| 139619 | ** more indexes of the table at some point during the lifetime of | ||
| 139620 | ** the current connection. | ||
| 139621 | ** | 141190 | ** |
| 139622 | ** (3) One or more indexes of the table are currently unanalyzed OR | 141191 | ** (4) One or more of the following is true: |
| 139623 | ** the number of rows in the table has increased by 25 times or more | 141192 | ** (4a) The 0x10000 MASK bit is set. |
| 139624 | ** since the last time ANALYZE was run. | 141193 | ** (4b) One or more indexes on the table lacks an entry |
| 141194 | ** in the sqlite_stat1 table. | ||
| 141195 | ** (4c) The query planner used sqlite_stat1-style statistics for one | ||
| 141196 | ** or more indexes of the table at some point during the lifetime | ||
| 141197 | ** of the current connection. | ||
| 141198 | ** | ||
| 141199 | ** (5) One or more of the following is true: | ||
| 141200 | ** (5a) One or more indexes on the table lacks an entry | ||
| 141201 | ** in the sqlite_stat1 table. (Same as 4a) | ||
| 141202 | ** (5b) The number of rows in the table has increased or decreased by | ||
| 141203 | ** 10-fold. In other words, the current size of the table is | ||
| 141204 | ** 10 times larger than the size in sqlite_stat1 or else the | ||
| 141205 | ** current size is less than 1/10th the size in sqlite_stat1. | ||
| 139625 | ** | 141206 | ** |
| 139626 | ** The rules for when tables are analyzed are likely to change in | 141207 | ** The rules for when tables are analyzed are likely to change in |
| 139627 | ** future releases. | 141208 | ** future releases. Future versions of SQLite might accept a string |
| 141209 | ** literal argument to this pragma that contains a mnemonic description | ||
| 141210 | ** of the options rather than a bitmap. | ||
| 139628 | */ | 141211 | */ |
| 139629 | case PragTyp_OPTIMIZE: { | 141212 | case PragTyp_OPTIMIZE: { |
| 139630 | int iDbLast; /* Loop termination point for the schema loop */ | 141213 | int iDbLast; /* Loop termination point for the schema loop */ |
| @@ -139636,6 +141219,10 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139636 | LogEst szThreshold; /* Size threshold above which reanalysis needed */ | 141219 | LogEst szThreshold; /* Size threshold above which reanalysis needed */ |
| 139637 | char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ | 141220 | char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ |
| 139638 | u32 opMask; /* Mask of operations to perform */ | 141221 | u32 opMask; /* Mask of operations to perform */ |
| 141222 | int nLimit; /* Analysis limit to use */ | ||
| 141223 | int nCheck = 0; /* Number of tables to be optimized */ | ||
| 141224 | int nBtree = 0; /* Number of btrees to scan */ | ||
| 141225 | int nIndex; /* Number of indexes on the current table */ | ||
| 139639 | 141226 | ||
| 139640 | if( zRight ){ | 141227 | if( zRight ){ |
| 139641 | opMask = (u32)sqlite3Atoi(zRight); | 141228 | opMask = (u32)sqlite3Atoi(zRight); |
| @@ -139643,6 +141230,14 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139643 | }else{ | 141230 | }else{ |
| 139644 | opMask = 0xfffe; | 141231 | opMask = 0xfffe; |
| 139645 | } | 141232 | } |
| 141233 | if( (opMask & 0x10)==0 ){ | ||
| 141234 | nLimit = 0; | ||
| 141235 | }else if( db->nAnalysisLimit>0 | ||
| 141236 | && db->nAnalysisLimit<SQLITE_DEFAULT_OPTIMIZE_LIMIT ){ | ||
| 141237 | nLimit = 0; | ||
| 141238 | }else{ | ||
| 141239 | nLimit = SQLITE_DEFAULT_OPTIMIZE_LIMIT; | ||
| 141240 | } | ||
| 139646 | iTabCur = pParse->nTab++; | 141241 | iTabCur = pParse->nTab++; |
| 139647 | for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ | 141242 | for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ |
| 139648 | if( iDb==1 ) continue; | 141243 | if( iDb==1 ) continue; |
| @@ -139651,23 +141246,61 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139651 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ | 141246 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 139652 | pTab = (Table*)sqliteHashData(k); | 141247 | pTab = (Table*)sqliteHashData(k); |
| 139653 | 141248 | ||
| 139654 | /* If table pTab has not been used in a way that would benefit from | 141249 | /* This only works for ordinary tables */ |
| 139655 | ** having analysis statistics during the current session, then skip it. | 141250 | if( !IsOrdinaryTable(pTab) ) continue; |
| 139656 | ** This also has the effect of skipping virtual tables and views */ | ||
| 139657 | if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; | ||
| 139658 | 141251 | ||
| 139659 | /* Reanalyze if the table is 25 times larger than the last analysis */ | 141252 | /* Do not scan system tables */ |
| 139660 | szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); | 141253 | if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue; |
| 141254 | |||
| 141255 | /* Find the size of the table as last recorded in sqlite_stat1. | ||
| 141256 | ** If any index is unanalyzed, then the threshold is -1 to | ||
| 141257 | ** indicate a new, unanalyzed index | ||
| 141258 | */ | ||
| 141259 | szThreshold = pTab->nRowLogEst; | ||
| 141260 | nIndex = 0; | ||
| 139661 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 141261 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 141262 | nIndex++; | ||
| 139662 | if( !pIdx->hasStat1 ){ | 141263 | if( !pIdx->hasStat1 ){ |
| 139663 | szThreshold = 0; /* Always analyze if any index lacks statistics */ | 141264 | szThreshold = -1; /* Always analyze if any index lacks statistics */ |
| 139664 | break; | ||
| 139665 | } | 141265 | } |
| 139666 | } | 141266 | } |
| 139667 | if( szThreshold ){ | 141267 | |
| 139668 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); | 141268 | /* If table pTab has not been used in a way that would benefit from |
| 139669 | sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, | 141269 | ** having analysis statistics during the current session, then skip it, |
| 139670 | sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); | 141270 | ** unless the 0x10000 MASK bit is set. */ |
| 141271 | if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){ | ||
| 141272 | /* Check for size change if stat1 has been used for a query */ | ||
| 141273 | }else if( opMask & 0x10000 ){ | ||
| 141274 | /* Check for size change if 0x10000 is set */ | ||
| 141275 | }else if( pTab->pIndex!=0 && szThreshold<0 ){ | ||
| 141276 | /* Do analysis if unanalyzed indexes exists */ | ||
| 141277 | }else{ | ||
| 141278 | /* Otherwise, we can skip this table */ | ||
| 141279 | continue; | ||
| 141280 | } | ||
| 141281 | |||
| 141282 | nCheck++; | ||
| 141283 | if( nCheck==2 ){ | ||
| 141284 | /* If ANALYZE might be invoked two or more times, hold a write | ||
| 141285 | ** transaction for efficiency */ | ||
| 141286 | sqlite3BeginWriteOperation(pParse, 0, iDb); | ||
| 141287 | } | ||
| 141288 | nBtree += nIndex+1; | ||
| 141289 | |||
| 141290 | /* Reanalyze if the table is 10 times larger or smaller than | ||
| 141291 | ** the last analysis. Unconditional reanalysis if there are | ||
| 141292 | ** unanalyzed indexes. */ | ||
| 141293 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); | ||
| 141294 | if( szThreshold>=0 ){ | ||
| 141295 | const LogEst iRange = 33; /* 10x size change */ | ||
| 141296 | sqlite3VdbeAddOp4Int(v, OP_IfSizeBetween, iTabCur, | ||
| 141297 | sqlite3VdbeCurrentAddr(v)+2+(opMask&1), | ||
| 141298 | szThreshold>=iRange ? szThreshold-iRange : -1, | ||
| 141299 | szThreshold+iRange); | ||
| 141300 | VdbeCoverage(v); | ||
| 141301 | }else{ | ||
| 141302 | sqlite3VdbeAddOp2(v, OP_Rewind, iTabCur, | ||
| 141303 | sqlite3VdbeCurrentAddr(v)+2+(opMask&1)); | ||
| 139671 | VdbeCoverage(v); | 141304 | VdbeCoverage(v); |
| 139672 | } | 141305 | } |
| 139673 | zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", | 141306 | zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", |
| @@ -139677,11 +141310,27 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 139677 | sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); | 141310 | sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); |
| 139678 | sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); | 141311 | sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); |
| 139679 | }else{ | 141312 | }else{ |
| 139680 | sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); | 141313 | sqlite3VdbeAddOp4(v, OP_SqlExec, nLimit ? 0x02 : 00, nLimit, 0, |
| 141314 | zSubSql, P4_DYNAMIC); | ||
| 139681 | } | 141315 | } |
| 139682 | } | 141316 | } |
| 139683 | } | 141317 | } |
| 139684 | sqlite3VdbeAddOp0(v, OP_Expire); | 141318 | sqlite3VdbeAddOp0(v, OP_Expire); |
| 141319 | |||
| 141320 | /* In a schema with a large number of tables and indexes, scale back | ||
| 141321 | ** the analysis_limit to avoid excess run-time in the worst case. | ||
| 141322 | */ | ||
| 141323 | if( !db->mallocFailed && nLimit>0 && nBtree>100 ){ | ||
| 141324 | int iAddr, iEnd; | ||
| 141325 | VdbeOp *aOp; | ||
| 141326 | nLimit = 100*nLimit/nBtree; | ||
| 141327 | if( nLimit<100 ) nLimit = 100; | ||
| 141328 | aOp = sqlite3VdbeGetOp(v, 0); | ||
| 141329 | iEnd = sqlite3VdbeCurrentAddr(v); | ||
| 141330 | for(iAddr=0; iAddr<iEnd; iAddr++){ | ||
| 141331 | if( aOp[iAddr].opcode==OP_SqlExec ) aOp[iAddr].p2 = nLimit; | ||
| 141332 | } | ||
| 141333 | } | ||
| 139685 | break; | 141334 | break; |
| 139686 | } | 141335 | } |
| 139687 | 141336 | ||
| @@ -139945,9 +141594,9 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 139945 | seen[0] = 0; | 141594 | seen[0] = 0; |
| 139946 | seen[1] = 0; | 141595 | seen[1] = 0; |
| 139947 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ | 141596 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
| 139948 | if( pConstraint->usable==0 ) continue; | ||
| 139949 | if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; | ||
| 139950 | if( pConstraint->iColumn < pTab->iHidden ) continue; | 141597 | if( pConstraint->iColumn < pTab->iHidden ) continue; |
| 141598 | if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; | ||
| 141599 | if( pConstraint->usable==0 ) return SQLITE_CONSTRAINT; | ||
| 139951 | j = pConstraint->iColumn - pTab->iHidden; | 141600 | j = pConstraint->iColumn - pTab->iHidden; |
| 139952 | assert( j < 2 ); | 141601 | assert( j < 2 ); |
| 139953 | seen[j] = i+1; | 141602 | seen[j] = i+1; |
| @@ -139960,12 +141609,13 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 139960 | j = seen[0]-1; | 141609 | j = seen[0]-1; |
| 139961 | pIdxInfo->aConstraintUsage[j].argvIndex = 1; | 141610 | pIdxInfo->aConstraintUsage[j].argvIndex = 1; |
| 139962 | pIdxInfo->aConstraintUsage[j].omit = 1; | 141611 | pIdxInfo->aConstraintUsage[j].omit = 1; |
| 139963 | if( seen[1]==0 ) return SQLITE_OK; | ||
| 139964 | pIdxInfo->estimatedCost = (double)20; | 141612 | pIdxInfo->estimatedCost = (double)20; |
| 139965 | pIdxInfo->estimatedRows = 20; | 141613 | pIdxInfo->estimatedRows = 20; |
| 139966 | j = seen[1]-1; | 141614 | if( seen[1] ){ |
| 139967 | pIdxInfo->aConstraintUsage[j].argvIndex = 2; | 141615 | j = seen[1]-1; |
| 139968 | pIdxInfo->aConstraintUsage[j].omit = 1; | 141616 | pIdxInfo->aConstraintUsage[j].argvIndex = 2; |
| 141617 | pIdxInfo->aConstraintUsage[j].omit = 1; | ||
| 141618 | } | ||
| 139969 | return SQLITE_OK; | 141619 | return SQLITE_OK; |
| 139970 | } | 141620 | } |
| 139971 | 141621 | ||
| @@ -139985,6 +141635,7 @@ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ | |||
| 139985 | int i; | 141635 | int i; |
| 139986 | sqlite3_finalize(pCsr->pPragma); | 141636 | sqlite3_finalize(pCsr->pPragma); |
| 139987 | pCsr->pPragma = 0; | 141637 | pCsr->pPragma = 0; |
| 141638 | pCsr->iRowid = 0; | ||
| 139988 | for(i=0; i<ArraySize(pCsr->azArg); i++){ | 141639 | for(i=0; i<ArraySize(pCsr->azArg); i++){ |
| 139989 | sqlite3_free(pCsr->azArg[i]); | 141640 | sqlite3_free(pCsr->azArg[i]); |
| 139990 | pCsr->azArg[i] = 0; | 141641 | pCsr->azArg[i] = 0; |
| @@ -140785,7 +142436,13 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup( | |||
| 140785 | void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ | 142436 | void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ |
| 140786 | void *pPtr /* Pointer to object to be cleaned up */ | 142437 | void *pPtr /* Pointer to object to be cleaned up */ |
| 140787 | ){ | 142438 | ){ |
| 140788 | ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); | 142439 | ParseCleanup *pCleanup; |
| 142440 | if( sqlite3FaultSim(300) ){ | ||
| 142441 | pCleanup = 0; | ||
| 142442 | sqlite3OomFault(pParse->db); | ||
| 142443 | }else{ | ||
| 142444 | pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); | ||
| 142445 | } | ||
| 140789 | if( pCleanup ){ | 142446 | if( pCleanup ){ |
| 140790 | pCleanup->pNext = pParse->pCleanup; | 142447 | pCleanup->pNext = pParse->pCleanup; |
| 140791 | pParse->pCleanup = pCleanup; | 142448 | pParse->pCleanup = pCleanup; |
| @@ -141020,6 +142677,7 @@ static int sqlite3LockAndPrepare( | |||
| 141020 | assert( (rc&db->errMask)==rc ); | 142677 | assert( (rc&db->errMask)==rc ); |
| 141021 | db->busyHandler.nBusy = 0; | 142678 | db->busyHandler.nBusy = 0; |
| 141022 | sqlite3_mutex_leave(db->mutex); | 142679 | sqlite3_mutex_leave(db->mutex); |
| 142680 | assert( rc==SQLITE_OK || (*ppStmt)==0 ); | ||
| 141023 | return rc; | 142681 | return rc; |
| 141024 | } | 142682 | } |
| 141025 | 142683 | ||
| @@ -141417,6 +143075,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( | |||
| 141417 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ | 143075 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ |
| 141418 | if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); | 143076 | if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); |
| 141419 | } | 143077 | } |
| 143078 | SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ | ||
| 143079 | if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); | ||
| 143080 | } | ||
| 141420 | 143081 | ||
| 141421 | /* | 143082 | /* |
| 141422 | ** Return a pointer to the right-most SELECT statement in a compound. | 143083 | ** Return a pointer to the right-most SELECT statement in a compound. |
| @@ -142903,9 +144564,16 @@ static void generateSortTail( | |||
| 142903 | int addrExplain; /* Address of OP_Explain instruction */ | 144564 | int addrExplain; /* Address of OP_Explain instruction */ |
| 142904 | #endif | 144565 | #endif |
| 142905 | 144566 | ||
| 142906 | ExplainQueryPlan2(addrExplain, (pParse, 0, | 144567 | nKey = pOrderBy->nExpr - pSort->nOBSat; |
| 142907 | "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") | 144568 | if( pSort->nOBSat==0 || nKey==1 ){ |
| 142908 | ); | 144569 | ExplainQueryPlan2(addrExplain, (pParse, 0, |
| 144570 | "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat?"LAST TERM OF ":"" | ||
| 144571 | )); | ||
| 144572 | }else{ | ||
| 144573 | ExplainQueryPlan2(addrExplain, (pParse, 0, | ||
| 144574 | "USE TEMP B-TREE FOR LAST %d TERMS OF ORDER BY", nKey | ||
| 144575 | )); | ||
| 144576 | } | ||
| 142909 | sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); | 144577 | sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); |
| 142910 | sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); | 144578 | sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); |
| 142911 | 144579 | ||
| @@ -142943,7 +144611,6 @@ static void generateSortTail( | |||
| 142943 | regRow = sqlite3GetTempRange(pParse, nColumn); | 144611 | regRow = sqlite3GetTempRange(pParse, nColumn); |
| 142944 | } | 144612 | } |
| 142945 | } | 144613 | } |
| 142946 | nKey = pOrderBy->nExpr - pSort->nOBSat; | ||
| 142947 | if( pSort->sortFlags & SORTFLAG_UseSorter ){ | 144614 | if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 142948 | int regSortOut = ++pParse->nMem; | 144615 | int regSortOut = ++pParse->nMem; |
| 142949 | iSortTab = pParse->nTab++; | 144616 | iSortTab = pParse->nTab++; |
| @@ -143183,11 +144850,7 @@ static const char *columnTypeImpl( | |||
| 143183 | ** data for the result-set column of the sub-select. | 144850 | ** data for the result-set column of the sub-select. |
| 143184 | */ | 144851 | */ |
| 143185 | if( iCol<pS->pEList->nExpr | 144852 | if( iCol<pS->pEList->nExpr |
| 143186 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | 144853 | && (!ViewCanHaveRowid || iCol>=0) |
| 143187 | && iCol>=0 | ||
| 143188 | #else | ||
| 143189 | && ALWAYS(iCol>=0) | ||
| 143190 | #endif | ||
| 143191 | ){ | 144854 | ){ |
| 143192 | /* If iCol is less than zero, then the expression requests the | 144855 | /* If iCol is less than zero, then the expression requests the |
| 143193 | ** rowid of the sub-select or view. This expression is legal (see | 144856 | ** rowid of the sub-select or view. This expression is legal (see |
| @@ -143563,17 +145226,22 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( | |||
| 143563 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ | 145226 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ |
| 143564 | const char *zType; | 145227 | const char *zType; |
| 143565 | i64 n; | 145228 | i64 n; |
| 145229 | int m = 0; | ||
| 145230 | Select *pS2 = pSelect; | ||
| 143566 | pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); | 145231 | pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); |
| 143567 | p = a[i].pExpr; | 145232 | p = a[i].pExpr; |
| 143568 | /* pCol->szEst = ... // Column size est for SELECT tables never used */ | 145233 | /* pCol->szEst = ... // Column size est for SELECT tables never used */ |
| 143569 | pCol->affinity = sqlite3ExprAffinity(p); | 145234 | pCol->affinity = sqlite3ExprAffinity(p); |
| 145235 | while( pCol->affinity<=SQLITE_AFF_NONE && pS2->pNext!=0 ){ | ||
| 145236 | m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); | ||
| 145237 | pS2 = pS2->pNext; | ||
| 145238 | pCol->affinity = sqlite3ExprAffinity(pS2->pEList->a[i].pExpr); | ||
| 145239 | } | ||
| 143570 | if( pCol->affinity<=SQLITE_AFF_NONE ){ | 145240 | if( pCol->affinity<=SQLITE_AFF_NONE ){ |
| 143571 | pCol->affinity = aff; | 145241 | pCol->affinity = aff; |
| 143572 | } | 145242 | } |
| 143573 | if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ | 145243 | if( pCol->affinity>=SQLITE_AFF_TEXT && (pS2->pNext || pS2!=pSelect) ){ |
| 143574 | int m = 0; | 145244 | for(pS2=pS2->pNext; pS2; pS2=pS2->pNext){ |
| 143575 | Select *pS2; | ||
| 143576 | for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ | ||
| 143577 | m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); | 145245 | m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); |
| 143578 | } | 145246 | } |
| 143579 | if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ | 145247 | if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ |
| @@ -143603,12 +145271,12 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( | |||
| 143603 | } | 145271 | } |
| 143604 | } | 145272 | } |
| 143605 | if( zType ){ | 145273 | if( zType ){ |
| 143606 | i64 m = sqlite3Strlen30(zType); | 145274 | const i64 k = sqlite3Strlen30(zType); |
| 143607 | n = sqlite3Strlen30(pCol->zCnName); | 145275 | n = sqlite3Strlen30(pCol->zCnName); |
| 143608 | pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); | 145276 | pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); |
| 143609 | pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); | 145277 | pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); |
| 143610 | if( pCol->zCnName ){ | 145278 | if( pCol->zCnName ){ |
| 143611 | memcpy(&pCol->zCnName[n+1], zType, m+1); | 145279 | memcpy(&pCol->zCnName[n+1], zType, k+1); |
| 143612 | pCol->colFlags |= COLFLAG_HASTYPE; | 145280 | pCol->colFlags |= COLFLAG_HASTYPE; |
| 143613 | } | 145281 | } |
| 143614 | } | 145282 | } |
| @@ -144436,9 +146104,7 @@ multi_select_end: | |||
| 144436 | pDest->iSdst = dest.iSdst; | 146104 | pDest->iSdst = dest.iSdst; |
| 144437 | pDest->nSdst = dest.nSdst; | 146105 | pDest->nSdst = dest.nSdst; |
| 144438 | if( pDelete ){ | 146106 | if( pDelete ){ |
| 144439 | sqlite3ParserAddCleanup(pParse, | 146107 | sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); |
| 144440 | (void(*)(sqlite3*,void*))sqlite3SelectDelete, | ||
| 144441 | pDelete); | ||
| 144442 | } | 146108 | } |
| 144443 | return rc; | 146109 | return rc; |
| 144444 | } | 146110 | } |
| @@ -144989,8 +146655,7 @@ static int multiSelectOrderBy( | |||
| 144989 | /* Make arrangements to free the 2nd and subsequent arms of the compound | 146655 | /* Make arrangements to free the 2nd and subsequent arms of the compound |
| 144990 | ** after the parse has finished */ | 146656 | ** after the parse has finished */ |
| 144991 | if( pSplit->pPrior ){ | 146657 | if( pSplit->pPrior ){ |
| 144992 | sqlite3ParserAddCleanup(pParse, | 146658 | sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); |
| 144993 | (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); | ||
| 144994 | } | 146659 | } |
| 144995 | pSplit->pPrior = pPrior; | 146660 | pSplit->pPrior = pPrior; |
| 144996 | pPrior->pNext = pSplit; | 146661 | pPrior->pNext = pSplit; |
| @@ -145811,9 +147476,7 @@ static int flattenSubquery( | |||
| 145811 | Table *pTabToDel = pSubitem->pTab; | 147476 | Table *pTabToDel = pSubitem->pTab; |
| 145812 | if( pTabToDel->nTabRef==1 ){ | 147477 | if( pTabToDel->nTabRef==1 ){ |
| 145813 | Parse *pToplevel = sqlite3ParseToplevel(pParse); | 147478 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 145814 | sqlite3ParserAddCleanup(pToplevel, | 147479 | sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); |
| 145815 | (void(*)(sqlite3*,void*))sqlite3DeleteTable, | ||
| 145816 | pTabToDel); | ||
| 145817 | testcase( pToplevel->earlyCleanup ); | 147480 | testcase( pToplevel->earlyCleanup ); |
| 145818 | }else{ | 147481 | }else{ |
| 145819 | pTabToDel->nTabRef--; | 147482 | pTabToDel->nTabRef--; |
| @@ -146010,7 +147673,7 @@ static void constInsert( | |||
| 146010 | ){ | 147673 | ){ |
| 146011 | int i; | 147674 | int i; |
| 146012 | assert( pColumn->op==TK_COLUMN ); | 147675 | assert( pColumn->op==TK_COLUMN ); |
| 146013 | assert( sqlite3ExprIsConstant(pValue) ); | 147676 | assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); |
| 146014 | 147677 | ||
| 146015 | if( ExprHasProperty(pColumn, EP_FixedCol) ) return; | 147678 | if( ExprHasProperty(pColumn, EP_FixedCol) ) return; |
| 146016 | if( sqlite3ExprAffinity(pValue)!=0 ) return; | 147679 | if( sqlite3ExprAffinity(pValue)!=0 ) return; |
| @@ -146068,10 +147731,10 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ | |||
| 146068 | pLeft = pExpr->pLeft; | 147731 | pLeft = pExpr->pLeft; |
| 146069 | assert( pRight!=0 ); | 147732 | assert( pRight!=0 ); |
| 146070 | assert( pLeft!=0 ); | 147733 | assert( pLeft!=0 ); |
| 146071 | if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ | 147734 | if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){ |
| 146072 | constInsert(pConst,pRight,pLeft,pExpr); | 147735 | constInsert(pConst,pRight,pLeft,pExpr); |
| 146073 | } | 147736 | } |
| 146074 | if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ | 147737 | if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){ |
| 146075 | constInsert(pConst,pLeft,pRight,pExpr); | 147738 | constInsert(pConst,pLeft,pRight,pExpr); |
| 146076 | } | 147739 | } |
| 146077 | } | 147740 | } |
| @@ -146292,6 +147955,18 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ | |||
| 146292 | ** The hope is that the terms added to the inner query will make it more | 147955 | ** The hope is that the terms added to the inner query will make it more |
| 146293 | ** efficient. | 147956 | ** efficient. |
| 146294 | ** | 147957 | ** |
| 147958 | ** NAME AMBIGUITY | ||
| 147959 | ** | ||
| 147960 | ** This optimization is called the "WHERE-clause push-down optimization". | ||
| 147961 | ** | ||
| 147962 | ** Do not confuse this optimization with another unrelated optimization | ||
| 147963 | ** with a similar name: The "MySQL push-down optimization" causes WHERE | ||
| 147964 | ** clause terms that can be evaluated using only the index and without | ||
| 147965 | ** reference to the table are run first, so that if they are false, | ||
| 147966 | ** unnecessary table seeks are avoided. | ||
| 147967 | ** | ||
| 147968 | ** RULES | ||
| 147969 | ** | ||
| 146295 | ** Do not attempt this optimization if: | 147970 | ** Do not attempt this optimization if: |
| 146296 | ** | 147971 | ** |
| 146297 | ** (1) (** This restriction was removed on 2017-09-29. We used to | 147972 | ** (1) (** This restriction was removed on 2017-09-29. We used to |
| @@ -146357,15 +148032,19 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ | |||
| 146357 | ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING | 148032 | ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING |
| 146358 | ** clause and the subquery. | 148033 | ** clause and the subquery. |
| 146359 | ** | 148034 | ** |
| 146360 | ** Without this restriction, the push-down optimization might move | 148035 | ** Without this restriction, the WHERE-clause push-down optimization |
| 146361 | ** the ON/USING filter expression from the left side of a RIGHT JOIN | 148036 | ** might move the ON/USING filter expression from the left side of a |
| 146362 | ** over to the right side, which leads to incorrect answers. See | 148037 | ** RIGHT JOIN over to the right side, which leads to incorrect answers. |
| 146363 | ** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). | 148038 | ** See also restriction (6) in sqlite3ExprIsSingleTableConstraint(). |
| 146364 | ** | 148039 | ** |
| 146365 | ** (10) The inner query is not the right-hand table of a RIGHT JOIN. | 148040 | ** (10) The inner query is not the right-hand table of a RIGHT JOIN. |
| 146366 | ** | 148041 | ** |
| 146367 | ** (11) The subquery is not a VALUES clause | 148042 | ** (11) The subquery is not a VALUES clause |
| 146368 | ** | 148043 | ** |
| 148044 | ** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This | ||
| 148045 | ** case only comes up if SQLite is compiled using | ||
| 148046 | ** SQLITE_ALLOW_ROWID_IN_VIEW. | ||
| 148047 | ** | ||
| 146369 | ** Return 0 if no changes are made and non-zero if one or more WHERE clause | 148048 | ** Return 0 if no changes are made and non-zero if one or more WHERE clause |
| 146370 | ** terms are duplicated into the subquery. | 148049 | ** terms are duplicated into the subquery. |
| 146371 | */ | 148050 | */ |
| @@ -146476,7 +148155,19 @@ static int pushDownWhereTerms( | |||
| 146476 | } | 148155 | } |
| 146477 | #endif | 148156 | #endif |
| 146478 | 148157 | ||
| 146479 | if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ | 148158 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW |
| 148159 | if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){ | ||
| 148160 | Expr *pLeft = pWhere->pLeft; | ||
| 148161 | if( ALWAYS(pLeft) | ||
| 148162 | && pLeft->op==TK_COLUMN | ||
| 148163 | && pLeft->iColumn < 0 | ||
| 148164 | ){ | ||
| 148165 | return 0; /* Restriction (12) */ | ||
| 148166 | } | ||
| 148167 | } | ||
| 148168 | #endif | ||
| 148169 | |||
| 148170 | if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){ | ||
| 146480 | nChng++; | 148171 | nChng++; |
| 146481 | pSubq->selFlags |= SF_PushDown; | 148172 | pSubq->selFlags |= SF_PushDown; |
| 146482 | while( pSubq ){ | 148173 | while( pSubq ){ |
| @@ -146860,8 +148551,7 @@ static struct Cte *searchWith( | |||
| 146860 | SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ | 148551 | SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ |
| 146861 | if( pWith ){ | 148552 | if( pWith ){ |
| 146862 | if( bFree ){ | 148553 | if( bFree ){ |
| 146863 | pWith = (With*)sqlite3ParserAddCleanup(pParse, | 148554 | pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, |
| 146864 | (void(*)(sqlite3*,void*))sqlite3WithDelete, | ||
| 146865 | pWith); | 148555 | pWith); |
| 146866 | if( pWith==0 ) return 0; | 148556 | if( pWith==0 ) return 0; |
| 146867 | } | 148557 | } |
| @@ -147104,12 +148794,14 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ | |||
| 147104 | while( pSel->pPrior ){ pSel = pSel->pPrior; } | 148794 | while( pSel->pPrior ){ pSel = pSel->pPrior; } |
| 147105 | sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); | 148795 | sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); |
| 147106 | pTab->iPKey = -1; | 148796 | pTab->iPKey = -1; |
| 148797 | pTab->eTabType = TABTYP_VIEW; | ||
| 147107 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | 148798 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 147108 | #ifndef SQLITE_ALLOW_ROWID_IN_VIEW | 148799 | #ifndef SQLITE_ALLOW_ROWID_IN_VIEW |
| 147109 | /* The usual case - do not allow ROWID on a subquery */ | 148800 | /* The usual case - do not allow ROWID on a subquery */ |
| 147110 | pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; | 148801 | pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; |
| 147111 | #else | 148802 | #else |
| 147112 | pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ | 148803 | /* Legacy compatibility mode */ |
| 148804 | pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid; | ||
| 147113 | #endif | 148805 | #endif |
| 147114 | return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; | 148806 | return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; |
| 147115 | } | 148807 | } |
| @@ -147377,7 +149069,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 147377 | pNestedFrom = pFrom->pSelect->pEList; | 149069 | pNestedFrom = pFrom->pSelect->pEList; |
| 147378 | assert( pNestedFrom!=0 ); | 149070 | assert( pNestedFrom!=0 ); |
| 147379 | assert( pNestedFrom->nExpr==pTab->nCol ); | 149071 | assert( pNestedFrom->nExpr==pTab->nCol ); |
| 147380 | assert( VisibleRowid(pTab)==0 ); | 149072 | assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); |
| 147381 | }else{ | 149073 | }else{ |
| 147382 | if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ | 149074 | if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ |
| 147383 | continue; | 149075 | continue; |
| @@ -147409,7 +149101,8 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 147409 | pUsing = 0; | 149101 | pUsing = 0; |
| 147410 | } | 149102 | } |
| 147411 | 149103 | ||
| 147412 | nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); | 149104 | nAdd = pTab->nCol; |
| 149105 | if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++; | ||
| 147413 | for(j=0; j<nAdd; j++){ | 149106 | for(j=0; j<nAdd; j++){ |
| 147414 | const char *zName; | 149107 | const char *zName; |
| 147415 | struct ExprList_item *pX; /* Newly added ExprList term */ | 149108 | struct ExprList_item *pX; /* Newly added ExprList term */ |
| @@ -147491,7 +149184,8 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 147491 | pX = &pNew->a[pNew->nExpr-1]; | 149184 | pX = &pNew->a[pNew->nExpr-1]; |
| 147492 | assert( pX->zEName==0 ); | 149185 | assert( pX->zEName==0 ); |
| 147493 | if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ | 149186 | if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ |
| 147494 | if( pNestedFrom ){ | 149187 | if( pNestedFrom && (!ViewCanHaveRowid || j<pNestedFrom->nExpr) ){ |
| 149188 | assert( j<pNestedFrom->nExpr ); | ||
| 147495 | pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); | 149189 | pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); |
| 147496 | testcase( pX->zEName==0 ); | 149190 | testcase( pX->zEName==0 ); |
| 147497 | }else{ | 149191 | }else{ |
| @@ -147605,10 +149299,10 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ | |||
| 147605 | SrcList *pTabList; | 149299 | SrcList *pTabList; |
| 147606 | SrcItem *pFrom; | 149300 | SrcItem *pFrom; |
| 147607 | 149301 | ||
| 147608 | assert( p->selFlags & SF_Resolved ); | ||
| 147609 | if( p->selFlags & SF_HasTypeInfo ) return; | 149302 | if( p->selFlags & SF_HasTypeInfo ) return; |
| 147610 | p->selFlags |= SF_HasTypeInfo; | 149303 | p->selFlags |= SF_HasTypeInfo; |
| 147611 | pParse = pWalker->pParse; | 149304 | pParse = pWalker->pParse; |
| 149305 | assert( (p->selFlags & SF_Resolved) ); | ||
| 147612 | pTabList = p->pSrc; | 149306 | pTabList = p->pSrc; |
| 147613 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | 149307 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ |
| 147614 | Table *pTab = pFrom->pTab; | 149308 | Table *pTab = pFrom->pTab; |
| @@ -147678,6 +149372,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep( | |||
| 147678 | */ | 149372 | */ |
| 147679 | static void printAggInfo(AggInfo *pAggInfo){ | 149373 | static void printAggInfo(AggInfo *pAggInfo){ |
| 147680 | int ii; | 149374 | int ii; |
| 149375 | sqlite3DebugPrintf("AggInfo %d/%p:\n", | ||
| 149376 | pAggInfo->selId, pAggInfo); | ||
| 147681 | for(ii=0; ii<pAggInfo->nColumn; ii++){ | 149377 | for(ii=0; ii<pAggInfo->nColumn; ii++){ |
| 147682 | struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; | 149378 | struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; |
| 147683 | sqlite3DebugPrintf( | 149379 | sqlite3DebugPrintf( |
| @@ -147893,6 +149589,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ | |||
| 147893 | assert( pFunc->pFExpr->pLeft!=0 ); | 149589 | assert( pFunc->pFExpr->pLeft!=0 ); |
| 147894 | assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); | 149590 | assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); |
| 147895 | assert( ExprUseXList(pFunc->pFExpr->pLeft) ); | 149591 | assert( ExprUseXList(pFunc->pFExpr->pLeft) ); |
| 149592 | assert( pFunc->pFunc!=0 ); | ||
| 147896 | pOBList = pFunc->pFExpr->pLeft->x.pList; | 149593 | pOBList = pFunc->pFExpr->pLeft->x.pList; |
| 147897 | if( !pFunc->bOBUnique ){ | 149594 | if( !pFunc->bOBUnique ){ |
| 147898 | nExtra++; /* One extra column for the OP_Sequence */ | 149595 | nExtra++; /* One extra column for the OP_Sequence */ |
| @@ -147902,6 +149599,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ | |||
| 147902 | assert( ExprUseXList(pFunc->pFExpr) ); | 149599 | assert( ExprUseXList(pFunc->pFExpr) ); |
| 147903 | nExtra += pFunc->pFExpr->x.pList->nExpr; | 149600 | nExtra += pFunc->pFExpr->x.pList->nExpr; |
| 147904 | } | 149601 | } |
| 149602 | if( pFunc->bUseSubtype ){ | ||
| 149603 | nExtra += pFunc->pFExpr->x.pList->nExpr; | ||
| 149604 | } | ||
| 147905 | pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); | 149605 | pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); |
| 147906 | if( !pFunc->bOBUnique && pParse->nErr==0 ){ | 149606 | if( !pFunc->bOBUnique && pParse->nErr==0 ){ |
| 147907 | pKeyInfo->nKeyField++; | 149607 | pKeyInfo->nKeyField++; |
| @@ -147928,9 +149628,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ | |||
| 147928 | assert( ExprUseXList(pF->pFExpr) ); | 149628 | assert( ExprUseXList(pF->pFExpr) ); |
| 147929 | pList = pF->pFExpr->x.pList; | 149629 | pList = pF->pFExpr->x.pList; |
| 147930 | if( pF->iOBTab>=0 ){ | 149630 | if( pF->iOBTab>=0 ){ |
| 147931 | /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and | 149631 | /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs |
| 147932 | ** all content was stored in emphermal table pF->iOBTab. Extract that | 149632 | ** were stored in emphermal table pF->iOBTab. Here, we extract those |
| 147933 | ** content now (in ORDER BY order) and make all calls to OP_AggStep | 149633 | ** inputs (in ORDER BY order) and make all calls to OP_AggStep |
| 147934 | ** before doing the OP_AggFinal call. */ | 149634 | ** before doing the OP_AggFinal call. */ |
| 147935 | int iTop; /* Start of loop for extracting columns */ | 149635 | int iTop; /* Start of loop for extracting columns */ |
| 147936 | int nArg; /* Number of columns to extract */ | 149636 | int nArg; /* Number of columns to extract */ |
| @@ -147938,6 +149638,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ | |||
| 147938 | int regAgg; /* Extract into this array */ | 149638 | int regAgg; /* Extract into this array */ |
| 147939 | int j; /* Loop counter */ | 149639 | int j; /* Loop counter */ |
| 147940 | 149640 | ||
| 149641 | assert( pF->pFunc!=0 ); | ||
| 147941 | nArg = pList->nExpr; | 149642 | nArg = pList->nExpr; |
| 147942 | regAgg = sqlite3GetTempRange(pParse, nArg); | 149643 | regAgg = sqlite3GetTempRange(pParse, nArg); |
| 147943 | 149644 | ||
| @@ -147954,6 +149655,15 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ | |||
| 147954 | for(j=nArg-1; j>=0; j--){ | 149655 | for(j=nArg-1; j>=0; j--){ |
| 147955 | sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); | 149656 | sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); |
| 147956 | } | 149657 | } |
| 149658 | if( pF->bUseSubtype ){ | ||
| 149659 | int regSubtype = sqlite3GetTempReg(pParse); | ||
| 149660 | int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); | ||
| 149661 | for(j=nArg-1; j>=0; j--){ | ||
| 149662 | sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); | ||
| 149663 | sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); | ||
| 149664 | } | ||
| 149665 | sqlite3ReleaseTempReg(pParse, regSubtype); | ||
| 149666 | } | ||
| 147957 | sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); | 149667 | sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); |
| 147958 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); | 149668 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); |
| 147959 | sqlite3VdbeChangeP5(v, (u8)nArg); | 149669 | sqlite3VdbeChangeP5(v, (u8)nArg); |
| @@ -148008,6 +149718,7 @@ static void updateAccumulator( | |||
| 148008 | ExprList *pList; | 149718 | ExprList *pList; |
| 148009 | assert( ExprUseXList(pF->pFExpr) ); | 149719 | assert( ExprUseXList(pF->pFExpr) ); |
| 148010 | assert( !IsWindowFunc(pF->pFExpr) ); | 149720 | assert( !IsWindowFunc(pF->pFExpr) ); |
| 149721 | assert( pF->pFunc!=0 ); | ||
| 148011 | pList = pF->pFExpr->x.pList; | 149722 | pList = pF->pFExpr->x.pList; |
| 148012 | if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ | 149723 | if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ |
| 148013 | Expr *pFilter = pF->pFExpr->y.pWin->pFilter; | 149724 | Expr *pFilter = pF->pFExpr->y.pWin->pFilter; |
| @@ -148052,6 +149763,9 @@ static void updateAccumulator( | |||
| 148052 | if( pF->bOBPayload ){ | 149763 | if( pF->bOBPayload ){ |
| 148053 | regAggSz += nArg; | 149764 | regAggSz += nArg; |
| 148054 | } | 149765 | } |
| 149766 | if( pF->bUseSubtype ){ | ||
| 149767 | regAggSz += nArg; | ||
| 149768 | } | ||
| 148055 | regAggSz++; /* One extra register to hold result of MakeRecord */ | 149769 | regAggSz++; /* One extra register to hold result of MakeRecord */ |
| 148056 | regAgg = sqlite3GetTempRange(pParse, regAggSz); | 149770 | regAgg = sqlite3GetTempRange(pParse, regAggSz); |
| 148057 | regDistinct = regAgg; | 149771 | regDistinct = regAgg; |
| @@ -148064,6 +149778,14 @@ static void updateAccumulator( | |||
| 148064 | if( pF->bOBPayload ){ | 149778 | if( pF->bOBPayload ){ |
| 148065 | regDistinct = regAgg+jj; | 149779 | regDistinct = regAgg+jj; |
| 148066 | sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); | 149780 | sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); |
| 149781 | jj += nArg; | ||
| 149782 | } | ||
| 149783 | if( pF->bUseSubtype ){ | ||
| 149784 | int kk; | ||
| 149785 | int regBase = pF->bOBPayload ? regDistinct : regAgg; | ||
| 149786 | for(kk=0; kk<nArg; kk++, jj++){ | ||
| 149787 | sqlite3VdbeAddOp2(v, OP_GetSubtype, regBase+kk, regAgg+jj); | ||
| 149788 | } | ||
| 148067 | } | 149789 | } |
| 148068 | }else if( pList ){ | 149790 | }else if( pList ){ |
| 148069 | nArg = pList->nExpr; | 149791 | nArg = pList->nExpr; |
| @@ -148268,7 +149990,8 @@ static SrcItem *isSelfJoinView( | |||
| 148268 | /* | 149990 | /* |
| 148269 | ** Deallocate a single AggInfo object | 149991 | ** Deallocate a single AggInfo object |
| 148270 | */ | 149992 | */ |
| 148271 | static void agginfoFree(sqlite3 *db, AggInfo *p){ | 149993 | static void agginfoFree(sqlite3 *db, void *pArg){ |
| 149994 | AggInfo *p = (AggInfo*)pArg; | ||
| 148272 | sqlite3DbFree(db, p->aCol); | 149995 | sqlite3DbFree(db, p->aCol); |
| 148273 | sqlite3DbFree(db, p->aFunc); | 149996 | sqlite3DbFree(db, p->aFunc); |
| 148274 | sqlite3DbFreeNN(db, p); | 149997 | sqlite3DbFreeNN(db, p); |
| @@ -148342,7 +150065,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 148342 | pSub->selFlags |= SF_Aggregate; | 150065 | pSub->selFlags |= SF_Aggregate; |
| 148343 | pSub->selFlags &= ~SF_Compound; | 150066 | pSub->selFlags &= ~SF_Compound; |
| 148344 | pSub->nSelectRow = 0; | 150067 | pSub->nSelectRow = 0; |
| 148345 | sqlite3ExprListDelete(db, pSub->pEList); | 150068 | sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); |
| 148346 | pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; | 150069 | pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; |
| 148347 | pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); | 150070 | pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); |
| 148348 | pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); | 150071 | pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); |
| @@ -148522,9 +150245,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148522 | sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); | 150245 | sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); |
| 148523 | } | 150246 | } |
| 148524 | #endif | 150247 | #endif |
| 148525 | sqlite3ParserAddCleanup(pParse, | 150248 | sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, |
| 148526 | (void(*)(sqlite3*,void*))sqlite3ExprListDelete, | 150249 | p->pOrderBy); |
| 148527 | p->pOrderBy); | ||
| 148528 | testcase( pParse->earlyCleanup ); | 150250 | testcase( pParse->earlyCleanup ); |
| 148529 | p->pOrderBy = 0; | 150251 | p->pOrderBy = 0; |
| 148530 | } | 150252 | } |
| @@ -148630,6 +150352,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148630 | TREETRACE(0x1000,pParse,p, | 150352 | TREETRACE(0x1000,pParse,p, |
| 148631 | ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); | 150353 | ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); |
| 148632 | pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); | 150354 | pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); |
| 150355 | unsetJoinExpr(p->pWhere, pItem->iCursor, 0); | ||
| 148633 | } | 150356 | } |
| 148634 | } | 150357 | } |
| 148635 | if( pItem->fg.jointype & JT_LTORJ ){ | 150358 | if( pItem->fg.jointype & JT_LTORJ ){ |
| @@ -148644,17 +150367,15 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148644 | TREETRACE(0x1000,pParse,p, | 150367 | TREETRACE(0x1000,pParse,p, |
| 148645 | ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); | 150368 | ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); |
| 148646 | pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); | 150369 | pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); |
| 150370 | unsetJoinExpr(p->pWhere, pI2->iCursor, 1); | ||
| 148647 | } | 150371 | } |
| 148648 | } | 150372 | } |
| 148649 | } | 150373 | } |
| 148650 | for(j=pTabList->nSrc-1; j>=i; j--){ | 150374 | for(j=pTabList->nSrc-1; j>=0; j--){ |
| 148651 | pTabList->a[j].fg.jointype &= ~JT_LTORJ; | 150375 | pTabList->a[j].fg.jointype &= ~JT_LTORJ; |
| 148652 | if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; | 150376 | if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; |
| 148653 | } | 150377 | } |
| 148654 | } | 150378 | } |
| 148655 | assert( pItem->iCursor>=0 ); | ||
| 148656 | unsetJoinExpr(p->pWhere, pItem->iCursor, | ||
| 148657 | pTabList->a[0].fg.jointype & JT_LTORJ); | ||
| 148658 | } | 150379 | } |
| 148659 | 150380 | ||
| 148660 | /* No further action if this term of the FROM clause is not a subquery */ | 150381 | /* No further action if this term of the FROM clause is not a subquery */ |
| @@ -148717,9 +150438,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148717 | ){ | 150438 | ){ |
| 148718 | TREETRACE(0x800,pParse,p, | 150439 | TREETRACE(0x800,pParse,p, |
| 148719 | ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); | 150440 | ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); |
| 148720 | sqlite3ParserAddCleanup(pParse, | 150441 | sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, |
| 148721 | (void(*)(sqlite3*,void*))sqlite3ExprListDelete, | 150442 | pSub->pOrderBy); |
| 148722 | pSub->pOrderBy); | ||
| 148723 | pSub->pOrderBy = 0; | 150443 | pSub->pOrderBy = 0; |
| 148724 | } | 150444 | } |
| 148725 | 150445 | ||
| @@ -148844,7 +150564,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148844 | /* Generate code for all sub-queries in the FROM clause | 150564 | /* Generate code for all sub-queries in the FROM clause |
| 148845 | */ | 150565 | */ |
| 148846 | pSub = pItem->pSelect; | 150566 | pSub = pItem->pSelect; |
| 148847 | if( pSub==0 ) continue; | 150567 | if( pSub==0 || pItem->addrFillSub!=0 ) continue; |
| 148848 | 150568 | ||
| 148849 | /* The code for a subquery should only be generated once. */ | 150569 | /* The code for a subquery should only be generated once. */ |
| 148850 | assert( pItem->addrFillSub==0 ); | 150570 | assert( pItem->addrFillSub==0 ); |
| @@ -148875,7 +150595,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 148875 | #endif | 150595 | #endif |
| 148876 | assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); | 150596 | assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); |
| 148877 | }else{ | 150597 | }else{ |
| 148878 | TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); | 150598 | TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); |
| 148879 | } | 150599 | } |
| 148880 | 150600 | ||
| 148881 | /* Convert unused result columns of the subquery into simple NULL | 150601 | /* Convert unused result columns of the subquery into simple NULL |
| @@ -149248,8 +150968,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 149248 | */ | 150968 | */ |
| 149249 | pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); | 150969 | pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); |
| 149250 | if( pAggInfo ){ | 150970 | if( pAggInfo ){ |
| 149251 | sqlite3ParserAddCleanup(pParse, | 150971 | sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); |
| 149252 | (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); | ||
| 149253 | testcase( pParse->earlyCleanup ); | 150972 | testcase( pParse->earlyCleanup ); |
| 149254 | } | 150973 | } |
| 149255 | if( db->mallocFailed ){ | 150974 | if( db->mallocFailed ){ |
| @@ -149757,6 +151476,12 @@ select_end: | |||
| 149757 | sqlite3ExprListDelete(db, pMinMaxOrderBy); | 151476 | sqlite3ExprListDelete(db, pMinMaxOrderBy); |
| 149758 | #ifdef SQLITE_DEBUG | 151477 | #ifdef SQLITE_DEBUG |
| 149759 | if( pAggInfo && !db->mallocFailed ){ | 151478 | if( pAggInfo && !db->mallocFailed ){ |
| 151479 | #if TREETRACE_ENABLED | ||
| 151480 | if( sqlite3TreeTrace & 0x20 ){ | ||
| 151481 | TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); | ||
| 151482 | printAggInfo(pAggInfo); | ||
| 151483 | } | ||
| 151484 | #endif | ||
| 149760 | for(i=0; i<pAggInfo->nColumn; i++){ | 151485 | for(i=0; i<pAggInfo->nColumn; i++){ |
| 149761 | Expr *pExpr = pAggInfo->aCol[i].pCExpr; | 151486 | Expr *pExpr = pAggInfo->aCol[i].pCExpr; |
| 149762 | if( pExpr==0 ) continue; | 151487 | if( pExpr==0 ) continue; |
| @@ -150938,6 +152663,72 @@ static ExprList *sqlite3ExpandReturning( | |||
| 150938 | return pNew; | 152663 | return pNew; |
| 150939 | } | 152664 | } |
| 150940 | 152665 | ||
| 152666 | /* If the Expr node is a subquery or an EXISTS operator or an IN operator that | ||
| 152667 | ** uses a subquery, and if the subquery is SF_Correlated, then mark the | ||
| 152668 | ** expression as EP_VarSelect. | ||
| 152669 | */ | ||
| 152670 | static int sqlite3ReturningSubqueryVarSelect(Walker *NotUsed, Expr *pExpr){ | ||
| 152671 | UNUSED_PARAMETER(NotUsed); | ||
| 152672 | if( ExprUseXSelect(pExpr) | ||
| 152673 | && (pExpr->x.pSelect->selFlags & SF_Correlated)!=0 | ||
| 152674 | ){ | ||
| 152675 | testcase( ExprHasProperty(pExpr, EP_VarSelect) ); | ||
| 152676 | ExprSetProperty(pExpr, EP_VarSelect); | ||
| 152677 | } | ||
| 152678 | return WRC_Continue; | ||
| 152679 | } | ||
| 152680 | |||
| 152681 | |||
| 152682 | /* | ||
| 152683 | ** If the SELECT references the table pWalker->u.pTab, then do two things: | ||
| 152684 | ** | ||
| 152685 | ** (1) Mark the SELECT as as SF_Correlated. | ||
| 152686 | ** (2) Set pWalker->eCode to non-zero so that the caller will know | ||
| 152687 | ** that (1) has happened. | ||
| 152688 | */ | ||
| 152689 | static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ | ||
| 152690 | int i; | ||
| 152691 | SrcList *pSrc; | ||
| 152692 | assert( pSelect!=0 ); | ||
| 152693 | pSrc = pSelect->pSrc; | ||
| 152694 | assert( pSrc!=0 ); | ||
| 152695 | for(i=0; i<pSrc->nSrc; i++){ | ||
| 152696 | if( pSrc->a[i].pTab==pWalker->u.pTab ){ | ||
| 152697 | testcase( pSelect->selFlags & SF_Correlated ); | ||
| 152698 | pSelect->selFlags |= SF_Correlated; | ||
| 152699 | pWalker->eCode = 1; | ||
| 152700 | break; | ||
| 152701 | } | ||
| 152702 | } | ||
| 152703 | return WRC_Continue; | ||
| 152704 | } | ||
| 152705 | |||
| 152706 | /* | ||
| 152707 | ** Scan the expression list that is the argument to RETURNING looking | ||
| 152708 | ** for subqueries that depend on the table which is being modified in the | ||
| 152709 | ** statement that is hosting the RETURNING clause (pTab). Mark all such | ||
| 152710 | ** subqueries as SF_Correlated. If the subqueries are part of an | ||
| 152711 | ** expression, mark the expression as EP_VarSelect. | ||
| 152712 | ** | ||
| 152713 | ** https://sqlite.org/forum/forumpost/2c83569ce8945d39 | ||
| 152714 | */ | ||
| 152715 | static void sqlite3ProcessReturningSubqueries( | ||
| 152716 | ExprList *pEList, | ||
| 152717 | Table *pTab | ||
| 152718 | ){ | ||
| 152719 | Walker w; | ||
| 152720 | memset(&w, 0, sizeof(w)); | ||
| 152721 | w.xExprCallback = sqlite3ExprWalkNoop; | ||
| 152722 | w.xSelectCallback = sqlite3ReturningSubqueryCorrelated; | ||
| 152723 | w.u.pTab = pTab; | ||
| 152724 | sqlite3WalkExprList(&w, pEList); | ||
| 152725 | if( w.eCode ){ | ||
| 152726 | w.xExprCallback = sqlite3ReturningSubqueryVarSelect; | ||
| 152727 | w.xSelectCallback = sqlite3SelectWalkNoop; | ||
| 152728 | sqlite3WalkExprList(&w, pEList); | ||
| 152729 | } | ||
| 152730 | } | ||
| 152731 | |||
| 150941 | /* | 152732 | /* |
| 150942 | ** Generate code for the RETURNING trigger. Unlike other triggers | 152733 | ** Generate code for the RETURNING trigger. Unlike other triggers |
| 150943 | ** that invoke a subprogram in the bytecode, the code for RETURNING | 152734 | ** that invoke a subprogram in the bytecode, the code for RETURNING |
| @@ -150974,6 +152765,7 @@ static void codeReturningTrigger( | |||
| 150974 | sSelect.pSrc = &sFrom; | 152765 | sSelect.pSrc = &sFrom; |
| 150975 | sFrom.nSrc = 1; | 152766 | sFrom.nSrc = 1; |
| 150976 | sFrom.a[0].pTab = pTab; | 152767 | sFrom.a[0].pTab = pTab; |
| 152768 | sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ | ||
| 150977 | sFrom.a[0].iCursor = -1; | 152769 | sFrom.a[0].iCursor = -1; |
| 150978 | sqlite3SelectPrep(pParse, &sSelect, 0); | 152770 | sqlite3SelectPrep(pParse, &sSelect, 0); |
| 150979 | if( pParse->nErr==0 ){ | 152771 | if( pParse->nErr==0 ){ |
| @@ -151000,6 +152792,7 @@ static void codeReturningTrigger( | |||
| 151000 | int i; | 152792 | int i; |
| 151001 | int nCol = pNew->nExpr; | 152793 | int nCol = pNew->nExpr; |
| 151002 | int reg = pParse->nMem+1; | 152794 | int reg = pParse->nMem+1; |
| 152795 | sqlite3ProcessReturningSubqueries(pNew, pTab); | ||
| 151003 | pParse->nMem += nCol+2; | 152796 | pParse->nMem += nCol+2; |
| 151004 | pReturning->iRetReg = reg; | 152797 | pReturning->iRetReg = reg; |
| 151005 | for(i=0; i<nCol; i++){ | 152798 | for(i=0; i<nCol; i++){ |
| @@ -152401,6 +154194,9 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 152401 | } | 154194 | } |
| 152402 | } | 154195 | } |
| 152403 | if( chngRowid==0 && pPk==0 ){ | 154196 | if( chngRowid==0 && pPk==0 ){ |
| 154197 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 154198 | if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); | ||
| 154199 | #endif | ||
| 152404 | sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); | 154200 | sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); |
| 152405 | } | 154201 | } |
| 152406 | } | 154202 | } |
| @@ -152938,7 +154734,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew( | |||
| 152938 | SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | 154734 | SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( |
| 152939 | Parse *pParse, /* The parsing context */ | 154735 | Parse *pParse, /* The parsing context */ |
| 152940 | SrcList *pTabList, /* Table into which we are inserting */ | 154736 | SrcList *pTabList, /* Table into which we are inserting */ |
| 152941 | Upsert *pUpsert /* The ON CONFLICT clauses */ | 154737 | Upsert *pUpsert, /* The ON CONFLICT clauses */ |
| 154738 | Upsert *pAll /* Complete list of all ON CONFLICT clauses */ | ||
| 152942 | ){ | 154739 | ){ |
| 152943 | Table *pTab; /* That table into which we are inserting */ | 154740 | Table *pTab; /* That table into which we are inserting */ |
| 152944 | int rc; /* Result code */ | 154741 | int rc; /* Result code */ |
| @@ -153041,6 +154838,14 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | |||
| 153041 | continue; | 154838 | continue; |
| 153042 | } | 154839 | } |
| 153043 | pUpsert->pUpsertIdx = pIdx; | 154840 | pUpsert->pUpsertIdx = pIdx; |
| 154841 | if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ | ||
| 154842 | /* Really this should be an error. The isDup ON CONFLICT clause will | ||
| 154843 | ** never fire. But this problem was not discovered until three years | ||
| 154844 | ** after multi-CONFLICT upsert was added, and so we silently ignore | ||
| 154845 | ** the problem to prevent breaking applications that might actually | ||
| 154846 | ** have redundant ON CONFLICT clauses. */ | ||
| 154847 | pUpsert->isDup = 1; | ||
| 154848 | } | ||
| 153044 | break; | 154849 | break; |
| 153045 | } | 154850 | } |
| 153046 | if( pUpsert->pUpsertIdx==0 ){ | 154851 | if( pUpsert->pUpsertIdx==0 ){ |
| @@ -153067,9 +154872,13 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ | |||
| 153067 | Upsert *pNext; | 154872 | Upsert *pNext; |
| 153068 | if( NEVER(pUpsert==0) ) return 0; | 154873 | if( NEVER(pUpsert==0) ) return 0; |
| 153069 | pNext = pUpsert->pNextUpsert; | 154874 | pNext = pUpsert->pNextUpsert; |
| 153070 | if( pNext==0 ) return 1; | 154875 | while( 1 /*exit-by-return*/ ){ |
| 153071 | if( pNext->pUpsertTarget==0 ) return 1; | 154876 | if( pNext==0 ) return 1; |
| 153072 | if( pNext->pUpsertIdx==0 ) return 1; | 154877 | if( pNext->pUpsertTarget==0 ) return 1; |
| 154878 | if( pNext->pUpsertIdx==0 ) return 1; | ||
| 154879 | if( !pNext->isDup ) return 0; | ||
| 154880 | pNext = pNext->pNextUpsert; | ||
| 154881 | } | ||
| 153073 | return 0; | 154882 | return 0; |
| 153074 | } | 154883 | } |
| 153075 | 154884 | ||
| @@ -153898,7 +155707,6 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ | |||
| 153898 | 155707 | ||
| 153899 | if( p ){ | 155708 | if( p ){ |
| 153900 | db->pDisconnect = 0; | 155709 | db->pDisconnect = 0; |
| 153901 | sqlite3ExpirePreparedStatements(db, 0); | ||
| 153902 | do { | 155710 | do { |
| 153903 | VTable *pNext = p->pNext; | 155711 | VTable *pNext = p->pNext; |
| 153904 | sqlite3VtabUnlock(p); | 155712 | sqlite3VtabUnlock(p); |
| @@ -154195,6 +156003,8 @@ static int vtabCallConstructor( | |||
| 154195 | db->pVtabCtx = &sCtx; | 156003 | db->pVtabCtx = &sCtx; |
| 154196 | pTab->nTabRef++; | 156004 | pTab->nTabRef++; |
| 154197 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); | 156005 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); |
| 156006 | assert( pTab!=0 ); | ||
| 156007 | assert( pTab->nTabRef>1 || rc!=SQLITE_OK ); | ||
| 154198 | sqlite3DeleteTable(db, pTab); | 156008 | sqlite3DeleteTable(db, pTab); |
| 154199 | db->pVtabCtx = sCtx.pPrior; | 156009 | db->pVtabCtx = sCtx.pPrior; |
| 154200 | if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); | 156010 | if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); |
| @@ -154217,7 +156027,7 @@ static int vtabCallConstructor( | |||
| 154217 | pVTable->nRef = 1; | 156027 | pVTable->nRef = 1; |
| 154218 | if( sCtx.bDeclared==0 ){ | 156028 | if( sCtx.bDeclared==0 ){ |
| 154219 | const char *zFormat = "vtable constructor did not declare schema: %s"; | 156029 | const char *zFormat = "vtable constructor did not declare schema: %s"; |
| 154220 | *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); | 156030 | *pzErr = sqlite3MPrintf(db, zFormat, zModuleName); |
| 154221 | sqlite3VtabUnlock(pVTable); | 156031 | sqlite3VtabUnlock(pVTable); |
| 154222 | rc = SQLITE_ERROR; | 156032 | rc = SQLITE_ERROR; |
| 154223 | }else{ | 156033 | }else{ |
| @@ -154395,12 +156205,30 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ | |||
| 154395 | Table *pTab; | 156205 | Table *pTab; |
| 154396 | Parse sParse; | 156206 | Parse sParse; |
| 154397 | int initBusy; | 156207 | int initBusy; |
| 156208 | int i; | ||
| 156209 | const unsigned char *z; | ||
| 156210 | static const u8 aKeyword[] = { TK_CREATE, TK_TABLE, 0 }; | ||
| 154398 | 156211 | ||
| 154399 | #ifdef SQLITE_ENABLE_API_ARMOR | 156212 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 154400 | if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ | 156213 | if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ |
| 154401 | return SQLITE_MISUSE_BKPT; | 156214 | return SQLITE_MISUSE_BKPT; |
| 154402 | } | 156215 | } |
| 154403 | #endif | 156216 | #endif |
| 156217 | |||
| 156218 | /* Verify that the first two keywords in the CREATE TABLE statement | ||
| 156219 | ** really are "CREATE" and "TABLE". If this is not the case, then | ||
| 156220 | ** sqlite3_declare_vtab() is being misused. | ||
| 156221 | */ | ||
| 156222 | z = (const unsigned char*)zCreateTable; | ||
| 156223 | for(i=0; aKeyword[i]; i++){ | ||
| 156224 | int tokenType = 0; | ||
| 156225 | do{ z += sqlite3GetToken(z, &tokenType); }while( tokenType==TK_SPACE ); | ||
| 156226 | if( tokenType!=aKeyword[i] ){ | ||
| 156227 | sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error"); | ||
| 156228 | return SQLITE_ERROR; | ||
| 156229 | } | ||
| 156230 | } | ||
| 156231 | |||
| 154404 | sqlite3_mutex_enter(db->mutex); | 156232 | sqlite3_mutex_enter(db->mutex); |
| 154405 | pCtx = db->pVtabCtx; | 156233 | pCtx = db->pVtabCtx; |
| 154406 | if( !pCtx || pCtx->bDeclared ){ | 156234 | if( !pCtx || pCtx->bDeclared ){ |
| @@ -154408,6 +156236,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ | |||
| 154408 | sqlite3_mutex_leave(db->mutex); | 156236 | sqlite3_mutex_leave(db->mutex); |
| 154409 | return SQLITE_MISUSE_BKPT; | 156237 | return SQLITE_MISUSE_BKPT; |
| 154410 | } | 156238 | } |
| 156239 | |||
| 154411 | pTab = pCtx->pTab; | 156240 | pTab = pCtx->pTab; |
| 154412 | assert( IsVirtual(pTab) ); | 156241 | assert( IsVirtual(pTab) ); |
| 154413 | 156242 | ||
| @@ -154421,11 +156250,10 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ | |||
| 154421 | initBusy = db->init.busy; | 156250 | initBusy = db->init.busy; |
| 154422 | db->init.busy = 0; | 156251 | db->init.busy = 0; |
| 154423 | sParse.nQueryLoop = 1; | 156252 | sParse.nQueryLoop = 1; |
| 154424 | if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) | 156253 | if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) ){ |
| 154425 | && ALWAYS(sParse.pNewTable!=0) | 156254 | assert( sParse.pNewTable!=0 ); |
| 154426 | && ALWAYS(!db->mallocFailed) | 156255 | assert( !db->mallocFailed ); |
| 154427 | && IsOrdinaryTable(sParse.pNewTable) | 156256 | assert( IsOrdinaryTable(sParse.pNewTable) ); |
| 154428 | ){ | ||
| 154429 | assert( sParse.zErrMsg==0 ); | 156257 | assert( sParse.zErrMsg==0 ); |
| 154430 | if( !pTab->aCol ){ | 156258 | if( !pTab->aCol ){ |
| 154431 | Table *pNew = sParse.pNewTable; | 156259 | Table *pNew = sParse.pNewTable; |
| @@ -155464,7 +157292,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); | |||
| 155464 | #ifdef WHERETRACE_ENABLED | 157292 | #ifdef WHERETRACE_ENABLED |
| 155465 | SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); | 157293 | SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); |
| 155466 | SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); | 157294 | SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); |
| 155467 | SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); | 157295 | SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); |
| 155468 | #endif | 157296 | #endif |
| 155469 | SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( | 157297 | SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( |
| 155470 | WhereClause *pWC, /* The WHERE clause to be searched */ | 157298 | WhereClause *pWC, /* The WHERE clause to be searched */ |
| @@ -156921,6 +158749,27 @@ static SQLITE_NOINLINE void filterPullDown( | |||
| 156921 | } | 158749 | } |
| 156922 | 158750 | ||
| 156923 | /* | 158751 | /* |
| 158752 | ** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...) | ||
| 158753 | ** operator. Return true if level pLoop is guaranteed to visit only one | ||
| 158754 | ** row for each key generated for the index. | ||
| 158755 | */ | ||
| 158756 | static int whereLoopIsOneRow(WhereLoop *pLoop){ | ||
| 158757 | if( pLoop->u.btree.pIndex->onError | ||
| 158758 | && pLoop->nSkip==0 | ||
| 158759 | && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol | ||
| 158760 | ){ | ||
| 158761 | int ii; | ||
| 158762 | for(ii=0; ii<pLoop->u.btree.nEq; ii++){ | ||
| 158763 | if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){ | ||
| 158764 | return 0; | ||
| 158765 | } | ||
| 158766 | } | ||
| 158767 | return 1; | ||
| 158768 | } | ||
| 158769 | return 0; | ||
| 158770 | } | ||
| 158771 | |||
| 158772 | /* | ||
| 156924 | ** Generate code for the start of the iLevel-th loop in the WHERE clause | 158773 | ** Generate code for the start of the iLevel-th loop in the WHERE clause |
| 156925 | ** implementation described by pWInfo. | 158774 | ** implementation described by pWInfo. |
| 156926 | */ | 158775 | */ |
| @@ -156998,7 +158847,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 156998 | if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ | 158847 | if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ |
| 156999 | pLevel->iLeftJoin = ++pParse->nMem; | 158848 | pLevel->iLeftJoin = ++pParse->nMem; |
| 157000 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); | 158849 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); |
| 157001 | VdbeComment((v, "init LEFT JOIN no-match flag")); | 158850 | VdbeComment((v, "init LEFT JOIN match flag")); |
| 157002 | } | 158851 | } |
| 157003 | 158852 | ||
| 157004 | /* Compute a safe address to jump to if we discover that the table for | 158853 | /* Compute a safe address to jump to if we discover that the table for |
| @@ -157667,7 +159516,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 157667 | } | 159516 | } |
| 157668 | 159517 | ||
| 157669 | /* Record the instruction used to terminate the loop. */ | 159518 | /* Record the instruction used to terminate the loop. */ |
| 157670 | if( pLoop->wsFlags & WHERE_ONEROW ){ | 159519 | if( (pLoop->wsFlags & WHERE_ONEROW) |
| 159520 | || (pLevel->u.in.nIn && regBignull==0 && whereLoopIsOneRow(pLoop)) | ||
| 159521 | ){ | ||
| 157671 | pLevel->op = OP_Noop; | 159522 | pLevel->op = OP_Noop; |
| 157672 | }else if( bRev ){ | 159523 | }else if( bRev ){ |
| 157673 | pLevel->op = OP_Prev; | 159524 | pLevel->op = OP_Prev; |
| @@ -158057,6 +159908,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 158057 | ** iLoop==3: Code all remaining expressions. | 159908 | ** iLoop==3: Code all remaining expressions. |
| 158058 | ** | 159909 | ** |
| 158059 | ** An effort is made to skip unnecessary iterations of the loop. | 159910 | ** An effort is made to skip unnecessary iterations of the loop. |
| 159911 | ** | ||
| 159912 | ** This optimization of causing simple query restrictions to occur before | ||
| 159913 | ** more complex one is call the "push-down" optimization in MySQL. Here | ||
| 159914 | ** in SQLite, the name is "MySQL push-down", since there is also another | ||
| 159915 | ** totally unrelated optimization called "WHERE-clause push-down". | ||
| 159916 | ** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware. | ||
| 158060 | */ | 159917 | */ |
| 158061 | iLoop = (pIdx ? 1 : 2); | 159918 | iLoop = (pIdx ? 1 : 2); |
| 158062 | do{ | 159919 | do{ |
| @@ -158307,7 +160164,16 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( | |||
| 158307 | pRJ->regReturn); | 160164 | pRJ->regReturn); |
| 158308 | for(k=0; k<iLevel; k++){ | 160165 | for(k=0; k<iLevel; k++){ |
| 158309 | int iIdxCur; | 160166 | int iIdxCur; |
| 160167 | SrcItem *pRight; | ||
| 160168 | assert( pWInfo->a[k].pWLoop->iTab == pWInfo->a[k].iFrom ); | ||
| 160169 | pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; | ||
| 158310 | mAll |= pWInfo->a[k].pWLoop->maskSelf; | 160170 | mAll |= pWInfo->a[k].pWLoop->maskSelf; |
| 160171 | if( pRight->fg.viaCoroutine ){ | ||
| 160172 | sqlite3VdbeAddOp3( | ||
| 160173 | v, OP_Null, 0, pRight->regResult, | ||
| 160174 | pRight->regResult + pRight->pSelect->pEList->nExpr-1 | ||
| 160175 | ); | ||
| 160176 | } | ||
| 158311 | sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); | 160177 | sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); |
| 158312 | iIdxCur = pWInfo->a[k].iIdxCur; | 160178 | iIdxCur = pWInfo->a[k].iIdxCur; |
| 158313 | if( iIdxCur ){ | 160179 | if( iIdxCur ){ |
| @@ -159364,7 +161230,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( | |||
| 159364 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; | 161230 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; |
| 159365 | assert( pIdx->bHasExpr ); | 161231 | assert( pIdx->bHasExpr ); |
| 159366 | if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 | 161232 | if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 |
| 159367 | && pExpr->op!=TK_STRING | 161233 | && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr) |
| 159368 | ){ | 161234 | ){ |
| 159369 | aiCurCol[0] = iCur; | 161235 | aiCurCol[0] = iCur; |
| 159370 | aiCurCol[1] = XN_EXPR; | 161236 | aiCurCol[1] = XN_EXPR; |
| @@ -160013,6 +161879,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec | |||
| 160013 | continue; | 161879 | continue; |
| 160014 | } | 161880 | } |
| 160015 | if( pWC->a[ii].leftCursor!=iCsr ) return; | 161881 | if( pWC->a[ii].leftCursor!=iCsr ) return; |
| 161882 | if( pWC->a[ii].prereqRight!=0 ) return; | ||
| 160016 | } | 161883 | } |
| 160017 | 161884 | ||
| 160018 | /* Check condition (5). Return early if it is not met. */ | 161885 | /* Check condition (5). Return early if it is not met. */ |
| @@ -160027,12 +161894,14 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec | |||
| 160027 | 161894 | ||
| 160028 | /* All conditions are met. Add the terms to the where-clause object. */ | 161895 | /* All conditions are met. Add the terms to the where-clause object. */ |
| 160029 | assert( p->pLimit->op==TK_LIMIT ); | 161896 | assert( p->pLimit->op==TK_LIMIT ); |
| 160030 | whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, | 161897 | if( p->iOffset!=0 && (p->selFlags & SF_Compound)==0 ){ |
| 160031 | iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); | ||
| 160032 | if( p->iOffset>0 ){ | ||
| 160033 | whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, | 161898 | whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, |
| 160034 | iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); | 161899 | iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); |
| 160035 | } | 161900 | } |
| 161901 | if( p->iOffset==0 || (p->selFlags & SF_Compound)==0 ){ | ||
| 161902 | whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, | ||
| 161903 | iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); | ||
| 161904 | } | ||
| 160036 | } | 161905 | } |
| 160037 | } | 161906 | } |
| 160038 | 161907 | ||
| @@ -160551,6 +162420,42 @@ static Expr *whereRightSubexprIsColumn(Expr *p){ | |||
| 160551 | } | 162420 | } |
| 160552 | 162421 | ||
| 160553 | /* | 162422 | /* |
| 162423 | ** Term pTerm is guaranteed to be a WO_IN term. It may be a component term | ||
| 162424 | ** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)". | ||
| 162425 | ** This function checks to see if the term is compatible with an index | ||
| 162426 | ** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so, | ||
| 162427 | ** it returns a pointer to the name of the collation sequence (e.g. "BINARY" | ||
| 162428 | ** or "NOCASE") used by the comparison in pTerm. If it is not compatible | ||
| 162429 | ** with affinity idxaff, NULL is returned. | ||
| 162430 | */ | ||
| 162431 | static SQLITE_NOINLINE const char *indexInAffinityOk( | ||
| 162432 | Parse *pParse, | ||
| 162433 | WhereTerm *pTerm, | ||
| 162434 | u8 idxaff | ||
| 162435 | ){ | ||
| 162436 | Expr *pX = pTerm->pExpr; | ||
| 162437 | Expr inexpr; | ||
| 162438 | |||
| 162439 | assert( pTerm->eOperator & WO_IN ); | ||
| 162440 | |||
| 162441 | if( sqlite3ExprIsVector(pX->pLeft) ){ | ||
| 162442 | int iField = pTerm->u.x.iField - 1; | ||
| 162443 | inexpr.flags = 0; | ||
| 162444 | inexpr.op = TK_EQ; | ||
| 162445 | inexpr.pLeft = pX->pLeft->x.pList->a[iField].pExpr; | ||
| 162446 | assert( ExprUseXSelect(pX) ); | ||
| 162447 | inexpr.pRight = pX->x.pSelect->pEList->a[iField].pExpr; | ||
| 162448 | pX = &inexpr; | ||
| 162449 | } | ||
| 162450 | |||
| 162451 | if( sqlite3IndexAffinityOk(pX, idxaff) ){ | ||
| 162452 | CollSeq *pRet = sqlite3ExprCompareCollSeq(pParse, pX); | ||
| 162453 | return pRet ? pRet->zName : sqlite3StrBINARY; | ||
| 162454 | } | ||
| 162455 | return 0; | ||
| 162456 | } | ||
| 162457 | |||
| 162458 | /* | ||
| 160554 | ** Advance to the next WhereTerm that matches according to the criteria | 162459 | ** Advance to the next WhereTerm that matches according to the criteria |
| 160555 | ** established when the pScan object was initialized by whereScanInit(). | 162460 | ** established when the pScan object was initialized by whereScanInit(). |
| 160556 | ** Return NULL if there are no more matching WhereTerms. | 162461 | ** Return NULL if there are no more matching WhereTerms. |
| @@ -160600,16 +162505,24 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ | |||
| 160600 | if( (pTerm->eOperator & pScan->opMask)!=0 ){ | 162505 | if( (pTerm->eOperator & pScan->opMask)!=0 ){ |
| 160601 | /* Verify the affinity and collating sequence match */ | 162506 | /* Verify the affinity and collating sequence match */ |
| 160602 | if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ | 162507 | if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ |
| 160603 | CollSeq *pColl; | 162508 | const char *zCollName; |
| 160604 | Parse *pParse = pWC->pWInfo->pParse; | 162509 | Parse *pParse = pWC->pWInfo->pParse; |
| 160605 | pX = pTerm->pExpr; | 162510 | pX = pTerm->pExpr; |
| 160606 | if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ | 162511 | |
| 160607 | continue; | 162512 | if( (pTerm->eOperator & WO_IN) ){ |
| 162513 | zCollName = indexInAffinityOk(pParse, pTerm, pScan->idxaff); | ||
| 162514 | if( !zCollName ) continue; | ||
| 162515 | }else{ | ||
| 162516 | CollSeq *pColl; | ||
| 162517 | if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ | ||
| 162518 | continue; | ||
| 162519 | } | ||
| 162520 | assert(pX->pLeft); | ||
| 162521 | pColl = sqlite3ExprCompareCollSeq(pParse, pX); | ||
| 162522 | zCollName = pColl ? pColl->zName : sqlite3StrBINARY; | ||
| 160608 | } | 162523 | } |
| 160609 | assert(pX->pLeft); | 162524 | |
| 160610 | pColl = sqlite3ExprCompareCollSeq(pParse, pX); | 162525 | if( sqlite3StrICmp(zCollName, pScan->zCollName) ){ |
| 160611 | if( pColl==0 ) pColl = pParse->db->pDfltColl; | ||
| 160612 | if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ | ||
| 160613 | continue; | 162526 | continue; |
| 160614 | } | 162527 | } |
| 160615 | } | 162528 | } |
| @@ -160926,12 +162839,22 @@ static void translateColumnToCopy( | |||
| 160926 | for(; iStart<iEnd; iStart++, pOp++){ | 162839 | for(; iStart<iEnd; iStart++, pOp++){ |
| 160927 | if( pOp->p1!=iTabCur ) continue; | 162840 | if( pOp->p1!=iTabCur ) continue; |
| 160928 | if( pOp->opcode==OP_Column ){ | 162841 | if( pOp->opcode==OP_Column ){ |
| 162842 | #ifdef SQLITE_DEBUG | ||
| 162843 | if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ | ||
| 162844 | printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); | ||
| 162845 | } | ||
| 162846 | #endif | ||
| 160929 | pOp->opcode = OP_Copy; | 162847 | pOp->opcode = OP_Copy; |
| 160930 | pOp->p1 = pOp->p2 + iRegister; | 162848 | pOp->p1 = pOp->p2 + iRegister; |
| 160931 | pOp->p2 = pOp->p3; | 162849 | pOp->p2 = pOp->p3; |
| 160932 | pOp->p3 = 0; | 162850 | pOp->p3 = 0; |
| 160933 | pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ | 162851 | pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ |
| 160934 | }else if( pOp->opcode==OP_Rowid ){ | 162852 | }else if( pOp->opcode==OP_Rowid ){ |
| 162853 | #ifdef SQLITE_DEBUG | ||
| 162854 | if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ | ||
| 162855 | printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); | ||
| 162856 | } | ||
| 162857 | #endif | ||
| 160935 | pOp->opcode = OP_Sequence; | 162858 | pOp->opcode = OP_Sequence; |
| 160936 | pOp->p1 = iAutoidxCur; | 162859 | pOp->p1 = iAutoidxCur; |
| 160937 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | 162860 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW |
| @@ -160951,9 +162874,13 @@ static void translateColumnToCopy( | |||
| 160951 | ** are no-ops. | 162874 | ** are no-ops. |
| 160952 | */ | 162875 | */ |
| 160953 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) | 162876 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) |
| 160954 | static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ | 162877 | static void whereTraceIndexInfoInputs( |
| 162878 | sqlite3_index_info *p, /* The IndexInfo object */ | ||
| 162879 | Table *pTab /* The TABLE that is the virtual table */ | ||
| 162880 | ){ | ||
| 160955 | int i; | 162881 | int i; |
| 160956 | if( (sqlite3WhereTrace & 0x10)==0 ) return; | 162882 | if( (sqlite3WhereTrace & 0x10)==0 ) return; |
| 162883 | sqlite3DebugPrintf("sqlite3_index_info inputs for %s:\n", pTab->zName); | ||
| 160957 | for(i=0; i<p->nConstraint; i++){ | 162884 | for(i=0; i<p->nConstraint; i++){ |
| 160958 | sqlite3DebugPrintf( | 162885 | sqlite3DebugPrintf( |
| 160959 | " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", | 162886 | " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", |
| @@ -160971,9 +162898,13 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ | |||
| 160971 | p->aOrderBy[i].desc); | 162898 | p->aOrderBy[i].desc); |
| 160972 | } | 162899 | } |
| 160973 | } | 162900 | } |
| 160974 | static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ | 162901 | static void whereTraceIndexInfoOutputs( |
| 162902 | sqlite3_index_info *p, /* The IndexInfo object */ | ||
| 162903 | Table *pTab /* The TABLE that is the virtual table */ | ||
| 162904 | ){ | ||
| 160975 | int i; | 162905 | int i; |
| 160976 | if( (sqlite3WhereTrace & 0x10)==0 ) return; | 162906 | if( (sqlite3WhereTrace & 0x10)==0 ) return; |
| 162907 | sqlite3DebugPrintf("sqlite3_index_info outputs for %s:\n", pTab->zName); | ||
| 160977 | for(i=0; i<p->nConstraint; i++){ | 162908 | for(i=0; i<p->nConstraint; i++){ |
| 160978 | sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", | 162909 | sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", |
| 160979 | i, | 162910 | i, |
| @@ -160987,8 +162918,8 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ | |||
| 160987 | sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); | 162918 | sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); |
| 160988 | } | 162919 | } |
| 160989 | #else | 162920 | #else |
| 160990 | #define whereTraceIndexInfoInputs(A) | 162921 | #define whereTraceIndexInfoInputs(A,B) |
| 160991 | #define whereTraceIndexInfoOutputs(A) | 162922 | #define whereTraceIndexInfoOutputs(A,B) |
| 160992 | #endif | 162923 | #endif |
| 160993 | 162924 | ||
| 160994 | /* | 162925 | /* |
| @@ -161172,7 +163103,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 161172 | ** WHERE clause (or the ON clause of a LEFT join) that constrain which | 163103 | ** WHERE clause (or the ON clause of a LEFT join) that constrain which |
| 161173 | ** rows of the target table (pSrc) that can be used. */ | 163104 | ** rows of the target table (pSrc) that can be used. */ |
| 161174 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 | 163105 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 161175 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) | 163106 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0) |
| 161176 | ){ | 163107 | ){ |
| 161177 | pPartial = sqlite3ExprAnd(pParse, pPartial, | 163108 | pPartial = sqlite3ExprAnd(pParse, pPartial, |
| 161178 | sqlite3ExprDup(pParse->db, pExpr, 0)); | 163109 | sqlite3ExprDup(pParse->db, pExpr, 0)); |
| @@ -161214,7 +163145,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 161214 | ** if they go out of sync. | 163145 | ** if they go out of sync. |
| 161215 | */ | 163146 | */ |
| 161216 | if( IsView(pTable) ){ | 163147 | if( IsView(pTable) ){ |
| 161217 | extraCols = ALLBITS; | 163148 | extraCols = ALLBITS & ~idxCols; |
| 161218 | }else{ | 163149 | }else{ |
| 161219 | extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); | 163150 | extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); |
| 161220 | } | 163151 | } |
| @@ -161441,7 +163372,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 161441 | for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ | 163372 | for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ |
| 161442 | Expr *pExpr = pTerm->pExpr; | 163373 | Expr *pExpr = pTerm->pExpr; |
| 161443 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 | 163374 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 161444 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) | 163375 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0) |
| 161445 | ){ | 163376 | ){ |
| 161446 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); | 163377 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); |
| 161447 | } | 163378 | } |
| @@ -161567,7 +163498,7 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 161567 | Expr *pE2; | 163498 | Expr *pE2; |
| 161568 | 163499 | ||
| 161569 | /* Skip over constant terms in the ORDER BY clause */ | 163500 | /* Skip over constant terms in the ORDER BY clause */ |
| 161570 | if( sqlite3ExprIsConstant(pExpr) ){ | 163501 | if( sqlite3ExprIsConstant(0, pExpr) ){ |
| 161571 | continue; | 163502 | continue; |
| 161572 | } | 163503 | } |
| 161573 | 163504 | ||
| @@ -161602,7 +163533,7 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 161602 | } | 163533 | } |
| 161603 | if( i==n ){ | 163534 | if( i==n ){ |
| 161604 | nOrderBy = n; | 163535 | nOrderBy = n; |
| 161605 | if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ | 163536 | if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ |
| 161606 | eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); | 163537 | eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); |
| 161607 | }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ | 163538 | }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ |
| 161608 | eDistinct = 1; | 163539 | eDistinct = 1; |
| @@ -161679,7 +163610,7 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 161679 | pIdxInfo->nConstraint = j; | 163610 | pIdxInfo->nConstraint = j; |
| 161680 | for(i=j=0; i<nOrderBy; i++){ | 163611 | for(i=j=0; i<nOrderBy; i++){ |
| 161681 | Expr *pExpr = pOrderBy->a[i].pExpr; | 163612 | Expr *pExpr = pOrderBy->a[i].pExpr; |
| 161682 | if( sqlite3ExprIsConstant(pExpr) ) continue; | 163613 | if( sqlite3ExprIsConstant(0, pExpr) ) continue; |
| 161683 | assert( pExpr->op==TK_COLUMN | 163614 | assert( pExpr->op==TK_COLUMN |
| 161684 | || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN | 163615 | || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN |
| 161685 | && pExpr->iColumn==pExpr->pLeft->iColumn) ); | 163616 | && pExpr->iColumn==pExpr->pLeft->iColumn) ); |
| @@ -161731,11 +163662,11 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ | |||
| 161731 | sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; | 163662 | sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; |
| 161732 | int rc; | 163663 | int rc; |
| 161733 | 163664 | ||
| 161734 | whereTraceIndexInfoInputs(p); | 163665 | whereTraceIndexInfoInputs(p, pTab); |
| 161735 | pParse->db->nSchemaLock++; | 163666 | pParse->db->nSchemaLock++; |
| 161736 | rc = pVtab->pModule->xBestIndex(pVtab, p); | 163667 | rc = pVtab->pModule->xBestIndex(pVtab, p); |
| 161737 | pParse->db->nSchemaLock--; | 163668 | pParse->db->nSchemaLock--; |
| 161738 | whereTraceIndexInfoOutputs(p); | 163669 | whereTraceIndexInfoOutputs(p, pTab); |
| 161739 | 163670 | ||
| 161740 | if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ | 163671 | if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ |
| 161741 | if( rc==SQLITE_NOMEM ){ | 163672 | if( rc==SQLITE_NOMEM ){ |
| @@ -162258,7 +164189,8 @@ static int whereRangeScanEst( | |||
| 162258 | ** sample, then assume they are 4x more selective. This brings | 164189 | ** sample, then assume they are 4x more selective. This brings |
| 162259 | ** the estimated selectivity more in line with what it would be | 164190 | ** the estimated selectivity more in line with what it would be |
| 162260 | ** if estimated without the use of STAT4 tables. */ | 164191 | ** if estimated without the use of STAT4 tables. */ |
| 162261 | if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); | 164192 | if( iLwrIdx==iUprIdx ){ nNew -= 20; } |
| 164193 | assert( 20==sqlite3LogEst(4) ); | ||
| 162262 | }else{ | 164194 | }else{ |
| 162263 | nNew = 10; assert( 10==sqlite3LogEst(2) ); | 164195 | nNew = 10; assert( 10==sqlite3LogEst(2) ); |
| 162264 | } | 164196 | } |
| @@ -162482,17 +164414,34 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ | |||
| 162482 | #ifdef WHERETRACE_ENABLED | 164414 | #ifdef WHERETRACE_ENABLED |
| 162483 | /* | 164415 | /* |
| 162484 | ** Print a WhereLoop object for debugging purposes | 164416 | ** Print a WhereLoop object for debugging purposes |
| 162485 | */ | 164417 | ** |
| 162486 | SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ | 164418 | ** Format example: |
| 162487 | WhereInfo *pWInfo = pWC->pWInfo; | 164419 | ** |
| 162488 | int nb = 1+(pWInfo->pTabList->nSrc+3)/4; | 164420 | ** .--- Position in WHERE clause rSetup, rRun, nOut ---. |
| 162489 | SrcItem *pItem = pWInfo->pTabList->a + p->iTab; | 164421 | ** | | |
| 162490 | Table *pTab = pItem->pTab; | 164422 | ** | .--- selfMask nTerm ------. | |
| 162491 | Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; | 164423 | ** | | | | |
| 162492 | sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, | 164424 | ** | | .-- prereq Idx wsFlags----. | | |
| 162493 | p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); | 164425 | ** | | | Name | | | |
| 162494 | sqlite3DebugPrintf(" %12s", | 164426 | ** | | | __|__ nEq ---. ___|__ | __|__ |
| 162495 | pItem->zAlias ? pItem->zAlias : pTab->zName); | 164427 | ** | / \ / \ / \ | / \ / \ / \ |
| 164428 | ** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 | ||
| 164429 | */ | ||
| 164430 | SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ | ||
| 164431 | if( pWC ){ | ||
| 164432 | WhereInfo *pWInfo = pWC->pWInfo; | ||
| 164433 | int nb = 1+(pWInfo->pTabList->nSrc+3)/4; | ||
| 164434 | SrcItem *pItem = pWInfo->pTabList->a + p->iTab; | ||
| 164435 | Table *pTab = pItem->pTab; | ||
| 164436 | Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; | ||
| 164437 | sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, | ||
| 164438 | p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); | ||
| 164439 | sqlite3DebugPrintf(" %12s", | ||
| 164440 | pItem->zAlias ? pItem->zAlias : pTab->zName); | ||
| 164441 | }else{ | ||
| 164442 | sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", | ||
| 164443 | p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); | ||
| 164444 | } | ||
| 162496 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ | 164445 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 162497 | const char *zName; | 164446 | const char *zName; |
| 162498 | if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ | 164447 | if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ |
| @@ -162529,6 +164478,15 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ | |||
| 162529 | } | 164478 | } |
| 162530 | } | 164479 | } |
| 162531 | } | 164480 | } |
| 164481 | SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ | ||
| 164482 | if( p ) sqlite3WhereLoopPrint(p, 0); | ||
| 164483 | } | ||
| 164484 | SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ | ||
| 164485 | while( p ){ | ||
| 164486 | sqlite3ShowWhereLoop(p); | ||
| 164487 | p = p->pNextLoop; | ||
| 164488 | } | ||
| 164489 | } | ||
| 162532 | #endif | 164490 | #endif |
| 162533 | 164491 | ||
| 162534 | /* | 164492 | /* |
| @@ -162641,46 +164599,60 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ | |||
| 162641 | } | 164599 | } |
| 162642 | 164600 | ||
| 162643 | /* | 164601 | /* |
| 162644 | ** Return TRUE if all of the following are true: | 164602 | ** Return TRUE if X is a proper subset of Y but is of equal or less cost. |
| 164603 | ** In other words, return true if all constraints of X are also part of Y | ||
| 164604 | ** 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. | ||
| 164606 | ** | ||
| 164607 | ** In other words, return true if the cost relationwship between X and Y | ||
| 164608 | ** is inverted and needs to be adjusted. | ||
| 164609 | ** | ||
| 164610 | ** Case 1: | ||
| 164611 | ** | ||
| 164612 | ** (1a) X and Y use the same index. | ||
| 164613 | ** (1b) X has fewer == terms than Y | ||
| 164614 | ** (1c) Neither X nor Y use skip-scan | ||
| 164615 | ** (1d) X does not have a a greater cost than Y | ||
| 162645 | ** | 164616 | ** |
| 162646 | ** (1) X has the same or lower cost, or returns the same or fewer rows, | 164617 | ** Case 2: |
| 162647 | ** than Y. | ||
| 162648 | ** (2) X uses fewer WHERE clause terms than Y | ||
| 162649 | ** (3) Every WHERE clause term used by X is also used by Y | ||
| 162650 | ** (4) X skips at least as many columns as Y | ||
| 162651 | ** (5) If X is a covering index, than Y is too | ||
| 162652 | ** | 164618 | ** |
| 162653 | ** Conditions (2) and (3) mean that X is a "proper subset" of Y. | 164619 | ** (2a) X has the same or lower cost, or returns the same or fewer rows, |
| 162654 | ** If X is a proper subset of Y then Y is a better choice and ought | 164620 | ** than Y. |
| 162655 | ** to have a lower cost. This routine returns TRUE when that cost | 164621 | ** (2b) X uses fewer WHERE clause terms than Y |
| 162656 | ** relationship is inverted and needs to be adjusted. Constraint (4) | 164622 | ** (2c) Every WHERE clause term used by X is also used by Y |
| 162657 | ** was added because if X uses skip-scan less than Y it still might | 164623 | ** (2d) X skips at least as many columns as Y |
| 162658 | ** deserve a lower cost even if it is a proper subset of Y. Constraint (5) | 164624 | ** (2e) If X is a covering index, than Y is too |
| 162659 | ** was added because a covering index probably deserves to have a lower cost | ||
| 162660 | ** than a non-covering index even if it is a proper subset. | ||
| 162661 | */ | 164625 | */ |
| 162662 | static int whereLoopCheaperProperSubset( | 164626 | static int whereLoopCheaperProperSubset( |
| 162663 | const WhereLoop *pX, /* First WhereLoop to compare */ | 164627 | const WhereLoop *pX, /* First WhereLoop to compare */ |
| 162664 | const WhereLoop *pY /* Compare against this WhereLoop */ | 164628 | const WhereLoop *pY /* Compare against this WhereLoop */ |
| 162665 | ){ | 164629 | ){ |
| 162666 | int i, j; | 164630 | int i, j; |
| 164631 | if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ | ||
| 164632 | assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); | ||
| 164633 | assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); | ||
| 164634 | if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ | ||
| 164635 | && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ | ||
| 164636 | && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ | ||
| 164637 | ){ | ||
| 164638 | return 1; /* Case 1 is true */ | ||
| 164639 | } | ||
| 162667 | if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ | 164640 | if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ |
| 162668 | return 0; /* X is not a subset of Y */ | 164641 | return 0; /* (2b) */ |
| 162669 | } | 164642 | } |
| 162670 | if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; | 164643 | if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ |
| 162671 | if( pY->nSkip > pX->nSkip ) return 0; | ||
| 162672 | for(i=pX->nLTerm-1; i>=0; i--){ | 164644 | for(i=pX->nLTerm-1; i>=0; i--){ |
| 162673 | if( pX->aLTerm[i]==0 ) continue; | 164645 | if( pX->aLTerm[i]==0 ) continue; |
| 162674 | for(j=pY->nLTerm-1; j>=0; j--){ | 164646 | for(j=pY->nLTerm-1; j>=0; j--){ |
| 162675 | if( pY->aLTerm[j]==pX->aLTerm[i] ) break; | 164647 | if( pY->aLTerm[j]==pX->aLTerm[i] ) break; |
| 162676 | } | 164648 | } |
| 162677 | if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ | 164649 | if( j<0 ) return 0; /* (2c) */ |
| 162678 | } | 164650 | } |
| 162679 | if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 | 164651 | if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 |
| 162680 | && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ | 164652 | && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ |
| 162681 | return 0; /* Constraint (5) */ | 164653 | return 0; /* (2e) */ |
| 162682 | } | 164654 | } |
| 162683 | return 1; /* All conditions meet */ | 164655 | return 1; /* Case 2 is true */ |
| 162684 | } | 164656 | } |
| 162685 | 164657 | ||
| 162686 | /* | 164658 | /* |
| @@ -163170,7 +165142,12 @@ static int whereLoopAddBtreeIndex( | |||
| 163170 | assert( pNew->u.btree.nBtm==0 ); | 165142 | assert( pNew->u.btree.nBtm==0 ); |
| 163171 | opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; | 165143 | opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; |
| 163172 | } | 165144 | } |
| 163173 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); | 165145 | if( pProbe->bUnordered || pProbe->bLowQual ){ |
| 165146 | if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); | ||
| 165147 | if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){ | ||
| 165148 | opMask &= ~(WO_EQ|WO_IN|WO_IS); | ||
| 165149 | } | ||
| 165150 | } | ||
| 163174 | 165151 | ||
| 163175 | assert( pNew->u.btree.nEq<pProbe->nColumn ); | 165152 | assert( pNew->u.btree.nEq<pProbe->nColumn ); |
| 163176 | assert( pNew->u.btree.nEq<pProbe->nKeyCol | 165153 | assert( pNew->u.btree.nEq<pProbe->nKeyCol |
| @@ -163436,10 +165413,13 @@ static int whereLoopAddBtreeIndex( | |||
| 163436 | } | 165413 | } |
| 163437 | } | 165414 | } |
| 163438 | 165415 | ||
| 163439 | /* Set rCostIdx to the cost of visiting selected rows in index. Add | 165416 | /* Set rCostIdx to the estimated cost of visiting selected rows in the |
| 163440 | ** it to pNew->rRun, which is currently set to the cost of the index | 165417 | ** index. The estimate is the sum of two values: |
| 163441 | ** seek only. Then, if this is a non-covering index, add the cost of | 165418 | ** 1. The cost of doing one search-by-key to find the first matching |
| 163442 | ** visiting the rows in the main table. */ | 165419 | ** entry |
| 165420 | ** 2. Stepping forward in the index pNew->nOut times to find all | ||
| 165421 | ** additional matching entries. | ||
| 165422 | */ | ||
| 163443 | assert( pSrc->pTab->szTabRow>0 ); | 165423 | assert( pSrc->pTab->szTabRow>0 ); |
| 163444 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ | 165424 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ |
| 163445 | /* The pProbe->szIdxRow is low for an IPK table since the interior | 165425 | /* The pProbe->szIdxRow is low for an IPK table since the interior |
| @@ -163450,7 +165430,15 @@ static int whereLoopAddBtreeIndex( | |||
| 163450 | }else{ | 165430 | }else{ |
| 163451 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; | 165431 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; |
| 163452 | } | 165432 | } |
| 163453 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); | 165433 | rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 165434 | |||
| 165435 | /* Estimate the cost of running the loop. If all data is coming | ||
| 165436 | ** from the index, then this is just the cost of doing the index | ||
| 165437 | ** lookup and scan. But if some data is coming out of the main table, | ||
| 165438 | ** we also have to add in the cost of doing pNew->nOut searches to | ||
| 165439 | ** locate the row in the main table that corresponds to the index entry. | ||
| 165440 | */ | ||
| 165441 | pNew->rRun = rCostIdx; | ||
| 163454 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ | 165442 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ |
| 163455 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); | 165443 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 163456 | } | 165444 | } |
| @@ -163556,7 +165544,9 @@ static int indexMightHelpWithOrderBy( | |||
| 163556 | for(ii=0; ii<pOB->nExpr; ii++){ | 165544 | for(ii=0; ii<pOB->nExpr; ii++){ |
| 163557 | Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); | 165545 | Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); |
| 163558 | if( NEVER(pExpr==0) ) continue; | 165546 | if( NEVER(pExpr==0) ) continue; |
| 163559 | if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ | 165547 | if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) |
| 165548 | && pExpr->iTable==iCursor | ||
| 165549 | ){ | ||
| 163560 | if( pExpr->iColumn<0 ) return 1; | 165550 | if( pExpr->iColumn<0 ) return 1; |
| 163561 | for(jj=0; jj<pIndex->nKeyCol; jj++){ | 165551 | for(jj=0; jj<pIndex->nKeyCol; jj++){ |
| 163562 | if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; | 165552 | if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; |
| @@ -163813,7 +165803,7 @@ static void wherePartIdxExpr( | |||
| 163813 | u8 aff; | 165803 | u8 aff; |
| 163814 | 165804 | ||
| 163815 | if( pLeft->op!=TK_COLUMN ) return; | 165805 | if( pLeft->op!=TK_COLUMN ) return; |
| 163816 | if( !sqlite3ExprIsConstant(pRight) ) return; | 165806 | if( !sqlite3ExprIsConstant(0, pRight) ) return; |
| 163817 | if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; | 165807 | if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; |
| 163818 | if( pLeft->iColumn<0 ) return; | 165808 | if( pLeft->iColumn<0 ) return; |
| 163819 | aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; | 165809 | aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; |
| @@ -164086,7 +166076,9 @@ static int whereLoopAddBtree( | |||
| 164086 | " according to whereIsCoveringIndex()\n", pProbe->zName)); | 166076 | " according to whereIsCoveringIndex()\n", pProbe->zName)); |
| 164087 | } | 166077 | } |
| 164088 | } | 166078 | } |
| 164089 | }else if( m==0 ){ | 166079 | }else if( m==0 |
| 166080 | && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) | ||
| 166081 | ){ | ||
| 164090 | WHERETRACE(0x200, | 166082 | WHERETRACE(0x200, |
| 164091 | ("-> %s a covering index according to bitmasks\n", | 166083 | ("-> %s a covering index according to bitmasks\n", |
| 164092 | pProbe->zName, m==0 ? "is" : "is not")); | 166084 | pProbe->zName, m==0 ? "is" : "is not")); |
| @@ -164162,7 +166154,7 @@ static int whereLoopAddBtree( | |||
| 164162 | ** unique index is used (making the index functionally non-unique) | 166154 | ** unique index is used (making the index functionally non-unique) |
| 164163 | ** then the sqlite_stat1 data becomes important for scoring the | 166155 | ** then the sqlite_stat1 data becomes important for scoring the |
| 164164 | ** plan */ | 166156 | ** plan */ |
| 164165 | pTab->tabFlags |= TF_StatsUsed; | 166157 | pTab->tabFlags |= TF_MaybeReanalyze; |
| 164166 | } | 166158 | } |
| 164167 | #ifdef SQLITE_ENABLE_STAT4 | 166159 | #ifdef SQLITE_ENABLE_STAT4 |
| 164168 | sqlite3Stat4ProbeFree(pBuilder->pRec); | 166160 | sqlite3Stat4ProbeFree(pBuilder->pRec); |
| @@ -164185,6 +166177,21 @@ static int isLimitTerm(WhereTerm *pTerm){ | |||
| 164185 | } | 166177 | } |
| 164186 | 166178 | ||
| 164187 | /* | 166179 | /* |
| 166180 | ** Return true if the first nCons constraints in the pUsage array are | ||
| 166181 | ** marked as in-use (have argvIndex>0). False otherwise. | ||
| 166182 | */ | ||
| 166183 | static int allConstraintsUsed( | ||
| 166184 | struct sqlite3_index_constraint_usage *aUsage, | ||
| 166185 | int nCons | ||
| 166186 | ){ | ||
| 166187 | int ii; | ||
| 166188 | for(ii=0; ii<nCons; ii++){ | ||
| 166189 | if( aUsage[ii].argvIndex<=0 ) return 0; | ||
| 166190 | } | ||
| 166191 | return 1; | ||
| 166192 | } | ||
| 166193 | |||
| 166194 | /* | ||
| 164188 | ** Argument pIdxInfo is already populated with all constraints that may | 166195 | ** Argument pIdxInfo is already populated with all constraints that may |
| 164189 | ** be used by the virtual table identified by pBuilder->pNew->iTab. This | 166196 | ** be used by the virtual table identified by pBuilder->pNew->iTab. This |
| 164190 | ** function marks a subset of those constraints usable, invokes the | 166197 | ** function marks a subset of those constraints usable, invokes the |
| @@ -164324,13 +166331,20 @@ static int whereLoopAddVirtualOne( | |||
| 164324 | *pbIn = 1; assert( (mExclude & WO_IN)==0 ); | 166331 | *pbIn = 1; assert( (mExclude & WO_IN)==0 ); |
| 164325 | } | 166332 | } |
| 164326 | 166333 | ||
| 166334 | /* Unless pbRetryLimit is non-NULL, there should be no LIMIT/OFFSET | ||
| 166335 | ** terms. And if there are any, they should follow all other terms. */ | ||
| 164327 | assert( pbRetryLimit || !isLimitTerm(pTerm) ); | 166336 | assert( pbRetryLimit || !isLimitTerm(pTerm) ); |
| 164328 | if( isLimitTerm(pTerm) && *pbIn ){ | 166337 | assert( !isLimitTerm(pTerm) || i>=nConstraint-2 ); |
| 166338 | assert( !isLimitTerm(pTerm) || i==nConstraint-1 || isLimitTerm(pTerm+1) ); | ||
| 166339 | |||
| 166340 | if( isLimitTerm(pTerm) && (*pbIn || !allConstraintsUsed(pUsage, i)) ){ | ||
| 164329 | /* If there is an IN(...) term handled as an == (separate call to | 166341 | /* If there is an IN(...) term handled as an == (separate call to |
| 164330 | ** xFilter for each value on the RHS of the IN) and a LIMIT or | 166342 | ** xFilter for each value on the RHS of the IN) and a LIMIT or |
| 164331 | ** OFFSET term handled as well, the plan is unusable. Set output | 166343 | ** OFFSET term handled as well, the plan is unusable. Similarly, |
| 164332 | ** variable *pbRetryLimit to true to tell the caller to retry with | 166344 | ** if there is a LIMIT/OFFSET and there are other unused terms, |
| 164333 | ** LIMIT and OFFSET disabled. */ | 166345 | ** the plan cannot be used. In these cases set variable *pbRetryLimit |
| 166346 | ** to true to tell the caller to retry with LIMIT and OFFSET | ||
| 166347 | ** disabled. */ | ||
| 164334 | if( pIdxInfo->needToFreeIdxStr ){ | 166348 | if( pIdxInfo->needToFreeIdxStr ){ |
| 164335 | sqlite3_free(pIdxInfo->idxStr); | 166349 | sqlite3_free(pIdxInfo->idxStr); |
| 164336 | pIdxInfo->idxStr = 0; | 166350 | pIdxInfo->idxStr = 0; |
| @@ -165187,7 +167201,7 @@ static i8 wherePathSatisfiesOrderBy( | |||
| 165187 | if( MASKBIT(i) & obSat ) continue; | 167201 | if( MASKBIT(i) & obSat ) continue; |
| 165188 | p = pOrderBy->a[i].pExpr; | 167202 | p = pOrderBy->a[i].pExpr; |
| 165189 | mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); | 167203 | mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); |
| 165190 | if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; | 167204 | if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue; |
| 165191 | if( (mTerm&~orderDistinctMask)==0 ){ | 167205 | if( (mTerm&~orderDistinctMask)==0 ){ |
| 165192 | obSat |= MASKBIT(i); | 167206 | obSat |= MASKBIT(i); |
| 165193 | } | 167207 | } |
| @@ -165656,10 +167670,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 165656 | if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ | 167670 | if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ |
| 165657 | pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; | 167671 | pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 165658 | } | 167672 | } |
| 165659 | if( pWInfo->pSelect->pOrderBy | 167673 | /* vvv--- See check-in [12ad822d9b827777] on 2023-03-16 ---vvv */ |
| 165660 | && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ | 167674 | assert( pWInfo->pSelect->pOrderBy==0 |
| 165661 | pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; | 167675 | || pWInfo->nOBSat <= pWInfo->pSelect->pOrderBy->nExpr ); |
| 165662 | } | ||
| 165663 | }else{ | 167676 | }else{ |
| 165664 | pWInfo->revMask = pFrom->revLoop; | 167677 | pWInfo->revMask = pFrom->revLoop; |
| 165665 | if( pWInfo->nOBSat<=0 ){ | 167678 | if( pWInfo->nOBSat<=0 ){ |
| @@ -165702,7 +167715,6 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 165702 | } | 167715 | } |
| 165703 | } | 167716 | } |
| 165704 | 167717 | ||
| 165705 | |||
| 165706 | pWInfo->nRowOut = pFrom->nRow; | 167718 | pWInfo->nRowOut = pFrom->nRow; |
| 165707 | 167719 | ||
| 165708 | /* Free temporary memory and return success */ | 167720 | /* Free temporary memory and return success */ |
| @@ -165711,6 +167723,83 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 165711 | } | 167723 | } |
| 165712 | 167724 | ||
| 165713 | /* | 167725 | /* |
| 167726 | ** This routine implements a heuristic designed to improve query planning. | ||
| 167727 | ** This routine is called in between the first and second call to | ||
| 167728 | ** wherePathSolver(). Hence the name "Interstage" "Heuristic". | ||
| 167729 | ** | ||
| 167730 | ** The first call to wherePathSolver() (hereafter just "solver()") computes | ||
| 167731 | ** the best path without regard to the order of the outputs. The second call | ||
| 167732 | ** to the solver() builds upon the first call to try to find an alternative | ||
| 167733 | ** path that satisfies the ORDER BY clause. | ||
| 167734 | ** | ||
| 167735 | ** This routine looks at the results of the first solver() run, and for | ||
| 167736 | ** every FROM clause term in the resulting query plan that uses an equality | ||
| 167737 | ** constraint against an index, disable other WhereLoops for that same | ||
| 167738 | ** FROM clause term that would try to do a full-table scan. This prevents | ||
| 167739 | ** an index search from being converted into a full-table scan in order to | ||
| 167740 | ** satisfy an ORDER BY clause, since even though we might get slightly better | ||
| 167741 | ** performance using the full-scan without sorting if the output size | ||
| 167742 | ** estimates are very precise, we might also get severe performance | ||
| 167743 | ** degradation using the full-scan if the output size estimate is too large. | ||
| 167744 | ** It is better to err on the side of caution. | ||
| 167745 | ** | ||
| 167746 | ** Except, if the first solver() call generated a full-table scan in an outer | ||
| 167747 | ** loop then stop this analysis at the first full-scan, since the second | ||
| 167748 | ** solver() run might try to swap that full-scan for another in order to | ||
| 167749 | ** get the output into the correct order. In other words, we allow a | ||
| 167750 | ** rewrite like this: | ||
| 167751 | ** | ||
| 167752 | ** First Solver() Second Solver() | ||
| 167753 | ** |-- SCAN t1 |-- SCAN t2 | ||
| 167754 | ** |-- SEARCH t2 `-- SEARCH t1 | ||
| 167755 | ** `-- SORT USING B-TREE | ||
| 167756 | ** | ||
| 167757 | ** The purpose of this routine is to disallow rewrites such as: | ||
| 167758 | ** | ||
| 167759 | ** First Solver() Second Solver() | ||
| 167760 | ** |-- SEARCH t1 |-- SCAN t2 <--- bad! | ||
| 167761 | ** |-- SEARCH t2 `-- SEARCH t1 | ||
| 167762 | ** `-- SORT USING B-TREE | ||
| 167763 | ** | ||
| 167764 | ** See test cases in test/whereN.test for the real-world query that | ||
| 167765 | ** originally provoked this heuristic. | ||
| 167766 | */ | ||
| 167767 | static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){ | ||
| 167768 | int i; | ||
| 167769 | #ifdef WHERETRACE_ENABLED | ||
| 167770 | int once = 0; | ||
| 167771 | #endif | ||
| 167772 | for(i=0; i<pWInfo->nLevel; i++){ | ||
| 167773 | WhereLoop *p = pWInfo->a[i].pWLoop; | ||
| 167774 | if( p==0 ) break; | ||
| 167775 | if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue; | ||
| 167776 | if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){ | ||
| 167777 | u8 iTab = p->iTab; | ||
| 167778 | WhereLoop *pLoop; | ||
| 167779 | for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){ | ||
| 167780 | if( pLoop->iTab!=iTab ) continue; | ||
| 167781 | if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){ | ||
| 167782 | /* Auto-index and index-constrained loops allowed to remain */ | ||
| 167783 | continue; | ||
| 167784 | } | ||
| 167785 | #ifdef WHERETRACE_ENABLED | ||
| 167786 | if( sqlite3WhereTrace & 0x80 ){ | ||
| 167787 | if( once==0 ){ | ||
| 167788 | sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n"); | ||
| 167789 | once = 1; | ||
| 167790 | } | ||
| 167791 | sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC); | ||
| 167792 | } | ||
| 167793 | #endif /* WHERETRACE_ENABLED */ | ||
| 167794 | pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */ | ||
| 167795 | } | ||
| 167796 | }else{ | ||
| 167797 | break; | ||
| 167798 | } | ||
| 167799 | } | ||
| 167800 | } | ||
| 167801 | |||
| 167802 | /* | ||
| 165714 | ** Most queries use only a single table (they are not joins) and have | 167803 | ** Most queries use only a single table (they are not joins) and have |
| 165715 | ** simple == constraints against indexed fields. This routine attempts | 167804 | ** simple == constraints against indexed fields. This routine attempts |
| 165716 | ** to plan those simple cases using much less ceremony than the | 167805 | ** to plan those simple cases using much less ceremony than the |
| @@ -165878,6 +167967,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ | |||
| 165878 | ** the right-most table of a subquery that was flattened into the | 167967 | ** the right-most table of a subquery that was flattened into the |
| 165879 | ** main query and that subquery was the right-hand operand of an | 167968 | ** main query and that subquery was the right-hand operand of an |
| 165880 | ** inner join that held an ON or USING clause. | 167969 | ** inner join that held an ON or USING clause. |
| 167970 | ** 6) The ORDER BY clause has 63 or fewer terms | ||
| 167971 | ** 7) The omit-noop-join optimization is enabled. | ||
| 167972 | ** | ||
| 167973 | ** Items (1), (6), and (7) are checked by the caller. | ||
| 165881 | ** | 167974 | ** |
| 165882 | ** For example, given: | 167975 | ** For example, given: |
| 165883 | ** | 167976 | ** |
| @@ -165998,7 +168091,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 165998 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; | 168091 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; |
| 165999 | Table *pTab = pItem->pTab; | 168092 | Table *pTab = pItem->pTab; |
| 166000 | if( (pTab->tabFlags & TF_HasStat1)==0 ) break; | 168093 | if( (pTab->tabFlags & TF_HasStat1)==0 ) break; |
| 166001 | pTab->tabFlags |= TF_StatsUsed; | 168094 | pTab->tabFlags |= TF_MaybeReanalyze; |
| 166002 | if( i>=1 | 168095 | if( i>=1 |
| 166003 | && (pLoop->wsFlags & reqFlags)==reqFlags | 168096 | && (pLoop->wsFlags & reqFlags)==reqFlags |
| 166004 | /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ | 168097 | /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ |
| @@ -166020,6 +168113,58 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 166020 | } | 168113 | } |
| 166021 | 168114 | ||
| 166022 | /* | 168115 | /* |
| 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 | /* | ||
| 166023 | ** The index pIdx is used by a query and contains one or more expressions. | 168168 | ** The index pIdx is used by a query and contains one or more expressions. |
| 166024 | ** In other words pIdx is an index on an expression. iIdxCur is the cursor | 168169 | ** In other words pIdx is an index on an expression. iIdxCur is the cursor |
| 166025 | ** number for the index and iDataCur is the cursor number for the corresponding | 168170 | ** number for the index and iDataCur is the cursor number for the corresponding |
| @@ -166044,20 +168189,20 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( | |||
| 166044 | for(i=0; i<pIdx->nColumn; i++){ | 168189 | for(i=0; i<pIdx->nColumn; i++){ |
| 166045 | Expr *pExpr; | 168190 | Expr *pExpr; |
| 166046 | int j = pIdx->aiColumn[i]; | 168191 | int j = pIdx->aiColumn[i]; |
| 166047 | int bMaybeNullRow; | ||
| 166048 | if( j==XN_EXPR ){ | 168192 | if( j==XN_EXPR ){ |
| 166049 | pExpr = pIdx->aColExpr->a[i].pExpr; | 168193 | pExpr = pIdx->aColExpr->a[i].pExpr; |
| 166050 | testcase( pTabItem->fg.jointype & JT_LEFT ); | ||
| 166051 | testcase( pTabItem->fg.jointype & JT_RIGHT ); | ||
| 166052 | testcase( pTabItem->fg.jointype & JT_LTORJ ); | ||
| 166053 | bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; | ||
| 166054 | }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ | 168194 | }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ |
| 166055 | pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); | 168195 | pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); |
| 166056 | bMaybeNullRow = 0; | ||
| 166057 | }else{ | 168196 | }else{ |
| 166058 | continue; | 168197 | continue; |
| 166059 | } | 168198 | } |
| 166060 | if( sqlite3ExprIsConstant(pExpr) ) continue; | 168199 | 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 | } | ||
| 166061 | p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); | 168206 | p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); |
| 166062 | if( p==0 ) break; | 168207 | if( p==0 ) break; |
| 166063 | p->pIENext = pParse->pIdxEpr; | 168208 | p->pIENext = pParse->pIdxEpr; |
| @@ -166071,7 +168216,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( | |||
| 166071 | p->iDataCur = pTabItem->iCursor; | 168216 | p->iDataCur = pTabItem->iCursor; |
| 166072 | p->iIdxCur = iIdxCur; | 168217 | p->iIdxCur = iIdxCur; |
| 166073 | p->iIdxCol = i; | 168218 | p->iIdxCol = i; |
| 166074 | p->bMaybeNullRow = bMaybeNullRow; | 168219 | p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; |
| 166075 | if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ | 168220 | if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ |
| 166076 | p->aff = pIdx->zColAff[i]; | 168221 | p->aff = pIdx->zColAff[i]; |
| 166077 | } | 168222 | } |
| @@ -166236,7 +168381,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 166236 | 168381 | ||
| 166237 | /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ | 168382 | /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ |
| 166238 | testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); | 168383 | testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); |
| 166239 | if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; | 168384 | if( pOrderBy && pOrderBy->nExpr>=BMS ){ |
| 168385 | pOrderBy = 0; | ||
| 168386 | wctrlFlags &= ~WHERE_WANT_DISTINCT; | ||
| 168387 | wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */ | ||
| 168388 | } | ||
| 166240 | 168389 | ||
| 166241 | /* The number of tables in the FROM clause is limited by the number of | 168390 | /* The number of tables in the FROM clause is limited by the number of |
| 166242 | ** bits in a Bitmask | 168391 | ** bits in a Bitmask |
| @@ -166261,7 +168410,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 166261 | ** field (type Bitmask) it must be aligned on an 8-byte boundary on | 168410 | ** field (type Bitmask) it must be aligned on an 8-byte boundary on |
| 166262 | ** some architectures. Hence the ROUND8() below. | 168411 | ** some architectures. Hence the ROUND8() below. |
| 166263 | */ | 168412 | */ |
| 166264 | nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); | 168413 | nByteWInfo = ROUND8P(sizeof(WhereInfo)); |
| 168414 | if( nTabList>1 ){ | ||
| 168415 | nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); | ||
| 168416 | } | ||
| 166265 | pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); | 168417 | pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); |
| 166266 | if( db->mallocFailed ){ | 168418 | if( db->mallocFailed ){ |
| 166267 | sqlite3DbFree(db, pWInfo); | 168419 | sqlite3DbFree(db, pWInfo); |
| @@ -166315,7 +168467,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 166315 | ){ | 168467 | ){ |
| 166316 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; | 168468 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 166317 | } | 168469 | } |
| 166318 | ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); | 168470 | if( ALWAYS(pWInfo->pSelect) |
| 168471 | && (pWInfo->pSelect->selFlags & SF_MultiValue)==0 | ||
| 168472 | ){ | ||
| 168473 | ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); | ||
| 168474 | } | ||
| 166319 | }else{ | 168475 | }else{ |
| 166320 | /* Assign a bit from the bitmask to every term in the FROM clause. | 168476 | /* Assign a bit from the bitmask to every term in the FROM clause. |
| 166321 | ** | 168477 | ** |
| @@ -166468,6 +168624,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 166468 | wherePathSolver(pWInfo, 0); | 168624 | wherePathSolver(pWInfo, 0); |
| 166469 | if( db->mallocFailed ) goto whereBeginError; | 168625 | if( db->mallocFailed ) goto whereBeginError; |
| 166470 | if( pWInfo->pOrderBy ){ | 168626 | if( pWInfo->pOrderBy ){ |
| 168627 | whereInterstageHeuristic(pWInfo); | ||
| 166471 | wherePathSolver(pWInfo, pWInfo->nRowOut+1); | 168628 | wherePathSolver(pWInfo, pWInfo->nRowOut+1); |
| 166472 | if( db->mallocFailed ) goto whereBeginError; | 168629 | if( db->mallocFailed ) goto whereBeginError; |
| 166473 | } | 168630 | } |
| @@ -166528,10 +168685,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 166528 | ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. | 168685 | ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. |
| 166529 | */ | 168686 | */ |
| 166530 | notReady = ~(Bitmask)0; | 168687 | notReady = ~(Bitmask)0; |
| 166531 | if( pWInfo->nLevel>=2 | 168688 | if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */ |
| 166532 | && pResultSet!=0 /* these two combine to guarantee */ | 168689 | && pResultSet!=0 /* Condition (1) */ |
| 166533 | && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ | 168690 | && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */ |
| 166534 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) | 168691 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */ |
| 166535 | ){ | 168692 | ){ |
| 166536 | notReady = whereOmitNoopJoin(pWInfo, notReady); | 168693 | notReady = whereOmitNoopJoin(pWInfo, notReady); |
| 166537 | nTabList = pWInfo->nLevel; | 168694 | nTabList = pWInfo->nLevel; |
| @@ -166823,6 +168980,11 @@ whereBeginError: | |||
| 166823 | pParse->nQueryLoop = pWInfo->savedNQueryLoop; | 168980 | pParse->nQueryLoop = pWInfo->savedNQueryLoop; |
| 166824 | whereInfoFree(db, pWInfo); | 168981 | whereInfoFree(db, pWInfo); |
| 166825 | } | 168982 | } |
| 168983 | #ifdef WHERETRACE_ENABLED | ||
| 168984 | /* Prevent harmless compiler warnings about debugging routines | ||
| 168985 | ** being declared but never used */ | ||
| 168986 | sqlite3ShowWhereLoopList(0); | ||
| 168987 | #endif /* WHERETRACE_ENABLED */ | ||
| 166826 | return 0; | 168988 | return 0; |
| 166827 | } | 168989 | } |
| 166828 | 168990 | ||
| @@ -166846,26 +169008,6 @@ whereBeginError: | |||
| 166846 | } | 169008 | } |
| 166847 | #endif | 169009 | #endif |
| 166848 | 169010 | ||
| 166849 | #ifdef SQLITE_DEBUG | ||
| 166850 | /* | ||
| 166851 | ** Return true if cursor iCur is opened by instruction k of the | ||
| 166852 | ** bytecode. Used inside of assert() only. | ||
| 166853 | */ | ||
| 166854 | static int cursorIsOpen(Vdbe *v, int iCur, int k){ | ||
| 166855 | while( k>=0 ){ | ||
| 166856 | VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); | ||
| 166857 | if( pOp->p1!=iCur ) continue; | ||
| 166858 | if( pOp->opcode==OP_Close ) return 0; | ||
| 166859 | if( pOp->opcode==OP_OpenRead ) return 1; | ||
| 166860 | if( pOp->opcode==OP_OpenWrite ) return 1; | ||
| 166861 | if( pOp->opcode==OP_OpenDup ) return 1; | ||
| 166862 | if( pOp->opcode==OP_OpenAutoindex ) return 1; | ||
| 166863 | if( pOp->opcode==OP_OpenEphemeral ) return 1; | ||
| 166864 | } | ||
| 166865 | return 0; | ||
| 166866 | } | ||
| 166867 | #endif /* SQLITE_DEBUG */ | ||
| 166868 | |||
| 166869 | /* | 169011 | /* |
| 166870 | ** Generate the end of the WHERE loop. See comments on | 169012 | ** Generate the end of the WHERE loop. See comments on |
| 166871 | ** sqlite3WhereBegin() for additional information. | 169013 | ** sqlite3WhereBegin() for additional information. |
| @@ -167012,7 +169154,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 167012 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); | 169154 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); |
| 167013 | assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); | 169155 | assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); |
| 167014 | if( (ws & WHERE_IDX_ONLY)==0 ){ | 169156 | if( (ws & WHERE_IDX_ONLY)==0 ){ |
| 167015 | assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); | 169157 | SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; |
| 169158 | assert( pLevel->iTabCur==pSrc->iCursor ); | ||
| 169159 | if( pSrc->fg.viaCoroutine ){ | ||
| 169160 | int m, n; | ||
| 169161 | n = pSrc->regResult; | ||
| 169162 | assert( pSrc->pTab!=0 ); | ||
| 169163 | m = pSrc->pTab->nCol; | ||
| 169164 | sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); | ||
| 169165 | } | ||
| 167016 | sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); | 169166 | sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); |
| 167017 | } | 169167 | } |
| 167018 | if( (ws & WHERE_INDEXED) | 169168 | if( (ws & WHERE_INDEXED) |
| @@ -167062,6 +169212,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 167062 | */ | 169212 | */ |
| 167063 | if( pTabItem->fg.viaCoroutine ){ | 169213 | if( pTabItem->fg.viaCoroutine ){ |
| 167064 | testcase( pParse->db->mallocFailed ); | 169214 | testcase( pParse->db->mallocFailed ); |
| 169215 | assert( pTabItem->regResult>=0 ); | ||
| 167065 | translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, | 169216 | translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, |
| 167066 | pTabItem->regResult, 0); | 169217 | pTabItem->regResult, 0); |
| 167067 | continue; | 169218 | continue; |
| @@ -167156,16 +169307,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 167156 | ** reference. Verify that this is harmless - that the | 169307 | ** reference. Verify that this is harmless - that the |
| 167157 | ** table being referenced really is open. | 169308 | ** table being referenced really is open. |
| 167158 | */ | 169309 | */ |
| 167159 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC | 169310 | if( pLoop->wsFlags & WHERE_IDX_ONLY ){ |
| 167160 | assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 | 169311 | sqlite3ErrorMsg(pParse, "internal query planner error"); |
| 167161 | || cursorIsOpen(v,pOp->p1,k) | 169312 | pParse->rc = SQLITE_INTERNAL; |
| 167162 | || pOp->opcode==OP_Offset | 169313 | } |
| 167163 | ); | ||
| 167164 | #else | ||
| 167165 | assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 | ||
| 167166 | || cursorIsOpen(v,pOp->p1,k) | ||
| 167167 | ); | ||
| 167168 | #endif | ||
| 167169 | } | 169314 | } |
| 167170 | }else if( pOp->opcode==OP_Rowid ){ | 169315 | }else if( pOp->opcode==OP_Rowid ){ |
| 167171 | pOp->p1 = pLevel->iIdxCur; | 169316 | pOp->p1 = pLevel->iIdxCur; |
| @@ -168240,7 +170385,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 168240 | assert( ExprUseXList(pWin->pOwner) ); | 170385 | assert( ExprUseXList(pWin->pOwner) ); |
| 168241 | assert( pWin->pWFunc!=0 ); | 170386 | assert( pWin->pWFunc!=0 ); |
| 168242 | pArgs = pWin->pOwner->x.pList; | 170387 | pArgs = pWin->pOwner->x.pList; |
| 168243 | if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ | 170388 | if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){ |
| 168244 | selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); | 170389 | selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); |
| 168245 | pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); | 170390 | pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); |
| 168246 | pWin->bExprArgs = 1; | 170391 | pWin->bExprArgs = 1; |
| @@ -168366,7 +170511,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ | |||
| 168366 | ** variable values in the expression tree. | 170511 | ** variable values in the expression tree. |
| 168367 | */ | 170512 | */ |
| 168368 | static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ | 170513 | static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ |
| 168369 | if( 0==sqlite3ExprIsConstant(pExpr) ){ | 170514 | if( 0==sqlite3ExprIsConstant(0,pExpr) ){ |
| 168370 | if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); | 170515 | if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); |
| 168371 | sqlite3ExprDelete(pParse->db, pExpr); | 170516 | sqlite3ExprDelete(pParse->db, pExpr); |
| 168372 | pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); | 170517 | pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); |
| @@ -170436,9 +172581,9 @@ static void updateDeleteLimitError( | |||
| 170436 | break; | 172581 | break; |
| 170437 | } | 172582 | } |
| 170438 | } | 172583 | } |
| 170439 | if( (p->selFlags & SF_MultiValue)==0 && | 172584 | if( (p->selFlags & (SF_MultiValue|SF_Values))==0 |
| 170440 | (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && | 172585 | && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 |
| 170441 | cnt>mxSelect | 172586 | && cnt>mxSelect |
| 170442 | ){ | 172587 | ){ |
| 170443 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); | 172588 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); |
| 170444 | } | 172589 | } |
| @@ -170458,6 +172603,14 @@ static void updateDeleteLimitError( | |||
| 170458 | return pSelect; | 172603 | return pSelect; |
| 170459 | } | 172604 | } |
| 170460 | 172605 | ||
| 172606 | /* Memory allocator for parser stack resizing. This is a thin wrapper around | ||
| 172607 | ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate | ||
| 172608 | ** testing. | ||
| 172609 | */ | ||
| 172610 | static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ | ||
| 172611 | return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); | ||
| 172612 | } | ||
| 172613 | |||
| 170461 | 172614 | ||
| 170462 | /* Construct a new Expr object from a single token */ | 172615 | /* Construct a new Expr object from a single token */ |
| 170463 | static Expr *tokenExpr(Parse *pParse, int op, Token t){ | 172616 | static Expr *tokenExpr(Parse *pParse, int op, Token t){ |
| @@ -170707,8 +172860,8 @@ static void updateDeleteLimitError( | |||
| 170707 | #define TK_TRUEFALSE 170 | 172860 | #define TK_TRUEFALSE 170 |
| 170708 | #define TK_ISNOT 171 | 172861 | #define TK_ISNOT 171 |
| 170709 | #define TK_FUNCTION 172 | 172862 | #define TK_FUNCTION 172 |
| 170710 | #define TK_UMINUS 173 | 172863 | #define TK_UPLUS 173 |
| 170711 | #define TK_UPLUS 174 | 172864 | #define TK_UMINUS 174 |
| 170712 | #define TK_TRUTH 175 | 172865 | #define TK_TRUTH 175 |
| 170713 | #define TK_REGISTER 176 | 172866 | #define TK_REGISTER 176 |
| 170714 | #define TK_VECTOR 177 | 172867 | #define TK_VECTOR 177 |
| @@ -170717,8 +172870,9 @@ static void updateDeleteLimitError( | |||
| 170717 | #define TK_ASTERISK 180 | 172870 | #define TK_ASTERISK 180 |
| 170718 | #define TK_SPAN 181 | 172871 | #define TK_SPAN 181 |
| 170719 | #define TK_ERROR 182 | 172872 | #define TK_ERROR 182 |
| 170720 | #define TK_SPACE 183 | 172873 | #define TK_QNUMBER 183 |
| 170721 | #define TK_ILLEGAL 184 | 172874 | #define TK_SPACE 184 |
| 172875 | #define TK_ILLEGAL 185 | ||
| 170722 | #endif | 172876 | #endif |
| 170723 | /**************** End token definitions ***************************************/ | 172877 | /**************** End token definitions ***************************************/ |
| 170724 | 172878 | ||
| @@ -170759,6 +172913,9 @@ static void updateDeleteLimitError( | |||
| 170759 | ** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser | 172913 | ** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser |
| 170760 | ** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser | 172914 | ** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser |
| 170761 | ** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context | 172915 | ** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context |
| 172916 | ** YYREALLOC Name of the realloc() function to use | ||
| 172917 | ** YYFREE Name of the free() function to use | ||
| 172918 | ** YYDYNSTACK True if stack space should be extended on heap | ||
| 170762 | ** YYERRORSYMBOL is the code number of the error symbol. If not | 172919 | ** YYERRORSYMBOL is the code number of the error symbol. If not |
| 170763 | ** defined, then do no error processing. | 172920 | ** defined, then do no error processing. |
| 170764 | ** YYNSTATE the combined number of states. | 172921 | ** YYNSTATE the combined number of states. |
| @@ -170772,37 +172929,39 @@ static void updateDeleteLimitError( | |||
| 170772 | ** YY_NO_ACTION The yy_action[] code for no-op | 172929 | ** YY_NO_ACTION The yy_action[] code for no-op |
| 170773 | ** YY_MIN_REDUCE Minimum value for reduce actions | 172930 | ** YY_MIN_REDUCE Minimum value for reduce actions |
| 170774 | ** YY_MAX_REDUCE Maximum value for reduce actions | 172931 | ** YY_MAX_REDUCE Maximum value for reduce actions |
| 172932 | ** YY_MIN_DSTRCTR Minimum symbol value that has a destructor | ||
| 172933 | ** YY_MAX_DSTRCTR Maximum symbol value that has a destructor | ||
| 170775 | */ | 172934 | */ |
| 170776 | #ifndef INTERFACE | 172935 | #ifndef INTERFACE |
| 170777 | # define INTERFACE 1 | 172936 | # define INTERFACE 1 |
| 170778 | #endif | 172937 | #endif |
| 170779 | /************* Begin control #defines *****************************************/ | 172938 | /************* Begin control #defines *****************************************/ |
| 170780 | #define YYCODETYPE unsigned short int | 172939 | #define YYCODETYPE unsigned short int |
| 170781 | #define YYNOCODE 319 | 172940 | #define YYNOCODE 322 |
| 170782 | #define YYACTIONTYPE unsigned short int | 172941 | #define YYACTIONTYPE unsigned short int |
| 170783 | #define YYWILDCARD 101 | 172942 | #define YYWILDCARD 101 |
| 170784 | #define sqlite3ParserTOKENTYPE Token | 172943 | #define sqlite3ParserTOKENTYPE Token |
| 170785 | typedef union { | 172944 | typedef union { |
| 170786 | int yyinit; | 172945 | int yyinit; |
| 170787 | sqlite3ParserTOKENTYPE yy0; | 172946 | sqlite3ParserTOKENTYPE yy0; |
| 170788 | TriggerStep* yy33; | 172947 | ExprList* yy14; |
| 170789 | Window* yy41; | 172948 | With* yy59; |
| 170790 | Select* yy47; | 172949 | Cte* yy67; |
| 170791 | SrcList* yy131; | 172950 | Upsert* yy122; |
| 170792 | struct TrigEvent yy180; | 172951 | IdList* yy132; |
| 170793 | struct {int value; int mask;} yy231; | 172952 | int yy144; |
| 170794 | IdList* yy254; | 172953 | const char* yy168; |
| 170795 | u32 yy285; | 172954 | SrcList* yy203; |
| 170796 | ExprList* yy322; | 172955 | Window* yy211; |
| 170797 | Cte* yy385; | 172956 | OnOrUsing yy269; |
| 170798 | int yy394; | 172957 | struct TrigEvent yy286; |
| 170799 | Upsert* yy444; | 172958 | struct {int value; int mask;} yy383; |
| 170800 | u8 yy516; | 172959 | u32 yy391; |
| 170801 | With* yy521; | 172960 | TriggerStep* yy427; |
| 170802 | const char* yy522; | 172961 | Expr* yy454; |
| 170803 | Expr* yy528; | 172962 | u8 yy462; |
| 170804 | OnOrUsing yy561; | 172963 | struct FrameBound yy509; |
| 170805 | struct FrameBound yy595; | 172964 | Select* yy555; |
| 170806 | } YYMINORTYPE; | 172965 | } YYMINORTYPE; |
| 170807 | #ifndef YYSTACKDEPTH | 172966 | #ifndef YYSTACKDEPTH |
| 170808 | #define YYSTACKDEPTH 100 | 172967 | #define YYSTACKDEPTH 100 |
| @@ -170812,24 +172971,29 @@ typedef union { | |||
| 170812 | #define sqlite3ParserARG_PARAM | 172971 | #define sqlite3ParserARG_PARAM |
| 170813 | #define sqlite3ParserARG_FETCH | 172972 | #define sqlite3ParserARG_FETCH |
| 170814 | #define sqlite3ParserARG_STORE | 172973 | #define sqlite3ParserARG_STORE |
| 172974 | #define YYREALLOC parserStackRealloc | ||
| 172975 | #define YYFREE sqlite3_free | ||
| 172976 | #define YYDYNSTACK 1 | ||
| 170815 | #define sqlite3ParserCTX_SDECL Parse *pParse; | 172977 | #define sqlite3ParserCTX_SDECL Parse *pParse; |
| 170816 | #define sqlite3ParserCTX_PDECL ,Parse *pParse | 172978 | #define sqlite3ParserCTX_PDECL ,Parse *pParse |
| 170817 | #define sqlite3ParserCTX_PARAM ,pParse | 172979 | #define sqlite3ParserCTX_PARAM ,pParse |
| 170818 | #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; | 172980 | #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; |
| 170819 | #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; | 172981 | #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; |
| 170820 | #define YYFALLBACK 1 | 172982 | #define YYFALLBACK 1 |
| 170821 | #define YYNSTATE 579 | 172983 | #define YYNSTATE 583 |
| 170822 | #define YYNRULE 405 | 172984 | #define YYNRULE 409 |
| 170823 | #define YYNRULE_WITH_ACTION 340 | 172985 | #define YYNRULE_WITH_ACTION 344 |
| 170824 | #define YYNTOKEN 185 | 172986 | #define YYNTOKEN 186 |
| 170825 | #define YY_MAX_SHIFT 578 | 172987 | #define YY_MAX_SHIFT 582 |
| 170826 | #define YY_MIN_SHIFTREDUCE 838 | 172988 | #define YY_MIN_SHIFTREDUCE 845 |
| 170827 | #define YY_MAX_SHIFTREDUCE 1242 | 172989 | #define YY_MAX_SHIFTREDUCE 1253 |
| 170828 | #define YY_ERROR_ACTION 1243 | 172990 | #define YY_ERROR_ACTION 1254 |
| 170829 | #define YY_ACCEPT_ACTION 1244 | 172991 | #define YY_ACCEPT_ACTION 1255 |
| 170830 | #define YY_NO_ACTION 1245 | 172992 | #define YY_NO_ACTION 1256 |
| 170831 | #define YY_MIN_REDUCE 1246 | 172993 | #define YY_MIN_REDUCE 1257 |
| 170832 | #define YY_MAX_REDUCE 1650 | 172994 | #define YY_MAX_REDUCE 1665 |
| 172995 | #define YY_MIN_DSTRCTR 205 | ||
| 172996 | #define YY_MAX_DSTRCTR 319 | ||
| 170833 | /************* End control #defines *******************************************/ | 172997 | /************* End control #defines *******************************************/ |
| 170834 | #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) | 172998 | #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) |
| 170835 | 172999 | ||
| @@ -170845,6 +173009,22 @@ typedef union { | |||
| 170845 | # define yytestcase(X) | 173009 | # define yytestcase(X) |
| 170846 | #endif | 173010 | #endif |
| 170847 | 173011 | ||
| 173012 | /* Macro to determine if stack space has the ability to grow using | ||
| 173013 | ** heap memory. | ||
| 173014 | */ | ||
| 173015 | #if YYSTACKDEPTH<=0 || YYDYNSTACK | ||
| 173016 | # define YYGROWABLESTACK 1 | ||
| 173017 | #else | ||
| 173018 | # define YYGROWABLESTACK 0 | ||
| 173019 | #endif | ||
| 173020 | |||
| 173021 | /* Guarantee a minimum number of initial stack slots. | ||
| 173022 | */ | ||
| 173023 | #if YYSTACKDEPTH<=0 | ||
| 173024 | # undef YYSTACKDEPTH | ||
| 173025 | # define YYSTACKDEPTH 2 /* Need a minimum stack size */ | ||
| 173026 | #endif | ||
| 173027 | |||
| 170848 | 173028 | ||
| 170849 | /* Next are the tables used to determine what action to take based on the | 173029 | /* Next are the tables used to determine what action to take based on the |
| 170850 | ** current state and lookahead token. These tables are used to implement | 173030 | ** current state and lookahead token. These tables are used to implement |
| @@ -170896,619 +173076,630 @@ typedef union { | |||
| 170896 | ** yy_default[] Default action for each state. | 173076 | ** yy_default[] Default action for each state. |
| 170897 | ** | 173077 | ** |
| 170898 | *********** Begin parsing tables **********************************************/ | 173078 | *********** Begin parsing tables **********************************************/ |
| 170899 | #define YY_ACTTAB_COUNT (2100) | 173079 | #define YY_ACTTAB_COUNT (2142) |
| 170900 | static const YYACTIONTYPE yy_action[] = { | 173080 | static const YYACTIONTYPE yy_action[] = { |
| 170901 | /* 0 */ 572, 210, 572, 119, 116, 231, 572, 119, 116, 231, | 173081 | /* 0 */ 576, 128, 125, 232, 1622, 549, 576, 1290, 1281, 576, |
| 170902 | /* 10 */ 572, 1317, 379, 1296, 410, 566, 566, 566, 572, 411, | 173082 | /* 10 */ 328, 576, 1300, 212, 576, 128, 125, 232, 578, 412, |
| 170903 | /* 20 */ 380, 1317, 1279, 42, 42, 42, 42, 210, 1529, 72, | 173083 | /* 20 */ 578, 391, 1542, 51, 51, 523, 405, 1293, 529, 51, |
| 170904 | /* 30 */ 72, 974, 421, 42, 42, 495, 305, 281, 305, 975, | 173084 | /* 30 */ 51, 983, 51, 51, 81, 81, 1107, 61, 61, 984, |
| 170905 | /* 40 */ 399, 72, 72, 126, 127, 81, 1217, 1217, 1054, 1057, | 173085 | /* 40 */ 1107, 1292, 380, 135, 136, 90, 1228, 1228, 1063, 1066, |
| 170906 | /* 50 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 480, 411, | 173086 | /* 50 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 1577, 412, |
| 170907 | /* 60 */ 1244, 1, 1, 578, 2, 1248, 554, 119, 116, 231, | 173087 | /* 60 */ 287, 287, 7, 287, 287, 422, 1050, 1050, 1064, 1067, |
| 170908 | /* 70 */ 319, 484, 147, 484, 528, 119, 116, 231, 533, 1330, | 173088 | /* 70 */ 289, 556, 492, 573, 524, 561, 573, 497, 561, 482, |
| 170909 | /* 80 */ 419, 527, 143, 126, 127, 81, 1217, 1217, 1054, 1057, | 173089 | /* 80 */ 530, 262, 229, 135, 136, 90, 1228, 1228, 1063, 1066, |
| 170910 | /* 90 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 119, 116, | 173090 | /* 90 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 128, 125, |
| 170911 | /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121, | 173091 | /* 100 */ 232, 1506, 132, 132, 132, 132, 131, 131, 130, 130, |
| 170912 | /* 110 */ 121, 120, 117, 448, 286, 286, 286, 286, 446, 446, | 173092 | /* 110 */ 130, 129, 126, 450, 1204, 1255, 1, 1, 582, 2, |
| 170913 | /* 120 */ 446, 1568, 378, 1570, 1193, 377, 1164, 569, 1164, 569, | 173093 | /* 120 */ 1259, 1571, 420, 1582, 379, 320, 1174, 153, 1174, 1584, |
| 170914 | /* 130 */ 411, 1568, 541, 261, 228, 448, 102, 146, 453, 318, | 173094 | /* 130 */ 412, 378, 1582, 543, 1341, 330, 111, 570, 570, 570, |
| 170915 | /* 140 */ 563, 242, 123, 123, 123, 123, 122, 122, 121, 121, | 173095 | /* 140 */ 293, 1054, 132, 132, 132, 132, 131, 131, 130, 130, |
| 170916 | /* 150 */ 121, 120, 117, 448, 126, 127, 81, 1217, 1217, 1054, | 173096 | /* 150 */ 130, 129, 126, 450, 135, 136, 90, 1228, 1228, 1063, |
| 170917 | /* 160 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 143, | 173097 | /* 160 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 287, |
| 170918 | /* 170 */ 296, 1193, 341, 452, 121, 121, 121, 120, 117, 448, | 173098 | /* 170 */ 287, 1204, 1205, 1204, 255, 287, 287, 510, 507, 506, |
| 170919 | /* 180 */ 128, 1193, 1194, 1193, 149, 445, 444, 572, 120, 117, | 173099 | /* 180 */ 137, 455, 573, 212, 561, 447, 446, 505, 573, 1616, |
| 170920 | /* 190 */ 448, 125, 125, 125, 125, 118, 123, 123, 123, 123, | 173100 | /* 190 */ 561, 134, 134, 134, 134, 127, 400, 243, 132, 132, |
| 170921 | /* 200 */ 122, 122, 121, 121, 121, 120, 117, 448, 458, 114, | 173101 | /* 200 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, |
| 170922 | /* 210 */ 13, 13, 550, 123, 123, 123, 123, 122, 122, 121, | 173102 | /* 210 */ 282, 471, 345, 132, 132, 132, 132, 131, 131, 130, |
| 170923 | /* 220 */ 121, 121, 120, 117, 448, 424, 318, 563, 1193, 1194, | 173103 | /* 220 */ 130, 130, 129, 126, 450, 574, 155, 936, 936, 454, |
| 170924 | /* 230 */ 1193, 150, 1225, 411, 1225, 125, 125, 125, 125, 123, | 173104 | /* 230 */ 227, 521, 1236, 412, 1236, 134, 134, 134, 134, 132, |
| 170925 | /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, | 173105 | /* 240 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, |
| 170926 | /* 250 */ 448, 469, 344, 1041, 1041, 1055, 1058, 126, 127, 81, | 173106 | /* 250 */ 450, 130, 130, 130, 129, 126, 450, 135, 136, 90, |
| 170927 | /* 260 */ 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, | 173107 | /* 260 */ 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, |
| 170928 | /* 270 */ 125, 125, 1282, 526, 224, 1193, 572, 411, 226, 519, | 173108 | /* 270 */ 134, 134, 128, 125, 232, 450, 576, 412, 397, 1249, |
| 170929 | /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121, | 173109 | /* 280 */ 180, 92, 93, 132, 132, 132, 132, 131, 131, 130, |
| 170930 | /* 290 */ 121, 121, 120, 117, 448, 1010, 16, 16, 1193, 134, | 173110 | /* 290 */ 130, 130, 129, 126, 450, 381, 387, 1204, 383, 81, |
| 170931 | /* 300 */ 134, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, | 173111 | /* 300 */ 81, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, |
| 170932 | /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123, | 173112 | /* 310 */ 133, 133, 134, 134, 134, 134, 132, 132, 132, 132, |
| 170933 | /* 320 */ 122, 122, 121, 121, 121, 120, 117, 448, 1045, 550, | 173113 | /* 320 */ 131, 131, 130, 130, 130, 129, 126, 450, 131, 131, |
| 170934 | /* 330 */ 1193, 375, 1193, 1194, 1193, 254, 1438, 401, 508, 505, | 173114 | /* 330 */ 130, 130, 130, 129, 126, 450, 556, 1204, 302, 319, |
| 170935 | /* 340 */ 504, 112, 564, 570, 4, 929, 929, 435, 503, 342, | 173115 | /* 340 */ 567, 121, 568, 480, 4, 555, 1149, 1657, 1628, 1657, |
| 170936 | /* 350 */ 464, 330, 362, 396, 1238, 1193, 1194, 1193, 567, 572, | 173116 | /* 350 */ 45, 128, 125, 232, 1204, 1205, 1204, 1250, 571, 1169, |
| 170937 | /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120, | 173117 | /* 360 */ 132, 132, 132, 132, 131, 131, 130, 130, 130, 129, |
| 170938 | /* 370 */ 117, 448, 286, 286, 371, 1581, 1607, 445, 444, 155, | 173118 | /* 370 */ 126, 450, 1169, 287, 287, 1169, 1019, 576, 422, 1019, |
| 170939 | /* 380 */ 411, 449, 72, 72, 1289, 569, 1222, 1193, 1194, 1193, | 173119 | /* 380 */ 412, 451, 1602, 582, 2, 1259, 573, 44, 561, 95, |
| 170940 | /* 390 */ 86, 1224, 273, 561, 547, 520, 520, 572, 99, 1223, | 173120 | /* 390 */ 320, 110, 153, 565, 1204, 1205, 1204, 522, 522, 1341, |
| 170941 | /* 400 */ 6, 1281, 476, 143, 126, 127, 81, 1217, 1217, 1054, | 173121 | /* 400 */ 81, 81, 7, 44, 135, 136, 90, 1228, 1228, 1063, |
| 170942 | /* 410 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 554, | 173122 | /* 410 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 295, |
| 170943 | /* 420 */ 13, 13, 1031, 511, 1225, 1193, 1225, 553, 110, 110, | 173123 | /* 420 */ 1149, 1658, 1040, 1658, 1204, 1147, 319, 567, 119, 119, |
| 170944 | /* 430 */ 224, 572, 1239, 177, 572, 429, 111, 199, 449, 573, | 173124 | /* 430 */ 343, 466, 331, 343, 287, 287, 120, 556, 451, 577, |
| 170945 | /* 440 */ 449, 432, 1555, 1019, 327, 555, 1193, 272, 289, 370, | 173125 | /* 440 */ 451, 1169, 1169, 1028, 319, 567, 438, 573, 210, 561, |
| 170946 | /* 450 */ 514, 365, 513, 259, 72, 72, 547, 72, 72, 361, | 173126 | /* 450 */ 1339, 1451, 546, 531, 1169, 1169, 1598, 1169, 1169, 416, |
| 170947 | /* 460 */ 318, 563, 1613, 123, 123, 123, 123, 122, 122, 121, | 173127 | /* 460 */ 319, 567, 243, 132, 132, 132, 132, 131, 131, 130, |
| 170948 | /* 470 */ 121, 121, 120, 117, 448, 1019, 1019, 1021, 1022, 28, | 173128 | /* 470 */ 130, 130, 129, 126, 450, 1028, 1028, 1030, 1031, 35, |
| 170949 | /* 480 */ 286, 286, 1193, 1194, 1193, 1159, 572, 1612, 411, 904, | 173129 | /* 480 */ 44, 1204, 1205, 1204, 472, 287, 287, 1328, 412, 1307, |
| 170950 | /* 490 */ 192, 554, 358, 569, 554, 940, 537, 521, 1159, 437, | 173130 | /* 490 */ 372, 1595, 359, 225, 454, 1204, 195, 1328, 573, 1147, |
| 170951 | /* 500 */ 415, 1159, 556, 1193, 1194, 1193, 572, 548, 548, 52, | 173131 | /* 500 */ 561, 1333, 1333, 274, 576, 1188, 576, 340, 46, 196, |
| 170952 | /* 510 */ 52, 216, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, | 173132 | /* 510 */ 537, 217, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, |
| 170953 | /* 520 */ 1044, 124, 124, 125, 125, 125, 125, 1193, 478, 136, | 173133 | /* 520 */ 1053, 133, 133, 134, 134, 134, 134, 19, 19, 19, |
| 170954 | /* 530 */ 136, 411, 286, 286, 1493, 509, 122, 122, 121, 121, | 173134 | /* 530 */ 19, 412, 581, 1204, 1259, 511, 1204, 319, 567, 320, |
| 170955 | /* 540 */ 121, 120, 117, 448, 1010, 569, 522, 219, 545, 545, | 173135 | /* 540 */ 944, 153, 425, 491, 430, 943, 1204, 488, 1341, 1450, |
| 170956 | /* 550 */ 318, 563, 143, 6, 536, 126, 127, 81, 1217, 1217, | 173136 | /* 550 */ 532, 1277, 1204, 1205, 1204, 135, 136, 90, 1228, 1228, |
| 170957 | /* 560 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, | 173137 | /* 560 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, |
| 170958 | /* 570 */ 1557, 123, 123, 123, 123, 122, 122, 121, 121, 121, | 173138 | /* 570 */ 575, 132, 132, 132, 132, 131, 131, 130, 130, 130, |
| 170959 | /* 580 */ 120, 117, 448, 489, 1193, 1194, 1193, 486, 283, 1270, | 173139 | /* 580 */ 129, 126, 450, 287, 287, 528, 287, 287, 372, 1595, |
| 170960 | /* 590 */ 960, 254, 1193, 375, 508, 505, 504, 1193, 342, 574, | 173140 | /* 590 */ 1204, 1205, 1204, 1204, 1205, 1204, 573, 486, 561, 573, |
| 170961 | /* 600 */ 1193, 574, 411, 294, 503, 960, 879, 193, 484, 318, | 173141 | /* 600 */ 889, 561, 412, 1204, 1205, 1204, 886, 40, 22, 22, |
| 170962 | /* 610 */ 563, 386, 292, 382, 123, 123, 123, 123, 122, 122, | 173142 | /* 610 */ 220, 243, 525, 1449, 132, 132, 132, 132, 131, 131, |
| 170963 | /* 620 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, | 173143 | /* 620 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, |
| 170964 | /* 630 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173144 | /* 630 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 170965 | /* 640 */ 125, 411, 396, 1139, 1193, 872, 101, 286, 286, 1193, | 173145 | /* 640 */ 134, 412, 180, 454, 1204, 879, 255, 287, 287, 510, |
| 170966 | /* 650 */ 1194, 1193, 375, 1096, 1193, 1194, 1193, 1193, 1194, 1193, | 173146 | /* 650 */ 507, 506, 372, 1595, 1568, 1331, 1331, 576, 889, 505, |
| 170967 | /* 660 */ 569, 459, 33, 375, 235, 126, 127, 81, 1217, 1217, | 173147 | /* 660 */ 573, 44, 561, 559, 1207, 135, 136, 90, 1228, 1228, |
| 170968 | /* 670 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, | 173148 | /* 670 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, |
| 170969 | /* 680 */ 1437, 962, 572, 230, 961, 123, 123, 123, 123, 122, | 173149 | /* 680 */ 81, 81, 422, 576, 377, 132, 132, 132, 132, 131, |
| 170970 | /* 690 */ 122, 121, 121, 121, 120, 117, 448, 1159, 230, 1193, | 173150 | /* 690 */ 131, 130, 130, 130, 129, 126, 450, 297, 287, 287, |
| 170971 | /* 700 */ 158, 1193, 1194, 1193, 1556, 13, 13, 303, 960, 1233, | 173151 | /* 700 */ 460, 1204, 1205, 1204, 1204, 534, 19, 19, 448, 448, |
| 170972 | /* 710 */ 1159, 154, 411, 1159, 375, 1584, 1177, 5, 371, 1581, | 173152 | /* 710 */ 448, 573, 412, 561, 230, 436, 1187, 535, 319, 567, |
| 170973 | /* 720 */ 431, 1239, 3, 960, 123, 123, 123, 123, 122, 122, | 173153 | /* 720 */ 363, 432, 1207, 1435, 132, 132, 132, 132, 131, 131, |
| 170974 | /* 730 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, | 173154 | /* 730 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, |
| 170975 | /* 740 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173155 | /* 740 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 170976 | /* 750 */ 125, 411, 210, 571, 1193, 1032, 1193, 1194, 1193, 1193, | 173156 | /* 750 */ 134, 412, 211, 949, 1169, 1041, 1110, 1110, 494, 547, |
| 170977 | /* 760 */ 390, 855, 156, 1555, 376, 404, 1101, 1101, 492, 572, | 173157 | /* 760 */ 547, 1204, 1205, 1204, 7, 539, 1570, 1169, 376, 576, |
| 170978 | /* 770 */ 469, 344, 1322, 1322, 1555, 126, 127, 81, 1217, 1217, | 173158 | /* 770 */ 1169, 5, 1204, 486, 3, 135, 136, 90, 1228, 1228, |
| 170979 | /* 780 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, | 173159 | /* 780 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, |
| 170980 | /* 790 */ 130, 572, 13, 13, 532, 123, 123, 123, 123, 122, | 173160 | /* 790 */ 576, 513, 19, 19, 427, 132, 132, 132, 132, 131, |
| 170981 | /* 800 */ 122, 121, 121, 121, 120, 117, 448, 304, 572, 457, | 173161 | /* 800 */ 131, 130, 130, 130, 129, 126, 450, 305, 1204, 433, |
| 170982 | /* 810 */ 229, 1193, 1194, 1193, 13, 13, 1193, 1194, 1193, 1300, | 173162 | /* 810 */ 225, 1204, 385, 19, 19, 273, 290, 371, 516, 366, |
| 170983 | /* 820 */ 467, 1270, 411, 1320, 1320, 1555, 1015, 457, 456, 436, | 173163 | /* 820 */ 515, 260, 412, 538, 1568, 549, 1024, 362, 437, 1204, |
| 170984 | /* 830 */ 301, 72, 72, 1268, 123, 123, 123, 123, 122, 122, | 173164 | /* 830 */ 1205, 1204, 902, 1552, 132, 132, 132, 132, 131, 131, |
| 170985 | /* 840 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, | 173165 | /* 840 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, |
| 170986 | /* 850 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173166 | /* 850 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 170987 | /* 860 */ 125, 411, 384, 1076, 1159, 286, 286, 421, 314, 280, | 173167 | /* 860 */ 134, 412, 1435, 514, 1281, 1204, 1205, 1204, 1204, 1205, |
| 170988 | /* 870 */ 280, 287, 287, 461, 408, 407, 1539, 1159, 569, 572, | 173168 | /* 870 */ 1204, 903, 48, 342, 1568, 1568, 1279, 1627, 1568, 911, |
| 170989 | /* 880 */ 1159, 1196, 569, 409, 569, 126, 127, 81, 1217, 1217, | 173169 | /* 880 */ 576, 129, 126, 450, 110, 135, 136, 90, 1228, 1228, |
| 170990 | /* 890 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, | 173170 | /* 890 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, |
| 170991 | /* 900 */ 457, 1485, 13, 13, 1541, 123, 123, 123, 123, 122, | 173171 | /* 900 */ 265, 576, 459, 19, 19, 132, 132, 132, 132, 131, |
| 170992 | /* 910 */ 122, 121, 121, 121, 120, 117, 448, 202, 572, 462, | 173172 | /* 910 */ 131, 130, 130, 130, 129, 126, 450, 1345, 204, 576, |
| 170993 | /* 920 */ 1587, 578, 2, 1248, 843, 844, 845, 1563, 319, 409, | 173173 | /* 920 */ 459, 458, 50, 47, 19, 19, 49, 434, 1105, 573, |
| 170994 | /* 930 */ 147, 6, 411, 257, 256, 255, 208, 1330, 9, 1196, | 173174 | /* 930 */ 497, 561, 412, 428, 108, 1224, 1569, 1554, 376, 205, |
| 170995 | /* 940 */ 264, 72, 72, 1436, 123, 123, 123, 123, 122, 122, | 173175 | /* 940 */ 550, 550, 81, 81, 132, 132, 132, 132, 131, 131, |
| 170996 | /* 950 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, | 173176 | /* 950 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, |
| 170997 | /* 960 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173177 | /* 960 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 170998 | /* 970 */ 125, 572, 286, 286, 572, 1213, 411, 577, 315, 1248, | 173178 | /* 970 */ 134, 480, 576, 1204, 576, 1541, 412, 1435, 969, 315, |
| 170999 | /* 980 */ 421, 371, 1581, 356, 319, 569, 147, 495, 529, 1644, | 173179 | /* 980 */ 1659, 398, 284, 497, 969, 893, 1569, 1569, 376, 376, |
| 171000 | /* 990 */ 397, 935, 495, 1330, 71, 71, 934, 72, 72, 242, | 173180 | /* 990 */ 1569, 461, 376, 1224, 459, 80, 80, 81, 81, 497, |
| 171001 | /* 1000 */ 1328, 105, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, | 173181 | /* 1000 */ 374, 114, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, |
| 171002 | /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122, | 173182 | /* 1010 */ 133, 134, 134, 134, 134, 132, 132, 132, 132, 131, |
| 171003 | /* 1020 */ 122, 121, 121, 121, 120, 117, 448, 1117, 286, 286, | 173183 | /* 1020 */ 131, 130, 130, 130, 129, 126, 450, 1204, 1505, 576, |
| 171004 | /* 1030 */ 1422, 452, 1528, 1213, 443, 286, 286, 1492, 1355, 313, | 173184 | /* 1030 */ 1204, 1205, 1204, 1366, 316, 486, 281, 281, 497, 431, |
| 171005 | /* 1040 */ 478, 569, 1118, 454, 351, 495, 354, 1266, 569, 209, | 173185 | /* 1040 */ 557, 288, 288, 402, 1340, 471, 345, 298, 429, 573, |
| 171006 | /* 1050 */ 572, 418, 179, 572, 1031, 242, 385, 1119, 523, 123, | 173186 | /* 1050 */ 576, 561, 81, 81, 573, 374, 561, 971, 386, 132, |
| 171007 | /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, | 173187 | /* 1060 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, |
| 171008 | /* 1070 */ 448, 1020, 108, 72, 72, 1019, 13, 13, 915, 572, | 173188 | /* 1070 */ 450, 231, 117, 81, 81, 287, 287, 231, 287, 287, |
| 171009 | /* 1080 */ 1498, 572, 286, 286, 98, 530, 1537, 452, 916, 1334, | 173189 | /* 1080 */ 576, 1511, 576, 1336, 1204, 1205, 1204, 139, 573, 556, |
| 171010 | /* 1090 */ 1329, 203, 411, 286, 286, 569, 152, 211, 1498, 1500, | 173190 | /* 1090 */ 561, 573, 412, 561, 441, 456, 969, 213, 558, 1511, |
| 171011 | /* 1100 */ 426, 569, 56, 56, 57, 57, 569, 1019, 1019, 1021, | 173191 | /* 1100 */ 1513, 1550, 969, 143, 143, 145, 145, 1368, 314, 478, |
| 171012 | /* 1110 */ 447, 572, 411, 531, 12, 297, 126, 127, 81, 1217, | 173192 | /* 1110 */ 444, 970, 412, 850, 851, 852, 135, 136, 90, 1228, |
| 171013 | /* 1120 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173193 | /* 1120 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 171014 | /* 1130 */ 125, 572, 411, 867, 15, 15, 126, 127, 81, 1217, | 173194 | /* 1130 */ 134, 357, 412, 397, 1148, 304, 135, 136, 90, 1228, |
| 171015 | /* 1140 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173195 | /* 1140 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 171016 | /* 1150 */ 125, 373, 529, 264, 44, 44, 126, 115, 81, 1217, | 173196 | /* 1150 */ 134, 1575, 323, 6, 862, 7, 135, 124, 90, 1228, |
| 171017 | /* 1160 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, | 173197 | /* 1160 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, |
| 171018 | /* 1170 */ 125, 1498, 478, 1271, 417, 123, 123, 123, 123, 122, | 173198 | /* 1170 */ 134, 409, 408, 1511, 212, 132, 132, 132, 132, 131, |
| 171019 | /* 1180 */ 122, 121, 121, 121, 120, 117, 448, 205, 1213, 495, | 173199 | /* 1180 */ 131, 130, 130, 130, 129, 126, 450, 411, 118, 1204, |
| 171020 | /* 1190 */ 430, 867, 468, 322, 495, 123, 123, 123, 123, 122, | 173200 | /* 1190 */ 116, 10, 352, 265, 355, 132, 132, 132, 132, 131, |
| 171021 | /* 1200 */ 122, 121, 121, 121, 120, 117, 448, 572, 557, 1140, | 173201 | /* 1200 */ 131, 130, 130, 130, 129, 126, 450, 576, 324, 306, |
| 171022 | /* 1210 */ 1642, 1422, 1642, 543, 572, 123, 123, 123, 123, 122, | 173202 | /* 1210 */ 576, 306, 1250, 469, 158, 132, 132, 132, 132, 131, |
| 171023 | /* 1220 */ 122, 121, 121, 121, 120, 117, 448, 572, 1422, 572, | 173203 | /* 1220 */ 131, 130, 130, 130, 129, 126, 450, 207, 1224, 1126, |
| 171024 | /* 1230 */ 13, 13, 542, 323, 1325, 411, 334, 58, 58, 349, | 173204 | /* 1230 */ 65, 65, 470, 66, 66, 412, 447, 446, 882, 531, |
| 171025 | /* 1240 */ 1422, 1170, 326, 286, 286, 549, 1213, 300, 895, 530, | 173205 | /* 1240 */ 335, 258, 257, 256, 1127, 1233, 1204, 1205, 1204, 327, |
| 171026 | /* 1250 */ 45, 45, 59, 59, 1140, 1643, 569, 1643, 565, 417, | 173206 | /* 1250 */ 1235, 874, 159, 576, 16, 480, 1085, 1040, 1234, 1128, |
| 171027 | /* 1260 */ 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, | 173207 | /* 1260 */ 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, |
| 171028 | /* 1270 */ 125, 125, 125, 125, 1367, 373, 500, 290, 1193, 512, | 173208 | /* 1270 */ 134, 134, 134, 134, 1029, 576, 81, 81, 1028, 1040, |
| 171029 | /* 1280 */ 1366, 427, 394, 394, 393, 275, 391, 896, 1138, 852, | 173209 | /* 1280 */ 922, 576, 463, 1236, 576, 1236, 1224, 502, 107, 1435, |
| 171030 | /* 1290 */ 478, 258, 1422, 1170, 463, 1159, 12, 331, 428, 333, | 173210 | /* 1290 */ 923, 6, 576, 410, 1498, 882, 1029, 480, 21, 21, |
| 171031 | /* 1300 */ 1117, 460, 236, 258, 325, 460, 544, 1544, 1159, 1098, | 173211 | /* 1300 */ 1028, 332, 1380, 334, 53, 53, 497, 81, 81, 874, |
| 171032 | /* 1310 */ 491, 1159, 324, 1098, 440, 1118, 335, 516, 123, 123, | 173212 | /* 1310 */ 1028, 1028, 1030, 445, 259, 19, 19, 533, 132, 132, |
| 171033 | /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 448, | 173213 | /* 1320 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, |
| 171034 | /* 1330 */ 1119, 318, 563, 1138, 572, 1193, 1194, 1193, 112, 564, | 173214 | /* 1330 */ 551, 301, 1028, 1028, 1030, 107, 532, 545, 121, 568, |
| 171035 | /* 1340 */ 201, 4, 238, 433, 935, 490, 285, 228, 1517, 934, | 173215 | /* 1340 */ 1188, 4, 1126, 1576, 449, 576, 462, 7, 1282, 418, |
| 171036 | /* 1350 */ 170, 560, 572, 142, 1516, 567, 572, 60, 60, 572, | 173216 | /* 1350 */ 462, 350, 1435, 576, 518, 571, 544, 1127, 121, 568, |
| 171037 | /* 1360 */ 416, 572, 441, 572, 535, 302, 875, 8, 487, 572, | 173217 | /* 1360 */ 442, 4, 1188, 464, 533, 1180, 1223, 9, 67, 67, |
| 171038 | /* 1370 */ 237, 572, 416, 572, 485, 61, 61, 572, 449, 62, | 173218 | /* 1370 */ 487, 576, 1128, 303, 410, 571, 54, 54, 451, 576, |
| 171039 | /* 1380 */ 62, 332, 63, 63, 46, 46, 47, 47, 361, 572, | 173219 | /* 1380 */ 123, 944, 576, 417, 576, 333, 943, 1379, 576, 236, |
| 171040 | /* 1390 */ 561, 572, 48, 48, 50, 50, 51, 51, 572, 295, | 173220 | /* 1390 */ 565, 576, 1574, 564, 68, 68, 7, 576, 451, 362, |
| 171041 | /* 1400 */ 64, 64, 482, 295, 539, 412, 471, 1031, 572, 538, | 173221 | /* 1400 */ 419, 182, 69, 69, 541, 70, 70, 71, 71, 540, |
| 171042 | /* 1410 */ 318, 563, 65, 65, 66, 66, 409, 475, 572, 1031, | 173222 | /* 1410 */ 565, 72, 72, 484, 55, 55, 473, 1180, 296, 1040, |
| 171043 | /* 1420 */ 572, 14, 14, 875, 1020, 110, 110, 409, 1019, 572, | 173223 | /* 1420 */ 56, 56, 296, 493, 541, 119, 119, 410, 1573, 542, |
| 171044 | /* 1430 */ 474, 67, 67, 111, 455, 449, 573, 449, 98, 317, | 173224 | /* 1430 */ 569, 418, 7, 120, 1244, 451, 577, 451, 465, 1040, |
| 171045 | /* 1440 */ 1019, 132, 132, 133, 133, 572, 1561, 572, 974, 409, | 173225 | /* 1440 */ 1028, 576, 1557, 552, 476, 119, 119, 527, 259, 121, |
| 171046 | /* 1450 */ 6, 1562, 68, 68, 1560, 6, 975, 572, 6, 1559, | 173226 | /* 1450 */ 568, 240, 4, 120, 576, 451, 577, 451, 576, 477, |
| 171047 | /* 1460 */ 1019, 1019, 1021, 6, 346, 218, 101, 531, 53, 53, | 173227 | /* 1460 */ 1028, 576, 156, 576, 57, 57, 571, 576, 286, 229, |
| 171048 | /* 1470 */ 69, 69, 1019, 1019, 1021, 1022, 28, 1586, 1181, 451, | 173228 | /* 1470 */ 410, 336, 1028, 1028, 1030, 1031, 35, 59, 59, 219, |
| 171049 | /* 1480 */ 70, 70, 290, 87, 215, 31, 1363, 394, 394, 393, | 173229 | /* 1480 */ 983, 60, 60, 220, 73, 73, 74, 74, 984, 451, |
| 171050 | /* 1490 */ 275, 391, 350, 109, 852, 107, 572, 112, 564, 483, | 173230 | /* 1490 */ 75, 75, 1028, 1028, 1030, 1031, 35, 96, 216, 291, |
| 171051 | /* 1500 */ 4, 1212, 572, 239, 153, 572, 39, 236, 1299, 325, | 173231 | /* 1500 */ 552, 565, 1188, 318, 395, 395, 394, 276, 392, 576, |
| 171052 | /* 1510 */ 112, 564, 1298, 4, 567, 572, 32, 324, 572, 54, | 173232 | /* 1510 */ 485, 859, 474, 1311, 410, 541, 576, 417, 1530, 1144, |
| 171053 | /* 1520 */ 54, 572, 1135, 353, 398, 165, 165, 567, 166, 166, | 173233 | /* 1520 */ 540, 399, 1188, 292, 237, 1153, 326, 38, 23, 576, |
| 171054 | /* 1530 */ 572, 291, 355, 572, 17, 357, 572, 449, 77, 77, | 173234 | /* 1530 */ 1040, 576, 20, 20, 325, 299, 119, 119, 164, 76, |
| 171055 | /* 1540 */ 1313, 55, 55, 1297, 73, 73, 572, 238, 470, 561, | 173235 | /* 1540 */ 76, 1529, 121, 568, 120, 4, 451, 577, 451, 203, |
| 171056 | /* 1550 */ 449, 472, 364, 135, 135, 170, 74, 74, 142, 163, | 173236 | /* 1550 */ 576, 1028, 141, 141, 142, 142, 576, 322, 39, 571, |
| 171057 | /* 1560 */ 163, 374, 561, 539, 572, 321, 572, 886, 540, 137, | 173237 | /* 1560 */ 341, 1021, 110, 264, 239, 901, 900, 423, 242, 908, |
| 171058 | /* 1570 */ 137, 339, 1353, 422, 298, 237, 539, 572, 1031, 572, | 173238 | /* 1570 */ 909, 370, 173, 77, 77, 43, 479, 1310, 264, 62, |
| 171059 | /* 1580 */ 340, 538, 101, 369, 110, 110, 162, 131, 131, 164, | 173239 | /* 1580 */ 62, 369, 451, 1028, 1028, 1030, 1031, 35, 1601, 1192, |
| 171060 | /* 1590 */ 164, 1031, 111, 368, 449, 573, 449, 110, 110, 1019, | 173240 | /* 1590 */ 453, 1092, 238, 291, 565, 163, 1309, 110, 395, 395, |
| 171061 | /* 1600 */ 157, 157, 141, 141, 572, 111, 572, 449, 573, 449, | 173241 | /* 1600 */ 394, 276, 392, 986, 987, 859, 481, 346, 264, 110, |
| 171062 | /* 1610 */ 412, 288, 1019, 572, 882, 318, 563, 572, 219, 572, | 173242 | /* 1610 */ 1032, 489, 576, 1188, 503, 1088, 261, 261, 237, 576, |
| 171063 | /* 1620 */ 241, 1012, 477, 263, 263, 894, 893, 140, 140, 138, | 173243 | /* 1620 */ 326, 121, 568, 1040, 4, 347, 1376, 413, 325, 119, |
| 171064 | /* 1630 */ 138, 1019, 1019, 1021, 1022, 28, 139, 139, 525, 455, | 173244 | /* 1630 */ 119, 948, 319, 567, 351, 78, 78, 120, 571, 451, |
| 171065 | /* 1640 */ 76, 76, 78, 78, 1019, 1019, 1021, 1022, 28, 1181, | 173245 | /* 1640 */ 577, 451, 79, 79, 1028, 354, 356, 576, 360, 1092, |
| 171066 | /* 1650 */ 451, 572, 1083, 290, 112, 564, 1575, 4, 394, 394, | 173246 | /* 1650 */ 110, 576, 974, 942, 264, 123, 457, 358, 239, 576, |
| 171067 | /* 1660 */ 393, 275, 391, 572, 1023, 852, 572, 479, 345, 263, | 173247 | /* 1660 */ 519, 451, 939, 1104, 123, 1104, 173, 576, 1032, 43, |
| 171068 | /* 1670 */ 101, 567, 882, 1376, 75, 75, 1421, 501, 236, 260, | 173248 | /* 1670 */ 63, 63, 1324, 565, 168, 168, 1028, 1028, 1030, 1031, |
| 171069 | /* 1680 */ 325, 112, 564, 359, 4, 101, 43, 43, 324, 49, | 173249 | /* 1680 */ 35, 576, 169, 169, 1308, 872, 238, 157, 1589, 576, |
| 171070 | /* 1690 */ 49, 901, 902, 161, 449, 101, 977, 978, 567, 1079, | 173250 | /* 1690 */ 86, 86, 365, 89, 568, 375, 4, 1103, 941, 1103, |
| 171071 | /* 1700 */ 1349, 260, 965, 932, 263, 114, 561, 1095, 517, 1095, | 173251 | /* 1700 */ 123, 576, 1040, 1389, 64, 64, 1188, 1434, 119, 119, |
| 171072 | /* 1710 */ 1083, 1094, 865, 1094, 151, 933, 1144, 114, 238, 1361, | 173252 | /* 1710 */ 571, 576, 82, 82, 563, 576, 120, 165, 451, 577, |
| 171073 | /* 1720 */ 558, 449, 1023, 559, 1426, 1278, 170, 1269, 1257, 142, | 173253 | /* 1720 */ 451, 413, 1362, 1028, 144, 144, 319, 567, 576, 1374, |
| 171074 | /* 1730 */ 1601, 1256, 1258, 561, 1594, 1031, 496, 278, 213, 1346, | 173254 | /* 1730 */ 562, 498, 279, 451, 83, 83, 1439, 576, 166, 166, |
| 171075 | /* 1740 */ 310, 110, 110, 939, 311, 312, 237, 11, 234, 111, | 173255 | /* 1740 */ 576, 1289, 554, 576, 1280, 565, 576, 12, 576, 1268, |
| 171076 | /* 1750 */ 221, 449, 573, 449, 293, 395, 1019, 1408, 337, 1403, | 173256 | /* 1750 */ 457, 146, 146, 1267, 576, 1028, 1028, 1030, 1031, 35, |
| 171077 | /* 1760 */ 1396, 338, 1031, 299, 343, 1413, 1412, 481, 110, 110, | 173257 | /* 1760 */ 140, 140, 1269, 167, 167, 1609, 160, 160, 1359, 150, |
| 171078 | /* 1770 */ 506, 402, 225, 1296, 206, 367, 111, 1358, 449, 573, | 173258 | /* 1770 */ 150, 149, 149, 311, 1040, 576, 312, 147, 147, 313, |
| 171079 | /* 1780 */ 449, 412, 1359, 1019, 1489, 1488, 318, 563, 1019, 1019, | 173259 | /* 1780 */ 119, 119, 222, 235, 576, 1188, 396, 576, 120, 576, |
| 171080 | /* 1790 */ 1021, 1022, 28, 562, 207, 220, 80, 564, 389, 4, | 173260 | /* 1790 */ 451, 577, 451, 1192, 453, 1028, 508, 291, 148, 148, |
| 171081 | /* 1800 */ 1597, 1357, 552, 1356, 1233, 181, 267, 232, 1536, 1534, | 173261 | /* 1800 */ 1421, 1612, 395, 395, 394, 276, 392, 85, 85, 859, |
| 171082 | /* 1810 */ 455, 1230, 420, 567, 82, 1019, 1019, 1021, 1022, 28, | 173262 | /* 1810 */ 87, 87, 84, 84, 553, 576, 294, 576, 1426, 338, |
| 171083 | /* 1820 */ 86, 217, 85, 1494, 190, 175, 183, 465, 185, 466, | 173263 | /* 1820 */ 339, 1425, 237, 300, 326, 1416, 1409, 1028, 1028, 1030, |
| 171084 | /* 1830 */ 36, 1409, 186, 187, 188, 499, 449, 244, 37, 99, | 173264 | /* 1830 */ 1031, 35, 325, 344, 403, 483, 226, 1307, 52, 52, |
| 171085 | /* 1840 */ 400, 1415, 1414, 488, 1417, 194, 473, 403, 561, 1483, | 173265 | /* 1840 */ 58, 58, 368, 1371, 1502, 566, 1501, 121, 568, 221, |
| 171086 | /* 1850 */ 248, 92, 1505, 494, 198, 279, 112, 564, 250, 4, | 173266 | /* 1850 */ 4, 208, 268, 209, 390, 1244, 1549, 1188, 1372, 1370, |
| 171087 | /* 1860 */ 348, 497, 405, 352, 1259, 251, 252, 515, 1316, 434, | 173267 | /* 1860 */ 1369, 1547, 239, 184, 571, 233, 421, 1241, 95, 218, |
| 171088 | /* 1870 */ 1315, 1314, 94, 567, 1307, 886, 1306, 1031, 226, 406, | 173268 | /* 1870 */ 173, 1507, 193, 43, 91, 94, 178, 186, 467, 188, |
| 171089 | /* 1880 */ 1611, 1610, 438, 110, 110, 1580, 1286, 524, 439, 308, | 173269 | /* 1880 */ 468, 1422, 13, 189, 190, 191, 501, 451, 245, 108, |
| 171090 | /* 1890 */ 266, 111, 1285, 449, 573, 449, 449, 309, 1019, 366, | 173270 | /* 1890 */ 238, 401, 1428, 1427, 1430, 475, 404, 1496, 197, 565, |
| 171091 | /* 1900 */ 1284, 1609, 265, 1566, 1565, 442, 372, 1381, 561, 129, | 173271 | /* 1900 */ 14, 490, 249, 101, 1518, 496, 349, 280, 251, 201, |
| 171092 | /* 1910 */ 550, 1380, 10, 1470, 383, 106, 316, 551, 100, 35, | 173272 | /* 1910 */ 353, 499, 252, 406, 1270, 253, 517, 1327, 1326, 435, |
| 171093 | /* 1920 */ 534, 575, 212, 1339, 381, 387, 1187, 1338, 274, 276, | 173273 | /* 1920 */ 1325, 1318, 103, 893, 1296, 413, 227, 407, 1040, 1626, |
| 171094 | /* 1930 */ 1019, 1019, 1021, 1022, 28, 277, 413, 1031, 576, 1254, | 173274 | /* 1930 */ 319, 567, 1625, 1297, 119, 119, 439, 367, 1317, 1295, |
| 171095 | /* 1940 */ 388, 1521, 1249, 110, 110, 167, 1522, 168, 148, 1520, | 173275 | /* 1940 */ 1624, 526, 120, 440, 451, 577, 451, 1594, 309, 1028, |
| 171096 | /* 1950 */ 1519, 111, 306, 449, 573, 449, 222, 223, 1019, 839, | 173276 | /* 1950 */ 310, 373, 266, 267, 457, 1580, 1579, 443, 138, 1394, |
| 171097 | /* 1960 */ 169, 79, 450, 214, 414, 233, 320, 145, 1093, 1091, | 173277 | /* 1960 */ 552, 1393, 11, 1483, 384, 115, 317, 1350, 109, 536, |
| 171098 | /* 1970 */ 328, 182, 171, 1212, 918, 184, 240, 336, 243, 1107, | 173278 | /* 1970 */ 42, 579, 382, 214, 1349, 388, 1198, 389, 275, 277, |
| 171099 | /* 1980 */ 189, 172, 173, 423, 425, 88, 180, 191, 89, 90, | 173279 | /* 1980 */ 278, 1028, 1028, 1030, 1031, 35, 580, 1265, 414, 1260, |
| 171100 | /* 1990 */ 1019, 1019, 1021, 1022, 28, 91, 174, 1110, 245, 1106, | 173280 | /* 1990 */ 170, 415, 183, 1534, 1535, 1533, 171, 154, 307, 1532, |
| 171101 | /* 2000 */ 246, 159, 18, 247, 347, 1099, 263, 195, 1227, 493, | 173281 | /* 2000 */ 846, 223, 224, 88, 452, 215, 172, 321, 234, 1102, |
| 171102 | /* 2010 */ 249, 196, 38, 854, 498, 368, 253, 360, 897, 197, | 173282 | /* 2010 */ 152, 1188, 1100, 329, 185, 174, 1223, 925, 187, 241, |
| 171103 | /* 2020 */ 502, 93, 19, 20, 507, 884, 363, 510, 95, 307, | 173283 | /* 2020 */ 337, 244, 1116, 192, 175, 176, 424, 426, 97, 194, |
| 171104 | /* 2030 */ 160, 96, 518, 97, 1175, 1060, 1146, 40, 21, 227, | 173284 | /* 2030 */ 98, 99, 100, 177, 1119, 1115, 246, 247, 161, 24, |
| 171105 | /* 2040 */ 176, 1145, 282, 284, 969, 200, 963, 114, 262, 1165, | 173285 | /* 2040 */ 248, 348, 1238, 264, 1108, 250, 495, 199, 198, 15, |
| 171106 | /* 2050 */ 22, 23, 24, 1161, 1169, 25, 1163, 1150, 34, 26, | 173286 | /* 2050 */ 861, 500, 369, 254, 504, 509, 512, 200, 102, 25, |
| 171107 | /* 2060 */ 1168, 546, 27, 204, 101, 103, 104, 1074, 7, 1061, | 173287 | /* 2060 */ 179, 361, 26, 364, 104, 891, 308, 162, 105, 904, |
| 171108 | /* 2070 */ 1059, 1063, 1116, 1064, 1115, 268, 269, 29, 41, 270, | 173288 | /* 2070 */ 520, 106, 1185, 1069, 1155, 17, 228, 27, 1154, 283, |
| 171109 | /* 2080 */ 1024, 866, 113, 30, 568, 392, 1183, 144, 178, 1182, | 173289 | /* 2080 */ 285, 263, 978, 202, 972, 123, 28, 1175, 29, 30, |
| 171110 | /* 2090 */ 271, 928, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1602, | 173290 | /* 2090 */ 1179, 1171, 31, 1173, 1160, 41, 32, 206, 548, 33, |
| 173291 | /* 2100 */ 110, 1178, 1083, 8, 112, 1070, 113, 1068, 1072, 34, | ||
| 173292 | /* 2110 */ 1073, 560, 1125, 269, 1124, 270, 36, 18, 1194, 1033, | ||
| 173293 | /* 2120 */ 873, 151, 122, 37, 393, 271, 272, 572, 181, 1193, | ||
| 173294 | /* 2130 */ 1256, 1256, 1256, 935, 1256, 1256, 1256, 1256, 1256, 1256, | ||
| 173295 | /* 2140 */ 1256, 1617, | ||
| 171111 | }; | 173296 | }; |
| 171112 | static const YYCODETYPE yy_lookahead[] = { | 173297 | static const YYCODETYPE yy_lookahead[] = { |
| 171113 | /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, | 173298 | /* 0 */ 194, 276, 277, 278, 216, 194, 194, 217, 194, 194, |
| 171114 | /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19, | 173299 | /* 10 */ 194, 194, 224, 194, 194, 276, 277, 278, 204, 19, |
| 171115 | /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216, | 173300 | /* 20 */ 206, 202, 297, 217, 218, 205, 207, 217, 205, 217, |
| 171116 | /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39, | 173301 | /* 30 */ 218, 31, 217, 218, 217, 218, 29, 217, 218, 39, |
| 171117 | /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49, | 173302 | /* 40 */ 33, 217, 220, 43, 44, 45, 46, 47, 48, 49, |
| 171118 | /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, | 173303 | /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 312, 19, |
| 171119 | /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, | 173304 | /* 60 */ 240, 241, 316, 240, 241, 194, 46, 47, 48, 49, |
| 171120 | /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204, | 173305 | /* 70 */ 22, 254, 65, 253, 254, 255, 253, 194, 255, 194, |
| 171121 | /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49, | 173306 | /* 80 */ 263, 258, 259, 43, 44, 45, 46, 47, 48, 49, |
| 171122 | /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275, | 173307 | /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 276, 277, |
| 171123 | /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109, | 173308 | /* 100 */ 278, 285, 102, 103, 104, 105, 106, 107, 108, 109, |
| 171124 | /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, | 173309 | /* 110 */ 110, 111, 112, 113, 59, 186, 187, 188, 189, 190, |
| 171125 | /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, | 173310 | /* 120 */ 191, 310, 239, 317, 318, 196, 86, 198, 88, 317, |
| 171126 | /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138, | 173311 | /* 130 */ 19, 319, 317, 318, 205, 264, 25, 211, 212, 213, |
| 171127 | /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109, | 173312 | /* 140 */ 205, 121, 102, 103, 104, 105, 106, 107, 108, 109, |
| 171128 | /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, | 173313 | /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, |
| 171129 | /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, | 173314 | /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 240, |
| 171130 | /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113, | 173315 | /* 170 */ 241, 116, 117, 118, 119, 240, 241, 122, 123, 124, |
| 171131 | /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112, | 173316 | /* 180 */ 69, 298, 253, 194, 255, 106, 107, 132, 253, 141, |
| 171132 | /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, | 173317 | /* 190 */ 255, 54, 55, 56, 57, 58, 207, 268, 102, 103, |
| 171133 | /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25, | 173318 | /* 200 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, |
| 171134 | /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108, | 173319 | /* 210 */ 214, 128, 129, 102, 103, 104, 105, 106, 107, 108, |
| 171135 | /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, | 173320 | /* 220 */ 109, 110, 111, 112, 113, 134, 25, 136, 137, 300, |
| 171136 | /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102, | 173321 | /* 230 */ 165, 166, 153, 19, 155, 54, 55, 56, 57, 102, |
| 171137 | /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, | 173322 | /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 171138 | /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45, | 173323 | /* 250 */ 113, 108, 109, 110, 111, 112, 113, 43, 44, 45, |
| 171139 | /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, | 173324 | /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, |
| 171140 | /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166, | 173325 | /* 270 */ 56, 57, 276, 277, 278, 113, 194, 19, 22, 23, |
| 171141 | /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108, | 173326 | /* 280 */ 194, 67, 24, 102, 103, 104, 105, 106, 107, 108, |
| 171142 | /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216, | 173327 | /* 290 */ 109, 110, 111, 112, 113, 220, 250, 59, 252, 217, |
| 171143 | /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, | 173328 | /* 300 */ 218, 43, 44, 45, 46, 47, 48, 49, 50, 51, |
| 171144 | /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, | 173329 | /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, |
| 171145 | /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145, | 173330 | /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 106, 107, |
| 171146 | /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123, | 173331 | /* 330 */ 108, 109, 110, 111, 112, 113, 254, 59, 205, 138, |
| 171147 | /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127, | 173332 | /* 340 */ 139, 19, 20, 194, 22, 263, 22, 23, 231, 25, |
| 171148 | /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193, | 173333 | /* 350 */ 72, 276, 277, 278, 116, 117, 118, 101, 36, 76, |
| 171149 | /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, | 173334 | /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, |
| 171150 | /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241, | 173335 | /* 370 */ 112, 113, 89, 240, 241, 92, 73, 194, 194, 73, |
| 171151 | /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, | 173336 | /* 380 */ 19, 59, 188, 189, 190, 191, 253, 81, 255, 151, |
| 171152 | /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128, | 173337 | /* 390 */ 196, 25, 198, 71, 116, 117, 118, 311, 312, 205, |
| 171153 | /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48, | 173338 | /* 400 */ 217, 218, 316, 81, 43, 44, 45, 46, 47, 48, |
| 171154 | /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253, | 173339 | /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 270, |
| 171155 | /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107, | 173340 | /* 420 */ 22, 23, 100, 25, 59, 101, 138, 139, 106, 107, |
| 171156 | /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117, | 173341 | /* 430 */ 127, 128, 129, 127, 240, 241, 114, 254, 116, 117, |
| 171157 | /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121, | 173342 | /* 440 */ 118, 76, 76, 121, 138, 139, 263, 253, 264, 255, |
| 171158 | /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131, | 173343 | /* 450 */ 205, 275, 87, 19, 89, 89, 194, 92, 92, 199, |
| 171159 | /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108, | 173344 | /* 460 */ 138, 139, 268, 102, 103, 104, 105, 106, 107, 108, |
| 171160 | /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, | 173345 | /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, |
| 171161 | /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25, | 173346 | /* 480 */ 81, 116, 117, 118, 129, 240, 241, 224, 19, 226, |
| 171162 | /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261, | 173347 | /* 490 */ 314, 315, 23, 25, 300, 59, 22, 234, 253, 101, |
| 171163 | /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216, | 173348 | /* 500 */ 255, 236, 237, 26, 194, 183, 194, 152, 72, 22, |
| 171164 | /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, | 173349 | /* 510 */ 145, 150, 43, 44, 45, 46, 47, 48, 49, 50, |
| 171165 | /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216, | 173350 | /* 520 */ 51, 52, 53, 54, 55, 56, 57, 217, 218, 217, |
| 171166 | /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109, | 173351 | /* 530 */ 218, 19, 189, 59, 191, 23, 59, 138, 139, 196, |
| 171167 | /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309, | 173352 | /* 540 */ 135, 198, 232, 283, 232, 140, 59, 287, 205, 275, |
| 171168 | /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47, | 173353 | /* 550 */ 116, 205, 116, 117, 118, 43, 44, 45, 46, 47, |
| 171169 | /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 173354 | /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 171170 | /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110, | 173355 | /* 570 */ 194, 102, 103, 104, 105, 106, 107, 108, 109, 110, |
| 171171 | /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193, | 173356 | /* 580 */ 111, 112, 113, 240, 241, 194, 240, 241, 314, 315, |
| 171172 | /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203, | 173357 | /* 590 */ 116, 117, 118, 116, 117, 118, 253, 194, 255, 253, |
| 171173 | /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138, | 173358 | /* 600 */ 59, 255, 19, 116, 117, 118, 23, 22, 217, 218, |
| 171174 | /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107, | 173359 | /* 610 */ 142, 268, 205, 275, 102, 103, 104, 105, 106, 107, |
| 171175 | /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 173360 | /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, |
| 171176 | /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173361 | /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171177 | /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116, | 173362 | /* 640 */ 57, 19, 194, 300, 59, 23, 119, 240, 241, 122, |
| 171178 | /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118, | 173363 | /* 650 */ 123, 124, 314, 315, 194, 236, 237, 194, 117, 132, |
| 171179 | /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47, | 173364 | /* 660 */ 253, 81, 255, 205, 59, 43, 44, 45, 46, 47, |
| 171180 | /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 173365 | /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 171181 | /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106, | 173366 | /* 680 */ 217, 218, 194, 194, 194, 102, 103, 104, 105, 106, |
| 171182 | /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, | 173367 | /* 690 */ 107, 108, 109, 110, 111, 112, 113, 294, 240, 241, |
| 171183 | /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60, | 173368 | /* 700 */ 120, 116, 117, 118, 59, 194, 217, 218, 211, 212, |
| 171184 | /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312, | 173369 | /* 710 */ 213, 253, 19, 255, 194, 19, 23, 254, 138, 139, |
| 171185 | /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107, | 173370 | /* 720 */ 24, 232, 117, 194, 102, 103, 104, 105, 106, 107, |
| 171186 | /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 173371 | /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, |
| 171187 | /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173372 | /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171188 | /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, | 173373 | /* 750 */ 57, 19, 264, 108, 76, 23, 127, 128, 129, 311, |
| 171189 | /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193, | 173374 | /* 760 */ 312, 116, 117, 118, 316, 87, 306, 89, 308, 194, |
| 171190 | /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, | 173375 | /* 770 */ 92, 22, 59, 194, 22, 43, 44, 45, 46, 47, |
| 171191 | /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 173376 | /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 171192 | /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, | 173377 | /* 790 */ 194, 95, 217, 218, 265, 102, 103, 104, 105, 106, |
| 171193 | /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193, | 173378 | /* 800 */ 107, 108, 109, 110, 111, 112, 113, 232, 59, 113, |
| 171194 | /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226, | 173379 | /* 810 */ 25, 59, 194, 217, 218, 119, 120, 121, 122, 123, |
| 171195 | /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231, | 173380 | /* 820 */ 124, 125, 19, 145, 194, 194, 23, 131, 232, 116, |
| 171196 | /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107, | 173381 | /* 830 */ 117, 118, 35, 194, 102, 103, 104, 105, 106, 107, |
| 171197 | /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 173382 | /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, |
| 171198 | /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173383 | /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171199 | /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, | 173384 | /* 860 */ 57, 19, 194, 66, 194, 116, 117, 118, 116, 117, |
| 171200 | /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193, | 173385 | /* 870 */ 118, 74, 242, 294, 194, 194, 206, 23, 194, 25, |
| 171201 | /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47, | 173386 | /* 880 */ 194, 111, 112, 113, 25, 43, 44, 45, 46, 47, |
| 171202 | /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, | 173387 | /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, |
| 171203 | /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, | 173388 | /* 900 */ 24, 194, 194, 217, 218, 102, 103, 104, 105, 106, |
| 171204 | /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244, | 173389 | /* 910 */ 107, 108, 109, 110, 111, 112, 113, 241, 232, 194, |
| 171205 | /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254, | 173390 | /* 920 */ 212, 213, 242, 242, 217, 218, 242, 130, 11, 253, |
| 171206 | /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, | 173391 | /* 930 */ 194, 255, 19, 265, 149, 59, 306, 194, 308, 232, |
| 171207 | /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107, | 173392 | /* 940 */ 309, 310, 217, 218, 102, 103, 104, 105, 106, 107, |
| 171208 | /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, | 173393 | /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, |
| 171209 | /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173394 | /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171210 | /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, | 173395 | /* 970 */ 57, 194, 194, 59, 194, 239, 19, 194, 25, 254, |
| 171211 | /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301, | 173396 | /* 980 */ 303, 304, 23, 194, 25, 126, 306, 306, 308, 308, |
| 171212 | /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266, | 173397 | /* 990 */ 306, 271, 308, 117, 286, 217, 218, 217, 218, 194, |
| 171213 | /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, | 173398 | /* 1000 */ 194, 159, 45, 46, 47, 48, 49, 50, 51, 52, |
| 171214 | /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, | 173399 | /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, |
| 171215 | /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, | 173400 | /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 59, 239, 194, |
| 171216 | /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260, | 173401 | /* 1030 */ 116, 117, 118, 260, 254, 194, 240, 241, 194, 233, |
| 171217 | /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262, | 173402 | /* 1040 */ 205, 240, 241, 205, 239, 128, 129, 270, 265, 253, |
| 171218 | /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102, | 173403 | /* 1050 */ 194, 255, 217, 218, 253, 194, 255, 143, 280, 102, |
| 171219 | /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, | 173404 | /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, |
| 171220 | /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, | 173405 | /* 1070 */ 113, 118, 159, 217, 218, 240, 241, 118, 240, 241, |
| 171221 | /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240, | 173406 | /* 1080 */ 194, 194, 194, 239, 116, 117, 118, 22, 253, 254, |
| 171222 | /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, | 173407 | /* 1090 */ 255, 253, 19, 255, 233, 194, 143, 24, 263, 212, |
| 171223 | /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155, | 173408 | /* 1100 */ 213, 194, 143, 217, 218, 217, 218, 261, 262, 271, |
| 171224 | /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46, | 173409 | /* 1110 */ 254, 143, 19, 7, 8, 9, 43, 44, 45, 46, |
| 171225 | /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173410 | /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171226 | /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46, | 173411 | /* 1130 */ 57, 16, 19, 22, 23, 294, 43, 44, 45, 46, |
| 171227 | /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173412 | /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171228 | /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46, | 173413 | /* 1150 */ 57, 312, 194, 214, 21, 316, 43, 44, 45, 46, |
| 171229 | /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, | 173414 | /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, |
| 171230 | /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106, | 173415 | /* 1170 */ 57, 106, 107, 286, 194, 102, 103, 104, 105, 106, |
| 171231 | /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193, | 173416 | /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 207, 158, 59, |
| 171232 | /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106, | 173417 | /* 1190 */ 160, 22, 77, 24, 79, 102, 103, 104, 105, 106, |
| 171233 | /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22, | 173418 | /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 194, 194, 229, |
| 171234 | /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106, | 173419 | /* 1210 */ 194, 231, 101, 80, 22, 102, 103, 104, 105, 106, |
| 171235 | /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193, | 173420 | /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 288, 59, 12, |
| 171236 | /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238, | 173421 | /* 1230 */ 217, 218, 293, 217, 218, 19, 106, 107, 59, 19, |
| 171237 | /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116, | 173422 | /* 1240 */ 16, 127, 128, 129, 27, 115, 116, 117, 118, 194, |
| 171238 | /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209, | 173423 | /* 1250 */ 120, 59, 22, 194, 24, 194, 123, 100, 128, 42, |
| 171239 | /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, | 173424 | /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, |
| 171240 | /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66, | 173425 | /* 1270 */ 54, 55, 56, 57, 117, 194, 217, 218, 121, 100, |
| 171241 | /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17, | 173426 | /* 1280 */ 63, 194, 245, 153, 194, 155, 117, 19, 115, 194, |
| 171242 | /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79, | 173427 | /* 1290 */ 73, 214, 194, 256, 161, 116, 117, 194, 217, 218, |
| 171243 | /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29, | 173428 | /* 1300 */ 121, 77, 194, 79, 217, 218, 194, 217, 218, 117, |
| 171244 | /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103, | 173429 | /* 1310 */ 153, 154, 155, 254, 46, 217, 218, 144, 102, 103, |
| 171245 | /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, | 173430 | /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, |
| 171246 | /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20, | 173431 | /* 1330 */ 232, 270, 153, 154, 155, 115, 116, 66, 19, 20, |
| 171247 | /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140, | 173432 | /* 1340 */ 183, 22, 12, 312, 254, 194, 262, 316, 209, 210, |
| 171248 | /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193, | 173433 | /* 1350 */ 266, 239, 194, 194, 108, 36, 85, 27, 19, 20, |
| 171249 | /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193, | 173434 | /* 1360 */ 265, 22, 183, 245, 144, 94, 25, 48, 217, 218, |
| 171250 | /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216, | 173435 | /* 1370 */ 293, 194, 42, 270, 256, 36, 217, 218, 59, 194, |
| 171251 | /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193, | 173436 | /* 1380 */ 25, 135, 194, 115, 194, 161, 140, 194, 194, 15, |
| 171252 | /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260, | 173437 | /* 1390 */ 71, 194, 312, 63, 217, 218, 316, 194, 59, 131, |
| 171253 | /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90, | 173438 | /* 1400 */ 301, 302, 217, 218, 85, 217, 218, 217, 218, 90, |
| 171254 | /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100, | 173439 | /* 1410 */ 71, 217, 218, 19, 217, 218, 245, 146, 262, 100, |
| 171255 | /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193, | 173440 | /* 1420 */ 217, 218, 266, 265, 85, 106, 107, 256, 312, 90, |
| 171256 | /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244, | 173441 | /* 1430 */ 209, 210, 316, 114, 60, 116, 117, 118, 194, 100, |
| 171257 | /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254, | 173442 | /* 1440 */ 121, 194, 194, 145, 115, 106, 107, 19, 46, 19, |
| 171258 | /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309, | 173443 | /* 1450 */ 20, 24, 22, 114, 194, 116, 117, 118, 194, 245, |
| 171259 | /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217, | 173444 | /* 1460 */ 121, 194, 164, 194, 217, 218, 36, 194, 258, 259, |
| 171260 | /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, | 173445 | /* 1470 */ 256, 194, 153, 154, 155, 156, 157, 217, 218, 150, |
| 171261 | /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12, | 173446 | /* 1480 */ 31, 217, 218, 142, 217, 218, 217, 218, 39, 59, |
| 171262 | /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116, | 173447 | /* 1490 */ 217, 218, 153, 154, 155, 156, 157, 149, 150, 5, |
| 171263 | /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32, | 173448 | /* 1500 */ 145, 71, 183, 245, 10, 11, 12, 13, 14, 194, |
| 171264 | /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216, | 173449 | /* 1510 */ 116, 17, 129, 227, 256, 85, 194, 115, 194, 23, |
| 171265 | /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217, | 173450 | /* 1520 */ 90, 25, 183, 99, 30, 97, 32, 22, 22, 194, |
| 171266 | /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217, | 173451 | /* 1530 */ 100, 194, 217, 218, 40, 152, 106, 107, 23, 217, |
| 171267 | /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71, | 173452 | /* 1540 */ 218, 194, 19, 20, 114, 22, 116, 117, 118, 257, |
| 171268 | /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216, | 173453 | /* 1550 */ 194, 121, 217, 218, 217, 218, 194, 133, 53, 36, |
| 171269 | /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216, | 173454 | /* 1560 */ 23, 23, 25, 25, 70, 120, 121, 61, 141, 7, |
| 171270 | /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193, | 173455 | /* 1570 */ 8, 121, 78, 217, 218, 81, 23, 227, 25, 217, |
| 171271 | /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216, | 173456 | /* 1580 */ 218, 131, 59, 153, 154, 155, 156, 157, 0, 1, |
| 171272 | /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, | 173457 | /* 1590 */ 2, 59, 98, 5, 71, 23, 227, 25, 10, 11, |
| 171273 | /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, | 173458 | /* 1600 */ 12, 13, 14, 83, 84, 17, 23, 23, 25, 25, |
| 171274 | /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193, | 173459 | /* 1610 */ 59, 194, 194, 183, 23, 23, 25, 25, 30, 194, |
| 171275 | /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216, | 173460 | /* 1620 */ 32, 19, 20, 100, 22, 194, 194, 133, 40, 106, |
| 171276 | /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162, | 173461 | /* 1630 */ 107, 108, 138, 139, 194, 217, 218, 114, 36, 116, |
| 171277 | /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, | 173462 | /* 1640 */ 117, 118, 217, 218, 121, 194, 194, 194, 23, 117, |
| 171278 | /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11, | 173463 | /* 1650 */ 25, 194, 23, 23, 25, 25, 162, 194, 70, 194, |
| 171279 | /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25, | 173464 | /* 1660 */ 145, 59, 23, 153, 25, 155, 78, 194, 117, 81, |
| 171280 | /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25, | 173465 | /* 1670 */ 217, 218, 194, 71, 217, 218, 153, 154, 155, 156, |
| 171281 | /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, | 173466 | /* 1680 */ 157, 194, 217, 218, 194, 23, 98, 25, 321, 194, |
| 171282 | /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23, | 173467 | /* 1690 */ 217, 218, 194, 19, 20, 194, 22, 153, 23, 155, |
| 171283 | /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155, | 173468 | /* 1700 */ 25, 194, 100, 194, 217, 218, 183, 194, 106, 107, |
| 171284 | /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193, | 173469 | /* 1710 */ 36, 194, 217, 218, 237, 194, 114, 243, 116, 117, |
| 171285 | /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81, | 173470 | /* 1720 */ 118, 133, 194, 121, 217, 218, 138, 139, 194, 194, |
| 171286 | /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255, | 173471 | /* 1730 */ 194, 290, 289, 59, 217, 218, 194, 194, 217, 218, |
| 171287 | /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114, | 173472 | /* 1740 */ 194, 194, 140, 194, 194, 71, 194, 244, 194, 194, |
| 171288 | /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267, | 173473 | /* 1750 */ 162, 217, 218, 194, 194, 153, 154, 155, 156, 157, |
| 171289 | /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107, | 173474 | /* 1760 */ 217, 218, 194, 217, 218, 194, 217, 218, 257, 217, |
| 171290 | /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117, | 173475 | /* 1770 */ 218, 217, 218, 257, 100, 194, 257, 217, 218, 257, |
| 171291 | /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154, | 173476 | /* 1780 */ 106, 107, 215, 299, 194, 183, 192, 194, 114, 194, |
| 171292 | /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22, | 173477 | /* 1790 */ 116, 117, 118, 1, 2, 121, 221, 5, 217, 218, |
| 171293 | /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200, | 173478 | /* 1800 */ 273, 197, 10, 11, 12, 13, 14, 217, 218, 17, |
| 171294 | /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157, | 173479 | /* 1810 */ 217, 218, 217, 218, 140, 194, 246, 194, 273, 295, |
| 171295 | /* 1820 */ 151, 150, 294, 283, 22, 43, 234, 18, 237, 200, | 173480 | /* 1820 */ 247, 273, 30, 247, 32, 269, 269, 153, 154, 155, |
| 171296 | /* 1830 */ 270, 272, 237, 237, 237, 18, 59, 199, 270, 149, | 173481 | /* 1830 */ 156, 157, 40, 246, 273, 295, 230, 226, 217, 218, |
| 171297 | /* 1840 */ 246, 272, 272, 200, 234, 234, 246, 246, 71, 246, | 173482 | /* 1840 */ 217, 218, 220, 261, 220, 282, 220, 19, 20, 244, |
| 171298 | /* 1850 */ 199, 158, 290, 62, 22, 200, 19, 20, 199, 22, | 173483 | /* 1850 */ 22, 250, 141, 250, 246, 60, 201, 183, 261, 261, |
| 171299 | /* 1860 */ 289, 221, 221, 200, 200, 199, 199, 115, 218, 64, | 173484 | /* 1860 */ 261, 201, 70, 299, 36, 299, 201, 38, 151, 150, |
| 171300 | /* 1870 */ 218, 218, 22, 36, 227, 126, 227, 100, 165, 221, | 173485 | /* 1870 */ 78, 285, 22, 81, 296, 296, 43, 235, 18, 238, |
| 171301 | /* 1880 */ 224, 224, 24, 106, 107, 312, 218, 305, 113, 282, | 173486 | /* 1880 */ 201, 274, 272, 238, 238, 238, 18, 59, 200, 149, |
| 171302 | /* 1890 */ 91, 114, 220, 116, 117, 118, 59, 282, 121, 218, | 173487 | /* 1890 */ 98, 247, 274, 274, 235, 247, 247, 247, 235, 71, |
| 171303 | /* 1900 */ 218, 218, 200, 317, 317, 82, 221, 265, 71, 148, | 173488 | /* 1900 */ 272, 201, 200, 158, 292, 62, 291, 201, 200, 22, |
| 171304 | /* 1910 */ 145, 265, 22, 277, 200, 158, 279, 140, 147, 25, | 173489 | /* 1910 */ 201, 222, 200, 222, 201, 200, 115, 219, 219, 64, |
| 171305 | /* 1920 */ 146, 202, 248, 250, 249, 247, 13, 250, 194, 194, | 173490 | /* 1920 */ 219, 228, 22, 126, 221, 133, 165, 222, 100, 225, |
| 171306 | /* 1930 */ 153, 154, 155, 156, 157, 6, 303, 100, 192, 192, | 173491 | /* 1930 */ 138, 139, 225, 219, 106, 107, 24, 219, 228, 219, |
| 171307 | /* 1940 */ 246, 213, 192, 106, 107, 207, 213, 207, 222, 213, | 173492 | /* 1940 */ 219, 307, 114, 113, 116, 117, 118, 315, 284, 121, |
| 171308 | /* 1950 */ 213, 114, 222, 116, 117, 118, 214, 214, 121, 4, | 173493 | /* 1950 */ 284, 222, 201, 91, 162, 320, 320, 82, 148, 267, |
| 171309 | /* 1960 */ 207, 213, 3, 22, 303, 15, 163, 16, 23, 23, | 173494 | /* 1960 */ 145, 267, 22, 279, 201, 158, 281, 251, 147, 146, |
| 171310 | /* 1970 */ 139, 151, 130, 25, 20, 142, 24, 16, 144, 1, | 173495 | /* 1970 */ 25, 203, 250, 249, 251, 248, 13, 247, 195, 195, |
| 171311 | /* 1980 */ 142, 130, 130, 61, 37, 53, 300, 151, 53, 53, | 173496 | /* 1980 */ 6, 153, 154, 155, 156, 157, 193, 193, 305, 193, |
| 171312 | /* 1990 */ 153, 154, 155, 156, 157, 53, 130, 116, 34, 1, | 173497 | /* 1990 */ 208, 305, 302, 214, 214, 214, 208, 223, 223, 214, |
| 171313 | /* 2000 */ 141, 5, 22, 115, 161, 68, 25, 68, 75, 41, | 173498 | /* 2000 */ 4, 215, 215, 214, 3, 22, 208, 163, 15, 23, |
| 171314 | /* 2010 */ 141, 115, 24, 20, 19, 131, 125, 23, 28, 22, | 173499 | /* 2010 */ 16, 183, 23, 139, 151, 130, 25, 20, 142, 24, |
| 171315 | /* 2020 */ 67, 22, 22, 22, 67, 59, 24, 96, 22, 67, | 173500 | /* 2020 */ 16, 144, 1, 142, 130, 130, 61, 37, 53, 151, |
| 171316 | /* 2030 */ 23, 149, 22, 25, 23, 23, 23, 22, 34, 141, | 173501 | /* 2030 */ 53, 53, 53, 130, 116, 1, 34, 141, 5, 22, |
| 171317 | /* 2040 */ 37, 97, 23, 23, 116, 22, 143, 25, 34, 75, | 173502 | /* 2040 */ 115, 161, 75, 25, 68, 141, 41, 115, 68, 24, |
| 171318 | /* 2050 */ 34, 34, 34, 88, 75, 34, 86, 23, 22, 34, | 173503 | /* 2050 */ 20, 19, 131, 125, 67, 67, 96, 22, 22, 22, |
| 171319 | /* 2060 */ 93, 24, 34, 25, 25, 142, 142, 23, 44, 23, | 173504 | /* 2060 */ 37, 23, 22, 24, 22, 59, 67, 23, 149, 28, |
| 171320 | /* 2070 */ 23, 23, 23, 11, 23, 25, 22, 22, 22, 141, | 173505 | /* 2070 */ 22, 25, 23, 23, 23, 22, 141, 34, 97, 23, |
| 171321 | /* 2080 */ 23, 23, 22, 22, 25, 15, 1, 23, 25, 1, | 173506 | /* 2080 */ 23, 34, 116, 22, 143, 25, 34, 75, 34, 34, |
| 171322 | /* 2090 */ 141, 135, 319, 319, 319, 319, 319, 319, 319, 141, | 173507 | /* 2090 */ 75, 88, 34, 86, 23, 22, 34, 25, 24, 34, |
| 171323 | /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173508 | /* 2100 */ 25, 93, 23, 44, 142, 23, 142, 23, 23, 22, |
| 171324 | /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173509 | /* 2110 */ 11, 25, 23, 25, 23, 22, 22, 22, 1, 23, |
| 171325 | /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173510 | /* 2120 */ 23, 23, 22, 22, 15, 141, 141, 25, 25, 1, |
| 171326 | /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173511 | /* 2130 */ 322, 322, 322, 135, 322, 322, 322, 322, 322, 322, |
| 171327 | /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173512 | /* 2140 */ 322, 141, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171328 | /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173513 | /* 2150 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171329 | /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173514 | /* 2160 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171330 | /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173515 | /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171331 | /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173516 | /* 2180 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171332 | /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173517 | /* 2190 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171333 | /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173518 | /* 2200 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171334 | /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173519 | /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171335 | /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173520 | /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171336 | /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173521 | /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171337 | /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173522 | /* 2240 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171338 | /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173523 | /* 2250 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171339 | /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173524 | /* 2260 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171340 | /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 173525 | /* 2270 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 171341 | /* 2280 */ 319, 319, 319, 319, 319, | 173526 | /* 2280 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, |
| 173527 | /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | ||
| 173528 | /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | ||
| 173529 | /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, | ||
| 173530 | /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, | ||
| 171342 | }; | 173531 | }; |
| 171343 | #define YY_SHIFT_COUNT (578) | 173532 | #define YY_SHIFT_COUNT (582) |
| 171344 | #define YY_SHIFT_MIN (0) | 173533 | #define YY_SHIFT_MIN (0) |
| 171345 | #define YY_SHIFT_MAX (2088) | 173534 | #define YY_SHIFT_MAX (2128) |
| 171346 | static const unsigned short int yy_shift_ofst[] = { | 173535 | static const unsigned short int yy_shift_ofst[] = { |
| 171347 | /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, | 173536 | /* 0 */ 1792, 1588, 1494, 322, 322, 399, 306, 1319, 1339, 1430, |
| 171348 | /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, | 173537 | /* 10 */ 1828, 1828, 1828, 580, 399, 399, 399, 399, 399, 0, |
| 171349 | /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173538 | /* 20 */ 0, 214, 1093, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171350 | /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1, | 173539 | /* 30 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1130, 1130, |
| 171351 | /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622, | 173540 | /* 40 */ 365, 365, 55, 278, 436, 713, 713, 201, 201, 201, |
| 171352 | /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, | 173541 | /* 50 */ 201, 40, 111, 258, 361, 469, 512, 583, 622, 693, |
| 171353 | /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, | 173542 | /* 60 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, |
| 171354 | /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, | 173543 | /* 70 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, |
| 171355 | /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173544 | /* 80 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1523, 1602, |
| 171356 | /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173545 | /* 90 */ 1674, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171357 | /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173546 | /* 100 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171358 | /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173547 | /* 110 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171359 | /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, | 173548 | /* 120 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171360 | /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94, | 173549 | /* 130 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, |
| 171361 | /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533, | 173550 | /* 140 */ 137, 181, 181, 181, 181, 181, 181, 181, 96, 222, |
| 171362 | /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123, | 173551 | /* 150 */ 143, 477, 713, 1133, 1268, 713, 713, 79, 79, 713, |
| 171363 | /* 160 */ 113, 113, 113, 22, 22, 2100, 2100, 328, 328, 328, | 173552 | /* 160 */ 770, 83, 65, 65, 65, 288, 162, 162, 2142, 2142, |
| 171364 | /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187, | 173553 | /* 170 */ 696, 696, 696, 238, 474, 474, 474, 474, 1217, 1217, |
| 171365 | /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533, | 173554 | /* 180 */ 678, 477, 324, 398, 713, 713, 713, 713, 713, 713, |
| 171366 | /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, | 173555 | /* 190 */ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, |
| 171367 | /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133, | 173556 | /* 200 */ 713, 713, 713, 1220, 366, 366, 713, 917, 283, 283, |
| 171368 | /* 210 */ 822, 822, 67, 1193, 2100, 2100, 2100, 2100, 2100, 2100, | 173557 | /* 210 */ 434, 434, 605, 605, 1298, 2142, 2142, 2142, 2142, 2142, |
| 171369 | /* 220 */ 2100, 1307, 954, 954, 585, 472, 640, 387, 695, 538, | 173558 | /* 220 */ 2142, 2142, 1179, 1157, 1157, 487, 527, 585, 645, 749, |
| 171370 | /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533, | 173559 | /* 230 */ 914, 968, 752, 713, 713, 713, 713, 713, 713, 713, |
| 171371 | /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533, | 173560 | /* 240 */ 713, 713, 713, 303, 713, 713, 713, 713, 713, 713, |
| 171372 | /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533, | 173561 | /* 250 */ 713, 713, 713, 713, 713, 713, 797, 797, 797, 713, |
| 171373 | /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288, | 173562 | /* 260 */ 713, 713, 959, 713, 713, 713, 1169, 1271, 713, 713, |
| 171374 | /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280, | 173563 | /* 270 */ 1330, 713, 713, 713, 713, 713, 713, 713, 713, 629, |
| 171375 | /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768, | 173564 | /* 280 */ 7, 91, 876, 876, 876, 876, 953, 91, 91, 1246, |
| 171376 | /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315, | 173565 | /* 290 */ 1065, 1106, 1374, 1329, 1348, 468, 1348, 1394, 785, 1329, |
| 171377 | /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417, | 173566 | /* 300 */ 1329, 785, 1329, 468, 1394, 859, 854, 1402, 1449, 1449, |
| 171378 | /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482, | 173567 | /* 310 */ 1449, 1173, 1173, 1173, 1173, 1355, 1355, 1030, 1341, 405, |
| 171379 | /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802, | 173568 | /* 320 */ 1230, 1795, 1795, 1711, 1711, 1829, 1829, 1711, 1717, 1719, |
| 171380 | /* 330 */ 1782, 1809, 1809, 1809, 1809, 1665, 1817, 1690, 1671, 1671, | 173569 | /* 330 */ 1850, 1833, 1860, 1860, 1860, 1860, 1711, 1868, 1740, 1719, |
| 171381 | /* 340 */ 1690, 1802, 1782, 1690, 1782, 1690, 1665, 1817, 1693, 1791, | 173570 | /* 340 */ 1719, 1740, 1850, 1833, 1740, 1833, 1740, 1711, 1868, 1745, |
| 171382 | /* 350 */ 1665, 1817, 1832, 1665, 1817, 1665, 1817, 1832, 1752, 1752, | 173571 | /* 350 */ 1843, 1711, 1868, 1887, 1711, 1868, 1711, 1868, 1887, 1801, |
| 171383 | /* 360 */ 1752, 1805, 1850, 1850, 1832, 1752, 1749, 1752, 1805, 1752, | 173572 | /* 360 */ 1801, 1801, 1855, 1900, 1900, 1887, 1801, 1797, 1801, 1855, |
| 171384 | /* 370 */ 1752, 1713, 1858, 1775, 1775, 1832, 1665, 1799, 1799, 1823, | 173573 | /* 370 */ 1801, 1801, 1761, 1912, 1830, 1830, 1887, 1711, 1862, 1862, |
| 171385 | /* 380 */ 1823, 1761, 1765, 1890, 1665, 1757, 1761, 1771, 1774, 1690, | 173574 | /* 380 */ 1875, 1875, 1810, 1815, 1940, 1711, 1807, 1810, 1821, 1823, |
| 171386 | /* 390 */ 1894, 1913, 1913, 1929, 1929, 1929, 2100, 2100, 2100, 2100, | 173575 | /* 390 */ 1740, 1945, 1963, 1963, 1974, 1974, 1974, 2142, 2142, 2142, |
| 171387 | /* 400 */ 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, | 173576 | /* 400 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, |
| 171388 | /* 410 */ 2100, 207, 1220, 331, 620, 967, 806, 1074, 1499, 1432, | 173577 | /* 410 */ 2142, 2142, 20, 1224, 256, 1111, 1115, 1114, 1192, 1496, |
| 171389 | /* 420 */ 1463, 1479, 1419, 1422, 1557, 1512, 1598, 1599, 1644, 1645, | 173578 | /* 420 */ 1424, 1505, 1427, 355, 1383, 1537, 1506, 1538, 1553, 1583, |
| 171390 | /* 430 */ 1654, 1660, 1555, 1505, 1684, 1462, 1670, 1563, 1619, 1593, | 173579 | /* 430 */ 1584, 1591, 1625, 541, 1445, 1562, 1450, 1572, 1515, 1428, |
| 171391 | /* 440 */ 1676, 1679, 1613, 1680, 1554, 1558, 1689, 1692, 1605, 1589, | 173580 | /* 440 */ 1532, 1592, 1629, 1520, 1630, 1639, 1510, 1544, 1662, 1675, |
| 171392 | /* 450 */ 1955, 1959, 1941, 1803, 1950, 1951, 1945, 1946, 1831, 1820, | 173581 | /* 450 */ 1551, 48, 1996, 2001, 1983, 1844, 1993, 1994, 1986, 1989, |
| 171393 | /* 460 */ 1842, 1948, 1948, 1952, 1833, 1954, 1834, 1961, 1978, 1838, | 173582 | /* 460 */ 1874, 1863, 1885, 1991, 1991, 1995, 1876, 1997, 1877, 2004, |
| 171394 | /* 470 */ 1851, 1948, 1852, 1922, 1947, 1948, 1836, 1932, 1935, 1936, | 173583 | /* 470 */ 2021, 1881, 1894, 1991, 1895, 1965, 1990, 1991, 1878, 1975, |
| 171395 | /* 480 */ 1942, 1866, 1881, 1964, 1859, 1998, 1996, 1980, 1888, 1843, | 173584 | /* 480 */ 1977, 1978, 1979, 1903, 1918, 2002, 1896, 2034, 2033, 2017, |
| 171396 | /* 490 */ 1937, 1981, 1939, 1933, 1968, 1869, 1896, 1988, 1993, 1995, | 173585 | /* 490 */ 1925, 1880, 1976, 2018, 1980, 1967, 2005, 1904, 1932, 2025, |
| 171397 | /* 500 */ 1884, 1891, 1997, 1953, 1999, 2000, 1994, 2001, 1957, 1966, | 173586 | /* 500 */ 2030, 2032, 1921, 1928, 2035, 1987, 2036, 2037, 2038, 2040, |
| 171398 | /* 510 */ 2002, 1931, 1990, 2006, 1962, 2003, 2007, 2004, 1882, 2010, | 173587 | /* 510 */ 1988, 2006, 2039, 1960, 2041, 2042, 1999, 2023, 2044, 2043, |
| 171399 | /* 520 */ 2011, 2012, 2008, 2013, 2015, 1944, 1898, 2019, 2020, 1928, | 173588 | /* 520 */ 1919, 2048, 2049, 2050, 2046, 2051, 2053, 1981, 1935, 2056, |
| 171400 | /* 530 */ 2014, 2023, 1903, 2022, 2016, 2017, 2018, 2021, 1965, 1974, | 173589 | /* 530 */ 2057, 1966, 2047, 2061, 1941, 2060, 2052, 2054, 2055, 2058, |
| 171401 | /* 540 */ 1970, 2024, 1979, 1967, 2025, 2034, 2036, 2037, 2038, 2039, | 173590 | /* 540 */ 2003, 2012, 2007, 2059, 2015, 2008, 2062, 2071, 2073, 2074, |
| 171402 | /* 550 */ 2028, 1923, 1924, 2044, 2022, 2046, 2047, 2048, 2049, 2050, | 173591 | /* 550 */ 2072, 2075, 2065, 1962, 1964, 2079, 2060, 2082, 2084, 2085, |
| 171403 | /* 560 */ 2051, 2054, 2062, 2055, 2056, 2057, 2058, 2060, 2061, 2059, | 173592 | /* 560 */ 2087, 2086, 2089, 2088, 2091, 2093, 2099, 2094, 2095, 2096, |
| 171404 | /* 570 */ 1956, 1938, 1949, 1958, 2063, 2064, 2070, 2085, 2088, | 173593 | /* 570 */ 2097, 2100, 2101, 2102, 1998, 1984, 1985, 2000, 2103, 2098, |
| 173594 | /* 580 */ 2109, 2117, 2128, | ||
| 171405 | }; | 173595 | }; |
| 171406 | #define YY_REDUCE_COUNT (410) | 173596 | #define YY_REDUCE_COUNT (411) |
| 171407 | #define YY_REDUCE_MIN (-271) | 173597 | #define YY_REDUCE_MIN (-275) |
| 171408 | #define YY_REDUCE_MAX (1753) | 173598 | #define YY_REDUCE_MAX (1798) |
| 171409 | static const short yy_reduce_ofst[] = { | 173599 | static const short yy_reduce_ofst[] = { |
| 171410 | /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, | 173600 | /* 0 */ -71, 194, 343, 835, -180, -177, 838, -194, -188, -185, |
| 171411 | /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, | 173601 | /* 10 */ -183, 82, 183, -65, 133, 245, 346, 407, 458, -178, |
| 171412 | /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781, | 173602 | /* 20 */ 75, -275, -4, 310, 312, 489, 575, 596, 463, 686, |
| 171413 | /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843, | 173603 | /* 30 */ 707, 725, 780, 1098, 856, 778, 1059, 1090, 708, 887, |
| 171414 | /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271, | 173604 | /* 40 */ 86, 448, 980, 630, 680, 681, 684, 796, 801, 796, |
| 171415 | /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, | 173605 | /* 50 */ 801, -261, -261, -261, -261, -261, -261, -261, -261, -261, |
| 171416 | /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, | 173606 | /* 60 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, |
| 171417 | /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80, | 173607 | /* 70 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, |
| 171418 | /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141, | 173608 | /* 80 */ -261, -261, -261, -261, -261, -261, -261, -261, 391, 886, |
| 171419 | /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196, | 173609 | /* 90 */ 888, 1013, 1016, 1081, 1087, 1151, 1159, 1177, 1185, 1188, |
| 171420 | /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303, | 173610 | /* 100 */ 1190, 1194, 1197, 1203, 1247, 1260, 1264, 1267, 1269, 1273, |
| 171421 | /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371, | 173611 | /* 110 */ 1315, 1322, 1335, 1337, 1356, 1362, 1418, 1425, 1453, 1457, |
| 171422 | /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470, | 173612 | /* 120 */ 1465, 1473, 1487, 1495, 1507, 1517, 1521, 1534, 1543, 1546, |
| 171423 | /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271, | 173613 | /* 130 */ 1549, 1552, 1554, 1560, 1581, 1590, 1593, 1595, 1621, 1623, |
| 171424 | /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521, | 173614 | /* 140 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, |
| 171425 | /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901, | 173615 | /* 150 */ -261, -186, -117, 260, 263, 460, 631, -74, 497, -181, |
| 171426 | /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161, | 173616 | /* 160 */ -261, 939, 176, 274, 338, 676, -261, -261, -261, -261, |
| 171427 | /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688, | 173617 | /* 170 */ -212, -212, -212, -184, 149, 777, 1061, 1103, 265, 419, |
| 171428 | /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122, | 173618 | /* 180 */ -254, 670, 677, 677, -11, -129, 184, 488, 736, 789, |
| 171429 | /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400, | 173619 | /* 190 */ 805, 844, 403, 529, 579, 668, 783, 841, 1158, 1112, |
| 171430 | /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139, | 173620 | /* 200 */ 806, 861, 1095, 846, 839, 1031, -189, 1077, 1080, 1116, |
| 171431 | /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090, | 173621 | /* 210 */ 1084, 1156, 1139, 1221, 46, 1099, 1037, 1118, 1171, 1214, |
| 171432 | /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601, | 173622 | /* 220 */ 1210, 1258, -210, -190, -176, -115, 117, 262, 376, 490, |
| 171433 | /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081, | 173623 | /* 230 */ 511, 520, 618, 639, 743, 901, 907, 958, 1014, 1055, |
| 171434 | /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293, | 173624 | /* 240 */ 1108, 1193, 1244, 720, 1248, 1277, 1324, 1347, 1417, 1431, |
| 171435 | /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359, | 173625 | /* 250 */ 1432, 1440, 1451, 1452, 1463, 1478, 1286, 1350, 1369, 1490, |
| 171436 | /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487, | 173626 | /* 260 */ 1498, 1501, 773, 1509, 1513, 1528, 1292, 1367, 1535, 1536, |
| 171437 | /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450, | 173627 | /* 270 */ 1477, 1542, 376, 1547, 1550, 1555, 1559, 1568, 1571, 1441, |
| 171438 | /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536, | 173628 | /* 280 */ 1443, 1474, 1511, 1516, 1519, 1522, 773, 1474, 1474, 1503, |
| 171439 | /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495, | 173629 | /* 290 */ 1567, 1594, 1484, 1527, 1556, 1570, 1557, 1524, 1573, 1545, |
| 171440 | /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566, | 173630 | /* 300 */ 1548, 1576, 1561, 1587, 1540, 1575, 1606, 1611, 1622, 1624, |
| 171441 | /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604, | 173631 | /* 310 */ 1626, 1582, 1597, 1598, 1599, 1601, 1603, 1563, 1608, 1605, |
| 171442 | /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560, | 173632 | /* 320 */ 1604, 1564, 1566, 1655, 1660, 1578, 1579, 1665, 1586, 1607, |
| 171443 | /* 330 */ 1592, 1591, 1595, 1596, 1597, 1629, 1638, 1594, 1569, 1570, | 173633 | /* 330 */ 1610, 1642, 1641, 1645, 1646, 1647, 1679, 1688, 1644, 1618, |
| 171444 | /* 340 */ 1600, 1568, 1610, 1601, 1611, 1603, 1643, 1651, 1562, 1571, | 173634 | /* 340 */ 1619, 1648, 1628, 1659, 1649, 1663, 1650, 1700, 1702, 1612, |
| 171445 | /* 350 */ 1655, 1659, 1640, 1663, 1666, 1664, 1667, 1641, 1650, 1652, | 173635 | /* 350 */ 1615, 1706, 1708, 1689, 1709, 1712, 1713, 1715, 1691, 1698, |
| 171446 | /* 360 */ 1653, 1647, 1656, 1657, 1658, 1668, 1672, 1681, 1649, 1682, | 173636 | /* 360 */ 1699, 1701, 1693, 1704, 1707, 1705, 1714, 1703, 1718, 1710, |
| 171447 | /* 370 */ 1683, 1573, 1582, 1607, 1615, 1685, 1702, 1586, 1587, 1642, | 173637 | /* 370 */ 1720, 1721, 1632, 1634, 1664, 1666, 1729, 1751, 1635, 1636, |
| 171448 | /* 380 */ 1646, 1673, 1675, 1636, 1714, 1637, 1677, 1674, 1678, 1694, | 173638 | /* 380 */ 1692, 1694, 1716, 1722, 1684, 1763, 1685, 1723, 1724, 1727, |
| 171449 | /* 390 */ 1719, 1734, 1735, 1746, 1747, 1750, 1633, 1661, 1686, 1738, | 173639 | /* 390 */ 1730, 1768, 1783, 1784, 1793, 1794, 1796, 1683, 1686, 1690, |
| 171450 | /* 400 */ 1728, 1733, 1736, 1737, 1740, 1726, 1730, 1742, 1743, 1748, | 173640 | /* 400 */ 1782, 1779, 1780, 1781, 1785, 1788, 1774, 1775, 1786, 1787, |
| 171451 | /* 410 */ 1753, | 173641 | /* 410 */ 1789, 1798, |
| 171452 | }; | 173642 | }; |
| 171453 | static const YYACTIONTYPE yy_default[] = { | 173643 | static const YYACTIONTYPE yy_default[] = { |
| 171454 | /* 0 */ 1648, 1648, 1648, 1478, 1243, 1354, 1243, 1243, 1243, 1478, | 173644 | /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, |
| 171455 | /* 10 */ 1478, 1478, 1243, 1384, 1384, 1531, 1276, 1243, 1243, 1243, | 173645 | /* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397, |
| 171456 | /* 20 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1477, 1243, | 173646 | /* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171457 | /* 30 */ 1243, 1243, 1243, 1564, 1564, 1243, 1243, 1243, 1243, 1243, | 173647 | /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, |
| 171458 | /* 40 */ 1243, 1243, 1243, 1393, 1243, 1400, 1243, 1243, 1243, 1243, | 173648 | /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, |
| 171459 | /* 50 */ 1243, 1479, 1480, 1243, 1243, 1243, 1530, 1532, 1495, 1407, | 173649 | /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, |
| 171460 | /* 60 */ 1406, 1405, 1404, 1513, 1372, 1398, 1391, 1395, 1474, 1475, | 173650 | /* 60 */ 1492, 1493, 1254, 1254, 1254, 1543, 1545, 1508, 1420, 1419, |
| 171461 | /* 70 */ 1473, 1626, 1480, 1479, 1243, 1394, 1442, 1458, 1441, 1243, | 173651 | /* 70 */ 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, 1486, |
| 171462 | /* 80 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173652 | /* 80 */ 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, 1254, |
| 171463 | /* 90 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173653 | /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171464 | /* 100 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173654 | /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171465 | /* 110 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173655 | /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171466 | /* 120 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173656 | /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171467 | /* 130 */ 1243, 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443, | 173657 | /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171468 | /* 140 */ 1445, 1446, 1243, 1243, 1267, 1243, 1243, 1264, 1318, 1243, | 173658 | /* 140 */ 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, 1456, 1458, |
| 171469 | /* 150 */ 1243, 1243, 1243, 1243, 1550, 1549, 1243, 1447, 1243, 1276, | 173659 | /* 150 */ 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, 1254, 1254, |
| 171470 | /* 160 */ 1435, 1434, 1433, 1461, 1448, 1460, 1459, 1538, 1600, 1599, | 173660 | /* 160 */ 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, 1473, 1472, |
| 171471 | /* 170 */ 1496, 1243, 1243, 1243, 1243, 1243, 1243, 1564, 1243, 1243, | 173661 | /* 170 */ 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171472 | /* 180 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173662 | /* 180 */ 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171473 | /* 190 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173663 | /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171474 | /* 200 */ 1243, 1374, 1564, 1564, 1243, 1276, 1564, 1564, 1375, 1375, | 173664 | /* 200 */ 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, 1578, 1578, |
| 171475 | /* 210 */ 1272, 1272, 1378, 1243, 1545, 1345, 1345, 1345, 1345, 1354, | 173665 | /* 210 */ 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, 1358, 1358, |
| 171476 | /* 220 */ 1345, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173666 | /* 220 */ 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171477 | /* 230 */ 1243, 1243, 1243, 1243, 1243, 1243, 1535, 1533, 1243, 1243, | 173667 | /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, 1546, 1254, |
| 171478 | /* 240 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173668 | /* 240 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171479 | /* 250 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173669 | /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171480 | /* 260 */ 1243, 1243, 1243, 1243, 1243, 1350, 1243, 1243, 1243, 1243, | 173670 | /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, 1254, 1254, |
| 171481 | /* 270 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1593, 1243, 1508, | 173671 | /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, 1254, |
| 171482 | /* 280 */ 1332, 1350, 1350, 1350, 1350, 1352, 1333, 1331, 1344, 1277, | 173672 | /* 280 */ 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, 1357, |
| 171483 | /* 290 */ 1250, 1640, 1410, 1399, 1351, 1399, 1637, 1397, 1410, 1410, | 173673 | /* 290 */ 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, 1423, |
| 171484 | /* 300 */ 1397, 1410, 1351, 1637, 1293, 1615, 1288, 1384, 1384, 1384, | 173674 | /* 300 */ 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, 1397, |
| 171485 | /* 310 */ 1374, 1374, 1374, 1374, 1378, 1378, 1476, 1351, 1344, 1243, | 173675 | /* 310 */ 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, 1357, |
| 171486 | /* 320 */ 1640, 1640, 1360, 1360, 1639, 1639, 1360, 1496, 1623, 1419, | 173676 | /* 320 */ 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, 1638, |
| 171487 | /* 330 */ 1321, 1327, 1327, 1327, 1327, 1360, 1261, 1397, 1623, 1623, | 173677 | /* 330 */ 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, 1638, |
| 171488 | /* 340 */ 1397, 1419, 1321, 1397, 1321, 1397, 1360, 1261, 1512, 1634, | 173678 | /* 340 */ 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, 1525, |
| 171489 | /* 350 */ 1360, 1261, 1486, 1360, 1261, 1360, 1261, 1486, 1319, 1319, | 173679 | /* 350 */ 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, 1330, |
| 171490 | /* 360 */ 1319, 1308, 1243, 1243, 1486, 1319, 1293, 1319, 1308, 1319, | 173680 | /* 360 */ 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, 1319, |
| 171491 | /* 370 */ 1319, 1582, 1243, 1490, 1490, 1486, 1360, 1574, 1574, 1387, | 173681 | /* 370 */ 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, 1588, |
| 171492 | /* 380 */ 1387, 1392, 1378, 1481, 1360, 1243, 1392, 1390, 1388, 1397, | 173682 | /* 380 */ 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, 1401, |
| 171493 | /* 390 */ 1311, 1596, 1596, 1592, 1592, 1592, 1645, 1645, 1545, 1608, | 173683 | /* 390 */ 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, 1558, |
| 171494 | /* 400 */ 1276, 1276, 1276, 1276, 1608, 1295, 1295, 1277, 1277, 1276, | 173684 | /* 400 */ 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, 1288, |
| 171495 | /* 410 */ 1608, 1243, 1243, 1243, 1243, 1243, 1243, 1603, 1243, 1540, | 173685 | /* 410 */ 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, 1254, |
| 171496 | /* 420 */ 1497, 1364, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173686 | /* 420 */ 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171497 | /* 430 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1551, 1243, | 173687 | /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1564, |
| 171498 | /* 440 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1424, | 173688 | /* 440 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171499 | /* 450 */ 1243, 1246, 1542, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173689 | /* 450 */ 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, 1254, |
| 171500 | /* 460 */ 1243, 1401, 1402, 1365, 1243, 1243, 1243, 1243, 1243, 1243, | 173690 | /* 460 */ 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, 1254, |
| 171501 | /* 470 */ 1243, 1416, 1243, 1243, 1243, 1411, 1243, 1243, 1243, 1243, | 173691 | /* 470 */ 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, 1254, |
| 171502 | /* 480 */ 1243, 1243, 1243, 1243, 1636, 1243, 1243, 1243, 1243, 1243, | 173692 | /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, 1254, |
| 171503 | /* 490 */ 1243, 1511, 1510, 1243, 1243, 1362, 1243, 1243, 1243, 1243, | 173693 | /* 490 */ 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, 1254, |
| 171504 | /* 500 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1291, | 173694 | /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171505 | /* 510 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173695 | /* 510 */ 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171506 | /* 520 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, | 173696 | /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171507 | /* 530 */ 1243, 1243, 1243, 1389, 1243, 1243, 1243, 1243, 1243, 1243, | 173697 | /* 530 */ 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, 1254, |
| 171508 | /* 540 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1579, 1379, | 173698 | /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171509 | /* 550 */ 1243, 1243, 1243, 1243, 1627, 1243, 1243, 1243, 1243, 1243, | 173699 | /* 550 */ 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, 1254, |
| 171510 | /* 560 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1619, | 173700 | /* 560 */ 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, |
| 171511 | /* 570 */ 1335, 1425, 1243, 1428, 1265, 1243, 1255, 1243, 1243, | 173701 | /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, |
| 173702 | /* 580 */ 1266, 1254, 1254, | ||
| 171512 | }; | 173703 | }; |
| 171513 | /********** End of lemon-generated parsing tables *****************************/ | 173704 | /********** End of lemon-generated parsing tables *****************************/ |
| 171514 | 173705 | ||
| @@ -171701,8 +173892,8 @@ static const YYCODETYPE yyFallback[] = { | |||
| 171701 | 0, /* TRUEFALSE => nothing */ | 173892 | 0, /* TRUEFALSE => nothing */ |
| 171702 | 0, /* ISNOT => nothing */ | 173893 | 0, /* ISNOT => nothing */ |
| 171703 | 0, /* FUNCTION => nothing */ | 173894 | 0, /* FUNCTION => nothing */ |
| 171704 | 0, /* UMINUS => nothing */ | ||
| 171705 | 0, /* UPLUS => nothing */ | 173895 | 0, /* UPLUS => nothing */ |
| 173896 | 0, /* UMINUS => nothing */ | ||
| 171706 | 0, /* TRUTH => nothing */ | 173897 | 0, /* TRUTH => nothing */ |
| 171707 | 0, /* REGISTER => nothing */ | 173898 | 0, /* REGISTER => nothing */ |
| 171708 | 0, /* VECTOR => nothing */ | 173899 | 0, /* VECTOR => nothing */ |
| @@ -171711,6 +173902,7 @@ static const YYCODETYPE yyFallback[] = { | |||
| 171711 | 0, /* ASTERISK => nothing */ | 173902 | 0, /* ASTERISK => nothing */ |
| 171712 | 0, /* SPAN => nothing */ | 173903 | 0, /* SPAN => nothing */ |
| 171713 | 0, /* ERROR => nothing */ | 173904 | 0, /* ERROR => nothing */ |
| 173905 | 0, /* QNUMBER => nothing */ | ||
| 171714 | 0, /* SPACE => nothing */ | 173906 | 0, /* SPACE => nothing */ |
| 171715 | 0, /* ILLEGAL => nothing */ | 173907 | 0, /* ILLEGAL => nothing */ |
| 171716 | }; | 173908 | }; |
| @@ -171753,14 +173945,9 @@ struct yyParser { | |||
| 171753 | #endif | 173945 | #endif |
| 171754 | sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ | 173946 | sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ |
| 171755 | sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ | 173947 | sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ |
| 171756 | #if YYSTACKDEPTH<=0 | 173948 | yyStackEntry *yystackEnd; /* Last entry in the stack */ |
| 171757 | int yystksz; /* Current side of the stack */ | 173949 | yyStackEntry *yystack; /* The parser stack */ |
| 171758 | yyStackEntry *yystack; /* The parser's stack */ | 173950 | yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */ |
| 171759 | yyStackEntry yystk0; /* First stack entry */ | ||
| 171760 | #else | ||
| 171761 | yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ | ||
| 171762 | yyStackEntry *yystackEnd; /* Last entry in the stack */ | ||
| 171763 | #endif | ||
| 171764 | }; | 173951 | }; |
| 171765 | typedef struct yyParser yyParser; | 173952 | typedef struct yyParser yyParser; |
| 171766 | 173953 | ||
| @@ -171974,8 +174161,8 @@ static const char *const yyTokenName[] = { | |||
| 171974 | /* 170 */ "TRUEFALSE", | 174161 | /* 170 */ "TRUEFALSE", |
| 171975 | /* 171 */ "ISNOT", | 174162 | /* 171 */ "ISNOT", |
| 171976 | /* 172 */ "FUNCTION", | 174163 | /* 172 */ "FUNCTION", |
| 171977 | /* 173 */ "UMINUS", | 174164 | /* 173 */ "UPLUS", |
| 171978 | /* 174 */ "UPLUS", | 174165 | /* 174 */ "UMINUS", |
| 171979 | /* 175 */ "TRUTH", | 174166 | /* 175 */ "TRUTH", |
| 171980 | /* 176 */ "REGISTER", | 174167 | /* 176 */ "REGISTER", |
| 171981 | /* 177 */ "VECTOR", | 174168 | /* 177 */ "VECTOR", |
| @@ -171984,142 +174171,145 @@ static const char *const yyTokenName[] = { | |||
| 171984 | /* 180 */ "ASTERISK", | 174171 | /* 180 */ "ASTERISK", |
| 171985 | /* 181 */ "SPAN", | 174172 | /* 181 */ "SPAN", |
| 171986 | /* 182 */ "ERROR", | 174173 | /* 182 */ "ERROR", |
| 171987 | /* 183 */ "SPACE", | 174174 | /* 183 */ "QNUMBER", |
| 171988 | /* 184 */ "ILLEGAL", | 174175 | /* 184 */ "SPACE", |
| 171989 | /* 185 */ "input", | 174176 | /* 185 */ "ILLEGAL", |
| 171990 | /* 186 */ "cmdlist", | 174177 | /* 186 */ "input", |
| 171991 | /* 187 */ "ecmd", | 174178 | /* 187 */ "cmdlist", |
| 171992 | /* 188 */ "cmdx", | 174179 | /* 188 */ "ecmd", |
| 171993 | /* 189 */ "explain", | 174180 | /* 189 */ "cmdx", |
| 171994 | /* 190 */ "cmd", | 174181 | /* 190 */ "explain", |
| 171995 | /* 191 */ "transtype", | 174182 | /* 191 */ "cmd", |
| 171996 | /* 192 */ "trans_opt", | 174183 | /* 192 */ "transtype", |
| 171997 | /* 193 */ "nm", | 174184 | /* 193 */ "trans_opt", |
| 171998 | /* 194 */ "savepoint_opt", | 174185 | /* 194 */ "nm", |
| 171999 | /* 195 */ "create_table", | 174186 | /* 195 */ "savepoint_opt", |
| 172000 | /* 196 */ "create_table_args", | 174187 | /* 196 */ "create_table", |
| 172001 | /* 197 */ "createkw", | 174188 | /* 197 */ "create_table_args", |
| 172002 | /* 198 */ "temp", | 174189 | /* 198 */ "createkw", |
| 172003 | /* 199 */ "ifnotexists", | 174190 | /* 199 */ "temp", |
| 172004 | /* 200 */ "dbnm", | 174191 | /* 200 */ "ifnotexists", |
| 172005 | /* 201 */ "columnlist", | 174192 | /* 201 */ "dbnm", |
| 172006 | /* 202 */ "conslist_opt", | 174193 | /* 202 */ "columnlist", |
| 172007 | /* 203 */ "table_option_set", | 174194 | /* 203 */ "conslist_opt", |
| 172008 | /* 204 */ "select", | 174195 | /* 204 */ "table_option_set", |
| 172009 | /* 205 */ "table_option", | 174196 | /* 205 */ "select", |
| 172010 | /* 206 */ "columnname", | 174197 | /* 206 */ "table_option", |
| 172011 | /* 207 */ "carglist", | 174198 | /* 207 */ "columnname", |
| 172012 | /* 208 */ "typetoken", | 174199 | /* 208 */ "carglist", |
| 172013 | /* 209 */ "typename", | 174200 | /* 209 */ "typetoken", |
| 172014 | /* 210 */ "signed", | 174201 | /* 210 */ "typename", |
| 172015 | /* 211 */ "plus_num", | 174202 | /* 211 */ "signed", |
| 172016 | /* 212 */ "minus_num", | 174203 | /* 212 */ "plus_num", |
| 172017 | /* 213 */ "scanpt", | 174204 | /* 213 */ "minus_num", |
| 172018 | /* 214 */ "scantok", | 174205 | /* 214 */ "scanpt", |
| 172019 | /* 215 */ "ccons", | 174206 | /* 215 */ "scantok", |
| 172020 | /* 216 */ "term", | 174207 | /* 216 */ "ccons", |
| 172021 | /* 217 */ "expr", | 174208 | /* 217 */ "term", |
| 172022 | /* 218 */ "onconf", | 174209 | /* 218 */ "expr", |
| 172023 | /* 219 */ "sortorder", | 174210 | /* 219 */ "onconf", |
| 172024 | /* 220 */ "autoinc", | 174211 | /* 220 */ "sortorder", |
| 172025 | /* 221 */ "eidlist_opt", | 174212 | /* 221 */ "autoinc", |
| 172026 | /* 222 */ "refargs", | 174213 | /* 222 */ "eidlist_opt", |
| 172027 | /* 223 */ "defer_subclause", | 174214 | /* 223 */ "refargs", |
| 172028 | /* 224 */ "generated", | 174215 | /* 224 */ "defer_subclause", |
| 172029 | /* 225 */ "refarg", | 174216 | /* 225 */ "generated", |
| 172030 | /* 226 */ "refact", | 174217 | /* 226 */ "refarg", |
| 172031 | /* 227 */ "init_deferred_pred_opt", | 174218 | /* 227 */ "refact", |
| 172032 | /* 228 */ "conslist", | 174219 | /* 228 */ "init_deferred_pred_opt", |
| 172033 | /* 229 */ "tconscomma", | 174220 | /* 229 */ "conslist", |
| 172034 | /* 230 */ "tcons", | 174221 | /* 230 */ "tconscomma", |
| 172035 | /* 231 */ "sortlist", | 174222 | /* 231 */ "tcons", |
| 172036 | /* 232 */ "eidlist", | 174223 | /* 232 */ "sortlist", |
| 172037 | /* 233 */ "defer_subclause_opt", | 174224 | /* 233 */ "eidlist", |
| 172038 | /* 234 */ "orconf", | 174225 | /* 234 */ "defer_subclause_opt", |
| 172039 | /* 235 */ "resolvetype", | 174226 | /* 235 */ "orconf", |
| 172040 | /* 236 */ "raisetype", | 174227 | /* 236 */ "resolvetype", |
| 172041 | /* 237 */ "ifexists", | 174228 | /* 237 */ "raisetype", |
| 172042 | /* 238 */ "fullname", | 174229 | /* 238 */ "ifexists", |
| 172043 | /* 239 */ "selectnowith", | 174230 | /* 239 */ "fullname", |
| 172044 | /* 240 */ "oneselect", | 174231 | /* 240 */ "selectnowith", |
| 172045 | /* 241 */ "wqlist", | 174232 | /* 241 */ "oneselect", |
| 172046 | /* 242 */ "multiselect_op", | 174233 | /* 242 */ "wqlist", |
| 172047 | /* 243 */ "distinct", | 174234 | /* 243 */ "multiselect_op", |
| 172048 | /* 244 */ "selcollist", | 174235 | /* 244 */ "distinct", |
| 172049 | /* 245 */ "from", | 174236 | /* 245 */ "selcollist", |
| 172050 | /* 246 */ "where_opt", | 174237 | /* 246 */ "from", |
| 172051 | /* 247 */ "groupby_opt", | 174238 | /* 247 */ "where_opt", |
| 172052 | /* 248 */ "having_opt", | 174239 | /* 248 */ "groupby_opt", |
| 172053 | /* 249 */ "orderby_opt", | 174240 | /* 249 */ "having_opt", |
| 172054 | /* 250 */ "limit_opt", | 174241 | /* 250 */ "orderby_opt", |
| 172055 | /* 251 */ "window_clause", | 174242 | /* 251 */ "limit_opt", |
| 172056 | /* 252 */ "values", | 174243 | /* 252 */ "window_clause", |
| 172057 | /* 253 */ "nexprlist", | 174244 | /* 253 */ "values", |
| 172058 | /* 254 */ "sclp", | 174245 | /* 254 */ "nexprlist", |
| 172059 | /* 255 */ "as", | 174246 | /* 255 */ "mvalues", |
| 172060 | /* 256 */ "seltablist", | 174247 | /* 256 */ "sclp", |
| 172061 | /* 257 */ "stl_prefix", | 174248 | /* 257 */ "as", |
| 172062 | /* 258 */ "joinop", | 174249 | /* 258 */ "seltablist", |
| 172063 | /* 259 */ "on_using", | 174250 | /* 259 */ "stl_prefix", |
| 172064 | /* 260 */ "indexed_by", | 174251 | /* 260 */ "joinop", |
| 172065 | /* 261 */ "exprlist", | 174252 | /* 261 */ "on_using", |
| 172066 | /* 262 */ "xfullname", | 174253 | /* 262 */ "indexed_by", |
| 172067 | /* 263 */ "idlist", | 174254 | /* 263 */ "exprlist", |
| 172068 | /* 264 */ "indexed_opt", | 174255 | /* 264 */ "xfullname", |
| 172069 | /* 265 */ "nulls", | 174256 | /* 265 */ "idlist", |
| 172070 | /* 266 */ "with", | 174257 | /* 266 */ "indexed_opt", |
| 172071 | /* 267 */ "where_opt_ret", | 174258 | /* 267 */ "nulls", |
| 172072 | /* 268 */ "setlist", | 174259 | /* 268 */ "with", |
| 172073 | /* 269 */ "insert_cmd", | 174260 | /* 269 */ "where_opt_ret", |
| 172074 | /* 270 */ "idlist_opt", | 174261 | /* 270 */ "setlist", |
| 172075 | /* 271 */ "upsert", | 174262 | /* 271 */ "insert_cmd", |
| 172076 | /* 272 */ "returning", | 174263 | /* 272 */ "idlist_opt", |
| 172077 | /* 273 */ "filter_over", | 174264 | /* 273 */ "upsert", |
| 172078 | /* 274 */ "likeop", | 174265 | /* 274 */ "returning", |
| 172079 | /* 275 */ "between_op", | 174266 | /* 275 */ "filter_over", |
| 172080 | /* 276 */ "in_op", | 174267 | /* 276 */ "likeop", |
| 172081 | /* 277 */ "paren_exprlist", | 174268 | /* 277 */ "between_op", |
| 172082 | /* 278 */ "case_operand", | 174269 | /* 278 */ "in_op", |
| 172083 | /* 279 */ "case_exprlist", | 174270 | /* 279 */ "paren_exprlist", |
| 172084 | /* 280 */ "case_else", | 174271 | /* 280 */ "case_operand", |
| 172085 | /* 281 */ "uniqueflag", | 174272 | /* 281 */ "case_exprlist", |
| 172086 | /* 282 */ "collate", | 174273 | /* 282 */ "case_else", |
| 172087 | /* 283 */ "vinto", | 174274 | /* 283 */ "uniqueflag", |
| 172088 | /* 284 */ "nmnum", | 174275 | /* 284 */ "collate", |
| 172089 | /* 285 */ "trigger_decl", | 174276 | /* 285 */ "vinto", |
| 172090 | /* 286 */ "trigger_cmd_list", | 174277 | /* 286 */ "nmnum", |
| 172091 | /* 287 */ "trigger_time", | 174278 | /* 287 */ "trigger_decl", |
| 172092 | /* 288 */ "trigger_event", | 174279 | /* 288 */ "trigger_cmd_list", |
| 172093 | /* 289 */ "foreach_clause", | 174280 | /* 289 */ "trigger_time", |
| 172094 | /* 290 */ "when_clause", | 174281 | /* 290 */ "trigger_event", |
| 172095 | /* 291 */ "trigger_cmd", | 174282 | /* 291 */ "foreach_clause", |
| 172096 | /* 292 */ "trnm", | 174283 | /* 292 */ "when_clause", |
| 172097 | /* 293 */ "tridxby", | 174284 | /* 293 */ "trigger_cmd", |
| 172098 | /* 294 */ "database_kw_opt", | 174285 | /* 294 */ "trnm", |
| 172099 | /* 295 */ "key_opt", | 174286 | /* 295 */ "tridxby", |
| 172100 | /* 296 */ "add_column_fullname", | 174287 | /* 296 */ "database_kw_opt", |
| 172101 | /* 297 */ "kwcolumn_opt", | 174288 | /* 297 */ "key_opt", |
| 172102 | /* 298 */ "create_vtab", | 174289 | /* 298 */ "add_column_fullname", |
| 172103 | /* 299 */ "vtabarglist", | 174290 | /* 299 */ "kwcolumn_opt", |
| 172104 | /* 300 */ "vtabarg", | 174291 | /* 300 */ "create_vtab", |
| 172105 | /* 301 */ "vtabargtoken", | 174292 | /* 301 */ "vtabarglist", |
| 172106 | /* 302 */ "lp", | 174293 | /* 302 */ "vtabarg", |
| 172107 | /* 303 */ "anylist", | 174294 | /* 303 */ "vtabargtoken", |
| 172108 | /* 304 */ "wqitem", | 174295 | /* 304 */ "lp", |
| 172109 | /* 305 */ "wqas", | 174296 | /* 305 */ "anylist", |
| 172110 | /* 306 */ "windowdefn_list", | 174297 | /* 306 */ "wqitem", |
| 172111 | /* 307 */ "windowdefn", | 174298 | /* 307 */ "wqas", |
| 172112 | /* 308 */ "window", | 174299 | /* 308 */ "withnm", |
| 172113 | /* 309 */ "frame_opt", | 174300 | /* 309 */ "windowdefn_list", |
| 172114 | /* 310 */ "part_opt", | 174301 | /* 310 */ "windowdefn", |
| 172115 | /* 311 */ "filter_clause", | 174302 | /* 311 */ "window", |
| 172116 | /* 312 */ "over_clause", | 174303 | /* 312 */ "frame_opt", |
| 172117 | /* 313 */ "range_or_rows", | 174304 | /* 313 */ "part_opt", |
| 172118 | /* 314 */ "frame_bound", | 174305 | /* 314 */ "filter_clause", |
| 172119 | /* 315 */ "frame_bound_s", | 174306 | /* 315 */ "over_clause", |
| 172120 | /* 316 */ "frame_bound_e", | 174307 | /* 316 */ "range_or_rows", |
| 172121 | /* 317 */ "frame_exclude_opt", | 174308 | /* 317 */ "frame_bound", |
| 172122 | /* 318 */ "frame_exclude", | 174309 | /* 318 */ "frame_bound_s", |
| 174310 | /* 319 */ "frame_bound_e", | ||
| 174311 | /* 320 */ "frame_exclude_opt", | ||
| 174312 | /* 321 */ "frame_exclude", | ||
| 172123 | }; | 174313 | }; |
| 172124 | #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ | 174314 | #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ |
| 172125 | 174315 | ||
| @@ -172222,351 +174412,363 @@ static const char *const yyRuleName[] = { | |||
| 172222 | /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", | 174412 | /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", |
| 172223 | /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", | 174413 | /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", |
| 172224 | /* 94 */ "values ::= VALUES LP nexprlist RP", | 174414 | /* 94 */ "values ::= VALUES LP nexprlist RP", |
| 172225 | /* 95 */ "values ::= values COMMA LP nexprlist RP", | 174415 | /* 95 */ "oneselect ::= mvalues", |
| 172226 | /* 96 */ "distinct ::= DISTINCT", | 174416 | /* 96 */ "mvalues ::= values COMMA LP nexprlist RP", |
| 172227 | /* 97 */ "distinct ::= ALL", | 174417 | /* 97 */ "mvalues ::= mvalues COMMA LP nexprlist RP", |
| 172228 | /* 98 */ "distinct ::=", | 174418 | /* 98 */ "distinct ::= DISTINCT", |
| 172229 | /* 99 */ "sclp ::=", | 174419 | /* 99 */ "distinct ::= ALL", |
| 172230 | /* 100 */ "selcollist ::= sclp scanpt expr scanpt as", | 174420 | /* 100 */ "distinct ::=", |
| 172231 | /* 101 */ "selcollist ::= sclp scanpt STAR", | 174421 | /* 101 */ "sclp ::=", |
| 172232 | /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR", | 174422 | /* 102 */ "selcollist ::= sclp scanpt expr scanpt as", |
| 172233 | /* 103 */ "as ::= AS nm", | 174423 | /* 103 */ "selcollist ::= sclp scanpt STAR", |
| 172234 | /* 104 */ "as ::=", | 174424 | /* 104 */ "selcollist ::= sclp scanpt nm DOT STAR", |
| 172235 | /* 105 */ "from ::=", | 174425 | /* 105 */ "as ::= AS nm", |
| 172236 | /* 106 */ "from ::= FROM seltablist", | 174426 | /* 106 */ "as ::=", |
| 172237 | /* 107 */ "stl_prefix ::= seltablist joinop", | 174427 | /* 107 */ "from ::=", |
| 172238 | /* 108 */ "stl_prefix ::=", | 174428 | /* 108 */ "from ::= FROM seltablist", |
| 172239 | /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using", | 174429 | /* 109 */ "stl_prefix ::= seltablist joinop", |
| 172240 | /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", | 174430 | /* 110 */ "stl_prefix ::=", |
| 172241 | /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", | 174431 | /* 111 */ "seltablist ::= stl_prefix nm dbnm as on_using", |
| 172242 | /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using", | 174432 | /* 112 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", |
| 172243 | /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", | 174433 | /* 113 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", |
| 172244 | /* 114 */ "dbnm ::=", | 174434 | /* 114 */ "seltablist ::= stl_prefix LP select RP as on_using", |
| 172245 | /* 115 */ "dbnm ::= DOT nm", | 174435 | /* 115 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", |
| 172246 | /* 116 */ "fullname ::= nm", | 174436 | /* 116 */ "dbnm ::=", |
| 172247 | /* 117 */ "fullname ::= nm DOT nm", | 174437 | /* 117 */ "dbnm ::= DOT nm", |
| 172248 | /* 118 */ "xfullname ::= nm", | 174438 | /* 118 */ "fullname ::= nm", |
| 172249 | /* 119 */ "xfullname ::= nm DOT nm", | 174439 | /* 119 */ "fullname ::= nm DOT nm", |
| 172250 | /* 120 */ "xfullname ::= nm DOT nm AS nm", | 174440 | /* 120 */ "xfullname ::= nm", |
| 172251 | /* 121 */ "xfullname ::= nm AS nm", | 174441 | /* 121 */ "xfullname ::= nm DOT nm", |
| 172252 | /* 122 */ "joinop ::= COMMA|JOIN", | 174442 | /* 122 */ "xfullname ::= nm DOT nm AS nm", |
| 172253 | /* 123 */ "joinop ::= JOIN_KW JOIN", | 174443 | /* 123 */ "xfullname ::= nm AS nm", |
| 172254 | /* 124 */ "joinop ::= JOIN_KW nm JOIN", | 174444 | /* 124 */ "joinop ::= COMMA|JOIN", |
| 172255 | /* 125 */ "joinop ::= JOIN_KW nm nm JOIN", | 174445 | /* 125 */ "joinop ::= JOIN_KW JOIN", |
| 172256 | /* 126 */ "on_using ::= ON expr", | 174446 | /* 126 */ "joinop ::= JOIN_KW nm JOIN", |
| 172257 | /* 127 */ "on_using ::= USING LP idlist RP", | 174447 | /* 127 */ "joinop ::= JOIN_KW nm nm JOIN", |
| 172258 | /* 128 */ "on_using ::=", | 174448 | /* 128 */ "on_using ::= ON expr", |
| 172259 | /* 129 */ "indexed_opt ::=", | 174449 | /* 129 */ "on_using ::= USING LP idlist RP", |
| 172260 | /* 130 */ "indexed_by ::= INDEXED BY nm", | 174450 | /* 130 */ "on_using ::=", |
| 172261 | /* 131 */ "indexed_by ::= NOT INDEXED", | 174451 | /* 131 */ "indexed_opt ::=", |
| 172262 | /* 132 */ "orderby_opt ::=", | 174452 | /* 132 */ "indexed_by ::= INDEXED BY nm", |
| 172263 | /* 133 */ "orderby_opt ::= ORDER BY sortlist", | 174453 | /* 133 */ "indexed_by ::= NOT INDEXED", |
| 172264 | /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", | 174454 | /* 134 */ "orderby_opt ::=", |
| 172265 | /* 135 */ "sortlist ::= expr sortorder nulls", | 174455 | /* 135 */ "orderby_opt ::= ORDER BY sortlist", |
| 172266 | /* 136 */ "sortorder ::= ASC", | 174456 | /* 136 */ "sortlist ::= sortlist COMMA expr sortorder nulls", |
| 172267 | /* 137 */ "sortorder ::= DESC", | 174457 | /* 137 */ "sortlist ::= expr sortorder nulls", |
| 172268 | /* 138 */ "sortorder ::=", | 174458 | /* 138 */ "sortorder ::= ASC", |
| 172269 | /* 139 */ "nulls ::= NULLS FIRST", | 174459 | /* 139 */ "sortorder ::= DESC", |
| 172270 | /* 140 */ "nulls ::= NULLS LAST", | 174460 | /* 140 */ "sortorder ::=", |
| 172271 | /* 141 */ "nulls ::=", | 174461 | /* 141 */ "nulls ::= NULLS FIRST", |
| 172272 | /* 142 */ "groupby_opt ::=", | 174462 | /* 142 */ "nulls ::= NULLS LAST", |
| 172273 | /* 143 */ "groupby_opt ::= GROUP BY nexprlist", | 174463 | /* 143 */ "nulls ::=", |
| 172274 | /* 144 */ "having_opt ::=", | 174464 | /* 144 */ "groupby_opt ::=", |
| 172275 | /* 145 */ "having_opt ::= HAVING expr", | 174465 | /* 145 */ "groupby_opt ::= GROUP BY nexprlist", |
| 172276 | /* 146 */ "limit_opt ::=", | 174466 | /* 146 */ "having_opt ::=", |
| 172277 | /* 147 */ "limit_opt ::= LIMIT expr", | 174467 | /* 147 */ "having_opt ::= HAVING expr", |
| 172278 | /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr", | 174468 | /* 148 */ "limit_opt ::=", |
| 172279 | /* 149 */ "limit_opt ::= LIMIT expr COMMA expr", | 174469 | /* 149 */ "limit_opt ::= LIMIT expr", |
| 172280 | /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", | 174470 | /* 150 */ "limit_opt ::= LIMIT expr OFFSET expr", |
| 172281 | /* 151 */ "where_opt ::=", | 174471 | /* 151 */ "limit_opt ::= LIMIT expr COMMA expr", |
| 172282 | /* 152 */ "where_opt ::= WHERE expr", | 174472 | /* 152 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", |
| 172283 | /* 153 */ "where_opt_ret ::=", | 174473 | /* 153 */ "where_opt ::=", |
| 172284 | /* 154 */ "where_opt_ret ::= WHERE expr", | 174474 | /* 154 */ "where_opt ::= WHERE expr", |
| 172285 | /* 155 */ "where_opt_ret ::= RETURNING selcollist", | 174475 | /* 155 */ "where_opt_ret ::=", |
| 172286 | /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", | 174476 | /* 156 */ "where_opt_ret ::= WHERE expr", |
| 172287 | /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", | 174477 | /* 157 */ "where_opt_ret ::= RETURNING selcollist", |
| 172288 | /* 158 */ "setlist ::= setlist COMMA nm EQ expr", | 174478 | /* 158 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", |
| 172289 | /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", | 174479 | /* 159 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", |
| 172290 | /* 160 */ "setlist ::= nm EQ expr", | 174480 | /* 160 */ "setlist ::= setlist COMMA nm EQ expr", |
| 172291 | /* 161 */ "setlist ::= LP idlist RP EQ expr", | 174481 | /* 161 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", |
| 172292 | /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", | 174482 | /* 162 */ "setlist ::= nm EQ expr", |
| 172293 | /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", | 174483 | /* 163 */ "setlist ::= LP idlist RP EQ expr", |
| 172294 | /* 164 */ "upsert ::=", | 174484 | /* 164 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", |
| 172295 | /* 165 */ "upsert ::= RETURNING selcollist", | 174485 | /* 165 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", |
| 172296 | /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", | 174486 | /* 166 */ "upsert ::=", |
| 172297 | /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", | 174487 | /* 167 */ "upsert ::= RETURNING selcollist", |
| 172298 | /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning", | 174488 | /* 168 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", |
| 172299 | /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", | 174489 | /* 169 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", |
| 172300 | /* 170 */ "returning ::= RETURNING selcollist", | 174490 | /* 170 */ "upsert ::= ON CONFLICT DO NOTHING returning", |
| 172301 | /* 171 */ "insert_cmd ::= INSERT orconf", | 174491 | /* 171 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", |
| 172302 | /* 172 */ "insert_cmd ::= REPLACE", | 174492 | /* 172 */ "returning ::= RETURNING selcollist", |
| 172303 | /* 173 */ "idlist_opt ::=", | 174493 | /* 173 */ "insert_cmd ::= INSERT orconf", |
| 172304 | /* 174 */ "idlist_opt ::= LP idlist RP", | 174494 | /* 174 */ "insert_cmd ::= REPLACE", |
| 172305 | /* 175 */ "idlist ::= idlist COMMA nm", | 174495 | /* 175 */ "idlist_opt ::=", |
| 172306 | /* 176 */ "idlist ::= nm", | 174496 | /* 176 */ "idlist_opt ::= LP idlist RP", |
| 172307 | /* 177 */ "expr ::= LP expr RP", | 174497 | /* 177 */ "idlist ::= idlist COMMA nm", |
| 172308 | /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", | 174498 | /* 178 */ "idlist ::= nm", |
| 172309 | /* 179 */ "expr ::= nm DOT nm", | 174499 | /* 179 */ "expr ::= LP expr RP", |
| 172310 | /* 180 */ "expr ::= nm DOT nm DOT nm", | 174500 | /* 180 */ "expr ::= ID|INDEXED|JOIN_KW", |
| 172311 | /* 181 */ "term ::= NULL|FLOAT|BLOB", | 174501 | /* 181 */ "expr ::= nm DOT nm", |
| 172312 | /* 182 */ "term ::= STRING", | 174502 | /* 182 */ "expr ::= nm DOT nm DOT nm", |
| 172313 | /* 183 */ "term ::= INTEGER", | 174503 | /* 183 */ "term ::= NULL|FLOAT|BLOB", |
| 172314 | /* 184 */ "expr ::= VARIABLE", | 174504 | /* 184 */ "term ::= STRING", |
| 172315 | /* 185 */ "expr ::= expr COLLATE ID|STRING", | 174505 | /* 185 */ "term ::= INTEGER", |
| 172316 | /* 186 */ "expr ::= CAST LP expr AS typetoken RP", | 174506 | /* 186 */ "expr ::= VARIABLE", |
| 172317 | /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", | 174507 | /* 187 */ "expr ::= expr COLLATE ID|STRING", |
| 172318 | /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", | 174508 | /* 188 */ "expr ::= CAST LP expr AS typetoken RP", |
| 172319 | /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", | 174509 | /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", |
| 172320 | /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", | 174510 | /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", |
| 172321 | /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", | 174511 | /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", |
| 172322 | /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", | 174512 | /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", |
| 172323 | /* 193 */ "term ::= CTIME_KW", | 174513 | /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", |
| 172324 | /* 194 */ "expr ::= LP nexprlist COMMA expr RP", | 174514 | /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", |
| 172325 | /* 195 */ "expr ::= expr AND expr", | 174515 | /* 195 */ "term ::= CTIME_KW", |
| 172326 | /* 196 */ "expr ::= expr OR expr", | 174516 | /* 196 */ "expr ::= LP nexprlist COMMA expr RP", |
| 172327 | /* 197 */ "expr ::= expr LT|GT|GE|LE expr", | 174517 | /* 197 */ "expr ::= expr AND expr", |
| 172328 | /* 198 */ "expr ::= expr EQ|NE expr", | 174518 | /* 198 */ "expr ::= expr OR expr", |
| 172329 | /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", | 174519 | /* 199 */ "expr ::= expr LT|GT|GE|LE expr", |
| 172330 | /* 200 */ "expr ::= expr PLUS|MINUS expr", | 174520 | /* 200 */ "expr ::= expr EQ|NE expr", |
| 172331 | /* 201 */ "expr ::= expr STAR|SLASH|REM expr", | 174521 | /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", |
| 172332 | /* 202 */ "expr ::= expr CONCAT expr", | 174522 | /* 202 */ "expr ::= expr PLUS|MINUS expr", |
| 172333 | /* 203 */ "likeop ::= NOT LIKE_KW|MATCH", | 174523 | /* 203 */ "expr ::= expr STAR|SLASH|REM expr", |
| 172334 | /* 204 */ "expr ::= expr likeop expr", | 174524 | /* 204 */ "expr ::= expr CONCAT expr", |
| 172335 | /* 205 */ "expr ::= expr likeop expr ESCAPE expr", | 174525 | /* 205 */ "likeop ::= NOT LIKE_KW|MATCH", |
| 172336 | /* 206 */ "expr ::= expr ISNULL|NOTNULL", | 174526 | /* 206 */ "expr ::= expr likeop expr", |
| 172337 | /* 207 */ "expr ::= expr NOT NULL", | 174527 | /* 207 */ "expr ::= expr likeop expr ESCAPE expr", |
| 172338 | /* 208 */ "expr ::= expr IS expr", | 174528 | /* 208 */ "expr ::= expr ISNULL|NOTNULL", |
| 172339 | /* 209 */ "expr ::= expr IS NOT expr", | 174529 | /* 209 */ "expr ::= expr NOT NULL", |
| 172340 | /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr", | 174530 | /* 210 */ "expr ::= expr IS expr", |
| 172341 | /* 211 */ "expr ::= expr IS DISTINCT FROM expr", | 174531 | /* 211 */ "expr ::= expr IS NOT expr", |
| 172342 | /* 212 */ "expr ::= NOT expr", | 174532 | /* 212 */ "expr ::= expr IS NOT DISTINCT FROM expr", |
| 172343 | /* 213 */ "expr ::= BITNOT expr", | 174533 | /* 213 */ "expr ::= expr IS DISTINCT FROM expr", |
| 172344 | /* 214 */ "expr ::= PLUS|MINUS expr", | 174534 | /* 214 */ "expr ::= NOT expr", |
| 172345 | /* 215 */ "expr ::= expr PTR expr", | 174535 | /* 215 */ "expr ::= BITNOT expr", |
| 172346 | /* 216 */ "between_op ::= BETWEEN", | 174536 | /* 216 */ "expr ::= PLUS|MINUS expr", |
| 172347 | /* 217 */ "between_op ::= NOT BETWEEN", | 174537 | /* 217 */ "expr ::= expr PTR expr", |
| 172348 | /* 218 */ "expr ::= expr between_op expr AND expr", | 174538 | /* 218 */ "between_op ::= BETWEEN", |
| 172349 | /* 219 */ "in_op ::= IN", | 174539 | /* 219 */ "between_op ::= NOT BETWEEN", |
| 172350 | /* 220 */ "in_op ::= NOT IN", | 174540 | /* 220 */ "expr ::= expr between_op expr AND expr", |
| 172351 | /* 221 */ "expr ::= expr in_op LP exprlist RP", | 174541 | /* 221 */ "in_op ::= IN", |
| 172352 | /* 222 */ "expr ::= LP select RP", | 174542 | /* 222 */ "in_op ::= NOT IN", |
| 172353 | /* 223 */ "expr ::= expr in_op LP select RP", | 174543 | /* 223 */ "expr ::= expr in_op LP exprlist RP", |
| 172354 | /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist", | 174544 | /* 224 */ "expr ::= LP select RP", |
| 172355 | /* 225 */ "expr ::= EXISTS LP select RP", | 174545 | /* 225 */ "expr ::= expr in_op LP select RP", |
| 172356 | /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END", | 174546 | /* 226 */ "expr ::= expr in_op nm dbnm paren_exprlist", |
| 172357 | /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", | 174547 | /* 227 */ "expr ::= EXISTS LP select RP", |
| 172358 | /* 228 */ "case_exprlist ::= WHEN expr THEN expr", | 174548 | /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END", |
| 172359 | /* 229 */ "case_else ::= ELSE expr", | 174549 | /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", |
| 172360 | /* 230 */ "case_else ::=", | 174550 | /* 230 */ "case_exprlist ::= WHEN expr THEN expr", |
| 172361 | /* 231 */ "case_operand ::=", | 174551 | /* 231 */ "case_else ::= ELSE expr", |
| 172362 | /* 232 */ "exprlist ::=", | 174552 | /* 232 */ "case_else ::=", |
| 172363 | /* 233 */ "nexprlist ::= nexprlist COMMA expr", | 174553 | /* 233 */ "case_operand ::=", |
| 172364 | /* 234 */ "nexprlist ::= expr", | 174554 | /* 234 */ "exprlist ::=", |
| 172365 | /* 235 */ "paren_exprlist ::=", | 174555 | /* 235 */ "nexprlist ::= nexprlist COMMA expr", |
| 172366 | /* 236 */ "paren_exprlist ::= LP exprlist RP", | 174556 | /* 236 */ "nexprlist ::= expr", |
| 172367 | /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", | 174557 | /* 237 */ "paren_exprlist ::=", |
| 172368 | /* 238 */ "uniqueflag ::= UNIQUE", | 174558 | /* 238 */ "paren_exprlist ::= LP exprlist RP", |
| 172369 | /* 239 */ "uniqueflag ::=", | 174559 | /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", |
| 172370 | /* 240 */ "eidlist_opt ::=", | 174560 | /* 240 */ "uniqueflag ::= UNIQUE", |
| 172371 | /* 241 */ "eidlist_opt ::= LP eidlist RP", | 174561 | /* 241 */ "uniqueflag ::=", |
| 172372 | /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", | 174562 | /* 242 */ "eidlist_opt ::=", |
| 172373 | /* 243 */ "eidlist ::= nm collate sortorder", | 174563 | /* 243 */ "eidlist_opt ::= LP eidlist RP", |
| 172374 | /* 244 */ "collate ::=", | 174564 | /* 244 */ "eidlist ::= eidlist COMMA nm collate sortorder", |
| 172375 | /* 245 */ "collate ::= COLLATE ID|STRING", | 174565 | /* 245 */ "eidlist ::= nm collate sortorder", |
| 172376 | /* 246 */ "cmd ::= DROP INDEX ifexists fullname", | 174566 | /* 246 */ "collate ::=", |
| 172377 | /* 247 */ "cmd ::= VACUUM vinto", | 174567 | /* 247 */ "collate ::= COLLATE ID|STRING", |
| 172378 | /* 248 */ "cmd ::= VACUUM nm vinto", | 174568 | /* 248 */ "cmd ::= DROP INDEX ifexists fullname", |
| 172379 | /* 249 */ "vinto ::= INTO expr", | 174569 | /* 249 */ "cmd ::= VACUUM vinto", |
| 172380 | /* 250 */ "vinto ::=", | 174570 | /* 250 */ "cmd ::= VACUUM nm vinto", |
| 172381 | /* 251 */ "cmd ::= PRAGMA nm dbnm", | 174571 | /* 251 */ "vinto ::= INTO expr", |
| 172382 | /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", | 174572 | /* 252 */ "vinto ::=", |
| 172383 | /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", | 174573 | /* 253 */ "cmd ::= PRAGMA nm dbnm", |
| 172384 | /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", | 174574 | /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", |
| 172385 | /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", | 174575 | /* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", |
| 172386 | /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", | 174576 | /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", |
| 172387 | /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", | 174577 | /* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", |
| 172388 | /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", | 174578 | /* 258 */ "plus_num ::= PLUS INTEGER|FLOAT", |
| 172389 | /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", | 174579 | /* 259 */ "minus_num ::= MINUS INTEGER|FLOAT", |
| 172390 | /* 260 */ "trigger_time ::= BEFORE|AFTER", | 174580 | /* 260 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", |
| 172391 | /* 261 */ "trigger_time ::= INSTEAD OF", | 174581 | /* 261 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", |
| 172392 | /* 262 */ "trigger_time ::=", | 174582 | /* 262 */ "trigger_time ::= BEFORE|AFTER", |
| 172393 | /* 263 */ "trigger_event ::= DELETE|INSERT", | 174583 | /* 263 */ "trigger_time ::= INSTEAD OF", |
| 172394 | /* 264 */ "trigger_event ::= UPDATE", | 174584 | /* 264 */ "trigger_time ::=", |
| 172395 | /* 265 */ "trigger_event ::= UPDATE OF idlist", | 174585 | /* 265 */ "trigger_event ::= DELETE|INSERT", |
| 172396 | /* 266 */ "when_clause ::=", | 174586 | /* 266 */ "trigger_event ::= UPDATE", |
| 172397 | /* 267 */ "when_clause ::= WHEN expr", | 174587 | /* 267 */ "trigger_event ::= UPDATE OF idlist", |
| 172398 | /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", | 174588 | /* 268 */ "when_clause ::=", |
| 172399 | /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", | 174589 | /* 269 */ "when_clause ::= WHEN expr", |
| 172400 | /* 270 */ "trnm ::= nm DOT nm", | 174590 | /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", |
| 172401 | /* 271 */ "tridxby ::= INDEXED BY nm", | 174591 | /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", |
| 172402 | /* 272 */ "tridxby ::= NOT INDEXED", | 174592 | /* 272 */ "trnm ::= nm DOT nm", |
| 172403 | /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", | 174593 | /* 273 */ "tridxby ::= INDEXED BY nm", |
| 172404 | /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", | 174594 | /* 274 */ "tridxby ::= NOT INDEXED", |
| 172405 | /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", | 174595 | /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", |
| 172406 | /* 276 */ "trigger_cmd ::= scanpt select scanpt", | 174596 | /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", |
| 172407 | /* 277 */ "expr ::= RAISE LP IGNORE RP", | 174597 | /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", |
| 172408 | /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", | 174598 | /* 278 */ "trigger_cmd ::= scanpt select scanpt", |
| 172409 | /* 279 */ "raisetype ::= ROLLBACK", | 174599 | /* 279 */ "expr ::= RAISE LP IGNORE RP", |
| 172410 | /* 280 */ "raisetype ::= ABORT", | 174600 | /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", |
| 172411 | /* 281 */ "raisetype ::= FAIL", | 174601 | /* 281 */ "raisetype ::= ROLLBACK", |
| 172412 | /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", | 174602 | /* 282 */ "raisetype ::= ABORT", |
| 172413 | /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", | 174603 | /* 283 */ "raisetype ::= FAIL", |
| 172414 | /* 284 */ "cmd ::= DETACH database_kw_opt expr", | 174604 | /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", |
| 172415 | /* 285 */ "key_opt ::=", | 174605 | /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", |
| 172416 | /* 286 */ "key_opt ::= KEY expr", | 174606 | /* 286 */ "cmd ::= DETACH database_kw_opt expr", |
| 172417 | /* 287 */ "cmd ::= REINDEX", | 174607 | /* 287 */ "key_opt ::=", |
| 172418 | /* 288 */ "cmd ::= REINDEX nm dbnm", | 174608 | /* 288 */ "key_opt ::= KEY expr", |
| 172419 | /* 289 */ "cmd ::= ANALYZE", | 174609 | /* 289 */ "cmd ::= REINDEX", |
| 172420 | /* 290 */ "cmd ::= ANALYZE nm dbnm", | 174610 | /* 290 */ "cmd ::= REINDEX nm dbnm", |
| 172421 | /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", | 174611 | /* 291 */ "cmd ::= ANALYZE", |
| 172422 | /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", | 174612 | /* 292 */ "cmd ::= ANALYZE nm dbnm", |
| 172423 | /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", | 174613 | /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", |
| 172424 | /* 294 */ "add_column_fullname ::= fullname", | 174614 | /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", |
| 172425 | /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", | 174615 | /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", |
| 172426 | /* 296 */ "cmd ::= create_vtab", | 174616 | /* 296 */ "add_column_fullname ::= fullname", |
| 172427 | /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", | 174617 | /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", |
| 172428 | /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", | 174618 | /* 298 */ "cmd ::= create_vtab", |
| 172429 | /* 299 */ "vtabarg ::=", | 174619 | /* 299 */ "cmd ::= create_vtab LP vtabarglist RP", |
| 172430 | /* 300 */ "vtabargtoken ::= ANY", | 174620 | /* 300 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", |
| 172431 | /* 301 */ "vtabargtoken ::= lp anylist RP", | 174621 | /* 301 */ "vtabarg ::=", |
| 172432 | /* 302 */ "lp ::= LP", | 174622 | /* 302 */ "vtabargtoken ::= ANY", |
| 172433 | /* 303 */ "with ::= WITH wqlist", | 174623 | /* 303 */ "vtabargtoken ::= lp anylist RP", |
| 172434 | /* 304 */ "with ::= WITH RECURSIVE wqlist", | 174624 | /* 304 */ "lp ::= LP", |
| 172435 | /* 305 */ "wqas ::= AS", | 174625 | /* 305 */ "with ::= WITH wqlist", |
| 172436 | /* 306 */ "wqas ::= AS MATERIALIZED", | 174626 | /* 306 */ "with ::= WITH RECURSIVE wqlist", |
| 172437 | /* 307 */ "wqas ::= AS NOT MATERIALIZED", | 174627 | /* 307 */ "wqas ::= AS", |
| 172438 | /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", | 174628 | /* 308 */ "wqas ::= AS MATERIALIZED", |
| 172439 | /* 309 */ "wqlist ::= wqitem", | 174629 | /* 309 */ "wqas ::= AS NOT MATERIALIZED", |
| 172440 | /* 310 */ "wqlist ::= wqlist COMMA wqitem", | 174630 | /* 310 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", |
| 172441 | /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", | 174631 | /* 311 */ "withnm ::= nm", |
| 172442 | /* 312 */ "windowdefn ::= nm AS LP window RP", | 174632 | /* 312 */ "wqlist ::= wqitem", |
| 172443 | /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", | 174633 | /* 313 */ "wqlist ::= wqlist COMMA wqitem", |
| 172444 | /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", | 174634 | /* 314 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", |
| 172445 | /* 315 */ "window ::= ORDER BY sortlist frame_opt", | 174635 | /* 315 */ "windowdefn ::= nm AS LP window RP", |
| 172446 | /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", | 174636 | /* 316 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", |
| 172447 | /* 317 */ "window ::= nm frame_opt", | 174637 | /* 317 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", |
| 172448 | /* 318 */ "frame_opt ::=", | 174638 | /* 318 */ "window ::= ORDER BY sortlist frame_opt", |
| 172449 | /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", | 174639 | /* 319 */ "window ::= nm ORDER BY sortlist frame_opt", |
| 172450 | /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", | 174640 | /* 320 */ "window ::= nm frame_opt", |
| 172451 | /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", | 174641 | /* 321 */ "frame_opt ::=", |
| 172452 | /* 322 */ "frame_bound_s ::= frame_bound", | 174642 | /* 322 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", |
| 172453 | /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", | 174643 | /* 323 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", |
| 172454 | /* 324 */ "frame_bound_e ::= frame_bound", | 174644 | /* 324 */ "range_or_rows ::= RANGE|ROWS|GROUPS", |
| 172455 | /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", | 174645 | /* 325 */ "frame_bound_s ::= frame_bound", |
| 172456 | /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", | 174646 | /* 326 */ "frame_bound_s ::= UNBOUNDED PRECEDING", |
| 172457 | /* 327 */ "frame_bound ::= CURRENT ROW", | 174647 | /* 327 */ "frame_bound_e ::= frame_bound", |
| 172458 | /* 328 */ "frame_exclude_opt ::=", | 174648 | /* 328 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", |
| 172459 | /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", | 174649 | /* 329 */ "frame_bound ::= expr PRECEDING|FOLLOWING", |
| 172460 | /* 330 */ "frame_exclude ::= NO OTHERS", | 174650 | /* 330 */ "frame_bound ::= CURRENT ROW", |
| 172461 | /* 331 */ "frame_exclude ::= CURRENT ROW", | 174651 | /* 331 */ "frame_exclude_opt ::=", |
| 172462 | /* 332 */ "frame_exclude ::= GROUP|TIES", | 174652 | /* 332 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", |
| 172463 | /* 333 */ "window_clause ::= WINDOW windowdefn_list", | 174653 | /* 333 */ "frame_exclude ::= NO OTHERS", |
| 172464 | /* 334 */ "filter_over ::= filter_clause over_clause", | 174654 | /* 334 */ "frame_exclude ::= CURRENT ROW", |
| 172465 | /* 335 */ "filter_over ::= over_clause", | 174655 | /* 335 */ "frame_exclude ::= GROUP|TIES", |
| 172466 | /* 336 */ "filter_over ::= filter_clause", | 174656 | /* 336 */ "window_clause ::= WINDOW windowdefn_list", |
| 172467 | /* 337 */ "over_clause ::= OVER LP window RP", | 174657 | /* 337 */ "filter_over ::= filter_clause over_clause", |
| 172468 | /* 338 */ "over_clause ::= OVER nm", | 174658 | /* 338 */ "filter_over ::= over_clause", |
| 172469 | /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", | 174659 | /* 339 */ "filter_over ::= filter_clause", |
| 172470 | /* 340 */ "input ::= cmdlist", | 174660 | /* 340 */ "over_clause ::= OVER LP window RP", |
| 172471 | /* 341 */ "cmdlist ::= cmdlist ecmd", | 174661 | /* 341 */ "over_clause ::= OVER nm", |
| 172472 | /* 342 */ "cmdlist ::= ecmd", | 174662 | /* 342 */ "filter_clause ::= FILTER LP WHERE expr RP", |
| 172473 | /* 343 */ "ecmd ::= SEMI", | 174663 | /* 343 */ "term ::= QNUMBER", |
| 172474 | /* 344 */ "ecmd ::= cmdx SEMI", | 174664 | /* 344 */ "input ::= cmdlist", |
| 172475 | /* 345 */ "ecmd ::= explain cmdx SEMI", | 174665 | /* 345 */ "cmdlist ::= cmdlist ecmd", |
| 172476 | /* 346 */ "trans_opt ::=", | 174666 | /* 346 */ "cmdlist ::= ecmd", |
| 172477 | /* 347 */ "trans_opt ::= TRANSACTION", | 174667 | /* 347 */ "ecmd ::= SEMI", |
| 172478 | /* 348 */ "trans_opt ::= TRANSACTION nm", | 174668 | /* 348 */ "ecmd ::= cmdx SEMI", |
| 172479 | /* 349 */ "savepoint_opt ::= SAVEPOINT", | 174669 | /* 349 */ "ecmd ::= explain cmdx SEMI", |
| 172480 | /* 350 */ "savepoint_opt ::=", | 174670 | /* 350 */ "trans_opt ::=", |
| 172481 | /* 351 */ "cmd ::= create_table create_table_args", | 174671 | /* 351 */ "trans_opt ::= TRANSACTION", |
| 172482 | /* 352 */ "table_option_set ::= table_option", | 174672 | /* 352 */ "trans_opt ::= TRANSACTION nm", |
| 172483 | /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", | 174673 | /* 353 */ "savepoint_opt ::= SAVEPOINT", |
| 172484 | /* 354 */ "columnlist ::= columnname carglist", | 174674 | /* 354 */ "savepoint_opt ::=", |
| 172485 | /* 355 */ "nm ::= ID|INDEXED|JOIN_KW", | 174675 | /* 355 */ "cmd ::= create_table create_table_args", |
| 172486 | /* 356 */ "nm ::= STRING", | 174676 | /* 356 */ "table_option_set ::= table_option", |
| 172487 | /* 357 */ "typetoken ::= typename", | 174677 | /* 357 */ "columnlist ::= columnlist COMMA columnname carglist", |
| 172488 | /* 358 */ "typename ::= ID|STRING", | 174678 | /* 358 */ "columnlist ::= columnname carglist", |
| 172489 | /* 359 */ "signed ::= plus_num", | 174679 | /* 359 */ "nm ::= ID|INDEXED|JOIN_KW", |
| 172490 | /* 360 */ "signed ::= minus_num", | 174680 | /* 360 */ "nm ::= STRING", |
| 172491 | /* 361 */ "carglist ::= carglist ccons", | 174681 | /* 361 */ "typetoken ::= typename", |
| 172492 | /* 362 */ "carglist ::=", | 174682 | /* 362 */ "typename ::= ID|STRING", |
| 172493 | /* 363 */ "ccons ::= NULL onconf", | 174683 | /* 363 */ "signed ::= plus_num", |
| 172494 | /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", | 174684 | /* 364 */ "signed ::= minus_num", |
| 172495 | /* 365 */ "ccons ::= AS generated", | 174685 | /* 365 */ "carglist ::= carglist ccons", |
| 172496 | /* 366 */ "conslist_opt ::= COMMA conslist", | 174686 | /* 366 */ "carglist ::=", |
| 172497 | /* 367 */ "conslist ::= conslist tconscomma tcons", | 174687 | /* 367 */ "ccons ::= NULL onconf", |
| 172498 | /* 368 */ "conslist ::= tcons", | 174688 | /* 368 */ "ccons ::= GENERATED ALWAYS AS generated", |
| 172499 | /* 369 */ "tconscomma ::=", | 174689 | /* 369 */ "ccons ::= AS generated", |
| 172500 | /* 370 */ "defer_subclause_opt ::= defer_subclause", | 174690 | /* 370 */ "conslist_opt ::= COMMA conslist", |
| 172501 | /* 371 */ "resolvetype ::= raisetype", | 174691 | /* 371 */ "conslist ::= conslist tconscomma tcons", |
| 172502 | /* 372 */ "selectnowith ::= oneselect", | 174692 | /* 372 */ "conslist ::= tcons", |
| 172503 | /* 373 */ "oneselect ::= values", | 174693 | /* 373 */ "tconscomma ::=", |
| 172504 | /* 374 */ "sclp ::= selcollist COMMA", | 174694 | /* 374 */ "defer_subclause_opt ::= defer_subclause", |
| 172505 | /* 375 */ "as ::= ID|STRING", | 174695 | /* 375 */ "resolvetype ::= raisetype", |
| 172506 | /* 376 */ "indexed_opt ::= indexed_by", | 174696 | /* 376 */ "selectnowith ::= oneselect", |
| 172507 | /* 377 */ "returning ::=", | 174697 | /* 377 */ "oneselect ::= values", |
| 172508 | /* 378 */ "expr ::= term", | 174698 | /* 378 */ "sclp ::= selcollist COMMA", |
| 172509 | /* 379 */ "likeop ::= LIKE_KW|MATCH", | 174699 | /* 379 */ "as ::= ID|STRING", |
| 172510 | /* 380 */ "case_operand ::= expr", | 174700 | /* 380 */ "indexed_opt ::= indexed_by", |
| 172511 | /* 381 */ "exprlist ::= nexprlist", | 174701 | /* 381 */ "returning ::=", |
| 172512 | /* 382 */ "nmnum ::= plus_num", | 174702 | /* 382 */ "expr ::= term", |
| 172513 | /* 383 */ "nmnum ::= nm", | 174703 | /* 383 */ "likeop ::= LIKE_KW|MATCH", |
| 172514 | /* 384 */ "nmnum ::= ON", | 174704 | /* 384 */ "case_operand ::= expr", |
| 172515 | /* 385 */ "nmnum ::= DELETE", | 174705 | /* 385 */ "exprlist ::= nexprlist", |
| 172516 | /* 386 */ "nmnum ::= DEFAULT", | 174706 | /* 386 */ "nmnum ::= plus_num", |
| 172517 | /* 387 */ "plus_num ::= INTEGER|FLOAT", | 174707 | /* 387 */ "nmnum ::= nm", |
| 172518 | /* 388 */ "foreach_clause ::=", | 174708 | /* 388 */ "nmnum ::= ON", |
| 172519 | /* 389 */ "foreach_clause ::= FOR EACH ROW", | 174709 | /* 389 */ "nmnum ::= DELETE", |
| 172520 | /* 390 */ "trnm ::= nm", | 174710 | /* 390 */ "nmnum ::= DEFAULT", |
| 172521 | /* 391 */ "tridxby ::=", | 174711 | /* 391 */ "plus_num ::= INTEGER|FLOAT", |
| 172522 | /* 392 */ "database_kw_opt ::= DATABASE", | 174712 | /* 392 */ "foreach_clause ::=", |
| 172523 | /* 393 */ "database_kw_opt ::=", | 174713 | /* 393 */ "foreach_clause ::= FOR EACH ROW", |
| 172524 | /* 394 */ "kwcolumn_opt ::=", | 174714 | /* 394 */ "trnm ::= nm", |
| 172525 | /* 395 */ "kwcolumn_opt ::= COLUMNKW", | 174715 | /* 395 */ "tridxby ::=", |
| 172526 | /* 396 */ "vtabarglist ::= vtabarg", | 174716 | /* 396 */ "database_kw_opt ::= DATABASE", |
| 172527 | /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", | 174717 | /* 397 */ "database_kw_opt ::=", |
| 172528 | /* 398 */ "vtabarg ::= vtabarg vtabargtoken", | 174718 | /* 398 */ "kwcolumn_opt ::=", |
| 172529 | /* 399 */ "anylist ::=", | 174719 | /* 399 */ "kwcolumn_opt ::= COLUMNKW", |
| 172530 | /* 400 */ "anylist ::= anylist LP anylist RP", | 174720 | /* 400 */ "vtabarglist ::= vtabarg", |
| 172531 | /* 401 */ "anylist ::= anylist ANY", | 174721 | /* 401 */ "vtabarglist ::= vtabarglist COMMA vtabarg", |
| 172532 | /* 402 */ "with ::=", | 174722 | /* 402 */ "vtabarg ::= vtabarg vtabargtoken", |
| 172533 | /* 403 */ "windowdefn_list ::= windowdefn", | 174723 | /* 403 */ "anylist ::=", |
| 172534 | /* 404 */ "window ::= frame_opt", | 174724 | /* 404 */ "anylist ::= anylist LP anylist RP", |
| 174725 | /* 405 */ "anylist ::= anylist ANY", | ||
| 174726 | /* 406 */ "with ::=", | ||
| 174727 | /* 407 */ "windowdefn_list ::= windowdefn", | ||
| 174728 | /* 408 */ "window ::= frame_opt", | ||
| 172535 | }; | 174729 | }; |
| 172536 | #endif /* NDEBUG */ | 174730 | #endif /* NDEBUG */ |
| 172537 | 174731 | ||
| 172538 | 174732 | ||
| 172539 | #if YYSTACKDEPTH<=0 | 174733 | #if YYGROWABLESTACK |
| 172540 | /* | 174734 | /* |
| 172541 | ** Try to increase the size of the parser stack. Return the number | 174735 | ** Try to increase the size of the parser stack. Return the number |
| 172542 | ** of errors. Return 0 on success. | 174736 | ** of errors. Return 0 on success. |
| 172543 | */ | 174737 | */ |
| 172544 | static int yyGrowStack(yyParser *p){ | 174738 | static int yyGrowStack(yyParser *p){ |
| 174739 | int oldSize = 1 + (int)(p->yystackEnd - p->yystack); | ||
| 172545 | int newSize; | 174740 | int newSize; |
| 172546 | int idx; | 174741 | int idx; |
| 172547 | yyStackEntry *pNew; | 174742 | yyStackEntry *pNew; |
| 172548 | 174743 | ||
| 172549 | newSize = p->yystksz*2 + 100; | 174744 | newSize = oldSize*2 + 100; |
| 172550 | idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; | 174745 | idx = (int)(p->yytos - p->yystack); |
| 172551 | if( p->yystack==&p->yystk0 ){ | 174746 | if( p->yystack==p->yystk0 ){ |
| 172552 | pNew = malloc(newSize*sizeof(pNew[0])); | 174747 | pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); |
| 172553 | if( pNew ) pNew[0] = p->yystk0; | 174748 | if( pNew==0 ) return 1; |
| 174749 | memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); | ||
| 172554 | }else{ | 174750 | }else{ |
| 172555 | pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); | 174751 | pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); |
| 174752 | if( pNew==0 ) return 1; | ||
| 172556 | } | 174753 | } |
| 172557 | if( pNew ){ | 174754 | p->yystack = pNew; |
| 172558 | p->yystack = pNew; | 174755 | p->yytos = &p->yystack[idx]; |
| 172559 | p->yytos = &p->yystack[idx]; | ||
| 172560 | #ifndef NDEBUG | 174756 | #ifndef NDEBUG |
| 172561 | if( yyTraceFILE ){ | 174757 | if( yyTraceFILE ){ |
| 172562 | fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", | 174758 | fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", |
| 172563 | yyTracePrompt, p->yystksz, newSize); | 174759 | yyTracePrompt, oldSize, newSize); |
| 172564 | } | ||
| 172565 | #endif | ||
| 172566 | p->yystksz = newSize; | ||
| 172567 | } | 174760 | } |
| 172568 | return pNew==0; | 174761 | #endif |
| 174762 | p->yystackEnd = &p->yystack[newSize-1]; | ||
| 174763 | return 0; | ||
| 172569 | } | 174764 | } |
| 174765 | #endif /* YYGROWABLESTACK */ | ||
| 174766 | |||
| 174767 | #if !YYGROWABLESTACK | ||
| 174768 | /* For builds that do no have a growable stack, yyGrowStack always | ||
| 174769 | ** returns an error. | ||
| 174770 | */ | ||
| 174771 | # define yyGrowStack(X) 1 | ||
| 172570 | #endif | 174772 | #endif |
| 172571 | 174773 | ||
| 172572 | /* Datatype of the argument to the memory allocated passed as the | 174774 | /* Datatype of the argument to the memory allocated passed as the |
| @@ -172586,24 +174788,14 @@ SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL) | |||
| 172586 | #ifdef YYTRACKMAXSTACKDEPTH | 174788 | #ifdef YYTRACKMAXSTACKDEPTH |
| 172587 | yypParser->yyhwm = 0; | 174789 | yypParser->yyhwm = 0; |
| 172588 | #endif | 174790 | #endif |
| 172589 | #if YYSTACKDEPTH<=0 | 174791 | yypParser->yystack = yypParser->yystk0; |
| 172590 | yypParser->yytos = NULL; | 174792 | yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; |
| 172591 | yypParser->yystack = NULL; | ||
| 172592 | yypParser->yystksz = 0; | ||
| 172593 | if( yyGrowStack(yypParser) ){ | ||
| 172594 | yypParser->yystack = &yypParser->yystk0; | ||
| 172595 | yypParser->yystksz = 1; | ||
| 172596 | } | ||
| 172597 | #endif | ||
| 172598 | #ifndef YYNOERRORRECOVERY | 174793 | #ifndef YYNOERRORRECOVERY |
| 172599 | yypParser->yyerrcnt = -1; | 174794 | yypParser->yyerrcnt = -1; |
| 172600 | #endif | 174795 | #endif |
| 172601 | yypParser->yytos = yypParser->yystack; | 174796 | yypParser->yytos = yypParser->yystack; |
| 172602 | yypParser->yystack[0].stateno = 0; | 174797 | yypParser->yystack[0].stateno = 0; |
| 172603 | yypParser->yystack[0].major = 0; | 174798 | yypParser->yystack[0].major = 0; |
| 172604 | #if YYSTACKDEPTH>0 | ||
| 172605 | yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; | ||
| 172606 | #endif | ||
| 172607 | } | 174799 | } |
| 172608 | 174800 | ||
| 172609 | #ifndef sqlite3Parser_ENGINEALWAYSONSTACK | 174801 | #ifndef sqlite3Parser_ENGINEALWAYSONSTACK |
| @@ -172657,97 +174849,98 @@ static void yy_destructor( | |||
| 172657 | ** inside the C code. | 174849 | ** inside the C code. |
| 172658 | */ | 174850 | */ |
| 172659 | /********* Begin destructor definitions ***************************************/ | 174851 | /********* Begin destructor definitions ***************************************/ |
| 172660 | case 204: /* select */ | 174852 | case 205: /* select */ |
| 172661 | case 239: /* selectnowith */ | 174853 | case 240: /* selectnowith */ |
| 172662 | case 240: /* oneselect */ | 174854 | case 241: /* oneselect */ |
| 172663 | case 252: /* values */ | 174855 | case 253: /* values */ |
| 174856 | case 255: /* mvalues */ | ||
| 172664 | { | 174857 | { |
| 172665 | sqlite3SelectDelete(pParse->db, (yypminor->yy47)); | 174858 | sqlite3SelectDelete(pParse->db, (yypminor->yy555)); |
| 172666 | } | 174859 | } |
| 172667 | break; | 174860 | break; |
| 172668 | case 216: /* term */ | 174861 | case 217: /* term */ |
| 172669 | case 217: /* expr */ | 174862 | case 218: /* expr */ |
| 172670 | case 246: /* where_opt */ | 174863 | case 247: /* where_opt */ |
| 172671 | case 248: /* having_opt */ | 174864 | case 249: /* having_opt */ |
| 172672 | case 267: /* where_opt_ret */ | 174865 | case 269: /* where_opt_ret */ |
| 172673 | case 278: /* case_operand */ | 174866 | case 280: /* case_operand */ |
| 172674 | case 280: /* case_else */ | 174867 | case 282: /* case_else */ |
| 172675 | case 283: /* vinto */ | 174868 | case 285: /* vinto */ |
| 172676 | case 290: /* when_clause */ | 174869 | case 292: /* when_clause */ |
| 172677 | case 295: /* key_opt */ | 174870 | case 297: /* key_opt */ |
| 172678 | case 311: /* filter_clause */ | 174871 | case 314: /* filter_clause */ |
| 172679 | { | 174872 | { |
| 172680 | sqlite3ExprDelete(pParse->db, (yypminor->yy528)); | 174873 | sqlite3ExprDelete(pParse->db, (yypminor->yy454)); |
| 172681 | } | 174874 | } |
| 172682 | break; | 174875 | break; |
| 172683 | case 221: /* eidlist_opt */ | 174876 | case 222: /* eidlist_opt */ |
| 172684 | case 231: /* sortlist */ | 174877 | case 232: /* sortlist */ |
| 172685 | case 232: /* eidlist */ | 174878 | case 233: /* eidlist */ |
| 172686 | case 244: /* selcollist */ | 174879 | case 245: /* selcollist */ |
| 172687 | case 247: /* groupby_opt */ | 174880 | case 248: /* groupby_opt */ |
| 172688 | case 249: /* orderby_opt */ | 174881 | case 250: /* orderby_opt */ |
| 172689 | case 253: /* nexprlist */ | 174882 | case 254: /* nexprlist */ |
| 172690 | case 254: /* sclp */ | 174883 | case 256: /* sclp */ |
| 172691 | case 261: /* exprlist */ | 174884 | case 263: /* exprlist */ |
| 172692 | case 268: /* setlist */ | 174885 | case 270: /* setlist */ |
| 172693 | case 277: /* paren_exprlist */ | 174886 | case 279: /* paren_exprlist */ |
| 172694 | case 279: /* case_exprlist */ | 174887 | case 281: /* case_exprlist */ |
| 172695 | case 310: /* part_opt */ | 174888 | case 313: /* part_opt */ |
| 172696 | { | 174889 | { |
| 172697 | sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); | 174890 | sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); |
| 172698 | } | 174891 | } |
| 172699 | break; | 174892 | break; |
| 172700 | case 238: /* fullname */ | 174893 | case 239: /* fullname */ |
| 172701 | case 245: /* from */ | 174894 | case 246: /* from */ |
| 172702 | case 256: /* seltablist */ | 174895 | case 258: /* seltablist */ |
| 172703 | case 257: /* stl_prefix */ | 174896 | case 259: /* stl_prefix */ |
| 172704 | case 262: /* xfullname */ | 174897 | case 264: /* xfullname */ |
| 172705 | { | 174898 | { |
| 172706 | sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); | 174899 | sqlite3SrcListDelete(pParse->db, (yypminor->yy203)); |
| 172707 | } | 174900 | } |
| 172708 | break; | 174901 | break; |
| 172709 | case 241: /* wqlist */ | 174902 | case 242: /* wqlist */ |
| 172710 | { | 174903 | { |
| 172711 | sqlite3WithDelete(pParse->db, (yypminor->yy521)); | 174904 | sqlite3WithDelete(pParse->db, (yypminor->yy59)); |
| 172712 | } | 174905 | } |
| 172713 | break; | 174906 | break; |
| 172714 | case 251: /* window_clause */ | 174907 | case 252: /* window_clause */ |
| 172715 | case 306: /* windowdefn_list */ | 174908 | case 309: /* windowdefn_list */ |
| 172716 | { | 174909 | { |
| 172717 | sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); | 174910 | sqlite3WindowListDelete(pParse->db, (yypminor->yy211)); |
| 172718 | } | 174911 | } |
| 172719 | break; | 174912 | break; |
| 172720 | case 263: /* idlist */ | 174913 | case 265: /* idlist */ |
| 172721 | case 270: /* idlist_opt */ | 174914 | case 272: /* idlist_opt */ |
| 172722 | { | 174915 | { |
| 172723 | sqlite3IdListDelete(pParse->db, (yypminor->yy254)); | 174916 | sqlite3IdListDelete(pParse->db, (yypminor->yy132)); |
| 172724 | } | 174917 | } |
| 172725 | break; | 174918 | break; |
| 172726 | case 273: /* filter_over */ | 174919 | case 275: /* filter_over */ |
| 172727 | case 307: /* windowdefn */ | 174920 | case 310: /* windowdefn */ |
| 172728 | case 308: /* window */ | 174921 | case 311: /* window */ |
| 172729 | case 309: /* frame_opt */ | 174922 | case 312: /* frame_opt */ |
| 172730 | case 312: /* over_clause */ | 174923 | case 315: /* over_clause */ |
| 172731 | { | 174924 | { |
| 172732 | sqlite3WindowDelete(pParse->db, (yypminor->yy41)); | 174925 | sqlite3WindowDelete(pParse->db, (yypminor->yy211)); |
| 172733 | } | 174926 | } |
| 172734 | break; | 174927 | break; |
| 172735 | case 286: /* trigger_cmd_list */ | 174928 | case 288: /* trigger_cmd_list */ |
| 172736 | case 291: /* trigger_cmd */ | 174929 | case 293: /* trigger_cmd */ |
| 172737 | { | 174930 | { |
| 172738 | sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); | 174931 | sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); |
| 172739 | } | 174932 | } |
| 172740 | break; | 174933 | break; |
| 172741 | case 288: /* trigger_event */ | 174934 | case 290: /* trigger_event */ |
| 172742 | { | 174935 | { |
| 172743 | sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); | 174936 | sqlite3IdListDelete(pParse->db, (yypminor->yy286).b); |
| 172744 | } | 174937 | } |
| 172745 | break; | 174938 | break; |
| 172746 | case 314: /* frame_bound */ | 174939 | case 317: /* frame_bound */ |
| 172747 | case 315: /* frame_bound_s */ | 174940 | case 318: /* frame_bound_s */ |
| 172748 | case 316: /* frame_bound_e */ | 174941 | case 319: /* frame_bound_e */ |
| 172749 | { | 174942 | { |
| 172750 | sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); | 174943 | sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr); |
| 172751 | } | 174944 | } |
| 172752 | break; | 174945 | break; |
| 172753 | /********* End destructor definitions *****************************************/ | 174946 | /********* End destructor definitions *****************************************/ |
| @@ -172781,9 +174974,26 @@ static void yy_pop_parser_stack(yyParser *pParser){ | |||
| 172781 | */ | 174974 | */ |
| 172782 | SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ | 174975 | SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ |
| 172783 | yyParser *pParser = (yyParser*)p; | 174976 | yyParser *pParser = (yyParser*)p; |
| 172784 | while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); | 174977 | |
| 172785 | #if YYSTACKDEPTH<=0 | 174978 | /* In-lined version of calling yy_pop_parser_stack() for each |
| 172786 | if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); | 174979 | ** element left in the stack */ |
| 174980 | yyStackEntry *yytos = pParser->yytos; | ||
| 174981 | while( yytos>pParser->yystack ){ | ||
| 174982 | #ifndef NDEBUG | ||
| 174983 | if( yyTraceFILE ){ | ||
| 174984 | fprintf(yyTraceFILE,"%sPopping %s\n", | ||
| 174985 | yyTracePrompt, | ||
| 174986 | yyTokenName[yytos->major]); | ||
| 174987 | } | ||
| 174988 | #endif | ||
| 174989 | if( yytos->major>=YY_MIN_DSTRCTR ){ | ||
| 174990 | yy_destructor(pParser, yytos->major, &yytos->minor); | ||
| 174991 | } | ||
| 174992 | yytos--; | ||
| 174993 | } | ||
| 174994 | |||
| 174995 | #if YYGROWABLESTACK | ||
| 174996 | if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); | ||
| 172787 | #endif | 174997 | #endif |
| 172788 | } | 174998 | } |
| 172789 | 174999 | ||
| @@ -172966,7 +175176,7 @@ static void yyStackOverflow(yyParser *yypParser){ | |||
| 172966 | ** stack every overflows */ | 175176 | ** stack every overflows */ |
| 172967 | /******** Begin %stack_overflow code ******************************************/ | 175177 | /******** Begin %stack_overflow code ******************************************/ |
| 172968 | 175178 | ||
| 172969 | sqlite3ErrorMsg(pParse, "parser stack overflow"); | 175179 | sqlite3OomFault(pParse->db); |
| 172970 | /******** End %stack_overflow code ********************************************/ | 175180 | /******** End %stack_overflow code ********************************************/ |
| 172971 | sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ | 175181 | sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ |
| 172972 | sqlite3ParserCTX_STORE | 175182 | sqlite3ParserCTX_STORE |
| @@ -173010,25 +175220,19 @@ static void yy_shift( | |||
| 173010 | assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); | 175220 | assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); |
| 173011 | } | 175221 | } |
| 173012 | #endif | 175222 | #endif |
| 173013 | #if YYSTACKDEPTH>0 | 175223 | yytos = yypParser->yytos; |
| 173014 | if( yypParser->yytos>yypParser->yystackEnd ){ | 175224 | if( yytos>yypParser->yystackEnd ){ |
| 173015 | yypParser->yytos--; | ||
| 173016 | yyStackOverflow(yypParser); | ||
| 173017 | return; | ||
| 173018 | } | ||
| 173019 | #else | ||
| 173020 | if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ | ||
| 173021 | if( yyGrowStack(yypParser) ){ | 175225 | if( yyGrowStack(yypParser) ){ |
| 173022 | yypParser->yytos--; | 175226 | yypParser->yytos--; |
| 173023 | yyStackOverflow(yypParser); | 175227 | yyStackOverflow(yypParser); |
| 173024 | return; | 175228 | return; |
| 173025 | } | 175229 | } |
| 175230 | yytos = yypParser->yytos; | ||
| 175231 | assert( yytos <= yypParser->yystackEnd ); | ||
| 173026 | } | 175232 | } |
| 173027 | #endif | ||
| 173028 | if( yyNewState > YY_MAX_SHIFT ){ | 175233 | if( yyNewState > YY_MAX_SHIFT ){ |
| 173029 | yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; | 175234 | yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; |
| 173030 | } | 175235 | } |
| 173031 | yytos = yypParser->yytos; | ||
| 173032 | yytos->stateno = yyNewState; | 175236 | yytos->stateno = yyNewState; |
| 173033 | yytos->major = yyMajor; | 175237 | yytos->major = yyMajor; |
| 173034 | yytos->minor.yy0 = yyMinor; | 175238 | yytos->minor.yy0 = yyMinor; |
| @@ -173038,411 +175242,415 @@ static void yy_shift( | |||
| 173038 | /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side | 175242 | /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side |
| 173039 | ** of that rule */ | 175243 | ** of that rule */ |
| 173040 | static const YYCODETYPE yyRuleInfoLhs[] = { | 175244 | static const YYCODETYPE yyRuleInfoLhs[] = { |
| 173041 | 189, /* (0) explain ::= EXPLAIN */ | 175245 | 190, /* (0) explain ::= EXPLAIN */ |
| 173042 | 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ | 175246 | 190, /* (1) explain ::= EXPLAIN QUERY PLAN */ |
| 173043 | 188, /* (2) cmdx ::= cmd */ | 175247 | 189, /* (2) cmdx ::= cmd */ |
| 173044 | 190, /* (3) cmd ::= BEGIN transtype trans_opt */ | 175248 | 191, /* (3) cmd ::= BEGIN transtype trans_opt */ |
| 173045 | 191, /* (4) transtype ::= */ | 175249 | 192, /* (4) transtype ::= */ |
| 173046 | 191, /* (5) transtype ::= DEFERRED */ | 175250 | 192, /* (5) transtype ::= DEFERRED */ |
| 173047 | 191, /* (6) transtype ::= IMMEDIATE */ | 175251 | 192, /* (6) transtype ::= IMMEDIATE */ |
| 173048 | 191, /* (7) transtype ::= EXCLUSIVE */ | 175252 | 192, /* (7) transtype ::= EXCLUSIVE */ |
| 173049 | 190, /* (8) cmd ::= COMMIT|END trans_opt */ | 175253 | 191, /* (8) cmd ::= COMMIT|END trans_opt */ |
| 173050 | 190, /* (9) cmd ::= ROLLBACK trans_opt */ | 175254 | 191, /* (9) cmd ::= ROLLBACK trans_opt */ |
| 173051 | 190, /* (10) cmd ::= SAVEPOINT nm */ | 175255 | 191, /* (10) cmd ::= SAVEPOINT nm */ |
| 173052 | 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ | 175256 | 191, /* (11) cmd ::= RELEASE savepoint_opt nm */ |
| 173053 | 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ | 175257 | 191, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ |
| 173054 | 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ | 175258 | 196, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ |
| 173055 | 197, /* (14) createkw ::= CREATE */ | 175259 | 198, /* (14) createkw ::= CREATE */ |
| 173056 | 199, /* (15) ifnotexists ::= */ | 175260 | 200, /* (15) ifnotexists ::= */ |
| 173057 | 199, /* (16) ifnotexists ::= IF NOT EXISTS */ | 175261 | 200, /* (16) ifnotexists ::= IF NOT EXISTS */ |
| 173058 | 198, /* (17) temp ::= TEMP */ | 175262 | 199, /* (17) temp ::= TEMP */ |
| 173059 | 198, /* (18) temp ::= */ | 175263 | 199, /* (18) temp ::= */ |
| 173060 | 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ | 175264 | 197, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ |
| 173061 | 196, /* (20) create_table_args ::= AS select */ | 175265 | 197, /* (20) create_table_args ::= AS select */ |
| 173062 | 203, /* (21) table_option_set ::= */ | 175266 | 204, /* (21) table_option_set ::= */ |
| 173063 | 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ | 175267 | 204, /* (22) table_option_set ::= table_option_set COMMA table_option */ |
| 173064 | 205, /* (23) table_option ::= WITHOUT nm */ | 175268 | 206, /* (23) table_option ::= WITHOUT nm */ |
| 173065 | 205, /* (24) table_option ::= nm */ | 175269 | 206, /* (24) table_option ::= nm */ |
| 173066 | 206, /* (25) columnname ::= nm typetoken */ | 175270 | 207, /* (25) columnname ::= nm typetoken */ |
| 173067 | 208, /* (26) typetoken ::= */ | 175271 | 209, /* (26) typetoken ::= */ |
| 173068 | 208, /* (27) typetoken ::= typename LP signed RP */ | 175272 | 209, /* (27) typetoken ::= typename LP signed RP */ |
| 173069 | 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ | 175273 | 209, /* (28) typetoken ::= typename LP signed COMMA signed RP */ |
| 173070 | 209, /* (29) typename ::= typename ID|STRING */ | 175274 | 210, /* (29) typename ::= typename ID|STRING */ |
| 173071 | 213, /* (30) scanpt ::= */ | 175275 | 214, /* (30) scanpt ::= */ |
| 173072 | 214, /* (31) scantok ::= */ | 175276 | 215, /* (31) scantok ::= */ |
| 173073 | 215, /* (32) ccons ::= CONSTRAINT nm */ | 175277 | 216, /* (32) ccons ::= CONSTRAINT nm */ |
| 173074 | 215, /* (33) ccons ::= DEFAULT scantok term */ | 175278 | 216, /* (33) ccons ::= DEFAULT scantok term */ |
| 173075 | 215, /* (34) ccons ::= DEFAULT LP expr RP */ | 175279 | 216, /* (34) ccons ::= DEFAULT LP expr RP */ |
| 173076 | 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ | 175280 | 216, /* (35) ccons ::= DEFAULT PLUS scantok term */ |
| 173077 | 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ | 175281 | 216, /* (36) ccons ::= DEFAULT MINUS scantok term */ |
| 173078 | 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ | 175282 | 216, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ |
| 173079 | 215, /* (38) ccons ::= NOT NULL onconf */ | 175283 | 216, /* (38) ccons ::= NOT NULL onconf */ |
| 173080 | 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ | 175284 | 216, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ |
| 173081 | 215, /* (40) ccons ::= UNIQUE onconf */ | 175285 | 216, /* (40) ccons ::= UNIQUE onconf */ |
| 173082 | 215, /* (41) ccons ::= CHECK LP expr RP */ | 175286 | 216, /* (41) ccons ::= CHECK LP expr RP */ |
| 173083 | 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ | 175287 | 216, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ |
| 173084 | 215, /* (43) ccons ::= defer_subclause */ | 175288 | 216, /* (43) ccons ::= defer_subclause */ |
| 173085 | 215, /* (44) ccons ::= COLLATE ID|STRING */ | 175289 | 216, /* (44) ccons ::= COLLATE ID|STRING */ |
| 173086 | 224, /* (45) generated ::= LP expr RP */ | 175290 | 225, /* (45) generated ::= LP expr RP */ |
| 173087 | 224, /* (46) generated ::= LP expr RP ID */ | 175291 | 225, /* (46) generated ::= LP expr RP ID */ |
| 173088 | 220, /* (47) autoinc ::= */ | 175292 | 221, /* (47) autoinc ::= */ |
| 173089 | 220, /* (48) autoinc ::= AUTOINCR */ | 175293 | 221, /* (48) autoinc ::= AUTOINCR */ |
| 173090 | 222, /* (49) refargs ::= */ | 175294 | 223, /* (49) refargs ::= */ |
| 173091 | 222, /* (50) refargs ::= refargs refarg */ | 175295 | 223, /* (50) refargs ::= refargs refarg */ |
| 173092 | 225, /* (51) refarg ::= MATCH nm */ | 175296 | 226, /* (51) refarg ::= MATCH nm */ |
| 173093 | 225, /* (52) refarg ::= ON INSERT refact */ | 175297 | 226, /* (52) refarg ::= ON INSERT refact */ |
| 173094 | 225, /* (53) refarg ::= ON DELETE refact */ | 175298 | 226, /* (53) refarg ::= ON DELETE refact */ |
| 173095 | 225, /* (54) refarg ::= ON UPDATE refact */ | 175299 | 226, /* (54) refarg ::= ON UPDATE refact */ |
| 173096 | 226, /* (55) refact ::= SET NULL */ | 175300 | 227, /* (55) refact ::= SET NULL */ |
| 173097 | 226, /* (56) refact ::= SET DEFAULT */ | 175301 | 227, /* (56) refact ::= SET DEFAULT */ |
| 173098 | 226, /* (57) refact ::= CASCADE */ | 175302 | 227, /* (57) refact ::= CASCADE */ |
| 173099 | 226, /* (58) refact ::= RESTRICT */ | 175303 | 227, /* (58) refact ::= RESTRICT */ |
| 173100 | 226, /* (59) refact ::= NO ACTION */ | 175304 | 227, /* (59) refact ::= NO ACTION */ |
| 173101 | 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ | 175305 | 224, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ |
| 173102 | 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ | 175306 | 224, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ |
| 173103 | 227, /* (62) init_deferred_pred_opt ::= */ | 175307 | 228, /* (62) init_deferred_pred_opt ::= */ |
| 173104 | 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ | 175308 | 228, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ |
| 173105 | 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ | 175309 | 228, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ |
| 173106 | 202, /* (65) conslist_opt ::= */ | 175310 | 203, /* (65) conslist_opt ::= */ |
| 173107 | 229, /* (66) tconscomma ::= COMMA */ | 175311 | 230, /* (66) tconscomma ::= COMMA */ |
| 173108 | 230, /* (67) tcons ::= CONSTRAINT nm */ | 175312 | 231, /* (67) tcons ::= CONSTRAINT nm */ |
| 173109 | 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ | 175313 | 231, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ |
| 173110 | 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ | 175314 | 231, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ |
| 173111 | 230, /* (70) tcons ::= CHECK LP expr RP onconf */ | 175315 | 231, /* (70) tcons ::= CHECK LP expr RP onconf */ |
| 173112 | 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ | 175316 | 231, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ |
| 173113 | 233, /* (72) defer_subclause_opt ::= */ | 175317 | 234, /* (72) defer_subclause_opt ::= */ |
| 173114 | 218, /* (73) onconf ::= */ | 175318 | 219, /* (73) onconf ::= */ |
| 173115 | 218, /* (74) onconf ::= ON CONFLICT resolvetype */ | 175319 | 219, /* (74) onconf ::= ON CONFLICT resolvetype */ |
| 173116 | 234, /* (75) orconf ::= */ | 175320 | 235, /* (75) orconf ::= */ |
| 173117 | 234, /* (76) orconf ::= OR resolvetype */ | 175321 | 235, /* (76) orconf ::= OR resolvetype */ |
| 173118 | 235, /* (77) resolvetype ::= IGNORE */ | 175322 | 236, /* (77) resolvetype ::= IGNORE */ |
| 173119 | 235, /* (78) resolvetype ::= REPLACE */ | 175323 | 236, /* (78) resolvetype ::= REPLACE */ |
| 173120 | 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ | 175324 | 191, /* (79) cmd ::= DROP TABLE ifexists fullname */ |
| 173121 | 237, /* (80) ifexists ::= IF EXISTS */ | 175325 | 238, /* (80) ifexists ::= IF EXISTS */ |
| 173122 | 237, /* (81) ifexists ::= */ | 175326 | 238, /* (81) ifexists ::= */ |
| 173123 | 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ | 175327 | 191, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ |
| 173124 | 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ | 175328 | 191, /* (83) cmd ::= DROP VIEW ifexists fullname */ |
| 173125 | 190, /* (84) cmd ::= select */ | 175329 | 191, /* (84) cmd ::= select */ |
| 173126 | 204, /* (85) select ::= WITH wqlist selectnowith */ | 175330 | 205, /* (85) select ::= WITH wqlist selectnowith */ |
| 173127 | 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ | 175331 | 205, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ |
| 173128 | 204, /* (87) select ::= selectnowith */ | 175332 | 205, /* (87) select ::= selectnowith */ |
| 173129 | 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ | 175333 | 240, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ |
| 173130 | 242, /* (89) multiselect_op ::= UNION */ | 175334 | 243, /* (89) multiselect_op ::= UNION */ |
| 173131 | 242, /* (90) multiselect_op ::= UNION ALL */ | 175335 | 243, /* (90) multiselect_op ::= UNION ALL */ |
| 173132 | 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ | 175336 | 243, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ |
| 173133 | 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ | 175337 | 241, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ |
| 173134 | 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ | 175338 | 241, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ |
| 173135 | 252, /* (94) values ::= VALUES LP nexprlist RP */ | 175339 | 253, /* (94) values ::= VALUES LP nexprlist RP */ |
| 173136 | 252, /* (95) values ::= values COMMA LP nexprlist RP */ | 175340 | 241, /* (95) oneselect ::= mvalues */ |
| 173137 | 243, /* (96) distinct ::= DISTINCT */ | 175341 | 255, /* (96) mvalues ::= values COMMA LP nexprlist RP */ |
| 173138 | 243, /* (97) distinct ::= ALL */ | 175342 | 255, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ |
| 173139 | 243, /* (98) distinct ::= */ | 175343 | 244, /* (98) distinct ::= DISTINCT */ |
| 173140 | 254, /* (99) sclp ::= */ | 175344 | 244, /* (99) distinct ::= ALL */ |
| 173141 | 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ | 175345 | 244, /* (100) distinct ::= */ |
| 173142 | 244, /* (101) selcollist ::= sclp scanpt STAR */ | 175346 | 256, /* (101) sclp ::= */ |
| 173143 | 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ | 175347 | 245, /* (102) selcollist ::= sclp scanpt expr scanpt as */ |
| 173144 | 255, /* (103) as ::= AS nm */ | 175348 | 245, /* (103) selcollist ::= sclp scanpt STAR */ |
| 173145 | 255, /* (104) as ::= */ | 175349 | 245, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ |
| 173146 | 245, /* (105) from ::= */ | 175350 | 257, /* (105) as ::= AS nm */ |
| 173147 | 245, /* (106) from ::= FROM seltablist */ | 175351 | 257, /* (106) as ::= */ |
| 173148 | 257, /* (107) stl_prefix ::= seltablist joinop */ | 175352 | 246, /* (107) from ::= */ |
| 173149 | 257, /* (108) stl_prefix ::= */ | 175353 | 246, /* (108) from ::= FROM seltablist */ |
| 173150 | 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ | 175354 | 259, /* (109) stl_prefix ::= seltablist joinop */ |
| 173151 | 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ | 175355 | 259, /* (110) stl_prefix ::= */ |
| 173152 | 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ | 175356 | 258, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ |
| 173153 | 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ | 175357 | 258, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ |
| 173154 | 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ | 175358 | 258, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ |
| 173155 | 200, /* (114) dbnm ::= */ | 175359 | 258, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ |
| 173156 | 200, /* (115) dbnm ::= DOT nm */ | 175360 | 258, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ |
| 173157 | 238, /* (116) fullname ::= nm */ | 175361 | 201, /* (116) dbnm ::= */ |
| 173158 | 238, /* (117) fullname ::= nm DOT nm */ | 175362 | 201, /* (117) dbnm ::= DOT nm */ |
| 173159 | 262, /* (118) xfullname ::= nm */ | 175363 | 239, /* (118) fullname ::= nm */ |
| 173160 | 262, /* (119) xfullname ::= nm DOT nm */ | 175364 | 239, /* (119) fullname ::= nm DOT nm */ |
| 173161 | 262, /* (120) xfullname ::= nm DOT nm AS nm */ | 175365 | 264, /* (120) xfullname ::= nm */ |
| 173162 | 262, /* (121) xfullname ::= nm AS nm */ | 175366 | 264, /* (121) xfullname ::= nm DOT nm */ |
| 173163 | 258, /* (122) joinop ::= COMMA|JOIN */ | 175367 | 264, /* (122) xfullname ::= nm DOT nm AS nm */ |
| 173164 | 258, /* (123) joinop ::= JOIN_KW JOIN */ | 175368 | 264, /* (123) xfullname ::= nm AS nm */ |
| 173165 | 258, /* (124) joinop ::= JOIN_KW nm JOIN */ | 175369 | 260, /* (124) joinop ::= COMMA|JOIN */ |
| 173166 | 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */ | 175370 | 260, /* (125) joinop ::= JOIN_KW JOIN */ |
| 173167 | 259, /* (126) on_using ::= ON expr */ | 175371 | 260, /* (126) joinop ::= JOIN_KW nm JOIN */ |
| 173168 | 259, /* (127) on_using ::= USING LP idlist RP */ | 175372 | 260, /* (127) joinop ::= JOIN_KW nm nm JOIN */ |
| 173169 | 259, /* (128) on_using ::= */ | 175373 | 261, /* (128) on_using ::= ON expr */ |
| 173170 | 264, /* (129) indexed_opt ::= */ | 175374 | 261, /* (129) on_using ::= USING LP idlist RP */ |
| 173171 | 260, /* (130) indexed_by ::= INDEXED BY nm */ | 175375 | 261, /* (130) on_using ::= */ |
| 173172 | 260, /* (131) indexed_by ::= NOT INDEXED */ | 175376 | 266, /* (131) indexed_opt ::= */ |
| 173173 | 249, /* (132) orderby_opt ::= */ | 175377 | 262, /* (132) indexed_by ::= INDEXED BY nm */ |
| 173174 | 249, /* (133) orderby_opt ::= ORDER BY sortlist */ | 175378 | 262, /* (133) indexed_by ::= NOT INDEXED */ |
| 173175 | 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ | 175379 | 250, /* (134) orderby_opt ::= */ |
| 173176 | 231, /* (135) sortlist ::= expr sortorder nulls */ | 175380 | 250, /* (135) orderby_opt ::= ORDER BY sortlist */ |
| 173177 | 219, /* (136) sortorder ::= ASC */ | 175381 | 232, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ |
| 173178 | 219, /* (137) sortorder ::= DESC */ | 175382 | 232, /* (137) sortlist ::= expr sortorder nulls */ |
| 173179 | 219, /* (138) sortorder ::= */ | 175383 | 220, /* (138) sortorder ::= ASC */ |
| 173180 | 265, /* (139) nulls ::= NULLS FIRST */ | 175384 | 220, /* (139) sortorder ::= DESC */ |
| 173181 | 265, /* (140) nulls ::= NULLS LAST */ | 175385 | 220, /* (140) sortorder ::= */ |
| 173182 | 265, /* (141) nulls ::= */ | 175386 | 267, /* (141) nulls ::= NULLS FIRST */ |
| 173183 | 247, /* (142) groupby_opt ::= */ | 175387 | 267, /* (142) nulls ::= NULLS LAST */ |
| 173184 | 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ | 175388 | 267, /* (143) nulls ::= */ |
| 173185 | 248, /* (144) having_opt ::= */ | 175389 | 248, /* (144) groupby_opt ::= */ |
| 173186 | 248, /* (145) having_opt ::= HAVING expr */ | 175390 | 248, /* (145) groupby_opt ::= GROUP BY nexprlist */ |
| 173187 | 250, /* (146) limit_opt ::= */ | 175391 | 249, /* (146) having_opt ::= */ |
| 173188 | 250, /* (147) limit_opt ::= LIMIT expr */ | 175392 | 249, /* (147) having_opt ::= HAVING expr */ |
| 173189 | 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ | 175393 | 251, /* (148) limit_opt ::= */ |
| 173190 | 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ | 175394 | 251, /* (149) limit_opt ::= LIMIT expr */ |
| 173191 | 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ | 175395 | 251, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ |
| 173192 | 246, /* (151) where_opt ::= */ | 175396 | 251, /* (151) limit_opt ::= LIMIT expr COMMA expr */ |
| 173193 | 246, /* (152) where_opt ::= WHERE expr */ | 175397 | 191, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ |
| 173194 | 267, /* (153) where_opt_ret ::= */ | 175398 | 247, /* (153) where_opt ::= */ |
| 173195 | 267, /* (154) where_opt_ret ::= WHERE expr */ | 175399 | 247, /* (154) where_opt ::= WHERE expr */ |
| 173196 | 267, /* (155) where_opt_ret ::= RETURNING selcollist */ | 175400 | 269, /* (155) where_opt_ret ::= */ |
| 173197 | 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ | 175401 | 269, /* (156) where_opt_ret ::= WHERE expr */ |
| 173198 | 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ | 175402 | 269, /* (157) where_opt_ret ::= RETURNING selcollist */ |
| 173199 | 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ | 175403 | 269, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ |
| 173200 | 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ | 175404 | 191, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ |
| 173201 | 268, /* (160) setlist ::= nm EQ expr */ | 175405 | 270, /* (160) setlist ::= setlist COMMA nm EQ expr */ |
| 173202 | 268, /* (161) setlist ::= LP idlist RP EQ expr */ | 175406 | 270, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ |
| 173203 | 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ | 175407 | 270, /* (162) setlist ::= nm EQ expr */ |
| 173204 | 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ | 175408 | 270, /* (163) setlist ::= LP idlist RP EQ expr */ |
| 173205 | 271, /* (164) upsert ::= */ | 175409 | 191, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ |
| 173206 | 271, /* (165) upsert ::= RETURNING selcollist */ | 175410 | 191, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ |
| 173207 | 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ | 175411 | 273, /* (166) upsert ::= */ |
| 173208 | 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ | 175412 | 273, /* (167) upsert ::= RETURNING selcollist */ |
| 173209 | 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ | 175413 | 273, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ |
| 173210 | 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ | 175414 | 273, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ |
| 173211 | 272, /* (170) returning ::= RETURNING selcollist */ | 175415 | 273, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ |
| 173212 | 269, /* (171) insert_cmd ::= INSERT orconf */ | 175416 | 273, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ |
| 173213 | 269, /* (172) insert_cmd ::= REPLACE */ | 175417 | 274, /* (172) returning ::= RETURNING selcollist */ |
| 173214 | 270, /* (173) idlist_opt ::= */ | 175418 | 271, /* (173) insert_cmd ::= INSERT orconf */ |
| 173215 | 270, /* (174) idlist_opt ::= LP idlist RP */ | 175419 | 271, /* (174) insert_cmd ::= REPLACE */ |
| 173216 | 263, /* (175) idlist ::= idlist COMMA nm */ | 175420 | 272, /* (175) idlist_opt ::= */ |
| 173217 | 263, /* (176) idlist ::= nm */ | 175421 | 272, /* (176) idlist_opt ::= LP idlist RP */ |
| 173218 | 217, /* (177) expr ::= LP expr RP */ | 175422 | 265, /* (177) idlist ::= idlist COMMA nm */ |
| 173219 | 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ | 175423 | 265, /* (178) idlist ::= nm */ |
| 173220 | 217, /* (179) expr ::= nm DOT nm */ | 175424 | 218, /* (179) expr ::= LP expr RP */ |
| 173221 | 217, /* (180) expr ::= nm DOT nm DOT nm */ | 175425 | 218, /* (180) expr ::= ID|INDEXED|JOIN_KW */ |
| 173222 | 216, /* (181) term ::= NULL|FLOAT|BLOB */ | 175426 | 218, /* (181) expr ::= nm DOT nm */ |
| 173223 | 216, /* (182) term ::= STRING */ | 175427 | 218, /* (182) expr ::= nm DOT nm DOT nm */ |
| 173224 | 216, /* (183) term ::= INTEGER */ | 175428 | 217, /* (183) term ::= NULL|FLOAT|BLOB */ |
| 173225 | 217, /* (184) expr ::= VARIABLE */ | 175429 | 217, /* (184) term ::= STRING */ |
| 173226 | 217, /* (185) expr ::= expr COLLATE ID|STRING */ | 175430 | 217, /* (185) term ::= INTEGER */ |
| 173227 | 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ | 175431 | 218, /* (186) expr ::= VARIABLE */ |
| 173228 | 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ | 175432 | 218, /* (187) expr ::= expr COLLATE ID|STRING */ |
| 173229 | 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ | 175433 | 218, /* (188) expr ::= CAST LP expr AS typetoken RP */ |
| 173230 | 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ | 175434 | 218, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 173231 | 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ | 175435 | 218, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ |
| 173232 | 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ | 175436 | 218, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 173233 | 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ | 175437 | 218, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 173234 | 216, /* (193) term ::= CTIME_KW */ | 175438 | 218, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ |
| 173235 | 217, /* (194) expr ::= LP nexprlist COMMA expr RP */ | 175439 | 218, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 173236 | 217, /* (195) expr ::= expr AND expr */ | 175440 | 217, /* (195) term ::= CTIME_KW */ |
| 173237 | 217, /* (196) expr ::= expr OR expr */ | 175441 | 218, /* (196) expr ::= LP nexprlist COMMA expr RP */ |
| 173238 | 217, /* (197) expr ::= expr LT|GT|GE|LE expr */ | 175442 | 218, /* (197) expr ::= expr AND expr */ |
| 173239 | 217, /* (198) expr ::= expr EQ|NE expr */ | 175443 | 218, /* (198) expr ::= expr OR expr */ |
| 173240 | 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ | 175444 | 218, /* (199) expr ::= expr LT|GT|GE|LE expr */ |
| 173241 | 217, /* (200) expr ::= expr PLUS|MINUS expr */ | 175445 | 218, /* (200) expr ::= expr EQ|NE expr */ |
| 173242 | 217, /* (201) expr ::= expr STAR|SLASH|REM expr */ | 175446 | 218, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ |
| 173243 | 217, /* (202) expr ::= expr CONCAT expr */ | 175447 | 218, /* (202) expr ::= expr PLUS|MINUS expr */ |
| 173244 | 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */ | 175448 | 218, /* (203) expr ::= expr STAR|SLASH|REM expr */ |
| 173245 | 217, /* (204) expr ::= expr likeop expr */ | 175449 | 218, /* (204) expr ::= expr CONCAT expr */ |
| 173246 | 217, /* (205) expr ::= expr likeop expr ESCAPE expr */ | 175450 | 276, /* (205) likeop ::= NOT LIKE_KW|MATCH */ |
| 173247 | 217, /* (206) expr ::= expr ISNULL|NOTNULL */ | 175451 | 218, /* (206) expr ::= expr likeop expr */ |
| 173248 | 217, /* (207) expr ::= expr NOT NULL */ | 175452 | 218, /* (207) expr ::= expr likeop expr ESCAPE expr */ |
| 173249 | 217, /* (208) expr ::= expr IS expr */ | 175453 | 218, /* (208) expr ::= expr ISNULL|NOTNULL */ |
| 173250 | 217, /* (209) expr ::= expr IS NOT expr */ | 175454 | 218, /* (209) expr ::= expr NOT NULL */ |
| 173251 | 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ | 175455 | 218, /* (210) expr ::= expr IS expr */ |
| 173252 | 217, /* (211) expr ::= expr IS DISTINCT FROM expr */ | 175456 | 218, /* (211) expr ::= expr IS NOT expr */ |
| 173253 | 217, /* (212) expr ::= NOT expr */ | 175457 | 218, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ |
| 173254 | 217, /* (213) expr ::= BITNOT expr */ | 175458 | 218, /* (213) expr ::= expr IS DISTINCT FROM expr */ |
| 173255 | 217, /* (214) expr ::= PLUS|MINUS expr */ | 175459 | 218, /* (214) expr ::= NOT expr */ |
| 173256 | 217, /* (215) expr ::= expr PTR expr */ | 175460 | 218, /* (215) expr ::= BITNOT expr */ |
| 173257 | 275, /* (216) between_op ::= BETWEEN */ | 175461 | 218, /* (216) expr ::= PLUS|MINUS expr */ |
| 173258 | 275, /* (217) between_op ::= NOT BETWEEN */ | 175462 | 218, /* (217) expr ::= expr PTR expr */ |
| 173259 | 217, /* (218) expr ::= expr between_op expr AND expr */ | 175463 | 277, /* (218) between_op ::= BETWEEN */ |
| 173260 | 276, /* (219) in_op ::= IN */ | 175464 | 277, /* (219) between_op ::= NOT BETWEEN */ |
| 173261 | 276, /* (220) in_op ::= NOT IN */ | 175465 | 218, /* (220) expr ::= expr between_op expr AND expr */ |
| 173262 | 217, /* (221) expr ::= expr in_op LP exprlist RP */ | 175466 | 278, /* (221) in_op ::= IN */ |
| 173263 | 217, /* (222) expr ::= LP select RP */ | 175467 | 278, /* (222) in_op ::= NOT IN */ |
| 173264 | 217, /* (223) expr ::= expr in_op LP select RP */ | 175468 | 218, /* (223) expr ::= expr in_op LP exprlist RP */ |
| 173265 | 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ | 175469 | 218, /* (224) expr ::= LP select RP */ |
| 173266 | 217, /* (225) expr ::= EXISTS LP select RP */ | 175470 | 218, /* (225) expr ::= expr in_op LP select RP */ |
| 173267 | 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ | 175471 | 218, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ |
| 173268 | 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 175472 | 218, /* (227) expr ::= EXISTS LP select RP */ |
| 173269 | 279, /* (228) case_exprlist ::= WHEN expr THEN expr */ | 175473 | 218, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ |
| 173270 | 280, /* (229) case_else ::= ELSE expr */ | 175474 | 281, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 173271 | 280, /* (230) case_else ::= */ | 175475 | 281, /* (230) case_exprlist ::= WHEN expr THEN expr */ |
| 173272 | 278, /* (231) case_operand ::= */ | 175476 | 282, /* (231) case_else ::= ELSE expr */ |
| 173273 | 261, /* (232) exprlist ::= */ | 175477 | 282, /* (232) case_else ::= */ |
| 173274 | 253, /* (233) nexprlist ::= nexprlist COMMA expr */ | 175478 | 280, /* (233) case_operand ::= */ |
| 173275 | 253, /* (234) nexprlist ::= expr */ | 175479 | 263, /* (234) exprlist ::= */ |
| 173276 | 277, /* (235) paren_exprlist ::= */ | 175480 | 254, /* (235) nexprlist ::= nexprlist COMMA expr */ |
| 173277 | 277, /* (236) paren_exprlist ::= LP exprlist RP */ | 175481 | 254, /* (236) nexprlist ::= expr */ |
| 173278 | 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 175482 | 279, /* (237) paren_exprlist ::= */ |
| 173279 | 281, /* (238) uniqueflag ::= UNIQUE */ | 175483 | 279, /* (238) paren_exprlist ::= LP exprlist RP */ |
| 173280 | 281, /* (239) uniqueflag ::= */ | 175484 | 191, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 173281 | 221, /* (240) eidlist_opt ::= */ | 175485 | 283, /* (240) uniqueflag ::= UNIQUE */ |
| 173282 | 221, /* (241) eidlist_opt ::= LP eidlist RP */ | 175486 | 283, /* (241) uniqueflag ::= */ |
| 173283 | 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ | 175487 | 222, /* (242) eidlist_opt ::= */ |
| 173284 | 232, /* (243) eidlist ::= nm collate sortorder */ | 175488 | 222, /* (243) eidlist_opt ::= LP eidlist RP */ |
| 173285 | 282, /* (244) collate ::= */ | 175489 | 233, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ |
| 173286 | 282, /* (245) collate ::= COLLATE ID|STRING */ | 175490 | 233, /* (245) eidlist ::= nm collate sortorder */ |
| 173287 | 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ | 175491 | 284, /* (246) collate ::= */ |
| 173288 | 190, /* (247) cmd ::= VACUUM vinto */ | 175492 | 284, /* (247) collate ::= COLLATE ID|STRING */ |
| 173289 | 190, /* (248) cmd ::= VACUUM nm vinto */ | 175493 | 191, /* (248) cmd ::= DROP INDEX ifexists fullname */ |
| 173290 | 283, /* (249) vinto ::= INTO expr */ | 175494 | 191, /* (249) cmd ::= VACUUM vinto */ |
| 173291 | 283, /* (250) vinto ::= */ | 175495 | 191, /* (250) cmd ::= VACUUM nm vinto */ |
| 173292 | 190, /* (251) cmd ::= PRAGMA nm dbnm */ | 175496 | 285, /* (251) vinto ::= INTO expr */ |
| 173293 | 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ | 175497 | 285, /* (252) vinto ::= */ |
| 173294 | 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 175498 | 191, /* (253) cmd ::= PRAGMA nm dbnm */ |
| 173295 | 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ | 175499 | 191, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 173296 | 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 175500 | 191, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 173297 | 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ | 175501 | 191, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 173298 | 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ | 175502 | 191, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 173299 | 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 175503 | 212, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ |
| 173300 | 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 175504 | 213, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ |
| 173301 | 287, /* (260) trigger_time ::= BEFORE|AFTER */ | 175505 | 191, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 173302 | 287, /* (261) trigger_time ::= INSTEAD OF */ | 175506 | 287, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 173303 | 287, /* (262) trigger_time ::= */ | 175507 | 289, /* (262) trigger_time ::= BEFORE|AFTER */ |
| 173304 | 288, /* (263) trigger_event ::= DELETE|INSERT */ | 175508 | 289, /* (263) trigger_time ::= INSTEAD OF */ |
| 173305 | 288, /* (264) trigger_event ::= UPDATE */ | 175509 | 289, /* (264) trigger_time ::= */ |
| 173306 | 288, /* (265) trigger_event ::= UPDATE OF idlist */ | 175510 | 290, /* (265) trigger_event ::= DELETE|INSERT */ |
| 173307 | 290, /* (266) when_clause ::= */ | 175511 | 290, /* (266) trigger_event ::= UPDATE */ |
| 173308 | 290, /* (267) when_clause ::= WHEN expr */ | 175512 | 290, /* (267) trigger_event ::= UPDATE OF idlist */ |
| 173309 | 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 175513 | 292, /* (268) when_clause ::= */ |
| 173310 | 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ | 175514 | 292, /* (269) when_clause ::= WHEN expr */ |
| 173311 | 292, /* (270) trnm ::= nm DOT nm */ | 175515 | 288, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 173312 | 293, /* (271) tridxby ::= INDEXED BY nm */ | 175516 | 288, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ |
| 173313 | 293, /* (272) tridxby ::= NOT INDEXED */ | 175517 | 294, /* (272) trnm ::= nm DOT nm */ |
| 173314 | 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 175518 | 295, /* (273) tridxby ::= INDEXED BY nm */ |
| 173315 | 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 175519 | 295, /* (274) tridxby ::= NOT INDEXED */ |
| 173316 | 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 175520 | 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 173317 | 291, /* (276) trigger_cmd ::= scanpt select scanpt */ | 175521 | 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 173318 | 217, /* (277) expr ::= RAISE LP IGNORE RP */ | 175522 | 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 173319 | 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ | 175523 | 293, /* (278) trigger_cmd ::= scanpt select scanpt */ |
| 173320 | 236, /* (279) raisetype ::= ROLLBACK */ | 175524 | 218, /* (279) expr ::= RAISE LP IGNORE RP */ |
| 173321 | 236, /* (280) raisetype ::= ABORT */ | 175525 | 218, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ |
| 173322 | 236, /* (281) raisetype ::= FAIL */ | 175526 | 237, /* (281) raisetype ::= ROLLBACK */ |
| 173323 | 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ | 175527 | 237, /* (282) raisetype ::= ABORT */ |
| 173324 | 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 175528 | 237, /* (283) raisetype ::= FAIL */ |
| 173325 | 190, /* (284) cmd ::= DETACH database_kw_opt expr */ | 175529 | 191, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ |
| 173326 | 295, /* (285) key_opt ::= */ | 175530 | 191, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 173327 | 295, /* (286) key_opt ::= KEY expr */ | 175531 | 191, /* (286) cmd ::= DETACH database_kw_opt expr */ |
| 173328 | 190, /* (287) cmd ::= REINDEX */ | 175532 | 297, /* (287) key_opt ::= */ |
| 173329 | 190, /* (288) cmd ::= REINDEX nm dbnm */ | 175533 | 297, /* (288) key_opt ::= KEY expr */ |
| 173330 | 190, /* (289) cmd ::= ANALYZE */ | 175534 | 191, /* (289) cmd ::= REINDEX */ |
| 173331 | 190, /* (290) cmd ::= ANALYZE nm dbnm */ | 175535 | 191, /* (290) cmd ::= REINDEX nm dbnm */ |
| 173332 | 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ | 175536 | 191, /* (291) cmd ::= ANALYZE */ |
| 173333 | 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 175537 | 191, /* (292) cmd ::= ANALYZE nm dbnm */ |
| 173334 | 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 175538 | 191, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 173335 | 296, /* (294) add_column_fullname ::= fullname */ | 175539 | 191, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 173336 | 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 175540 | 191, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 173337 | 190, /* (296) cmd ::= create_vtab */ | 175541 | 298, /* (296) add_column_fullname ::= fullname */ |
| 173338 | 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ | 175542 | 191, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 173339 | 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 175543 | 191, /* (298) cmd ::= create_vtab */ |
| 173340 | 300, /* (299) vtabarg ::= */ | 175544 | 191, /* (299) cmd ::= create_vtab LP vtabarglist RP */ |
| 173341 | 301, /* (300) vtabargtoken ::= ANY */ | 175545 | 300, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 173342 | 301, /* (301) vtabargtoken ::= lp anylist RP */ | 175546 | 302, /* (301) vtabarg ::= */ |
| 173343 | 302, /* (302) lp ::= LP */ | 175547 | 303, /* (302) vtabargtoken ::= ANY */ |
| 173344 | 266, /* (303) with ::= WITH wqlist */ | 175548 | 303, /* (303) vtabargtoken ::= lp anylist RP */ |
| 173345 | 266, /* (304) with ::= WITH RECURSIVE wqlist */ | 175549 | 304, /* (304) lp ::= LP */ |
| 173346 | 305, /* (305) wqas ::= AS */ | 175550 | 268, /* (305) with ::= WITH wqlist */ |
| 173347 | 305, /* (306) wqas ::= AS MATERIALIZED */ | 175551 | 268, /* (306) with ::= WITH RECURSIVE wqlist */ |
| 173348 | 305, /* (307) wqas ::= AS NOT MATERIALIZED */ | 175552 | 307, /* (307) wqas ::= AS */ |
| 173349 | 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ | 175553 | 307, /* (308) wqas ::= AS MATERIALIZED */ |
| 173350 | 241, /* (309) wqlist ::= wqitem */ | 175554 | 307, /* (309) wqas ::= AS NOT MATERIALIZED */ |
| 173351 | 241, /* (310) wqlist ::= wqlist COMMA wqitem */ | 175555 | 306, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ |
| 173352 | 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ | 175556 | 308, /* (311) withnm ::= nm */ |
| 173353 | 307, /* (312) windowdefn ::= nm AS LP window RP */ | 175557 | 242, /* (312) wqlist ::= wqitem */ |
| 173354 | 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 175558 | 242, /* (313) wqlist ::= wqlist COMMA wqitem */ |
| 173355 | 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 175559 | 309, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 173356 | 308, /* (315) window ::= ORDER BY sortlist frame_opt */ | 175560 | 310, /* (315) windowdefn ::= nm AS LP window RP */ |
| 173357 | 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ | 175561 | 311, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 173358 | 308, /* (317) window ::= nm frame_opt */ | 175562 | 311, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 173359 | 309, /* (318) frame_opt ::= */ | 175563 | 311, /* (318) window ::= ORDER BY sortlist frame_opt */ |
| 173360 | 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 175564 | 311, /* (319) window ::= nm ORDER BY sortlist frame_opt */ |
| 173361 | 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 175565 | 311, /* (320) window ::= nm frame_opt */ |
| 173362 | 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ | 175566 | 312, /* (321) frame_opt ::= */ |
| 173363 | 315, /* (322) frame_bound_s ::= frame_bound */ | 175567 | 312, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 173364 | 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ | 175568 | 312, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 173365 | 316, /* (324) frame_bound_e ::= frame_bound */ | 175569 | 316, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ |
| 173366 | 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ | 175570 | 318, /* (325) frame_bound_s ::= frame_bound */ |
| 173367 | 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ | 175571 | 318, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 173368 | 314, /* (327) frame_bound ::= CURRENT ROW */ | 175572 | 319, /* (327) frame_bound_e ::= frame_bound */ |
| 173369 | 317, /* (328) frame_exclude_opt ::= */ | 175573 | 319, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ |
| 173370 | 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ | 175574 | 317, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 173371 | 318, /* (330) frame_exclude ::= NO OTHERS */ | 175575 | 317, /* (330) frame_bound ::= CURRENT ROW */ |
| 173372 | 318, /* (331) frame_exclude ::= CURRENT ROW */ | 175576 | 320, /* (331) frame_exclude_opt ::= */ |
| 173373 | 318, /* (332) frame_exclude ::= GROUP|TIES */ | 175577 | 320, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 173374 | 251, /* (333) window_clause ::= WINDOW windowdefn_list */ | 175578 | 321, /* (333) frame_exclude ::= NO OTHERS */ |
| 173375 | 273, /* (334) filter_over ::= filter_clause over_clause */ | 175579 | 321, /* (334) frame_exclude ::= CURRENT ROW */ |
| 173376 | 273, /* (335) filter_over ::= over_clause */ | 175580 | 321, /* (335) frame_exclude ::= GROUP|TIES */ |
| 173377 | 273, /* (336) filter_over ::= filter_clause */ | 175581 | 252, /* (336) window_clause ::= WINDOW windowdefn_list */ |
| 173378 | 312, /* (337) over_clause ::= OVER LP window RP */ | 175582 | 275, /* (337) filter_over ::= filter_clause over_clause */ |
| 173379 | 312, /* (338) over_clause ::= OVER nm */ | 175583 | 275, /* (338) filter_over ::= over_clause */ |
| 173380 | 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ | 175584 | 275, /* (339) filter_over ::= filter_clause */ |
| 173381 | 185, /* (340) input ::= cmdlist */ | 175585 | 315, /* (340) over_clause ::= OVER LP window RP */ |
| 173382 | 186, /* (341) cmdlist ::= cmdlist ecmd */ | 175586 | 315, /* (341) over_clause ::= OVER nm */ |
| 173383 | 186, /* (342) cmdlist ::= ecmd */ | 175587 | 314, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ |
| 173384 | 187, /* (343) ecmd ::= SEMI */ | 175588 | 217, /* (343) term ::= QNUMBER */ |
| 173385 | 187, /* (344) ecmd ::= cmdx SEMI */ | 175589 | 186, /* (344) input ::= cmdlist */ |
| 173386 | 187, /* (345) ecmd ::= explain cmdx SEMI */ | 175590 | 187, /* (345) cmdlist ::= cmdlist ecmd */ |
| 173387 | 192, /* (346) trans_opt ::= */ | 175591 | 187, /* (346) cmdlist ::= ecmd */ |
| 173388 | 192, /* (347) trans_opt ::= TRANSACTION */ | 175592 | 188, /* (347) ecmd ::= SEMI */ |
| 173389 | 192, /* (348) trans_opt ::= TRANSACTION nm */ | 175593 | 188, /* (348) ecmd ::= cmdx SEMI */ |
| 173390 | 194, /* (349) savepoint_opt ::= SAVEPOINT */ | 175594 | 188, /* (349) ecmd ::= explain cmdx SEMI */ |
| 173391 | 194, /* (350) savepoint_opt ::= */ | 175595 | 193, /* (350) trans_opt ::= */ |
| 173392 | 190, /* (351) cmd ::= create_table create_table_args */ | 175596 | 193, /* (351) trans_opt ::= TRANSACTION */ |
| 173393 | 203, /* (352) table_option_set ::= table_option */ | 175597 | 193, /* (352) trans_opt ::= TRANSACTION nm */ |
| 173394 | 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ | 175598 | 195, /* (353) savepoint_opt ::= SAVEPOINT */ |
| 173395 | 201, /* (354) columnlist ::= columnname carglist */ | 175599 | 195, /* (354) savepoint_opt ::= */ |
| 173396 | 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */ | 175600 | 191, /* (355) cmd ::= create_table create_table_args */ |
| 173397 | 193, /* (356) nm ::= STRING */ | 175601 | 204, /* (356) table_option_set ::= table_option */ |
| 173398 | 208, /* (357) typetoken ::= typename */ | 175602 | 202, /* (357) columnlist ::= columnlist COMMA columnname carglist */ |
| 173399 | 209, /* (358) typename ::= ID|STRING */ | 175603 | 202, /* (358) columnlist ::= columnname carglist */ |
| 173400 | 210, /* (359) signed ::= plus_num */ | 175604 | 194, /* (359) nm ::= ID|INDEXED|JOIN_KW */ |
| 173401 | 210, /* (360) signed ::= minus_num */ | 175605 | 194, /* (360) nm ::= STRING */ |
| 173402 | 207, /* (361) carglist ::= carglist ccons */ | 175606 | 209, /* (361) typetoken ::= typename */ |
| 173403 | 207, /* (362) carglist ::= */ | 175607 | 210, /* (362) typename ::= ID|STRING */ |
| 173404 | 215, /* (363) ccons ::= NULL onconf */ | 175608 | 211, /* (363) signed ::= plus_num */ |
| 173405 | 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */ | 175609 | 211, /* (364) signed ::= minus_num */ |
| 173406 | 215, /* (365) ccons ::= AS generated */ | 175610 | 208, /* (365) carglist ::= carglist ccons */ |
| 173407 | 202, /* (366) conslist_opt ::= COMMA conslist */ | 175611 | 208, /* (366) carglist ::= */ |
| 173408 | 228, /* (367) conslist ::= conslist tconscomma tcons */ | 175612 | 216, /* (367) ccons ::= NULL onconf */ |
| 173409 | 228, /* (368) conslist ::= tcons */ | 175613 | 216, /* (368) ccons ::= GENERATED ALWAYS AS generated */ |
| 173410 | 229, /* (369) tconscomma ::= */ | 175614 | 216, /* (369) ccons ::= AS generated */ |
| 173411 | 233, /* (370) defer_subclause_opt ::= defer_subclause */ | 175615 | 203, /* (370) conslist_opt ::= COMMA conslist */ |
| 173412 | 235, /* (371) resolvetype ::= raisetype */ | 175616 | 229, /* (371) conslist ::= conslist tconscomma tcons */ |
| 173413 | 239, /* (372) selectnowith ::= oneselect */ | 175617 | 229, /* (372) conslist ::= tcons */ |
| 173414 | 240, /* (373) oneselect ::= values */ | 175618 | 230, /* (373) tconscomma ::= */ |
| 173415 | 254, /* (374) sclp ::= selcollist COMMA */ | 175619 | 234, /* (374) defer_subclause_opt ::= defer_subclause */ |
| 173416 | 255, /* (375) as ::= ID|STRING */ | 175620 | 236, /* (375) resolvetype ::= raisetype */ |
| 173417 | 264, /* (376) indexed_opt ::= indexed_by */ | 175621 | 240, /* (376) selectnowith ::= oneselect */ |
| 173418 | 272, /* (377) returning ::= */ | 175622 | 241, /* (377) oneselect ::= values */ |
| 173419 | 217, /* (378) expr ::= term */ | 175623 | 256, /* (378) sclp ::= selcollist COMMA */ |
| 173420 | 274, /* (379) likeop ::= LIKE_KW|MATCH */ | 175624 | 257, /* (379) as ::= ID|STRING */ |
| 173421 | 278, /* (380) case_operand ::= expr */ | 175625 | 266, /* (380) indexed_opt ::= indexed_by */ |
| 173422 | 261, /* (381) exprlist ::= nexprlist */ | 175626 | 274, /* (381) returning ::= */ |
| 173423 | 284, /* (382) nmnum ::= plus_num */ | 175627 | 218, /* (382) expr ::= term */ |
| 173424 | 284, /* (383) nmnum ::= nm */ | 175628 | 276, /* (383) likeop ::= LIKE_KW|MATCH */ |
| 173425 | 284, /* (384) nmnum ::= ON */ | 175629 | 280, /* (384) case_operand ::= expr */ |
| 173426 | 284, /* (385) nmnum ::= DELETE */ | 175630 | 263, /* (385) exprlist ::= nexprlist */ |
| 173427 | 284, /* (386) nmnum ::= DEFAULT */ | 175631 | 286, /* (386) nmnum ::= plus_num */ |
| 173428 | 211, /* (387) plus_num ::= INTEGER|FLOAT */ | 175632 | 286, /* (387) nmnum ::= nm */ |
| 173429 | 289, /* (388) foreach_clause ::= */ | 175633 | 286, /* (388) nmnum ::= ON */ |
| 173430 | 289, /* (389) foreach_clause ::= FOR EACH ROW */ | 175634 | 286, /* (389) nmnum ::= DELETE */ |
| 173431 | 292, /* (390) trnm ::= nm */ | 175635 | 286, /* (390) nmnum ::= DEFAULT */ |
| 173432 | 293, /* (391) tridxby ::= */ | 175636 | 212, /* (391) plus_num ::= INTEGER|FLOAT */ |
| 173433 | 294, /* (392) database_kw_opt ::= DATABASE */ | 175637 | 291, /* (392) foreach_clause ::= */ |
| 173434 | 294, /* (393) database_kw_opt ::= */ | 175638 | 291, /* (393) foreach_clause ::= FOR EACH ROW */ |
| 173435 | 297, /* (394) kwcolumn_opt ::= */ | 175639 | 294, /* (394) trnm ::= nm */ |
| 173436 | 297, /* (395) kwcolumn_opt ::= COLUMNKW */ | 175640 | 295, /* (395) tridxby ::= */ |
| 173437 | 299, /* (396) vtabarglist ::= vtabarg */ | 175641 | 296, /* (396) database_kw_opt ::= DATABASE */ |
| 173438 | 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ | 175642 | 296, /* (397) database_kw_opt ::= */ |
| 173439 | 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ | 175643 | 299, /* (398) kwcolumn_opt ::= */ |
| 173440 | 303, /* (399) anylist ::= */ | 175644 | 299, /* (399) kwcolumn_opt ::= COLUMNKW */ |
| 173441 | 303, /* (400) anylist ::= anylist LP anylist RP */ | 175645 | 301, /* (400) vtabarglist ::= vtabarg */ |
| 173442 | 303, /* (401) anylist ::= anylist ANY */ | 175646 | 301, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ |
| 173443 | 266, /* (402) with ::= */ | 175647 | 302, /* (402) vtabarg ::= vtabarg vtabargtoken */ |
| 173444 | 306, /* (403) windowdefn_list ::= windowdefn */ | 175648 | 305, /* (403) anylist ::= */ |
| 173445 | 308, /* (404) window ::= frame_opt */ | 175649 | 305, /* (404) anylist ::= anylist LP anylist RP */ |
| 175650 | 305, /* (405) anylist ::= anylist ANY */ | ||
| 175651 | 268, /* (406) with ::= */ | ||
| 175652 | 309, /* (407) windowdefn_list ::= windowdefn */ | ||
| 175653 | 311, /* (408) window ::= frame_opt */ | ||
| 173446 | }; | 175654 | }; |
| 173447 | 175655 | ||
| 173448 | /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number | 175656 | /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number |
| @@ -173543,316 +175751,320 @@ static const signed char yyRuleInfoNRhs[] = { | |||
| 173543 | -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ | 175751 | -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ |
| 173544 | -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ | 175752 | -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ |
| 173545 | -4, /* (94) values ::= VALUES LP nexprlist RP */ | 175753 | -4, /* (94) values ::= VALUES LP nexprlist RP */ |
| 173546 | -5, /* (95) values ::= values COMMA LP nexprlist RP */ | 175754 | -1, /* (95) oneselect ::= mvalues */ |
| 173547 | -1, /* (96) distinct ::= DISTINCT */ | 175755 | -5, /* (96) mvalues ::= values COMMA LP nexprlist RP */ |
| 173548 | -1, /* (97) distinct ::= ALL */ | 175756 | -5, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ |
| 173549 | 0, /* (98) distinct ::= */ | 175757 | -1, /* (98) distinct ::= DISTINCT */ |
| 173550 | 0, /* (99) sclp ::= */ | 175758 | -1, /* (99) distinct ::= ALL */ |
| 173551 | -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */ | 175759 | 0, /* (100) distinct ::= */ |
| 173552 | -3, /* (101) selcollist ::= sclp scanpt STAR */ | 175760 | 0, /* (101) sclp ::= */ |
| 173553 | -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ | 175761 | -5, /* (102) selcollist ::= sclp scanpt expr scanpt as */ |
| 173554 | -2, /* (103) as ::= AS nm */ | 175762 | -3, /* (103) selcollist ::= sclp scanpt STAR */ |
| 173555 | 0, /* (104) as ::= */ | 175763 | -5, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ |
| 173556 | 0, /* (105) from ::= */ | 175764 | -2, /* (105) as ::= AS nm */ |
| 173557 | -2, /* (106) from ::= FROM seltablist */ | 175765 | 0, /* (106) as ::= */ |
| 173558 | -2, /* (107) stl_prefix ::= seltablist joinop */ | 175766 | 0, /* (107) from ::= */ |
| 173559 | 0, /* (108) stl_prefix ::= */ | 175767 | -2, /* (108) from ::= FROM seltablist */ |
| 173560 | -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */ | 175768 | -2, /* (109) stl_prefix ::= seltablist joinop */ |
| 173561 | -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ | 175769 | 0, /* (110) stl_prefix ::= */ |
| 173562 | -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ | 175770 | -5, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ |
| 173563 | -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */ | 175771 | -6, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ |
| 173564 | -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */ | 175772 | -8, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ |
| 173565 | 0, /* (114) dbnm ::= */ | 175773 | -6, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ |
| 173566 | -2, /* (115) dbnm ::= DOT nm */ | 175774 | -6, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ |
| 173567 | -1, /* (116) fullname ::= nm */ | 175775 | 0, /* (116) dbnm ::= */ |
| 173568 | -3, /* (117) fullname ::= nm DOT nm */ | 175776 | -2, /* (117) dbnm ::= DOT nm */ |
| 173569 | -1, /* (118) xfullname ::= nm */ | 175777 | -1, /* (118) fullname ::= nm */ |
| 173570 | -3, /* (119) xfullname ::= nm DOT nm */ | 175778 | -3, /* (119) fullname ::= nm DOT nm */ |
| 173571 | -5, /* (120) xfullname ::= nm DOT nm AS nm */ | 175779 | -1, /* (120) xfullname ::= nm */ |
| 173572 | -3, /* (121) xfullname ::= nm AS nm */ | 175780 | -3, /* (121) xfullname ::= nm DOT nm */ |
| 173573 | -1, /* (122) joinop ::= COMMA|JOIN */ | 175781 | -5, /* (122) xfullname ::= nm DOT nm AS nm */ |
| 173574 | -2, /* (123) joinop ::= JOIN_KW JOIN */ | 175782 | -3, /* (123) xfullname ::= nm AS nm */ |
| 173575 | -3, /* (124) joinop ::= JOIN_KW nm JOIN */ | 175783 | -1, /* (124) joinop ::= COMMA|JOIN */ |
| 173576 | -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */ | 175784 | -2, /* (125) joinop ::= JOIN_KW JOIN */ |
| 173577 | -2, /* (126) on_using ::= ON expr */ | 175785 | -3, /* (126) joinop ::= JOIN_KW nm JOIN */ |
| 173578 | -4, /* (127) on_using ::= USING LP idlist RP */ | 175786 | -4, /* (127) joinop ::= JOIN_KW nm nm JOIN */ |
| 173579 | 0, /* (128) on_using ::= */ | 175787 | -2, /* (128) on_using ::= ON expr */ |
| 173580 | 0, /* (129) indexed_opt ::= */ | 175788 | -4, /* (129) on_using ::= USING LP idlist RP */ |
| 173581 | -3, /* (130) indexed_by ::= INDEXED BY nm */ | 175789 | 0, /* (130) on_using ::= */ |
| 173582 | -2, /* (131) indexed_by ::= NOT INDEXED */ | 175790 | 0, /* (131) indexed_opt ::= */ |
| 173583 | 0, /* (132) orderby_opt ::= */ | 175791 | -3, /* (132) indexed_by ::= INDEXED BY nm */ |
| 173584 | -3, /* (133) orderby_opt ::= ORDER BY sortlist */ | 175792 | -2, /* (133) indexed_by ::= NOT INDEXED */ |
| 173585 | -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ | 175793 | 0, /* (134) orderby_opt ::= */ |
| 173586 | -3, /* (135) sortlist ::= expr sortorder nulls */ | 175794 | -3, /* (135) orderby_opt ::= ORDER BY sortlist */ |
| 173587 | -1, /* (136) sortorder ::= ASC */ | 175795 | -5, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ |
| 173588 | -1, /* (137) sortorder ::= DESC */ | 175796 | -3, /* (137) sortlist ::= expr sortorder nulls */ |
| 173589 | 0, /* (138) sortorder ::= */ | 175797 | -1, /* (138) sortorder ::= ASC */ |
| 173590 | -2, /* (139) nulls ::= NULLS FIRST */ | 175798 | -1, /* (139) sortorder ::= DESC */ |
| 173591 | -2, /* (140) nulls ::= NULLS LAST */ | 175799 | 0, /* (140) sortorder ::= */ |
| 173592 | 0, /* (141) nulls ::= */ | 175800 | -2, /* (141) nulls ::= NULLS FIRST */ |
| 173593 | 0, /* (142) groupby_opt ::= */ | 175801 | -2, /* (142) nulls ::= NULLS LAST */ |
| 173594 | -3, /* (143) groupby_opt ::= GROUP BY nexprlist */ | 175802 | 0, /* (143) nulls ::= */ |
| 173595 | 0, /* (144) having_opt ::= */ | 175803 | 0, /* (144) groupby_opt ::= */ |
| 173596 | -2, /* (145) having_opt ::= HAVING expr */ | 175804 | -3, /* (145) groupby_opt ::= GROUP BY nexprlist */ |
| 173597 | 0, /* (146) limit_opt ::= */ | 175805 | 0, /* (146) having_opt ::= */ |
| 173598 | -2, /* (147) limit_opt ::= LIMIT expr */ | 175806 | -2, /* (147) having_opt ::= HAVING expr */ |
| 173599 | -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ | 175807 | 0, /* (148) limit_opt ::= */ |
| 173600 | -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */ | 175808 | -2, /* (149) limit_opt ::= LIMIT expr */ |
| 173601 | -6, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ | 175809 | -4, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ |
| 173602 | 0, /* (151) where_opt ::= */ | 175810 | -4, /* (151) limit_opt ::= LIMIT expr COMMA expr */ |
| 173603 | -2, /* (152) where_opt ::= WHERE expr */ | 175811 | -6, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ |
| 173604 | 0, /* (153) where_opt_ret ::= */ | 175812 | 0, /* (153) where_opt ::= */ |
| 173605 | -2, /* (154) where_opt_ret ::= WHERE expr */ | 175813 | -2, /* (154) where_opt ::= WHERE expr */ |
| 173606 | -2, /* (155) where_opt_ret ::= RETURNING selcollist */ | 175814 | 0, /* (155) where_opt_ret ::= */ |
| 173607 | -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ | 175815 | -2, /* (156) where_opt_ret ::= WHERE expr */ |
| 173608 | -9, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ | 175816 | -2, /* (157) where_opt_ret ::= RETURNING selcollist */ |
| 173609 | -5, /* (158) setlist ::= setlist COMMA nm EQ expr */ | 175817 | -4, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ |
| 173610 | -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ | 175818 | -9, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ |
| 173611 | -3, /* (160) setlist ::= nm EQ expr */ | 175819 | -5, /* (160) setlist ::= setlist COMMA nm EQ expr */ |
| 173612 | -5, /* (161) setlist ::= LP idlist RP EQ expr */ | 175820 | -7, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ |
| 173613 | -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ | 175821 | -3, /* (162) setlist ::= nm EQ expr */ |
| 173614 | -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ | 175822 | -5, /* (163) setlist ::= LP idlist RP EQ expr */ |
| 173615 | 0, /* (164) upsert ::= */ | 175823 | -7, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ |
| 173616 | -2, /* (165) upsert ::= RETURNING selcollist */ | 175824 | -8, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ |
| 173617 | -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ | 175825 | 0, /* (166) upsert ::= */ |
| 173618 | -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ | 175826 | -2, /* (167) upsert ::= RETURNING selcollist */ |
| 173619 | -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ | 175827 | -12, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ |
| 173620 | -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ | 175828 | -9, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ |
| 173621 | -2, /* (170) returning ::= RETURNING selcollist */ | 175829 | -5, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ |
| 173622 | -2, /* (171) insert_cmd ::= INSERT orconf */ | 175830 | -8, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ |
| 173623 | -1, /* (172) insert_cmd ::= REPLACE */ | 175831 | -2, /* (172) returning ::= RETURNING selcollist */ |
| 173624 | 0, /* (173) idlist_opt ::= */ | 175832 | -2, /* (173) insert_cmd ::= INSERT orconf */ |
| 173625 | -3, /* (174) idlist_opt ::= LP idlist RP */ | 175833 | -1, /* (174) insert_cmd ::= REPLACE */ |
| 173626 | -3, /* (175) idlist ::= idlist COMMA nm */ | 175834 | 0, /* (175) idlist_opt ::= */ |
| 173627 | -1, /* (176) idlist ::= nm */ | 175835 | -3, /* (176) idlist_opt ::= LP idlist RP */ |
| 173628 | -3, /* (177) expr ::= LP expr RP */ | 175836 | -3, /* (177) idlist ::= idlist COMMA nm */ |
| 173629 | -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ | 175837 | -1, /* (178) idlist ::= nm */ |
| 173630 | -3, /* (179) expr ::= nm DOT nm */ | 175838 | -3, /* (179) expr ::= LP expr RP */ |
| 173631 | -5, /* (180) expr ::= nm DOT nm DOT nm */ | 175839 | -1, /* (180) expr ::= ID|INDEXED|JOIN_KW */ |
| 173632 | -1, /* (181) term ::= NULL|FLOAT|BLOB */ | 175840 | -3, /* (181) expr ::= nm DOT nm */ |
| 173633 | -1, /* (182) term ::= STRING */ | 175841 | -5, /* (182) expr ::= nm DOT nm DOT nm */ |
| 173634 | -1, /* (183) term ::= INTEGER */ | 175842 | -1, /* (183) term ::= NULL|FLOAT|BLOB */ |
| 173635 | -1, /* (184) expr ::= VARIABLE */ | 175843 | -1, /* (184) term ::= STRING */ |
| 173636 | -3, /* (185) expr ::= expr COLLATE ID|STRING */ | 175844 | -1, /* (185) term ::= INTEGER */ |
| 173637 | -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ | 175845 | -1, /* (186) expr ::= VARIABLE */ |
| 173638 | -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ | 175846 | -3, /* (187) expr ::= expr COLLATE ID|STRING */ |
| 173639 | -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ | 175847 | -6, /* (188) expr ::= CAST LP expr AS typetoken RP */ |
| 173640 | -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ | 175848 | -5, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 173641 | -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ | 175849 | -8, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ |
| 173642 | -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ | 175850 | -4, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 173643 | -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ | 175851 | -6, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 173644 | -1, /* (193) term ::= CTIME_KW */ | 175852 | -9, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ |
| 173645 | -5, /* (194) expr ::= LP nexprlist COMMA expr RP */ | 175853 | -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 173646 | -3, /* (195) expr ::= expr AND expr */ | 175854 | -1, /* (195) term ::= CTIME_KW */ |
| 173647 | -3, /* (196) expr ::= expr OR expr */ | 175855 | -5, /* (196) expr ::= LP nexprlist COMMA expr RP */ |
| 173648 | -3, /* (197) expr ::= expr LT|GT|GE|LE expr */ | 175856 | -3, /* (197) expr ::= expr AND expr */ |
| 173649 | -3, /* (198) expr ::= expr EQ|NE expr */ | 175857 | -3, /* (198) expr ::= expr OR expr */ |
| 173650 | -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ | 175858 | -3, /* (199) expr ::= expr LT|GT|GE|LE expr */ |
| 173651 | -3, /* (200) expr ::= expr PLUS|MINUS expr */ | 175859 | -3, /* (200) expr ::= expr EQ|NE expr */ |
| 173652 | -3, /* (201) expr ::= expr STAR|SLASH|REM expr */ | 175860 | -3, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ |
| 173653 | -3, /* (202) expr ::= expr CONCAT expr */ | 175861 | -3, /* (202) expr ::= expr PLUS|MINUS expr */ |
| 173654 | -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */ | 175862 | -3, /* (203) expr ::= expr STAR|SLASH|REM expr */ |
| 173655 | -3, /* (204) expr ::= expr likeop expr */ | 175863 | -3, /* (204) expr ::= expr CONCAT expr */ |
| 173656 | -5, /* (205) expr ::= expr likeop expr ESCAPE expr */ | 175864 | -2, /* (205) likeop ::= NOT LIKE_KW|MATCH */ |
| 173657 | -2, /* (206) expr ::= expr ISNULL|NOTNULL */ | 175865 | -3, /* (206) expr ::= expr likeop expr */ |
| 173658 | -3, /* (207) expr ::= expr NOT NULL */ | 175866 | -5, /* (207) expr ::= expr likeop expr ESCAPE expr */ |
| 173659 | -3, /* (208) expr ::= expr IS expr */ | 175867 | -2, /* (208) expr ::= expr ISNULL|NOTNULL */ |
| 173660 | -4, /* (209) expr ::= expr IS NOT expr */ | 175868 | -3, /* (209) expr ::= expr NOT NULL */ |
| 173661 | -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ | 175869 | -3, /* (210) expr ::= expr IS expr */ |
| 173662 | -5, /* (211) expr ::= expr IS DISTINCT FROM expr */ | 175870 | -4, /* (211) expr ::= expr IS NOT expr */ |
| 173663 | -2, /* (212) expr ::= NOT expr */ | 175871 | -6, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ |
| 173664 | -2, /* (213) expr ::= BITNOT expr */ | 175872 | -5, /* (213) expr ::= expr IS DISTINCT FROM expr */ |
| 173665 | -2, /* (214) expr ::= PLUS|MINUS expr */ | 175873 | -2, /* (214) expr ::= NOT expr */ |
| 173666 | -3, /* (215) expr ::= expr PTR expr */ | 175874 | -2, /* (215) expr ::= BITNOT expr */ |
| 173667 | -1, /* (216) between_op ::= BETWEEN */ | 175875 | -2, /* (216) expr ::= PLUS|MINUS expr */ |
| 173668 | -2, /* (217) between_op ::= NOT BETWEEN */ | 175876 | -3, /* (217) expr ::= expr PTR expr */ |
| 173669 | -5, /* (218) expr ::= expr between_op expr AND expr */ | 175877 | -1, /* (218) between_op ::= BETWEEN */ |
| 173670 | -1, /* (219) in_op ::= IN */ | 175878 | -2, /* (219) between_op ::= NOT BETWEEN */ |
| 173671 | -2, /* (220) in_op ::= NOT IN */ | 175879 | -5, /* (220) expr ::= expr between_op expr AND expr */ |
| 173672 | -5, /* (221) expr ::= expr in_op LP exprlist RP */ | 175880 | -1, /* (221) in_op ::= IN */ |
| 173673 | -3, /* (222) expr ::= LP select RP */ | 175881 | -2, /* (222) in_op ::= NOT IN */ |
| 173674 | -5, /* (223) expr ::= expr in_op LP select RP */ | 175882 | -5, /* (223) expr ::= expr in_op LP exprlist RP */ |
| 173675 | -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ | 175883 | -3, /* (224) expr ::= LP select RP */ |
| 173676 | -4, /* (225) expr ::= EXISTS LP select RP */ | 175884 | -5, /* (225) expr ::= expr in_op LP select RP */ |
| 173677 | -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ | 175885 | -5, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ |
| 173678 | -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 175886 | -4, /* (227) expr ::= EXISTS LP select RP */ |
| 173679 | -4, /* (228) case_exprlist ::= WHEN expr THEN expr */ | 175887 | -5, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ |
| 173680 | -2, /* (229) case_else ::= ELSE expr */ | 175888 | -5, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 173681 | 0, /* (230) case_else ::= */ | 175889 | -4, /* (230) case_exprlist ::= WHEN expr THEN expr */ |
| 173682 | 0, /* (231) case_operand ::= */ | 175890 | -2, /* (231) case_else ::= ELSE expr */ |
| 173683 | 0, /* (232) exprlist ::= */ | 175891 | 0, /* (232) case_else ::= */ |
| 173684 | -3, /* (233) nexprlist ::= nexprlist COMMA expr */ | 175892 | 0, /* (233) case_operand ::= */ |
| 173685 | -1, /* (234) nexprlist ::= expr */ | 175893 | 0, /* (234) exprlist ::= */ |
| 173686 | 0, /* (235) paren_exprlist ::= */ | 175894 | -3, /* (235) nexprlist ::= nexprlist COMMA expr */ |
| 173687 | -3, /* (236) paren_exprlist ::= LP exprlist RP */ | 175895 | -1, /* (236) nexprlist ::= expr */ |
| 173688 | -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 175896 | 0, /* (237) paren_exprlist ::= */ |
| 173689 | -1, /* (238) uniqueflag ::= UNIQUE */ | 175897 | -3, /* (238) paren_exprlist ::= LP exprlist RP */ |
| 173690 | 0, /* (239) uniqueflag ::= */ | 175898 | -12, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 173691 | 0, /* (240) eidlist_opt ::= */ | 175899 | -1, /* (240) uniqueflag ::= UNIQUE */ |
| 173692 | -3, /* (241) eidlist_opt ::= LP eidlist RP */ | 175900 | 0, /* (241) uniqueflag ::= */ |
| 173693 | -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ | 175901 | 0, /* (242) eidlist_opt ::= */ |
| 173694 | -3, /* (243) eidlist ::= nm collate sortorder */ | 175902 | -3, /* (243) eidlist_opt ::= LP eidlist RP */ |
| 173695 | 0, /* (244) collate ::= */ | 175903 | -5, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ |
| 173696 | -2, /* (245) collate ::= COLLATE ID|STRING */ | 175904 | -3, /* (245) eidlist ::= nm collate sortorder */ |
| 173697 | -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ | 175905 | 0, /* (246) collate ::= */ |
| 173698 | -2, /* (247) cmd ::= VACUUM vinto */ | 175906 | -2, /* (247) collate ::= COLLATE ID|STRING */ |
| 173699 | -3, /* (248) cmd ::= VACUUM nm vinto */ | 175907 | -4, /* (248) cmd ::= DROP INDEX ifexists fullname */ |
| 173700 | -2, /* (249) vinto ::= INTO expr */ | 175908 | -2, /* (249) cmd ::= VACUUM vinto */ |
| 173701 | 0, /* (250) vinto ::= */ | 175909 | -3, /* (250) cmd ::= VACUUM nm vinto */ |
| 173702 | -3, /* (251) cmd ::= PRAGMA nm dbnm */ | 175910 | -2, /* (251) vinto ::= INTO expr */ |
| 173703 | -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ | 175911 | 0, /* (252) vinto ::= */ |
| 173704 | -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 175912 | -3, /* (253) cmd ::= PRAGMA nm dbnm */ |
| 173705 | -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ | 175913 | -5, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 173706 | -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 175914 | -6, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 173707 | -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ | 175915 | -5, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 173708 | -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ | 175916 | -6, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 173709 | -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 175917 | -2, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ |
| 173710 | -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 175918 | -2, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ |
| 173711 | -1, /* (260) trigger_time ::= BEFORE|AFTER */ | 175919 | -5, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 173712 | -2, /* (261) trigger_time ::= INSTEAD OF */ | 175920 | -11, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 173713 | 0, /* (262) trigger_time ::= */ | 175921 | -1, /* (262) trigger_time ::= BEFORE|AFTER */ |
| 173714 | -1, /* (263) trigger_event ::= DELETE|INSERT */ | 175922 | -2, /* (263) trigger_time ::= INSTEAD OF */ |
| 173715 | -1, /* (264) trigger_event ::= UPDATE */ | 175923 | 0, /* (264) trigger_time ::= */ |
| 173716 | -3, /* (265) trigger_event ::= UPDATE OF idlist */ | 175924 | -1, /* (265) trigger_event ::= DELETE|INSERT */ |
| 173717 | 0, /* (266) when_clause ::= */ | 175925 | -1, /* (266) trigger_event ::= UPDATE */ |
| 173718 | -2, /* (267) when_clause ::= WHEN expr */ | 175926 | -3, /* (267) trigger_event ::= UPDATE OF idlist */ |
| 173719 | -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 175927 | 0, /* (268) when_clause ::= */ |
| 173720 | -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ | 175928 | -2, /* (269) when_clause ::= WHEN expr */ |
| 173721 | -3, /* (270) trnm ::= nm DOT nm */ | 175929 | -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 173722 | -3, /* (271) tridxby ::= INDEXED BY nm */ | 175930 | -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ |
| 173723 | -2, /* (272) tridxby ::= NOT INDEXED */ | 175931 | -3, /* (272) trnm ::= nm DOT nm */ |
| 173724 | -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 175932 | -3, /* (273) tridxby ::= INDEXED BY nm */ |
| 173725 | -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 175933 | -2, /* (274) tridxby ::= NOT INDEXED */ |
| 173726 | -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 175934 | -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 173727 | -3, /* (276) trigger_cmd ::= scanpt select scanpt */ | 175935 | -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 173728 | -4, /* (277) expr ::= RAISE LP IGNORE RP */ | 175936 | -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 173729 | -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ | 175937 | -3, /* (278) trigger_cmd ::= scanpt select scanpt */ |
| 173730 | -1, /* (279) raisetype ::= ROLLBACK */ | 175938 | -4, /* (279) expr ::= RAISE LP IGNORE RP */ |
| 173731 | -1, /* (280) raisetype ::= ABORT */ | 175939 | -6, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ |
| 173732 | -1, /* (281) raisetype ::= FAIL */ | 175940 | -1, /* (281) raisetype ::= ROLLBACK */ |
| 173733 | -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ | 175941 | -1, /* (282) raisetype ::= ABORT */ |
| 173734 | -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 175942 | -1, /* (283) raisetype ::= FAIL */ |
| 173735 | -3, /* (284) cmd ::= DETACH database_kw_opt expr */ | 175943 | -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ |
| 173736 | 0, /* (285) key_opt ::= */ | 175944 | -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 173737 | -2, /* (286) key_opt ::= KEY expr */ | 175945 | -3, /* (286) cmd ::= DETACH database_kw_opt expr */ |
| 173738 | -1, /* (287) cmd ::= REINDEX */ | 175946 | 0, /* (287) key_opt ::= */ |
| 173739 | -3, /* (288) cmd ::= REINDEX nm dbnm */ | 175947 | -2, /* (288) key_opt ::= KEY expr */ |
| 173740 | -1, /* (289) cmd ::= ANALYZE */ | 175948 | -1, /* (289) cmd ::= REINDEX */ |
| 173741 | -3, /* (290) cmd ::= ANALYZE nm dbnm */ | 175949 | -3, /* (290) cmd ::= REINDEX nm dbnm */ |
| 173742 | -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ | 175950 | -1, /* (291) cmd ::= ANALYZE */ |
| 173743 | -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 175951 | -3, /* (292) cmd ::= ANALYZE nm dbnm */ |
| 173744 | -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 175952 | -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 173745 | -1, /* (294) add_column_fullname ::= fullname */ | 175953 | -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 173746 | -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 175954 | -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 173747 | -1, /* (296) cmd ::= create_vtab */ | 175955 | -1, /* (296) add_column_fullname ::= fullname */ |
| 173748 | -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ | 175956 | -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 173749 | -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 175957 | -1, /* (298) cmd ::= create_vtab */ |
| 173750 | 0, /* (299) vtabarg ::= */ | 175958 | -4, /* (299) cmd ::= create_vtab LP vtabarglist RP */ |
| 173751 | -1, /* (300) vtabargtoken ::= ANY */ | 175959 | -8, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 173752 | -3, /* (301) vtabargtoken ::= lp anylist RP */ | 175960 | 0, /* (301) vtabarg ::= */ |
| 173753 | -1, /* (302) lp ::= LP */ | 175961 | -1, /* (302) vtabargtoken ::= ANY */ |
| 173754 | -2, /* (303) with ::= WITH wqlist */ | 175962 | -3, /* (303) vtabargtoken ::= lp anylist RP */ |
| 173755 | -3, /* (304) with ::= WITH RECURSIVE wqlist */ | 175963 | -1, /* (304) lp ::= LP */ |
| 173756 | -1, /* (305) wqas ::= AS */ | 175964 | -2, /* (305) with ::= WITH wqlist */ |
| 173757 | -2, /* (306) wqas ::= AS MATERIALIZED */ | 175965 | -3, /* (306) with ::= WITH RECURSIVE wqlist */ |
| 173758 | -3, /* (307) wqas ::= AS NOT MATERIALIZED */ | 175966 | -1, /* (307) wqas ::= AS */ |
| 173759 | -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ | 175967 | -2, /* (308) wqas ::= AS MATERIALIZED */ |
| 173760 | -1, /* (309) wqlist ::= wqitem */ | 175968 | -3, /* (309) wqas ::= AS NOT MATERIALIZED */ |
| 173761 | -3, /* (310) wqlist ::= wqlist COMMA wqitem */ | 175969 | -6, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ |
| 173762 | -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ | 175970 | -1, /* (311) withnm ::= nm */ |
| 173763 | -5, /* (312) windowdefn ::= nm AS LP window RP */ | 175971 | -1, /* (312) wqlist ::= wqitem */ |
| 173764 | -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 175972 | -3, /* (313) wqlist ::= wqlist COMMA wqitem */ |
| 173765 | -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 175973 | -3, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 173766 | -4, /* (315) window ::= ORDER BY sortlist frame_opt */ | 175974 | -5, /* (315) windowdefn ::= nm AS LP window RP */ |
| 173767 | -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ | 175975 | -5, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 173768 | -2, /* (317) window ::= nm frame_opt */ | 175976 | -6, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 173769 | 0, /* (318) frame_opt ::= */ | 175977 | -4, /* (318) window ::= ORDER BY sortlist frame_opt */ |
| 173770 | -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 175978 | -5, /* (319) window ::= nm ORDER BY sortlist frame_opt */ |
| 173771 | -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 175979 | -2, /* (320) window ::= nm frame_opt */ |
| 173772 | -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ | 175980 | 0, /* (321) frame_opt ::= */ |
| 173773 | -1, /* (322) frame_bound_s ::= frame_bound */ | 175981 | -3, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 173774 | -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ | 175982 | -6, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 173775 | -1, /* (324) frame_bound_e ::= frame_bound */ | 175983 | -1, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ |
| 173776 | -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ | 175984 | -1, /* (325) frame_bound_s ::= frame_bound */ |
| 173777 | -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ | 175985 | -2, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 173778 | -2, /* (327) frame_bound ::= CURRENT ROW */ | 175986 | -1, /* (327) frame_bound_e ::= frame_bound */ |
| 173779 | 0, /* (328) frame_exclude_opt ::= */ | 175987 | -2, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ |
| 173780 | -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ | 175988 | -2, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 173781 | -2, /* (330) frame_exclude ::= NO OTHERS */ | 175989 | -2, /* (330) frame_bound ::= CURRENT ROW */ |
| 173782 | -2, /* (331) frame_exclude ::= CURRENT ROW */ | 175990 | 0, /* (331) frame_exclude_opt ::= */ |
| 173783 | -1, /* (332) frame_exclude ::= GROUP|TIES */ | 175991 | -2, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 173784 | -2, /* (333) window_clause ::= WINDOW windowdefn_list */ | 175992 | -2, /* (333) frame_exclude ::= NO OTHERS */ |
| 173785 | -2, /* (334) filter_over ::= filter_clause over_clause */ | 175993 | -2, /* (334) frame_exclude ::= CURRENT ROW */ |
| 173786 | -1, /* (335) filter_over ::= over_clause */ | 175994 | -1, /* (335) frame_exclude ::= GROUP|TIES */ |
| 173787 | -1, /* (336) filter_over ::= filter_clause */ | 175995 | -2, /* (336) window_clause ::= WINDOW windowdefn_list */ |
| 173788 | -4, /* (337) over_clause ::= OVER LP window RP */ | 175996 | -2, /* (337) filter_over ::= filter_clause over_clause */ |
| 173789 | -2, /* (338) over_clause ::= OVER nm */ | 175997 | -1, /* (338) filter_over ::= over_clause */ |
| 173790 | -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ | 175998 | -1, /* (339) filter_over ::= filter_clause */ |
| 173791 | -1, /* (340) input ::= cmdlist */ | 175999 | -4, /* (340) over_clause ::= OVER LP window RP */ |
| 173792 | -2, /* (341) cmdlist ::= cmdlist ecmd */ | 176000 | -2, /* (341) over_clause ::= OVER nm */ |
| 173793 | -1, /* (342) cmdlist ::= ecmd */ | 176001 | -5, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ |
| 173794 | -1, /* (343) ecmd ::= SEMI */ | 176002 | -1, /* (343) term ::= QNUMBER */ |
| 173795 | -2, /* (344) ecmd ::= cmdx SEMI */ | 176003 | -1, /* (344) input ::= cmdlist */ |
| 173796 | -3, /* (345) ecmd ::= explain cmdx SEMI */ | 176004 | -2, /* (345) cmdlist ::= cmdlist ecmd */ |
| 173797 | 0, /* (346) trans_opt ::= */ | 176005 | -1, /* (346) cmdlist ::= ecmd */ |
| 173798 | -1, /* (347) trans_opt ::= TRANSACTION */ | 176006 | -1, /* (347) ecmd ::= SEMI */ |
| 173799 | -2, /* (348) trans_opt ::= TRANSACTION nm */ | 176007 | -2, /* (348) ecmd ::= cmdx SEMI */ |
| 173800 | -1, /* (349) savepoint_opt ::= SAVEPOINT */ | 176008 | -3, /* (349) ecmd ::= explain cmdx SEMI */ |
| 173801 | 0, /* (350) savepoint_opt ::= */ | 176009 | 0, /* (350) trans_opt ::= */ |
| 173802 | -2, /* (351) cmd ::= create_table create_table_args */ | 176010 | -1, /* (351) trans_opt ::= TRANSACTION */ |
| 173803 | -1, /* (352) table_option_set ::= table_option */ | 176011 | -2, /* (352) trans_opt ::= TRANSACTION nm */ |
| 173804 | -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ | 176012 | -1, /* (353) savepoint_opt ::= SAVEPOINT */ |
| 173805 | -2, /* (354) columnlist ::= columnname carglist */ | 176013 | 0, /* (354) savepoint_opt ::= */ |
| 173806 | -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */ | 176014 | -2, /* (355) cmd ::= create_table create_table_args */ |
| 173807 | -1, /* (356) nm ::= STRING */ | 176015 | -1, /* (356) table_option_set ::= table_option */ |
| 173808 | -1, /* (357) typetoken ::= typename */ | 176016 | -4, /* (357) columnlist ::= columnlist COMMA columnname carglist */ |
| 173809 | -1, /* (358) typename ::= ID|STRING */ | 176017 | -2, /* (358) columnlist ::= columnname carglist */ |
| 173810 | -1, /* (359) signed ::= plus_num */ | 176018 | -1, /* (359) nm ::= ID|INDEXED|JOIN_KW */ |
| 173811 | -1, /* (360) signed ::= minus_num */ | 176019 | -1, /* (360) nm ::= STRING */ |
| 173812 | -2, /* (361) carglist ::= carglist ccons */ | 176020 | -1, /* (361) typetoken ::= typename */ |
| 173813 | 0, /* (362) carglist ::= */ | 176021 | -1, /* (362) typename ::= ID|STRING */ |
| 173814 | -2, /* (363) ccons ::= NULL onconf */ | 176022 | -1, /* (363) signed ::= plus_num */ |
| 173815 | -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ | 176023 | -1, /* (364) signed ::= minus_num */ |
| 173816 | -2, /* (365) ccons ::= AS generated */ | 176024 | -2, /* (365) carglist ::= carglist ccons */ |
| 173817 | -2, /* (366) conslist_opt ::= COMMA conslist */ | 176025 | 0, /* (366) carglist ::= */ |
| 173818 | -3, /* (367) conslist ::= conslist tconscomma tcons */ | 176026 | -2, /* (367) ccons ::= NULL onconf */ |
| 173819 | -1, /* (368) conslist ::= tcons */ | 176027 | -4, /* (368) ccons ::= GENERATED ALWAYS AS generated */ |
| 173820 | 0, /* (369) tconscomma ::= */ | 176028 | -2, /* (369) ccons ::= AS generated */ |
| 173821 | -1, /* (370) defer_subclause_opt ::= defer_subclause */ | 176029 | -2, /* (370) conslist_opt ::= COMMA conslist */ |
| 173822 | -1, /* (371) resolvetype ::= raisetype */ | 176030 | -3, /* (371) conslist ::= conslist tconscomma tcons */ |
| 173823 | -1, /* (372) selectnowith ::= oneselect */ | 176031 | -1, /* (372) conslist ::= tcons */ |
| 173824 | -1, /* (373) oneselect ::= values */ | 176032 | 0, /* (373) tconscomma ::= */ |
| 173825 | -2, /* (374) sclp ::= selcollist COMMA */ | 176033 | -1, /* (374) defer_subclause_opt ::= defer_subclause */ |
| 173826 | -1, /* (375) as ::= ID|STRING */ | 176034 | -1, /* (375) resolvetype ::= raisetype */ |
| 173827 | -1, /* (376) indexed_opt ::= indexed_by */ | 176035 | -1, /* (376) selectnowith ::= oneselect */ |
| 173828 | 0, /* (377) returning ::= */ | 176036 | -1, /* (377) oneselect ::= values */ |
| 173829 | -1, /* (378) expr ::= term */ | 176037 | -2, /* (378) sclp ::= selcollist COMMA */ |
| 173830 | -1, /* (379) likeop ::= LIKE_KW|MATCH */ | 176038 | -1, /* (379) as ::= ID|STRING */ |
| 173831 | -1, /* (380) case_operand ::= expr */ | 176039 | -1, /* (380) indexed_opt ::= indexed_by */ |
| 173832 | -1, /* (381) exprlist ::= nexprlist */ | 176040 | 0, /* (381) returning ::= */ |
| 173833 | -1, /* (382) nmnum ::= plus_num */ | 176041 | -1, /* (382) expr ::= term */ |
| 173834 | -1, /* (383) nmnum ::= nm */ | 176042 | -1, /* (383) likeop ::= LIKE_KW|MATCH */ |
| 173835 | -1, /* (384) nmnum ::= ON */ | 176043 | -1, /* (384) case_operand ::= expr */ |
| 173836 | -1, /* (385) nmnum ::= DELETE */ | 176044 | -1, /* (385) exprlist ::= nexprlist */ |
| 173837 | -1, /* (386) nmnum ::= DEFAULT */ | 176045 | -1, /* (386) nmnum ::= plus_num */ |
| 173838 | -1, /* (387) plus_num ::= INTEGER|FLOAT */ | 176046 | -1, /* (387) nmnum ::= nm */ |
| 173839 | 0, /* (388) foreach_clause ::= */ | 176047 | -1, /* (388) nmnum ::= ON */ |
| 173840 | -3, /* (389) foreach_clause ::= FOR EACH ROW */ | 176048 | -1, /* (389) nmnum ::= DELETE */ |
| 173841 | -1, /* (390) trnm ::= nm */ | 176049 | -1, /* (390) nmnum ::= DEFAULT */ |
| 173842 | 0, /* (391) tridxby ::= */ | 176050 | -1, /* (391) plus_num ::= INTEGER|FLOAT */ |
| 173843 | -1, /* (392) database_kw_opt ::= DATABASE */ | 176051 | 0, /* (392) foreach_clause ::= */ |
| 173844 | 0, /* (393) database_kw_opt ::= */ | 176052 | -3, /* (393) foreach_clause ::= FOR EACH ROW */ |
| 173845 | 0, /* (394) kwcolumn_opt ::= */ | 176053 | -1, /* (394) trnm ::= nm */ |
| 173846 | -1, /* (395) kwcolumn_opt ::= COLUMNKW */ | 176054 | 0, /* (395) tridxby ::= */ |
| 173847 | -1, /* (396) vtabarglist ::= vtabarg */ | 176055 | -1, /* (396) database_kw_opt ::= DATABASE */ |
| 173848 | -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ | 176056 | 0, /* (397) database_kw_opt ::= */ |
| 173849 | -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ | 176057 | 0, /* (398) kwcolumn_opt ::= */ |
| 173850 | 0, /* (399) anylist ::= */ | 176058 | -1, /* (399) kwcolumn_opt ::= COLUMNKW */ |
| 173851 | -4, /* (400) anylist ::= anylist LP anylist RP */ | 176059 | -1, /* (400) vtabarglist ::= vtabarg */ |
| 173852 | -2, /* (401) anylist ::= anylist ANY */ | 176060 | -3, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ |
| 173853 | 0, /* (402) with ::= */ | 176061 | -2, /* (402) vtabarg ::= vtabarg vtabargtoken */ |
| 173854 | -1, /* (403) windowdefn_list ::= windowdefn */ | 176062 | 0, /* (403) anylist ::= */ |
| 173855 | -1, /* (404) window ::= frame_opt */ | 176063 | -4, /* (404) anylist ::= anylist LP anylist RP */ |
| 176064 | -2, /* (405) anylist ::= anylist ANY */ | ||
| 176065 | 0, /* (406) with ::= */ | ||
| 176066 | -1, /* (407) windowdefn_list ::= windowdefn */ | ||
| 176067 | -1, /* (408) window ::= frame_opt */ | ||
| 173856 | }; | 176068 | }; |
| 173857 | 176069 | ||
| 173858 | static void yy_accept(yyParser*); /* Forward Declaration */ | 176070 | static void yy_accept(yyParser*); /* Forward Declaration */ |
| @@ -173904,16 +176116,16 @@ static YYACTIONTYPE yy_reduce( | |||
| 173904 | { sqlite3FinishCoding(pParse); } | 176116 | { sqlite3FinishCoding(pParse); } |
| 173905 | break; | 176117 | break; |
| 173906 | case 3: /* cmd ::= BEGIN transtype trans_opt */ | 176118 | case 3: /* cmd ::= BEGIN transtype trans_opt */ |
| 173907 | {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} | 176119 | {sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);} |
| 173908 | break; | 176120 | break; |
| 173909 | case 4: /* transtype ::= */ | 176121 | case 4: /* transtype ::= */ |
| 173910 | {yymsp[1].minor.yy394 = TK_DEFERRED;} | 176122 | {yymsp[1].minor.yy144 = TK_DEFERRED;} |
| 173911 | break; | 176123 | break; |
| 173912 | case 5: /* transtype ::= DEFERRED */ | 176124 | case 5: /* transtype ::= DEFERRED */ |
| 173913 | case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); | 176125 | case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); |
| 173914 | case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); | 176126 | case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); |
| 173915 | case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); | 176127 | case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324); |
| 173916 | {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} | 176128 | {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/} |
| 173917 | break; | 176129 | break; |
| 173918 | case 8: /* cmd ::= COMMIT|END trans_opt */ | 176130 | case 8: /* cmd ::= COMMIT|END trans_opt */ |
| 173919 | case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); | 176131 | case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); |
| @@ -173936,7 +176148,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 173936 | break; | 176148 | break; |
| 173937 | case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ | 176149 | case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ |
| 173938 | { | 176150 | { |
| 173939 | sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); | 176151 | sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144); |
| 173940 | } | 176152 | } |
| 173941 | break; | 176153 | break; |
| 173942 | case 14: /* createkw ::= CREATE */ | 176154 | case 14: /* createkw ::= CREATE */ |
| @@ -173948,40 +176160,40 @@ static YYACTIONTYPE yy_reduce( | |||
| 173948 | case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); | 176160 | case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); |
| 173949 | case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); | 176161 | case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); |
| 173950 | case 81: /* ifexists ::= */ yytestcase(yyruleno==81); | 176162 | case 81: /* ifexists ::= */ yytestcase(yyruleno==81); |
| 173951 | case 98: /* distinct ::= */ yytestcase(yyruleno==98); | 176163 | case 100: /* distinct ::= */ yytestcase(yyruleno==100); |
| 173952 | case 244: /* collate ::= */ yytestcase(yyruleno==244); | 176164 | case 246: /* collate ::= */ yytestcase(yyruleno==246); |
| 173953 | {yymsp[1].minor.yy394 = 0;} | 176165 | {yymsp[1].minor.yy144 = 0;} |
| 173954 | break; | 176166 | break; |
| 173955 | case 16: /* ifnotexists ::= IF NOT EXISTS */ | 176167 | case 16: /* ifnotexists ::= IF NOT EXISTS */ |
| 173956 | {yymsp[-2].minor.yy394 = 1;} | 176168 | {yymsp[-2].minor.yy144 = 1;} |
| 173957 | break; | 176169 | break; |
| 173958 | case 17: /* temp ::= TEMP */ | 176170 | case 17: /* temp ::= TEMP */ |
| 173959 | {yymsp[0].minor.yy394 = pParse->db->init.busy==0;} | 176171 | {yymsp[0].minor.yy144 = pParse->db->init.busy==0;} |
| 173960 | break; | 176172 | break; |
| 173961 | case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ | 176173 | case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ |
| 173962 | { | 176174 | { |
| 173963 | sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); | 176175 | sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0); |
| 173964 | } | 176176 | } |
| 173965 | break; | 176177 | break; |
| 173966 | case 20: /* create_table_args ::= AS select */ | 176178 | case 20: /* create_table_args ::= AS select */ |
| 173967 | { | 176179 | { |
| 173968 | sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); | 176180 | sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555); |
| 173969 | sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); | 176181 | sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); |
| 173970 | } | 176182 | } |
| 173971 | break; | 176183 | break; |
| 173972 | case 21: /* table_option_set ::= */ | 176184 | case 21: /* table_option_set ::= */ |
| 173973 | {yymsp[1].minor.yy285 = 0;} | 176185 | {yymsp[1].minor.yy391 = 0;} |
| 173974 | break; | 176186 | break; |
| 173975 | case 22: /* table_option_set ::= table_option_set COMMA table_option */ | 176187 | case 22: /* table_option_set ::= table_option_set COMMA table_option */ |
| 173976 | {yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} | 176188 | {yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;} |
| 173977 | yymsp[-2].minor.yy285 = yylhsminor.yy285; | 176189 | yymsp[-2].minor.yy391 = yylhsminor.yy391; |
| 173978 | break; | 176190 | break; |
| 173979 | case 23: /* table_option ::= WITHOUT nm */ | 176191 | case 23: /* table_option ::= WITHOUT nm */ |
| 173980 | { | 176192 | { |
| 173981 | if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ | 176193 | if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ |
| 173982 | yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; | 176194 | yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid; |
| 173983 | }else{ | 176195 | }else{ |
| 173984 | yymsp[-1].minor.yy285 = 0; | 176196 | yymsp[-1].minor.yy391 = 0; |
| 173985 | sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); | 176197 | sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); |
| 173986 | } | 176198 | } |
| 173987 | } | 176199 | } |
| @@ -173989,20 +176201,20 @@ static YYACTIONTYPE yy_reduce( | |||
| 173989 | case 24: /* table_option ::= nm */ | 176201 | case 24: /* table_option ::= nm */ |
| 173990 | { | 176202 | { |
| 173991 | if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ | 176203 | if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ |
| 173992 | yylhsminor.yy285 = TF_Strict; | 176204 | yylhsminor.yy391 = TF_Strict; |
| 173993 | }else{ | 176205 | }else{ |
| 173994 | yylhsminor.yy285 = 0; | 176206 | yylhsminor.yy391 = 0; |
| 173995 | sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); | 176207 | sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); |
| 173996 | } | 176208 | } |
| 173997 | } | 176209 | } |
| 173998 | yymsp[0].minor.yy285 = yylhsminor.yy285; | 176210 | yymsp[0].minor.yy391 = yylhsminor.yy391; |
| 173999 | break; | 176211 | break; |
| 174000 | case 25: /* columnname ::= nm typetoken */ | 176212 | case 25: /* columnname ::= nm typetoken */ |
| 174001 | {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} | 176213 | {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} |
| 174002 | break; | 176214 | break; |
| 174003 | case 26: /* typetoken ::= */ | 176215 | case 26: /* typetoken ::= */ |
| 174004 | case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); | 176216 | case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); |
| 174005 | case 104: /* as ::= */ yytestcase(yyruleno==104); | 176217 | case 106: /* as ::= */ yytestcase(yyruleno==106); |
| 174006 | {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} | 176218 | {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} |
| 174007 | break; | 176219 | break; |
| 174008 | case 27: /* typetoken ::= typename LP signed RP */ | 176220 | case 27: /* typetoken ::= typename LP signed RP */ |
| @@ -174021,7 +176233,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 174021 | case 30: /* scanpt ::= */ | 176233 | case 30: /* scanpt ::= */ |
| 174022 | { | 176234 | { |
| 174023 | assert( yyLookahead!=YYNOCODE ); | 176235 | assert( yyLookahead!=YYNOCODE ); |
| 174024 | yymsp[1].minor.yy522 = yyLookaheadToken.z; | 176236 | yymsp[1].minor.yy168 = yyLookaheadToken.z; |
| 174025 | } | 176237 | } |
| 174026 | break; | 176238 | break; |
| 174027 | case 31: /* scantok ::= */ | 176239 | case 31: /* scantok ::= */ |
| @@ -174035,17 +176247,17 @@ static YYACTIONTYPE yy_reduce( | |||
| 174035 | {pParse->constraintName = yymsp[0].minor.yy0;} | 176247 | {pParse->constraintName = yymsp[0].minor.yy0;} |
| 174036 | break; | 176248 | break; |
| 174037 | case 33: /* ccons ::= DEFAULT scantok term */ | 176249 | case 33: /* ccons ::= DEFAULT scantok term */ |
| 174038 | {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} | 176250 | {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} |
| 174039 | break; | 176251 | break; |
| 174040 | case 34: /* ccons ::= DEFAULT LP expr RP */ | 176252 | case 34: /* ccons ::= DEFAULT LP expr RP */ |
| 174041 | {sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} | 176253 | {sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} |
| 174042 | break; | 176254 | break; |
| 174043 | case 35: /* ccons ::= DEFAULT PLUS scantok term */ | 176255 | case 35: /* ccons ::= DEFAULT PLUS scantok term */ |
| 174044 | {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} | 176256 | {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} |
| 174045 | break; | 176257 | break; |
| 174046 | case 36: /* ccons ::= DEFAULT MINUS scantok term */ | 176258 | case 36: /* ccons ::= DEFAULT MINUS scantok term */ |
| 174047 | { | 176259 | { |
| 174048 | Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); | 176260 | Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0); |
| 174049 | sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); | 176261 | sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); |
| 174050 | } | 176262 | } |
| 174051 | break; | 176263 | break; |
| @@ -174060,151 +176272,151 @@ static YYACTIONTYPE yy_reduce( | |||
| 174060 | } | 176272 | } |
| 174061 | break; | 176273 | break; |
| 174062 | case 38: /* ccons ::= NOT NULL onconf */ | 176274 | case 38: /* ccons ::= NOT NULL onconf */ |
| 174063 | {sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} | 176275 | {sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);} |
| 174064 | break; | 176276 | break; |
| 174065 | case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ | 176277 | case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ |
| 174066 | {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} | 176278 | {sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);} |
| 174067 | break; | 176279 | break; |
| 174068 | case 40: /* ccons ::= UNIQUE onconf */ | 176280 | case 40: /* ccons ::= UNIQUE onconf */ |
| 174069 | {sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, | 176281 | {sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0, |
| 174070 | SQLITE_IDXTYPE_UNIQUE);} | 176282 | SQLITE_IDXTYPE_UNIQUE);} |
| 174071 | break; | 176283 | break; |
| 174072 | case 41: /* ccons ::= CHECK LP expr RP */ | 176284 | case 41: /* ccons ::= CHECK LP expr RP */ |
| 174073 | {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} | 176285 | {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} |
| 174074 | break; | 176286 | break; |
| 174075 | case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ | 176287 | case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ |
| 174076 | {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} | 176288 | {sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);} |
| 174077 | break; | 176289 | break; |
| 174078 | case 43: /* ccons ::= defer_subclause */ | 176290 | case 43: /* ccons ::= defer_subclause */ |
| 174079 | {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} | 176291 | {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);} |
| 174080 | break; | 176292 | break; |
| 174081 | case 44: /* ccons ::= COLLATE ID|STRING */ | 176293 | case 44: /* ccons ::= COLLATE ID|STRING */ |
| 174082 | {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} | 176294 | {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} |
| 174083 | break; | 176295 | break; |
| 174084 | case 45: /* generated ::= LP expr RP */ | 176296 | case 45: /* generated ::= LP expr RP */ |
| 174085 | {sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} | 176297 | {sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);} |
| 174086 | break; | 176298 | break; |
| 174087 | case 46: /* generated ::= LP expr RP ID */ | 176299 | case 46: /* generated ::= LP expr RP ID */ |
| 174088 | {sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} | 176300 | {sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);} |
| 174089 | break; | 176301 | break; |
| 174090 | case 48: /* autoinc ::= AUTOINCR */ | 176302 | case 48: /* autoinc ::= AUTOINCR */ |
| 174091 | {yymsp[0].minor.yy394 = 1;} | 176303 | {yymsp[0].minor.yy144 = 1;} |
| 174092 | break; | 176304 | break; |
| 174093 | case 49: /* refargs ::= */ | 176305 | case 49: /* refargs ::= */ |
| 174094 | { yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} | 176306 | { yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */} |
| 174095 | break; | 176307 | break; |
| 174096 | case 50: /* refargs ::= refargs refarg */ | 176308 | case 50: /* refargs ::= refargs refarg */ |
| 174097 | { yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } | 176309 | { yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; } |
| 174098 | break; | 176310 | break; |
| 174099 | case 51: /* refarg ::= MATCH nm */ | 176311 | case 51: /* refarg ::= MATCH nm */ |
| 174100 | { yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } | 176312 | { yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; } |
| 174101 | break; | 176313 | break; |
| 174102 | case 52: /* refarg ::= ON INSERT refact */ | 176314 | case 52: /* refarg ::= ON INSERT refact */ |
| 174103 | { yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } | 176315 | { yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; } |
| 174104 | break; | 176316 | break; |
| 174105 | case 53: /* refarg ::= ON DELETE refact */ | 176317 | case 53: /* refarg ::= ON DELETE refact */ |
| 174106 | { yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } | 176318 | { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; } |
| 174107 | break; | 176319 | break; |
| 174108 | case 54: /* refarg ::= ON UPDATE refact */ | 176320 | case 54: /* refarg ::= ON UPDATE refact */ |
| 174109 | { yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } | 176321 | { yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; } |
| 174110 | break; | 176322 | break; |
| 174111 | case 55: /* refact ::= SET NULL */ | 176323 | case 55: /* refact ::= SET NULL */ |
| 174112 | { yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} | 176324 | { yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */} |
| 174113 | break; | 176325 | break; |
| 174114 | case 56: /* refact ::= SET DEFAULT */ | 176326 | case 56: /* refact ::= SET DEFAULT */ |
| 174115 | { yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} | 176327 | { yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */} |
| 174116 | break; | 176328 | break; |
| 174117 | case 57: /* refact ::= CASCADE */ | 176329 | case 57: /* refact ::= CASCADE */ |
| 174118 | { yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} | 176330 | { yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */} |
| 174119 | break; | 176331 | break; |
| 174120 | case 58: /* refact ::= RESTRICT */ | 176332 | case 58: /* refact ::= RESTRICT */ |
| 174121 | { yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} | 176333 | { yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */} |
| 174122 | break; | 176334 | break; |
| 174123 | case 59: /* refact ::= NO ACTION */ | 176335 | case 59: /* refact ::= NO ACTION */ |
| 174124 | { yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} | 176336 | { yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */} |
| 174125 | break; | 176337 | break; |
| 174126 | case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ | 176338 | case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ |
| 174127 | {yymsp[-2].minor.yy394 = 0;} | 176339 | {yymsp[-2].minor.yy144 = 0;} |
| 174128 | break; | 176340 | break; |
| 174129 | case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ | 176341 | case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ |
| 174130 | case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); | 176342 | case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); |
| 174131 | case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); | 176343 | case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173); |
| 174132 | {yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} | 176344 | {yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;} |
| 174133 | break; | 176345 | break; |
| 174134 | case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ | 176346 | case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ |
| 174135 | case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); | 176347 | case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); |
| 174136 | case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217); | 176348 | case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); |
| 174137 | case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220); | 176349 | case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); |
| 174138 | case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); | 176350 | case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); |
| 174139 | {yymsp[-1].minor.yy394 = 1;} | 176351 | {yymsp[-1].minor.yy144 = 1;} |
| 174140 | break; | 176352 | break; |
| 174141 | case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ | 176353 | case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ |
| 174142 | {yymsp[-1].minor.yy394 = 0;} | 176354 | {yymsp[-1].minor.yy144 = 0;} |
| 174143 | break; | 176355 | break; |
| 174144 | case 66: /* tconscomma ::= COMMA */ | 176356 | case 66: /* tconscomma ::= COMMA */ |
| 174145 | {pParse->constraintName.n = 0;} | 176357 | {pParse->constraintName.n = 0;} |
| 174146 | break; | 176358 | break; |
| 174147 | case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ | 176359 | case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ |
| 174148 | {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} | 176360 | {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);} |
| 174149 | break; | 176361 | break; |
| 174150 | case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ | 176362 | case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ |
| 174151 | {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, | 176363 | {sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0, |
| 174152 | SQLITE_IDXTYPE_UNIQUE);} | 176364 | SQLITE_IDXTYPE_UNIQUE);} |
| 174153 | break; | 176365 | break; |
| 174154 | case 70: /* tcons ::= CHECK LP expr RP onconf */ | 176366 | case 70: /* tcons ::= CHECK LP expr RP onconf */ |
| 174155 | {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} | 176367 | {sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} |
| 174156 | break; | 176368 | break; |
| 174157 | case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ | 176369 | case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ |
| 174158 | { | 176370 | { |
| 174159 | sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); | 176371 | sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144); |
| 174160 | sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); | 176372 | sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144); |
| 174161 | } | 176373 | } |
| 174162 | break; | 176374 | break; |
| 174163 | case 73: /* onconf ::= */ | 176375 | case 73: /* onconf ::= */ |
| 174164 | case 75: /* orconf ::= */ yytestcase(yyruleno==75); | 176376 | case 75: /* orconf ::= */ yytestcase(yyruleno==75); |
| 174165 | {yymsp[1].minor.yy394 = OE_Default;} | 176377 | {yymsp[1].minor.yy144 = OE_Default;} |
| 174166 | break; | 176378 | break; |
| 174167 | case 74: /* onconf ::= ON CONFLICT resolvetype */ | 176379 | case 74: /* onconf ::= ON CONFLICT resolvetype */ |
| 174168 | {yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} | 176380 | {yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;} |
| 174169 | break; | 176381 | break; |
| 174170 | case 77: /* resolvetype ::= IGNORE */ | 176382 | case 77: /* resolvetype ::= IGNORE */ |
| 174171 | {yymsp[0].minor.yy394 = OE_Ignore;} | 176383 | {yymsp[0].minor.yy144 = OE_Ignore;} |
| 174172 | break; | 176384 | break; |
| 174173 | case 78: /* resolvetype ::= REPLACE */ | 176385 | case 78: /* resolvetype ::= REPLACE */ |
| 174174 | case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); | 176386 | case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174); |
| 174175 | {yymsp[0].minor.yy394 = OE_Replace;} | 176387 | {yymsp[0].minor.yy144 = OE_Replace;} |
| 174176 | break; | 176388 | break; |
| 174177 | case 79: /* cmd ::= DROP TABLE ifexists fullname */ | 176389 | case 79: /* cmd ::= DROP TABLE ifexists fullname */ |
| 174178 | { | 176390 | { |
| 174179 | sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); | 176391 | sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144); |
| 174180 | } | 176392 | } |
| 174181 | break; | 176393 | break; |
| 174182 | case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ | 176394 | case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ |
| 174183 | { | 176395 | { |
| 174184 | sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); | 176396 | sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144); |
| 174185 | } | 176397 | } |
| 174186 | break; | 176398 | break; |
| 174187 | case 83: /* cmd ::= DROP VIEW ifexists fullname */ | 176399 | case 83: /* cmd ::= DROP VIEW ifexists fullname */ |
| 174188 | { | 176400 | { |
| 174189 | sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); | 176401 | sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144); |
| 174190 | } | 176402 | } |
| 174191 | break; | 176403 | break; |
| 174192 | case 84: /* cmd ::= select */ | 176404 | case 84: /* cmd ::= select */ |
| 174193 | { | 176405 | { |
| 174194 | SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; | 176406 | SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; |
| 174195 | sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); | 176407 | sqlite3Select(pParse, yymsp[0].minor.yy555, &dest); |
| 174196 | sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); | 176408 | sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); |
| 174197 | } | 176409 | } |
| 174198 | break; | 176410 | break; |
| 174199 | case 85: /* select ::= WITH wqlist selectnowith */ | 176411 | case 85: /* select ::= WITH wqlist selectnowith */ |
| 174200 | {yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} | 176412 | {yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} |
| 174201 | break; | 176413 | break; |
| 174202 | case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ | 176414 | case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ |
| 174203 | {yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} | 176415 | {yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} |
| 174204 | break; | 176416 | break; |
| 174205 | case 87: /* select ::= selectnowith */ | 176417 | case 87: /* select ::= selectnowith */ |
| 174206 | { | 176418 | { |
| 174207 | Select *p = yymsp[0].minor.yy47; | 176419 | Select *p = yymsp[0].minor.yy555; |
| 174208 | if( p ){ | 176420 | if( p ){ |
| 174209 | parserDoubleLinkSelect(pParse, p); | 176421 | parserDoubleLinkSelect(pParse, p); |
| 174210 | } | 176422 | } |
| @@ -174212,8 +176424,8 @@ static YYACTIONTYPE yy_reduce( | |||
| 174212 | break; | 176424 | break; |
| 174213 | case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ | 176425 | case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ |
| 174214 | { | 176426 | { |
| 174215 | Select *pRhs = yymsp[0].minor.yy47; | 176427 | Select *pRhs = yymsp[0].minor.yy555; |
| 174216 | Select *pLhs = yymsp[-2].minor.yy47; | 176428 | Select *pLhs = yymsp[-2].minor.yy555; |
| 174217 | if( pRhs && pRhs->pPrior ){ | 176429 | if( pRhs && pRhs->pPrior ){ |
| 174218 | SrcList *pFrom; | 176430 | SrcList *pFrom; |
| 174219 | Token x; | 176431 | Token x; |
| @@ -174223,148 +176435,145 @@ static YYACTIONTYPE yy_reduce( | |||
| 174223 | pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); | 176435 | pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); |
| 174224 | } | 176436 | } |
| 174225 | if( pRhs ){ | 176437 | if( pRhs ){ |
| 174226 | pRhs->op = (u8)yymsp[-1].minor.yy394; | 176438 | pRhs->op = (u8)yymsp[-1].minor.yy144; |
| 174227 | pRhs->pPrior = pLhs; | 176439 | pRhs->pPrior = pLhs; |
| 174228 | if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; | 176440 | if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; |
| 174229 | pRhs->selFlags &= ~SF_MultiValue; | 176441 | pRhs->selFlags &= ~SF_MultiValue; |
| 174230 | if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; | 176442 | if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1; |
| 174231 | }else{ | 176443 | }else{ |
| 174232 | sqlite3SelectDelete(pParse->db, pLhs); | 176444 | sqlite3SelectDelete(pParse->db, pLhs); |
| 174233 | } | 176445 | } |
| 174234 | yymsp[-2].minor.yy47 = pRhs; | 176446 | yymsp[-2].minor.yy555 = pRhs; |
| 174235 | } | 176447 | } |
| 174236 | break; | 176448 | break; |
| 174237 | case 89: /* multiselect_op ::= UNION */ | 176449 | case 89: /* multiselect_op ::= UNION */ |
| 174238 | case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); | 176450 | case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); |
| 174239 | {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} | 176451 | {yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/} |
| 174240 | break; | 176452 | break; |
| 174241 | case 90: /* multiselect_op ::= UNION ALL */ | 176453 | case 90: /* multiselect_op ::= UNION ALL */ |
| 174242 | {yymsp[-1].minor.yy394 = TK_ALL;} | 176454 | {yymsp[-1].minor.yy144 = TK_ALL;} |
| 174243 | break; | 176455 | break; |
| 174244 | case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ | 176456 | case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ |
| 174245 | { | 176457 | { |
| 174246 | yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); | 176458 | yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454); |
| 174247 | } | 176459 | } |
| 174248 | break; | 176460 | break; |
| 174249 | case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ | 176461 | case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ |
| 174250 | { | 176462 | { |
| 174251 | yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); | 176463 | yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454); |
| 174252 | if( yymsp[-9].minor.yy47 ){ | 176464 | if( yymsp[-9].minor.yy555 ){ |
| 174253 | yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; | 176465 | yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211; |
| 174254 | }else{ | 176466 | }else{ |
| 174255 | sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); | 176467 | sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211); |
| 174256 | } | 176468 | } |
| 174257 | } | 176469 | } |
| 174258 | break; | 176470 | break; |
| 174259 | case 94: /* values ::= VALUES LP nexprlist RP */ | 176471 | case 94: /* values ::= VALUES LP nexprlist RP */ |
| 174260 | { | 176472 | { |
| 174261 | yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); | 176473 | yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0); |
| 174262 | } | 176474 | } |
| 174263 | break; | 176475 | break; |
| 174264 | case 95: /* values ::= values COMMA LP nexprlist RP */ | 176476 | case 95: /* oneselect ::= mvalues */ |
| 174265 | { | 176477 | { |
| 174266 | Select *pRight, *pLeft = yymsp[-4].minor.yy47; | 176478 | sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555); |
| 174267 | pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); | 176479 | } |
| 174268 | if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; | 176480 | break; |
| 174269 | if( pRight ){ | 176481 | case 96: /* mvalues ::= values COMMA LP nexprlist RP */ |
| 174270 | pRight->op = TK_ALL; | 176482 | case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97); |
| 174271 | pRight->pPrior = pLeft; | 176483 | { |
| 174272 | yymsp[-4].minor.yy47 = pRight; | 176484 | yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14); |
| 174273 | }else{ | ||
| 174274 | yymsp[-4].minor.yy47 = pLeft; | ||
| 174275 | } | ||
| 174276 | } | 176485 | } |
| 174277 | break; | 176486 | break; |
| 174278 | case 96: /* distinct ::= DISTINCT */ | 176487 | case 98: /* distinct ::= DISTINCT */ |
| 174279 | {yymsp[0].minor.yy394 = SF_Distinct;} | 176488 | {yymsp[0].minor.yy144 = SF_Distinct;} |
| 174280 | break; | 176489 | break; |
| 174281 | case 97: /* distinct ::= ALL */ | 176490 | case 99: /* distinct ::= ALL */ |
| 174282 | {yymsp[0].minor.yy394 = SF_All;} | 176491 | {yymsp[0].minor.yy144 = SF_All;} |
| 174283 | break; | 176492 | break; |
| 174284 | case 99: /* sclp ::= */ | 176493 | case 101: /* sclp ::= */ |
| 174285 | case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); | 176494 | case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134); |
| 174286 | case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); | 176495 | case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144); |
| 174287 | case 232: /* exprlist ::= */ yytestcase(yyruleno==232); | 176496 | case 234: /* exprlist ::= */ yytestcase(yyruleno==234); |
| 174288 | case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); | 176497 | case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); |
| 174289 | case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); | 176498 | case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); |
| 174290 | {yymsp[1].minor.yy322 = 0;} | 176499 | {yymsp[1].minor.yy14 = 0;} |
| 174291 | break; | 176500 | break; |
| 174292 | case 100: /* selcollist ::= sclp scanpt expr scanpt as */ | 176501 | case 102: /* selcollist ::= sclp scanpt expr scanpt as */ |
| 174293 | { | 176502 | { |
| 174294 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); | 176503 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); |
| 174295 | if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); | 176504 | if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1); |
| 174296 | sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); | 176505 | sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168); |
| 174297 | } | 176506 | } |
| 174298 | break; | 176507 | break; |
| 174299 | case 101: /* selcollist ::= sclp scanpt STAR */ | 176508 | case 103: /* selcollist ::= sclp scanpt STAR */ |
| 174300 | { | 176509 | { |
| 174301 | Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); | 176510 | Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); |
| 174302 | sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); | 176511 | sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); |
| 174303 | yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); | 176512 | yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p); |
| 174304 | } | 176513 | } |
| 174305 | break; | 176514 | break; |
| 174306 | case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ | 176515 | case 104: /* selcollist ::= sclp scanpt nm DOT STAR */ |
| 174307 | { | 176516 | { |
| 174308 | Expr *pRight, *pLeft, *pDot; | 176517 | Expr *pRight, *pLeft, *pDot; |
| 174309 | pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); | 176518 | pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); |
| 174310 | sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); | 176519 | sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); |
| 174311 | pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); | 176520 | pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); |
| 174312 | pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); | 176521 | pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); |
| 174313 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); | 176522 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot); |
| 174314 | } | 176523 | } |
| 174315 | break; | 176524 | break; |
| 174316 | case 103: /* as ::= AS nm */ | 176525 | case 105: /* as ::= AS nm */ |
| 174317 | case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); | 176526 | case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117); |
| 174318 | case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); | 176527 | case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258); |
| 174319 | case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); | 176528 | case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259); |
| 174320 | {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} | 176529 | {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} |
| 174321 | break; | 176530 | break; |
| 174322 | case 105: /* from ::= */ | 176531 | case 107: /* from ::= */ |
| 174323 | case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); | 176532 | case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110); |
| 174324 | {yymsp[1].minor.yy131 = 0;} | 176533 | {yymsp[1].minor.yy203 = 0;} |
| 174325 | break; | 176534 | break; |
| 174326 | case 106: /* from ::= FROM seltablist */ | 176535 | case 108: /* from ::= FROM seltablist */ |
| 174327 | { | 176536 | { |
| 174328 | yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; | 176537 | yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; |
| 174329 | sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131); | 176538 | sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203); |
| 174330 | } | 176539 | } |
| 174331 | break; | 176540 | break; |
| 174332 | case 107: /* stl_prefix ::= seltablist joinop */ | 176541 | case 109: /* stl_prefix ::= seltablist joinop */ |
| 174333 | { | 176542 | { |
| 174334 | if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; | 176543 | if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144; |
| 174335 | } | 176544 | } |
| 174336 | break; | 176545 | break; |
| 174337 | case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */ | 176546 | case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */ |
| 174338 | { | 176547 | { |
| 174339 | yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); | 176548 | yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); |
| 174340 | } | 176549 | } |
| 174341 | break; | 176550 | break; |
| 174342 | case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ | 176551 | case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ |
| 174343 | { | 176552 | { |
| 174344 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561); | 176553 | yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269); |
| 174345 | sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0); | 176554 | sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0); |
| 174346 | } | 176555 | } |
| 174347 | break; | 176556 | break; |
| 174348 | case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ | 176557 | case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ |
| 174349 | { | 176558 | { |
| 174350 | yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); | 176559 | yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); |
| 174351 | sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322); | 176560 | sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14); |
| 174352 | } | 176561 | } |
| 174353 | break; | 176562 | break; |
| 174354 | case 112: /* seltablist ::= stl_prefix LP select RP as on_using */ | 176563 | case 114: /* seltablist ::= stl_prefix LP select RP as on_using */ |
| 174355 | { | 176564 | { |
| 174356 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561); | 176565 | yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269); |
| 174357 | } | 176566 | } |
| 174358 | break; | 176567 | break; |
| 174359 | case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ | 176568 | case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ |
| 174360 | { | 176569 | { |
| 174361 | if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ | 176570 | if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ |
| 174362 | yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; | 176571 | yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; |
| 174363 | }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){ | 176572 | }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ |
| 174364 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); | 176573 | yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); |
| 174365 | if( yymsp[-5].minor.yy131 ){ | 176574 | if( yymsp[-5].minor.yy203 ){ |
| 174366 | SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; | 176575 | SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; |
| 174367 | SrcItem *pOld = yymsp[-3].minor.yy131->a; | 176576 | SrcItem *pOld = yymsp[-3].minor.yy203->a; |
| 174368 | pNew->zName = pOld->zName; | 176577 | pNew->zName = pOld->zName; |
| 174369 | pNew->zDatabase = pOld->zDatabase; | 176578 | pNew->zDatabase = pOld->zDatabase; |
| 174370 | pNew->pSelect = pOld->pSelect; | 176579 | pNew->pSelect = pOld->pSelect; |
| @@ -174380,153 +176589,153 @@ static YYACTIONTYPE yy_reduce( | |||
| 174380 | pOld->zName = pOld->zDatabase = 0; | 176589 | pOld->zName = pOld->zDatabase = 0; |
| 174381 | pOld->pSelect = 0; | 176590 | pOld->pSelect = 0; |
| 174382 | } | 176591 | } |
| 174383 | sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131); | 176592 | sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); |
| 174384 | }else{ | 176593 | }else{ |
| 174385 | Select *pSubquery; | 176594 | Select *pSubquery; |
| 174386 | sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131); | 176595 | sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); |
| 174387 | pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0); | 176596 | pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); |
| 174388 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561); | 176597 | yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); |
| 174389 | } | 176598 | } |
| 174390 | } | 176599 | } |
| 174391 | break; | 176600 | break; |
| 174392 | case 114: /* dbnm ::= */ | 176601 | case 116: /* dbnm ::= */ |
| 174393 | case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129); | 176602 | case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131); |
| 174394 | {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} | 176603 | {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} |
| 174395 | break; | 176604 | break; |
| 174396 | case 116: /* fullname ::= nm */ | 176605 | case 118: /* fullname ::= nm */ |
| 174397 | { | 176606 | { |
| 174398 | yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); | 176607 | yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); |
| 174399 | if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); | 176608 | if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); |
| 174400 | } | 176609 | } |
| 174401 | yymsp[0].minor.yy131 = yylhsminor.yy131; | 176610 | yymsp[0].minor.yy203 = yylhsminor.yy203; |
| 174402 | break; | 176611 | break; |
| 174403 | case 117: /* fullname ::= nm DOT nm */ | 176612 | case 119: /* fullname ::= nm DOT nm */ |
| 174404 | { | 176613 | { |
| 174405 | yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); | 176614 | yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); |
| 174406 | if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); | 176615 | if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); |
| 174407 | } | 176616 | } |
| 174408 | yymsp[-2].minor.yy131 = yylhsminor.yy131; | 176617 | yymsp[-2].minor.yy203 = yylhsminor.yy203; |
| 174409 | break; | 176618 | break; |
| 174410 | case 118: /* xfullname ::= nm */ | 176619 | case 120: /* xfullname ::= nm */ |
| 174411 | {yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} | 176620 | {yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} |
| 174412 | break; | 176621 | break; |
| 174413 | case 119: /* xfullname ::= nm DOT nm */ | 176622 | case 121: /* xfullname ::= nm DOT nm */ |
| 174414 | {yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} | 176623 | {yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} |
| 174415 | break; | 176624 | break; |
| 174416 | case 120: /* xfullname ::= nm DOT nm AS nm */ | 176625 | case 122: /* xfullname ::= nm DOT nm AS nm */ |
| 174417 | { | 176626 | { |
| 174418 | yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ | 176627 | yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ |
| 174419 | if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); | 176628 | if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); |
| 174420 | } | 176629 | } |
| 174421 | break; | 176630 | break; |
| 174422 | case 121: /* xfullname ::= nm AS nm */ | 176631 | case 123: /* xfullname ::= nm AS nm */ |
| 174423 | { | 176632 | { |
| 174424 | yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ | 176633 | yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ |
| 174425 | if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); | 176634 | if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); |
| 174426 | } | 176635 | } |
| 174427 | break; | 176636 | break; |
| 174428 | case 122: /* joinop ::= COMMA|JOIN */ | 176637 | case 124: /* joinop ::= COMMA|JOIN */ |
| 174429 | { yymsp[0].minor.yy394 = JT_INNER; } | 176638 | { yymsp[0].minor.yy144 = JT_INNER; } |
| 174430 | break; | 176639 | break; |
| 174431 | case 123: /* joinop ::= JOIN_KW JOIN */ | 176640 | case 125: /* joinop ::= JOIN_KW JOIN */ |
| 174432 | {yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} | 176641 | {yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} |
| 174433 | break; | 176642 | break; |
| 174434 | case 124: /* joinop ::= JOIN_KW nm JOIN */ | 176643 | case 126: /* joinop ::= JOIN_KW nm JOIN */ |
| 174435 | {yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} | 176644 | {yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} |
| 174436 | break; | 176645 | break; |
| 174437 | case 125: /* joinop ::= JOIN_KW nm nm JOIN */ | 176646 | case 127: /* joinop ::= JOIN_KW nm nm JOIN */ |
| 174438 | {yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} | 176647 | {yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} |
| 174439 | break; | 176648 | break; |
| 174440 | case 126: /* on_using ::= ON expr */ | 176649 | case 128: /* on_using ::= ON expr */ |
| 174441 | {yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;} | 176650 | {yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;} |
| 174442 | break; | 176651 | break; |
| 174443 | case 127: /* on_using ::= USING LP idlist RP */ | 176652 | case 129: /* on_using ::= USING LP idlist RP */ |
| 174444 | {yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;} | 176653 | {yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;} |
| 174445 | break; | 176654 | break; |
| 174446 | case 128: /* on_using ::= */ | 176655 | case 130: /* on_using ::= */ |
| 174447 | {yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;} | 176656 | {yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;} |
| 174448 | break; | 176657 | break; |
| 174449 | case 130: /* indexed_by ::= INDEXED BY nm */ | 176658 | case 132: /* indexed_by ::= INDEXED BY nm */ |
| 174450 | {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} | 176659 | {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} |
| 174451 | break; | 176660 | break; |
| 174452 | case 131: /* indexed_by ::= NOT INDEXED */ | 176661 | case 133: /* indexed_by ::= NOT INDEXED */ |
| 174453 | {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} | 176662 | {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} |
| 174454 | break; | 176663 | break; |
| 174455 | case 133: /* orderby_opt ::= ORDER BY sortlist */ | 176664 | case 135: /* orderby_opt ::= ORDER BY sortlist */ |
| 174456 | case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); | 176665 | case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145); |
| 174457 | {yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} | 176666 | {yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;} |
| 174458 | break; | 176667 | break; |
| 174459 | case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ | 176668 | case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */ |
| 174460 | { | 176669 | { |
| 174461 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); | 176670 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454); |
| 174462 | sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); | 176671 | sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); |
| 174463 | } | 176672 | } |
| 174464 | break; | 176673 | break; |
| 174465 | case 135: /* sortlist ::= expr sortorder nulls */ | 176674 | case 137: /* sortlist ::= expr sortorder nulls */ |
| 174466 | { | 176675 | { |
| 174467 | yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ | 176676 | yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/ |
| 174468 | sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); | 176677 | sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); |
| 174469 | } | 176678 | } |
| 174470 | break; | 176679 | break; |
| 174471 | case 136: /* sortorder ::= ASC */ | 176680 | case 138: /* sortorder ::= ASC */ |
| 174472 | {yymsp[0].minor.yy394 = SQLITE_SO_ASC;} | 176681 | {yymsp[0].minor.yy144 = SQLITE_SO_ASC;} |
| 174473 | break; | 176682 | break; |
| 174474 | case 137: /* sortorder ::= DESC */ | 176683 | case 139: /* sortorder ::= DESC */ |
| 174475 | {yymsp[0].minor.yy394 = SQLITE_SO_DESC;} | 176684 | {yymsp[0].minor.yy144 = SQLITE_SO_DESC;} |
| 174476 | break; | 176685 | break; |
| 174477 | case 138: /* sortorder ::= */ | 176686 | case 140: /* sortorder ::= */ |
| 174478 | case 141: /* nulls ::= */ yytestcase(yyruleno==141); | 176687 | case 143: /* nulls ::= */ yytestcase(yyruleno==143); |
| 174479 | {yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} | 176688 | {yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;} |
| 174480 | break; | 176689 | break; |
| 174481 | case 139: /* nulls ::= NULLS FIRST */ | 176690 | case 141: /* nulls ::= NULLS FIRST */ |
| 174482 | {yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} | 176691 | {yymsp[-1].minor.yy144 = SQLITE_SO_ASC;} |
| 174483 | break; | 176692 | break; |
| 174484 | case 140: /* nulls ::= NULLS LAST */ | 176693 | case 142: /* nulls ::= NULLS LAST */ |
| 174485 | {yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} | 176694 | {yymsp[-1].minor.yy144 = SQLITE_SO_DESC;} |
| 174486 | break; | 176695 | break; |
| 174487 | case 144: /* having_opt ::= */ | 176696 | case 146: /* having_opt ::= */ |
| 174488 | case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); | 176697 | case 148: /* limit_opt ::= */ yytestcase(yyruleno==148); |
| 174489 | case 151: /* where_opt ::= */ yytestcase(yyruleno==151); | 176698 | case 153: /* where_opt ::= */ yytestcase(yyruleno==153); |
| 174490 | case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); | 176699 | case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155); |
| 174491 | case 230: /* case_else ::= */ yytestcase(yyruleno==230); | 176700 | case 232: /* case_else ::= */ yytestcase(yyruleno==232); |
| 174492 | case 231: /* case_operand ::= */ yytestcase(yyruleno==231); | 176701 | case 233: /* case_operand ::= */ yytestcase(yyruleno==233); |
| 174493 | case 250: /* vinto ::= */ yytestcase(yyruleno==250); | 176702 | case 252: /* vinto ::= */ yytestcase(yyruleno==252); |
| 174494 | {yymsp[1].minor.yy528 = 0;} | 176703 | {yymsp[1].minor.yy454 = 0;} |
| 174495 | break; | 176704 | break; |
| 174496 | case 145: /* having_opt ::= HAVING expr */ | 176705 | case 147: /* having_opt ::= HAVING expr */ |
| 174497 | case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); | 176706 | case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154); |
| 174498 | case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); | 176707 | case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156); |
| 174499 | case 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229); | 176708 | case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); |
| 174500 | case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); | 176709 | case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); |
| 174501 | {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} | 176710 | {yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} |
| 174502 | break; | 176711 | break; |
| 174503 | case 147: /* limit_opt ::= LIMIT expr */ | 176712 | case 149: /* limit_opt ::= LIMIT expr */ |
| 174504 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} | 176713 | {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);} |
| 174505 | break; | 176714 | break; |
| 174506 | case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ | 176715 | case 150: /* limit_opt ::= LIMIT expr OFFSET expr */ |
| 174507 | {yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} | 176716 | {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} |
| 174508 | break; | 176717 | break; |
| 174509 | case 149: /* limit_opt ::= LIMIT expr COMMA expr */ | 176718 | case 151: /* limit_opt ::= LIMIT expr COMMA expr */ |
| 174510 | {yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} | 176719 | {yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);} |
| 174511 | break; | 176720 | break; |
| 174512 | case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ | 176721 | case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ |
| 174513 | { | 176722 | { |
| 174514 | sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0); | 176723 | sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0); |
| 174515 | sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0); | 176724 | sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0); |
| 174516 | } | 176725 | } |
| 174517 | break; | 176726 | break; |
| 174518 | case 155: /* where_opt_ret ::= RETURNING selcollist */ | 176727 | case 157: /* where_opt_ret ::= RETURNING selcollist */ |
| 174519 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} | 176728 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;} |
| 174520 | break; | 176729 | break; |
| 174521 | case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ | 176730 | case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ |
| 174522 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} | 176731 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;} |
| 174523 | break; | 176732 | break; |
| 174524 | case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ | 176733 | case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ |
| 174525 | { | 176734 | { |
| 174526 | sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); | 176735 | sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0); |
| 174527 | sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); | 176736 | sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list"); |
| 174528 | if( yymsp[-1].minor.yy131 ){ | 176737 | if( yymsp[-1].minor.yy203 ){ |
| 174529 | SrcList *pFromClause = yymsp[-1].minor.yy131; | 176738 | SrcList *pFromClause = yymsp[-1].minor.yy203; |
| 174530 | if( pFromClause->nSrc>1 ){ | 176739 | if( pFromClause->nSrc>1 ){ |
| 174531 | Select *pSubquery; | 176740 | Select *pSubquery; |
| 174532 | Token as; | 176741 | Token as; |
| @@ -174535,92 +176744,92 @@ static YYACTIONTYPE yy_reduce( | |||
| 174535 | as.z = 0; | 176744 | as.z = 0; |
| 174536 | pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); | 176745 | pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); |
| 174537 | } | 176746 | } |
| 174538 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause); | 176747 | yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause); |
| 174539 | } | 176748 | } |
| 174540 | sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); | 176749 | sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0); |
| 174541 | } | 176750 | } |
| 174542 | break; | 176751 | break; |
| 174543 | case 158: /* setlist ::= setlist COMMA nm EQ expr */ | 176752 | case 160: /* setlist ::= setlist COMMA nm EQ expr */ |
| 174544 | { | 176753 | { |
| 174545 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); | 176754 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454); |
| 174546 | sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); | 176755 | sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1); |
| 174547 | } | 176756 | } |
| 174548 | break; | 176757 | break; |
| 174549 | case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ | 176758 | case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ |
| 174550 | { | 176759 | { |
| 174551 | yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); | 176760 | yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); |
| 174552 | } | 176761 | } |
| 174553 | break; | 176762 | break; |
| 174554 | case 160: /* setlist ::= nm EQ expr */ | 176763 | case 162: /* setlist ::= nm EQ expr */ |
| 174555 | { | 176764 | { |
| 174556 | yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); | 176765 | yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454); |
| 174557 | sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); | 176766 | sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1); |
| 174558 | } | 176767 | } |
| 174559 | yymsp[-2].minor.yy322 = yylhsminor.yy322; | 176768 | yymsp[-2].minor.yy14 = yylhsminor.yy14; |
| 174560 | break; | 176769 | break; |
| 174561 | case 161: /* setlist ::= LP idlist RP EQ expr */ | 176770 | case 163: /* setlist ::= LP idlist RP EQ expr */ |
| 174562 | { | 176771 | { |
| 174563 | yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); | 176772 | yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); |
| 174564 | } | 176773 | } |
| 174565 | break; | 176774 | break; |
| 174566 | case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ | 176775 | case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ |
| 174567 | { | 176776 | { |
| 174568 | sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); | 176777 | sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122); |
| 174569 | } | 176778 | } |
| 174570 | break; | 176779 | break; |
| 174571 | case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ | 176780 | case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ |
| 174572 | { | 176781 | { |
| 174573 | sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); | 176782 | sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0); |
| 174574 | } | 176783 | } |
| 174575 | break; | 176784 | break; |
| 174576 | case 164: /* upsert ::= */ | 176785 | case 166: /* upsert ::= */ |
| 174577 | { yymsp[1].minor.yy444 = 0; } | 176786 | { yymsp[1].minor.yy122 = 0; } |
| 174578 | break; | 176787 | break; |
| 174579 | case 165: /* upsert ::= RETURNING selcollist */ | 176788 | case 167: /* upsert ::= RETURNING selcollist */ |
| 174580 | { yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } | 176789 | { yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); } |
| 174581 | break; | 176790 | break; |
| 174582 | case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ | 176791 | case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ |
| 174583 | { yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} | 176792 | { yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);} |
| 174584 | break; | 176793 | break; |
| 174585 | case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ | 176794 | case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ |
| 174586 | { yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } | 176795 | { yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); } |
| 174587 | break; | 176796 | break; |
| 174588 | case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ | 176797 | case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */ |
| 174589 | { yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } | 176798 | { yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } |
| 174590 | break; | 176799 | break; |
| 174591 | case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ | 176800 | case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ |
| 174592 | { yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} | 176801 | { yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);} |
| 174593 | break; | 176802 | break; |
| 174594 | case 170: /* returning ::= RETURNING selcollist */ | 176803 | case 172: /* returning ::= RETURNING selcollist */ |
| 174595 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} | 176804 | {sqlite3AddReturning(pParse,yymsp[0].minor.yy14);} |
| 174596 | break; | 176805 | break; |
| 174597 | case 173: /* idlist_opt ::= */ | 176806 | case 175: /* idlist_opt ::= */ |
| 174598 | {yymsp[1].minor.yy254 = 0;} | 176807 | {yymsp[1].minor.yy132 = 0;} |
| 174599 | break; | 176808 | break; |
| 174600 | case 174: /* idlist_opt ::= LP idlist RP */ | 176809 | case 176: /* idlist_opt ::= LP idlist RP */ |
| 174601 | {yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} | 176810 | {yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;} |
| 174602 | break; | 176811 | break; |
| 174603 | case 175: /* idlist ::= idlist COMMA nm */ | 176812 | case 177: /* idlist ::= idlist COMMA nm */ |
| 174604 | {yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} | 176813 | {yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);} |
| 174605 | break; | 176814 | break; |
| 174606 | case 176: /* idlist ::= nm */ | 176815 | case 178: /* idlist ::= nm */ |
| 174607 | {yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} | 176816 | {yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} |
| 174608 | break; | 176817 | break; |
| 174609 | case 177: /* expr ::= LP expr RP */ | 176818 | case 179: /* expr ::= LP expr RP */ |
| 174610 | {yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} | 176819 | {yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;} |
| 174611 | break; | 176820 | break; |
| 174612 | case 178: /* expr ::= ID|INDEXED|JOIN_KW */ | 176821 | case 180: /* expr ::= ID|INDEXED|JOIN_KW */ |
| 174613 | {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} | 176822 | {yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} |
| 174614 | break; | 176823 | break; |
| 174615 | case 179: /* expr ::= nm DOT nm */ | 176824 | case 181: /* expr ::= nm DOT nm */ |
| 174616 | { | 176825 | { |
| 174617 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); | 176826 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); |
| 174618 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); | 176827 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); |
| 174619 | yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); | 176828 | yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); |
| 174620 | } | 176829 | } |
| 174621 | yymsp[-2].minor.yy528 = yylhsminor.yy528; | 176830 | yymsp[-2].minor.yy454 = yylhsminor.yy454; |
| 174622 | break; | 176831 | break; |
| 174623 | case 180: /* expr ::= nm DOT nm DOT nm */ | 176832 | case 182: /* expr ::= nm DOT nm DOT nm */ |
| 174624 | { | 176833 | { |
| 174625 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); | 176834 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); |
| 174626 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); | 176835 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); |
| @@ -174629,27 +176838,27 @@ static YYACTIONTYPE yy_reduce( | |||
| 174629 | if( IN_RENAME_OBJECT ){ | 176838 | if( IN_RENAME_OBJECT ){ |
| 174630 | sqlite3RenameTokenRemap(pParse, 0, temp1); | 176839 | sqlite3RenameTokenRemap(pParse, 0, temp1); |
| 174631 | } | 176840 | } |
| 174632 | yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); | 176841 | yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); |
| 174633 | } | 176842 | } |
| 174634 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 176843 | yymsp[-4].minor.yy454 = yylhsminor.yy454; |
| 174635 | break; | 176844 | break; |
| 174636 | case 181: /* term ::= NULL|FLOAT|BLOB */ | 176845 | case 183: /* term ::= NULL|FLOAT|BLOB */ |
| 174637 | case 182: /* term ::= STRING */ yytestcase(yyruleno==182); | 176846 | case 184: /* term ::= STRING */ yytestcase(yyruleno==184); |
| 174638 | {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} | 176847 | {yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} |
| 174639 | break; | 176848 | break; |
| 174640 | case 183: /* term ::= INTEGER */ | 176849 | case 185: /* term ::= INTEGER */ |
| 174641 | { | 176850 | { |
| 174642 | yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); | 176851 | yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); |
| 174643 | if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); | 176852 | if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); |
| 174644 | } | 176853 | } |
| 174645 | yymsp[0].minor.yy528 = yylhsminor.yy528; | 176854 | yymsp[0].minor.yy454 = yylhsminor.yy454; |
| 174646 | break; | 176855 | break; |
| 174647 | case 184: /* expr ::= VARIABLE */ | 176856 | case 186: /* expr ::= VARIABLE */ |
| 174648 | { | 176857 | { |
| 174649 | if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ | 176858 | if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ |
| 174650 | u32 n = yymsp[0].minor.yy0.n; | 176859 | u32 n = yymsp[0].minor.yy0.n; |
| 174651 | yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); | 176860 | yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); |
| 174652 | sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); | 176861 | sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n); |
| 174653 | }else{ | 176862 | }else{ |
| 174654 | /* When doing a nested parse, one can include terms in an expression | 176863 | /* When doing a nested parse, one can include terms in an expression |
| 174655 | ** that look like this: #1 #2 ... These terms refer to registers | 176864 | ** that look like this: #1 #2 ... These terms refer to registers |
| @@ -174658,194 +176867,203 @@ static YYACTIONTYPE yy_reduce( | |||
| 174658 | assert( t.n>=2 ); | 176867 | assert( t.n>=2 ); |
| 174659 | if( pParse->nested==0 ){ | 176868 | if( pParse->nested==0 ){ |
| 174660 | sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); | 176869 | sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); |
| 174661 | yymsp[0].minor.yy528 = 0; | 176870 | yymsp[0].minor.yy454 = 0; |
| 174662 | }else{ | 176871 | }else{ |
| 174663 | yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); | 176872 | yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); |
| 174664 | if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); | 176873 | if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable); |
| 174665 | } | 176874 | } |
| 174666 | } | 176875 | } |
| 174667 | } | 176876 | } |
| 174668 | break; | 176877 | break; |
| 174669 | case 185: /* expr ::= expr COLLATE ID|STRING */ | 176878 | case 187: /* expr ::= expr COLLATE ID|STRING */ |
| 174670 | { | 176879 | { |
| 174671 | yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); | 176880 | yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1); |
| 174672 | } | 176881 | } |
| 174673 | break; | 176882 | break; |
| 174674 | case 186: /* expr ::= CAST LP expr AS typetoken RP */ | 176883 | case 188: /* expr ::= CAST LP expr AS typetoken RP */ |
| 174675 | { | 176884 | { |
| 174676 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); | 176885 | yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); |
| 174677 | sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); | 176886 | sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0); |
| 174678 | } | 176887 | } |
| 174679 | break; | 176888 | break; |
| 174680 | case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ | 176889 | case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 174681 | { | 176890 | { |
| 174682 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); | 176891 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144); |
| 174683 | } | 176892 | } |
| 174684 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 176893 | yymsp[-4].minor.yy454 = yylhsminor.yy454; |
| 174685 | break; | 176894 | break; |
| 174686 | case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ | 176895 | case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ |
| 174687 | { | 176896 | { |
| 174688 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394); | 176897 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144); |
| 174689 | sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322); | 176898 | sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14); |
| 174690 | } | 176899 | } |
| 174691 | yymsp[-7].minor.yy528 = yylhsminor.yy528; | 176900 | yymsp[-7].minor.yy454 = yylhsminor.yy454; |
| 174692 | break; | 176901 | break; |
| 174693 | case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ | 176902 | case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 174694 | { | 176903 | { |
| 174695 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); | 176904 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); |
| 174696 | } | 176905 | } |
| 174697 | yymsp[-3].minor.yy528 = yylhsminor.yy528; | 176906 | yymsp[-3].minor.yy454 = yylhsminor.yy454; |
| 174698 | break; | 176907 | break; |
| 174699 | case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ | 176908 | case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 174700 | { | 176909 | { |
| 174701 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); | 176910 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144); |
| 174702 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); | 176911 | sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); |
| 174703 | } | 176912 | } |
| 174704 | yymsp[-5].minor.yy528 = yylhsminor.yy528; | 176913 | yymsp[-5].minor.yy454 = yylhsminor.yy454; |
| 174705 | break; | 176914 | break; |
| 174706 | case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ | 176915 | case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ |
| 174707 | { | 176916 | { |
| 174708 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394); | 176917 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144); |
| 174709 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); | 176918 | sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); |
| 174710 | sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322); | 176919 | sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14); |
| 174711 | } | 176920 | } |
| 174712 | yymsp[-8].minor.yy528 = yylhsminor.yy528; | 176921 | yymsp[-8].minor.yy454 = yylhsminor.yy454; |
| 174713 | break; | 176922 | break; |
| 174714 | case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ | 176923 | case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 174715 | { | 176924 | { |
| 174716 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); | 176925 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); |
| 174717 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); | 176926 | sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); |
| 174718 | } | 176927 | } |
| 174719 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 176928 | yymsp[-4].minor.yy454 = yylhsminor.yy454; |
| 174720 | break; | 176929 | break; |
| 174721 | case 193: /* term ::= CTIME_KW */ | 176930 | case 195: /* term ::= CTIME_KW */ |
| 174722 | { | 176931 | { |
| 174723 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); | 176932 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); |
| 174724 | } | 176933 | } |
| 174725 | yymsp[0].minor.yy528 = yylhsminor.yy528; | 176934 | yymsp[0].minor.yy454 = yylhsminor.yy454; |
| 174726 | break; | 176935 | break; |
| 174727 | case 194: /* expr ::= LP nexprlist COMMA expr RP */ | 176936 | case 196: /* expr ::= LP nexprlist COMMA expr RP */ |
| 174728 | { | 176937 | { |
| 174729 | ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); | 176938 | ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); |
| 174730 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); | 176939 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); |
| 174731 | if( yymsp[-4].minor.yy528 ){ | 176940 | if( yymsp[-4].minor.yy454 ){ |
| 174732 | yymsp[-4].minor.yy528->x.pList = pList; | 176941 | yymsp[-4].minor.yy454->x.pList = pList; |
| 174733 | if( ALWAYS(pList->nExpr) ){ | 176942 | if( ALWAYS(pList->nExpr) ){ |
| 174734 | yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; | 176943 | yymsp[-4].minor.yy454->flags |= pList->a[0].pExpr->flags & EP_Propagate; |
| 174735 | } | 176944 | } |
| 174736 | }else{ | 176945 | }else{ |
| 174737 | sqlite3ExprListDelete(pParse->db, pList); | 176946 | sqlite3ExprListDelete(pParse->db, pList); |
| 174738 | } | 176947 | } |
| 174739 | } | 176948 | } |
| 174740 | break; | 176949 | break; |
| 174741 | case 195: /* expr ::= expr AND expr */ | 176950 | case 197: /* expr ::= expr AND expr */ |
| 174742 | {yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} | 176951 | {yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} |
| 174743 | break; | 176952 | break; |
| 174744 | case 196: /* expr ::= expr OR expr */ | 176953 | case 198: /* expr ::= expr OR expr */ |
| 174745 | case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197); | 176954 | case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); |
| 174746 | case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198); | 176955 | case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200); |
| 174747 | case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199); | 176956 | case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201); |
| 174748 | case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200); | 176957 | case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); |
| 174749 | case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201); | 176958 | case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); |
| 174750 | case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202); | 176959 | case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); |
| 174751 | {yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} | 176960 | {yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} |
| 174752 | break; | 176961 | break; |
| 174753 | case 203: /* likeop ::= NOT LIKE_KW|MATCH */ | 176962 | case 205: /* likeop ::= NOT LIKE_KW|MATCH */ |
| 174754 | {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} | 176963 | {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} |
| 174755 | break; | 176964 | break; |
| 174756 | case 204: /* expr ::= expr likeop expr */ | 176965 | case 206: /* expr ::= expr likeop expr */ |
| 174757 | { | 176966 | { |
| 174758 | ExprList *pList; | 176967 | ExprList *pList; |
| 174759 | int bNot = yymsp[-1].minor.yy0.n & 0x80000000; | 176968 | int bNot = yymsp[-1].minor.yy0.n & 0x80000000; |
| 174760 | yymsp[-1].minor.yy0.n &= 0x7fffffff; | 176969 | yymsp[-1].minor.yy0.n &= 0x7fffffff; |
| 174761 | pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); | 176970 | pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454); |
| 174762 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); | 176971 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454); |
| 174763 | yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); | 176972 | yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); |
| 174764 | if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); | 176973 | if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0); |
| 174765 | if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; | 176974 | if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc; |
| 174766 | } | 176975 | } |
| 174767 | break; | 176976 | break; |
| 174768 | case 205: /* expr ::= expr likeop expr ESCAPE expr */ | 176977 | case 207: /* expr ::= expr likeop expr ESCAPE expr */ |
| 174769 | { | 176978 | { |
| 174770 | ExprList *pList; | 176979 | ExprList *pList; |
| 174771 | int bNot = yymsp[-3].minor.yy0.n & 0x80000000; | 176980 | int bNot = yymsp[-3].minor.yy0.n & 0x80000000; |
| 174772 | yymsp[-3].minor.yy0.n &= 0x7fffffff; | 176981 | yymsp[-3].minor.yy0.n &= 0x7fffffff; |
| 174773 | pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); | 176982 | pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); |
| 174774 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); | 176983 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454); |
| 174775 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); | 176984 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); |
| 174776 | yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); | 176985 | yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); |
| 174777 | if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 176986 | if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); |
| 174778 | if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; | 176987 | if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc; |
| 174779 | } | 176988 | } |
| 174780 | break; | 176989 | break; |
| 174781 | case 206: /* expr ::= expr ISNULL|NOTNULL */ | 176990 | case 208: /* expr ::= expr ISNULL|NOTNULL */ |
| 174782 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} | 176991 | {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);} |
| 174783 | break; | 176992 | break; |
| 174784 | case 207: /* expr ::= expr NOT NULL */ | 176993 | case 209: /* expr ::= expr NOT NULL */ |
| 174785 | {yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} | 176994 | {yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);} |
| 174786 | break; | 176995 | break; |
| 174787 | case 208: /* expr ::= expr IS expr */ | 176996 | case 210: /* expr ::= expr IS expr */ |
| 174788 | { | 176997 | { |
| 174789 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); | 176998 | yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454); |
| 174790 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); | 176999 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL); |
| 174791 | } | 177000 | } |
| 174792 | break; | 177001 | break; |
| 174793 | case 209: /* expr ::= expr IS NOT expr */ | 177002 | case 211: /* expr ::= expr IS NOT expr */ |
| 174794 | { | 177003 | { |
| 174795 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); | 177004 | yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454); |
| 174796 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); | 177005 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL); |
| 174797 | } | 177006 | } |
| 174798 | break; | 177007 | break; |
| 174799 | case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */ | 177008 | case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ |
| 174800 | { | 177009 | { |
| 174801 | yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); | 177010 | yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454); |
| 174802 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); | 177011 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL); |
| 174803 | } | 177012 | } |
| 174804 | break; | 177013 | break; |
| 174805 | case 211: /* expr ::= expr IS DISTINCT FROM expr */ | 177014 | case 213: /* expr ::= expr IS DISTINCT FROM expr */ |
| 174806 | { | 177015 | { |
| 174807 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); | 177016 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454); |
| 174808 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); | 177017 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL); |
| 174809 | } | 177018 | } |
| 174810 | break; | 177019 | break; |
| 174811 | case 212: /* expr ::= NOT expr */ | 177020 | case 214: /* expr ::= NOT expr */ |
| 174812 | case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213); | 177021 | case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); |
| 174813 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} | 177022 | {yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/} |
| 174814 | break; | 177023 | break; |
| 174815 | case 214: /* expr ::= PLUS|MINUS expr */ | 177024 | case 216: /* expr ::= PLUS|MINUS expr */ |
| 174816 | { | 177025 | { |
| 174817 | yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); | 177026 | Expr *p = yymsp[0].minor.yy454; |
| 174818 | /*A-overwrites-B*/ | 177027 | u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS); |
| 177028 | assert( TK_UPLUS>TK_PLUS ); | ||
| 177029 | assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); | ||
| 177030 | if( p && p->op==TK_UPLUS ){ | ||
| 177031 | p->op = op; | ||
| 177032 | yymsp[-1].minor.yy454 = p; | ||
| 177033 | }else{ | ||
| 177034 | yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0); | ||
| 177035 | /*A-overwrites-B*/ | ||
| 177036 | } | ||
| 174819 | } | 177037 | } |
| 174820 | break; | 177038 | break; |
| 174821 | case 215: /* expr ::= expr PTR expr */ | 177039 | case 217: /* expr ::= expr PTR expr */ |
| 174822 | { | 177040 | { |
| 174823 | ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); | 177041 | ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454); |
| 174824 | pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); | 177042 | pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454); |
| 174825 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); | 177043 | yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); |
| 174826 | } | 177044 | } |
| 174827 | yymsp[-2].minor.yy528 = yylhsminor.yy528; | 177045 | yymsp[-2].minor.yy454 = yylhsminor.yy454; |
| 174828 | break; | 177046 | break; |
| 174829 | case 216: /* between_op ::= BETWEEN */ | 177047 | case 218: /* between_op ::= BETWEEN */ |
| 174830 | case 219: /* in_op ::= IN */ yytestcase(yyruleno==219); | 177048 | case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); |
| 174831 | {yymsp[0].minor.yy394 = 0;} | 177049 | {yymsp[0].minor.yy144 = 0;} |
| 174832 | break; | 177050 | break; |
| 174833 | case 218: /* expr ::= expr between_op expr AND expr */ | 177051 | case 220: /* expr ::= expr between_op expr AND expr */ |
| 174834 | { | 177052 | { |
| 174835 | ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); | 177053 | ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); |
| 174836 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); | 177054 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); |
| 174837 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); | 177055 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0); |
| 174838 | if( yymsp[-4].minor.yy528 ){ | 177056 | if( yymsp[-4].minor.yy454 ){ |
| 174839 | yymsp[-4].minor.yy528->x.pList = pList; | 177057 | yymsp[-4].minor.yy454->x.pList = pList; |
| 174840 | }else{ | 177058 | }else{ |
| 174841 | sqlite3ExprListDelete(pParse->db, pList); | 177059 | sqlite3ExprListDelete(pParse->db, pList); |
| 174842 | } | 177060 | } |
| 174843 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 177061 | if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); |
| 174844 | } | 177062 | } |
| 174845 | break; | 177063 | break; |
| 174846 | case 221: /* expr ::= expr in_op LP exprlist RP */ | 177064 | case 223: /* expr ::= expr in_op LP exprlist RP */ |
| 174847 | { | 177065 | { |
| 174848 | if( yymsp[-1].minor.yy322==0 ){ | 177066 | if( yymsp[-1].minor.yy14==0 ){ |
| 174849 | /* Expressions of the form | 177067 | /* Expressions of the form |
| 174850 | ** | 177068 | ** |
| 174851 | ** expr1 IN () | 177069 | ** expr1 IN () |
| @@ -174854,208 +177072,208 @@ static YYACTIONTYPE yy_reduce( | |||
| 174854 | ** simplify to constants 0 (false) and 1 (true), respectively, | 177072 | ** simplify to constants 0 (false) and 1 (true), respectively, |
| 174855 | ** regardless of the value of expr1. | 177073 | ** regardless of the value of expr1. |
| 174856 | */ | 177074 | */ |
| 174857 | sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); | 177075 | sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454); |
| 174858 | yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false"); | 177076 | yymsp[-4].minor.yy454 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false"); |
| 174859 | if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528); | 177077 | if( yymsp[-4].minor.yy454 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy454); |
| 174860 | }else{ | 177078 | }else{ |
| 174861 | Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; | 177079 | Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; |
| 174862 | if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ | 177080 | if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){ |
| 174863 | yymsp[-1].minor.yy322->a[0].pExpr = 0; | 177081 | yymsp[-1].minor.yy14->a[0].pExpr = 0; |
| 174864 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); | 177082 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); |
| 174865 | pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); | 177083 | pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); |
| 174866 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); | 177084 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS); |
| 174867 | }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ | 177085 | }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){ |
| 174868 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 177086 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); |
| 174869 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); | 177087 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect); |
| 174870 | pRHS->x.pSelect = 0; | 177088 | pRHS->x.pSelect = 0; |
| 174871 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); | 177089 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); |
| 174872 | }else{ | 177090 | }else{ |
| 174873 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 177091 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); |
| 174874 | if( yymsp[-4].minor.yy528==0 ){ | 177092 | if( yymsp[-4].minor.yy454==0 ){ |
| 174875 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); | 177093 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); |
| 174876 | }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ | 177094 | }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){ |
| 174877 | int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; | 177095 | int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr; |
| 174878 | Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); | 177096 | Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14); |
| 174879 | if( pSelectRHS ){ | 177097 | if( pSelectRHS ){ |
| 174880 | parserDoubleLinkSelect(pParse, pSelectRHS); | 177098 | parserDoubleLinkSelect(pParse, pSelectRHS); |
| 174881 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); | 177099 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS); |
| 174882 | } | 177100 | } |
| 174883 | }else{ | 177101 | }else{ |
| 174884 | yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; | 177102 | yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14; |
| 174885 | sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); | 177103 | sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); |
| 174886 | } | 177104 | } |
| 174887 | } | 177105 | } |
| 174888 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 177106 | if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); |
| 174889 | } | 177107 | } |
| 174890 | } | 177108 | } |
| 174891 | break; | 177109 | break; |
| 174892 | case 222: /* expr ::= LP select RP */ | 177110 | case 224: /* expr ::= LP select RP */ |
| 174893 | { | 177111 | { |
| 174894 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); | 177112 | yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); |
| 174895 | sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); | 177113 | sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555); |
| 174896 | } | 177114 | } |
| 174897 | break; | 177115 | break; |
| 174898 | case 223: /* expr ::= expr in_op LP select RP */ | 177116 | case 225: /* expr ::= expr in_op LP select RP */ |
| 174899 | { | 177117 | { |
| 174900 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 177118 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); |
| 174901 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); | 177119 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555); |
| 174902 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 177120 | if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); |
| 174903 | } | 177121 | } |
| 174904 | break; | 177122 | break; |
| 174905 | case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */ | 177123 | case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */ |
| 174906 | { | 177124 | { |
| 174907 | SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); | 177125 | SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); |
| 174908 | Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); | 177126 | Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); |
| 174909 | if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); | 177127 | if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14); |
| 174910 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 177128 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); |
| 174911 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); | 177129 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect); |
| 174912 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 177130 | if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); |
| 174913 | } | 177131 | } |
| 174914 | break; | 177132 | break; |
| 174915 | case 225: /* expr ::= EXISTS LP select RP */ | 177133 | case 227: /* expr ::= EXISTS LP select RP */ |
| 174916 | { | 177134 | { |
| 174917 | Expr *p; | 177135 | Expr *p; |
| 174918 | p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); | 177136 | p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); |
| 174919 | sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); | 177137 | sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555); |
| 174920 | } | 177138 | } |
| 174921 | break; | 177139 | break; |
| 174922 | case 226: /* expr ::= CASE case_operand case_exprlist case_else END */ | 177140 | case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ |
| 174923 | { | 177141 | { |
| 174924 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); | 177142 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0); |
| 174925 | if( yymsp[-4].minor.yy528 ){ | 177143 | if( yymsp[-4].minor.yy454 ){ |
| 174926 | yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; | 177144 | yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14; |
| 174927 | sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); | 177145 | sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); |
| 174928 | }else{ | 177146 | }else{ |
| 174929 | sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); | 177147 | sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); |
| 174930 | sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); | 177148 | sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); |
| 174931 | } | 177149 | } |
| 174932 | } | 177150 | } |
| 174933 | break; | 177151 | break; |
| 174934 | case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 177152 | case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 174935 | { | 177153 | { |
| 174936 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); | 177154 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); |
| 174937 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); | 177155 | yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454); |
| 174938 | } | 177156 | } |
| 174939 | break; | 177157 | break; |
| 174940 | case 228: /* case_exprlist ::= WHEN expr THEN expr */ | 177158 | case 230: /* case_exprlist ::= WHEN expr THEN expr */ |
| 174941 | { | 177159 | { |
| 174942 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); | 177160 | yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); |
| 174943 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); | 177161 | yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454); |
| 174944 | } | 177162 | } |
| 174945 | break; | 177163 | break; |
| 174946 | case 233: /* nexprlist ::= nexprlist COMMA expr */ | 177164 | case 235: /* nexprlist ::= nexprlist COMMA expr */ |
| 174947 | {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} | 177165 | {yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);} |
| 174948 | break; | 177166 | break; |
| 174949 | case 234: /* nexprlist ::= expr */ | 177167 | case 236: /* nexprlist ::= expr */ |
| 174950 | {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} | 177168 | {yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/} |
| 174951 | break; | 177169 | break; |
| 174952 | case 236: /* paren_exprlist ::= LP exprlist RP */ | 177170 | case 238: /* paren_exprlist ::= LP exprlist RP */ |
| 174953 | case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); | 177171 | case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); |
| 174954 | {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} | 177172 | {yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} |
| 174955 | break; | 177173 | break; |
| 174956 | case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 177174 | case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 174957 | { | 177175 | { |
| 174958 | sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, | 177176 | sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, |
| 174959 | sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, | 177177 | sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144, |
| 174960 | &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); | 177178 | &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF); |
| 174961 | if( IN_RENAME_OBJECT && pParse->pNewIndex ){ | 177179 | if( IN_RENAME_OBJECT && pParse->pNewIndex ){ |
| 174962 | sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); | 177180 | sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); |
| 174963 | } | 177181 | } |
| 174964 | } | 177182 | } |
| 174965 | break; | 177183 | break; |
| 174966 | case 238: /* uniqueflag ::= UNIQUE */ | 177184 | case 240: /* uniqueflag ::= UNIQUE */ |
| 174967 | case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); | 177185 | case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282); |
| 174968 | {yymsp[0].minor.yy394 = OE_Abort;} | 177186 | {yymsp[0].minor.yy144 = OE_Abort;} |
| 174969 | break; | 177187 | break; |
| 174970 | case 239: /* uniqueflag ::= */ | 177188 | case 241: /* uniqueflag ::= */ |
| 174971 | {yymsp[1].minor.yy394 = OE_None;} | 177189 | {yymsp[1].minor.yy144 = OE_None;} |
| 174972 | break; | 177190 | break; |
| 174973 | case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ | 177191 | case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ |
| 174974 | { | 177192 | { |
| 174975 | yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); | 177193 | yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); |
| 174976 | } | 177194 | } |
| 174977 | break; | 177195 | break; |
| 174978 | case 243: /* eidlist ::= nm collate sortorder */ | 177196 | case 245: /* eidlist ::= nm collate sortorder */ |
| 174979 | { | 177197 | { |
| 174980 | yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ | 177198 | yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/ |
| 174981 | } | 177199 | } |
| 174982 | break; | 177200 | break; |
| 174983 | case 246: /* cmd ::= DROP INDEX ifexists fullname */ | 177201 | case 248: /* cmd ::= DROP INDEX ifexists fullname */ |
| 174984 | {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} | 177202 | {sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);} |
| 174985 | break; | 177203 | break; |
| 174986 | case 247: /* cmd ::= VACUUM vinto */ | 177204 | case 249: /* cmd ::= VACUUM vinto */ |
| 174987 | {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} | 177205 | {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);} |
| 174988 | break; | 177206 | break; |
| 174989 | case 248: /* cmd ::= VACUUM nm vinto */ | 177207 | case 250: /* cmd ::= VACUUM nm vinto */ |
| 174990 | {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} | 177208 | {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);} |
| 174991 | break; | 177209 | break; |
| 174992 | case 251: /* cmd ::= PRAGMA nm dbnm */ | 177210 | case 253: /* cmd ::= PRAGMA nm dbnm */ |
| 174993 | {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} | 177211 | {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} |
| 174994 | break; | 177212 | break; |
| 174995 | case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ | 177213 | case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 174996 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} | 177214 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} |
| 174997 | break; | 177215 | break; |
| 174998 | case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 177216 | case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 174999 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} | 177217 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} |
| 175000 | break; | 177218 | break; |
| 175001 | case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ | 177219 | case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 175002 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} | 177220 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} |
| 175003 | break; | 177221 | break; |
| 175004 | case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 177222 | case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 175005 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} | 177223 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} |
| 175006 | break; | 177224 | break; |
| 175007 | case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 177225 | case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 175008 | { | 177226 | { |
| 175009 | Token all; | 177227 | Token all; |
| 175010 | all.z = yymsp[-3].minor.yy0.z; | 177228 | all.z = yymsp[-3].minor.yy0.z; |
| 175011 | all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; | 177229 | all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; |
| 175012 | sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); | 177230 | sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); |
| 175013 | } | 177231 | } |
| 175014 | break; | 177232 | break; |
| 175015 | case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 177233 | case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 175016 | { | 177234 | { |
| 175017 | sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); | 177235 | sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144); |
| 175018 | yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ | 177236 | yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ |
| 175019 | } | 177237 | } |
| 175020 | break; | 177238 | break; |
| 175021 | case 260: /* trigger_time ::= BEFORE|AFTER */ | 177239 | case 262: /* trigger_time ::= BEFORE|AFTER */ |
| 175022 | { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } | 177240 | { yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ } |
| 175023 | break; | 177241 | break; |
| 175024 | case 261: /* trigger_time ::= INSTEAD OF */ | 177242 | case 263: /* trigger_time ::= INSTEAD OF */ |
| 175025 | { yymsp[-1].minor.yy394 = TK_INSTEAD;} | 177243 | { yymsp[-1].minor.yy144 = TK_INSTEAD;} |
| 175026 | break; | 177244 | break; |
| 175027 | case 262: /* trigger_time ::= */ | 177245 | case 264: /* trigger_time ::= */ |
| 175028 | { yymsp[1].minor.yy394 = TK_BEFORE; } | 177246 | { yymsp[1].minor.yy144 = TK_BEFORE; } |
| 175029 | break; | 177247 | break; |
| 175030 | case 263: /* trigger_event ::= DELETE|INSERT */ | 177248 | case 265: /* trigger_event ::= DELETE|INSERT */ |
| 175031 | case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); | 177249 | case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); |
| 175032 | {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} | 177250 | {yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;} |
| 175033 | break; | 177251 | break; |
| 175034 | case 265: /* trigger_event ::= UPDATE OF idlist */ | 177252 | case 267: /* trigger_event ::= UPDATE OF idlist */ |
| 175035 | {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} | 177253 | {yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;} |
| 175036 | break; | 177254 | break; |
| 175037 | case 266: /* when_clause ::= */ | 177255 | case 268: /* when_clause ::= */ |
| 175038 | case 285: /* key_opt ::= */ yytestcase(yyruleno==285); | 177256 | case 287: /* key_opt ::= */ yytestcase(yyruleno==287); |
| 175039 | { yymsp[1].minor.yy528 = 0; } | 177257 | { yymsp[1].minor.yy454 = 0; } |
| 175040 | break; | 177258 | break; |
| 175041 | case 267: /* when_clause ::= WHEN expr */ | 177259 | case 269: /* when_clause ::= WHEN expr */ |
| 175042 | case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); | 177260 | case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288); |
| 175043 | { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } | 177261 | { yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; } |
| 175044 | break; | 177262 | break; |
| 175045 | case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 177263 | case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 175046 | { | 177264 | { |
| 175047 | assert( yymsp[-2].minor.yy33!=0 ); | 177265 | assert( yymsp[-2].minor.yy427!=0 ); |
| 175048 | yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; | 177266 | yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; |
| 175049 | yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; | 177267 | yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; |
| 175050 | } | 177268 | } |
| 175051 | break; | 177269 | break; |
| 175052 | case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ | 177270 | case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ |
| 175053 | { | 177271 | { |
| 175054 | assert( yymsp[-1].minor.yy33!=0 ); | 177272 | assert( yymsp[-1].minor.yy427!=0 ); |
| 175055 | yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; | 177273 | yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; |
| 175056 | } | 177274 | } |
| 175057 | break; | 177275 | break; |
| 175058 | case 270: /* trnm ::= nm DOT nm */ | 177276 | case 272: /* trnm ::= nm DOT nm */ |
| 175059 | { | 177277 | { |
| 175060 | yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; | 177278 | yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; |
| 175061 | sqlite3ErrorMsg(pParse, | 177279 | sqlite3ErrorMsg(pParse, |
| @@ -175063,367 +177281,377 @@ static YYACTIONTYPE yy_reduce( | |||
| 175063 | "statements within triggers"); | 177281 | "statements within triggers"); |
| 175064 | } | 177282 | } |
| 175065 | break; | 177283 | break; |
| 175066 | case 271: /* tridxby ::= INDEXED BY nm */ | 177284 | case 273: /* tridxby ::= INDEXED BY nm */ |
| 175067 | { | 177285 | { |
| 175068 | sqlite3ErrorMsg(pParse, | 177286 | sqlite3ErrorMsg(pParse, |
| 175069 | "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " | 177287 | "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " |
| 175070 | "within triggers"); | 177288 | "within triggers"); |
| 175071 | } | 177289 | } |
| 175072 | break; | 177290 | break; |
| 175073 | case 272: /* tridxby ::= NOT INDEXED */ | 177291 | case 274: /* tridxby ::= NOT INDEXED */ |
| 175074 | { | 177292 | { |
| 175075 | sqlite3ErrorMsg(pParse, | 177293 | sqlite3ErrorMsg(pParse, |
| 175076 | "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " | 177294 | "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " |
| 175077 | "within triggers"); | 177295 | "within triggers"); |
| 175078 | } | 177296 | } |
| 175079 | break; | 177297 | break; |
| 175080 | case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 177298 | case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 175081 | {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} | 177299 | {yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);} |
| 175082 | yymsp[-8].minor.yy33 = yylhsminor.yy33; | 177300 | yymsp[-8].minor.yy427 = yylhsminor.yy427; |
| 175083 | break; | 177301 | break; |
| 175084 | case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 177302 | case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 175085 | { | 177303 | { |
| 175086 | yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ | 177304 | yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/ |
| 175087 | } | 177305 | } |
| 175088 | yymsp[-7].minor.yy33 = yylhsminor.yy33; | 177306 | yymsp[-7].minor.yy427 = yylhsminor.yy427; |
| 175089 | break; | 177307 | break; |
| 175090 | case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 177308 | case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 175091 | {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} | 177309 | {yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);} |
| 175092 | yymsp[-5].minor.yy33 = yylhsminor.yy33; | 177310 | yymsp[-5].minor.yy427 = yylhsminor.yy427; |
| 175093 | break; | 177311 | break; |
| 175094 | case 276: /* trigger_cmd ::= scanpt select scanpt */ | 177312 | case 278: /* trigger_cmd ::= scanpt select scanpt */ |
| 175095 | {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} | 177313 | {yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/} |
| 175096 | yymsp[-2].minor.yy33 = yylhsminor.yy33; | 177314 | yymsp[-2].minor.yy427 = yylhsminor.yy427; |
| 175097 | break; | 177315 | break; |
| 175098 | case 277: /* expr ::= RAISE LP IGNORE RP */ | 177316 | case 279: /* expr ::= RAISE LP IGNORE RP */ |
| 175099 | { | 177317 | { |
| 175100 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); | 177318 | yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); |
| 175101 | if( yymsp[-3].minor.yy528 ){ | 177319 | if( yymsp[-3].minor.yy454 ){ |
| 175102 | yymsp[-3].minor.yy528->affExpr = OE_Ignore; | 177320 | yymsp[-3].minor.yy454->affExpr = OE_Ignore; |
| 175103 | } | 177321 | } |
| 175104 | } | 177322 | } |
| 175105 | break; | 177323 | break; |
| 175106 | case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ | 177324 | case 280: /* expr ::= RAISE LP raisetype COMMA nm RP */ |
| 175107 | { | 177325 | { |
| 175108 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); | 177326 | yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); |
| 175109 | if( yymsp[-5].minor.yy528 ) { | 177327 | if( yymsp[-5].minor.yy454 ) { |
| 175110 | yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; | 177328 | yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; |
| 175111 | } | 177329 | } |
| 175112 | } | 177330 | } |
| 175113 | break; | 177331 | break; |
| 175114 | case 279: /* raisetype ::= ROLLBACK */ | 177332 | case 281: /* raisetype ::= ROLLBACK */ |
| 175115 | {yymsp[0].minor.yy394 = OE_Rollback;} | 177333 | {yymsp[0].minor.yy144 = OE_Rollback;} |
| 175116 | break; | 177334 | break; |
| 175117 | case 281: /* raisetype ::= FAIL */ | 177335 | case 283: /* raisetype ::= FAIL */ |
| 175118 | {yymsp[0].minor.yy394 = OE_Fail;} | 177336 | {yymsp[0].minor.yy144 = OE_Fail;} |
| 175119 | break; | 177337 | break; |
| 175120 | case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ | 177338 | case 284: /* cmd ::= DROP TRIGGER ifexists fullname */ |
| 175121 | { | 177339 | { |
| 175122 | sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); | 177340 | sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144); |
| 175123 | } | 177341 | } |
| 175124 | break; | 177342 | break; |
| 175125 | case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 177343 | case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 175126 | { | 177344 | { |
| 175127 | sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); | 177345 | sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454); |
| 175128 | } | 177346 | } |
| 175129 | break; | 177347 | break; |
| 175130 | case 284: /* cmd ::= DETACH database_kw_opt expr */ | 177348 | case 286: /* cmd ::= DETACH database_kw_opt expr */ |
| 175131 | { | 177349 | { |
| 175132 | sqlite3Detach(pParse, yymsp[0].minor.yy528); | 177350 | sqlite3Detach(pParse, yymsp[0].minor.yy454); |
| 175133 | } | 177351 | } |
| 175134 | break; | 177352 | break; |
| 175135 | case 287: /* cmd ::= REINDEX */ | 177353 | case 289: /* cmd ::= REINDEX */ |
| 175136 | {sqlite3Reindex(pParse, 0, 0);} | 177354 | {sqlite3Reindex(pParse, 0, 0);} |
| 175137 | break; | 177355 | break; |
| 175138 | case 288: /* cmd ::= REINDEX nm dbnm */ | 177356 | case 290: /* cmd ::= REINDEX nm dbnm */ |
| 175139 | {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} | 177357 | {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} |
| 175140 | break; | 177358 | break; |
| 175141 | case 289: /* cmd ::= ANALYZE */ | 177359 | case 291: /* cmd ::= ANALYZE */ |
| 175142 | {sqlite3Analyze(pParse, 0, 0);} | 177360 | {sqlite3Analyze(pParse, 0, 0);} |
| 175143 | break; | 177361 | break; |
| 175144 | case 290: /* cmd ::= ANALYZE nm dbnm */ | 177362 | case 292: /* cmd ::= ANALYZE nm dbnm */ |
| 175145 | {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} | 177363 | {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} |
| 175146 | break; | 177364 | break; |
| 175147 | case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ | 177365 | case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 175148 | { | 177366 | { |
| 175149 | sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); | 177367 | sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0); |
| 175150 | } | 177368 | } |
| 175151 | break; | 177369 | break; |
| 175152 | case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 177370 | case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 175153 | { | 177371 | { |
| 175154 | yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; | 177372 | yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; |
| 175155 | sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); | 177373 | sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); |
| 175156 | } | 177374 | } |
| 175157 | break; | 177375 | break; |
| 175158 | case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 177376 | case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 175159 | { | 177377 | { |
| 175160 | sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); | 177378 | sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0); |
| 175161 | } | 177379 | } |
| 175162 | break; | 177380 | break; |
| 175163 | case 294: /* add_column_fullname ::= fullname */ | 177381 | case 296: /* add_column_fullname ::= fullname */ |
| 175164 | { | 177382 | { |
| 175165 | disableLookaside(pParse); | 177383 | disableLookaside(pParse); |
| 175166 | sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); | 177384 | sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203); |
| 175167 | } | 177385 | } |
| 175168 | break; | 177386 | break; |
| 175169 | case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 177387 | case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 175170 | { | 177388 | { |
| 175171 | sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); | 177389 | sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); |
| 175172 | } | 177390 | } |
| 175173 | break; | 177391 | break; |
| 175174 | case 296: /* cmd ::= create_vtab */ | 177392 | case 298: /* cmd ::= create_vtab */ |
| 175175 | {sqlite3VtabFinishParse(pParse,0);} | 177393 | {sqlite3VtabFinishParse(pParse,0);} |
| 175176 | break; | 177394 | break; |
| 175177 | case 297: /* cmd ::= create_vtab LP vtabarglist RP */ | 177395 | case 299: /* cmd ::= create_vtab LP vtabarglist RP */ |
| 175178 | {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} | 177396 | {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} |
| 175179 | break; | 177397 | break; |
| 175180 | case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 177398 | case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 175181 | { | 177399 | { |
| 175182 | sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); | 177400 | sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144); |
| 175183 | } | 177401 | } |
| 175184 | break; | 177402 | break; |
| 175185 | case 299: /* vtabarg ::= */ | 177403 | case 301: /* vtabarg ::= */ |
| 175186 | {sqlite3VtabArgInit(pParse);} | 177404 | {sqlite3VtabArgInit(pParse);} |
| 175187 | break; | 177405 | break; |
| 175188 | case 300: /* vtabargtoken ::= ANY */ | 177406 | case 302: /* vtabargtoken ::= ANY */ |
| 175189 | case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); | 177407 | case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303); |
| 175190 | case 302: /* lp ::= LP */ yytestcase(yyruleno==302); | 177408 | case 304: /* lp ::= LP */ yytestcase(yyruleno==304); |
| 175191 | {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} | 177409 | {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} |
| 175192 | break; | 177410 | break; |
| 175193 | case 303: /* with ::= WITH wqlist */ | 177411 | case 305: /* with ::= WITH wqlist */ |
| 175194 | case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); | 177412 | case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306); |
| 175195 | { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } | 177413 | { sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); } |
| 175196 | break; | 177414 | break; |
| 175197 | case 305: /* wqas ::= AS */ | 177415 | case 307: /* wqas ::= AS */ |
| 175198 | {yymsp[0].minor.yy516 = M10d_Any;} | 177416 | {yymsp[0].minor.yy462 = M10d_Any;} |
| 175199 | break; | 177417 | break; |
| 175200 | case 306: /* wqas ::= AS MATERIALIZED */ | 177418 | case 308: /* wqas ::= AS MATERIALIZED */ |
| 175201 | {yymsp[-1].minor.yy516 = M10d_Yes;} | 177419 | {yymsp[-1].minor.yy462 = M10d_Yes;} |
| 175202 | break; | 177420 | break; |
| 175203 | case 307: /* wqas ::= AS NOT MATERIALIZED */ | 177421 | case 309: /* wqas ::= AS NOT MATERIALIZED */ |
| 175204 | {yymsp[-2].minor.yy516 = M10d_No;} | 177422 | {yymsp[-2].minor.yy462 = M10d_No;} |
| 175205 | break; | 177423 | break; |
| 175206 | case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ | 177424 | case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ |
| 175207 | { | 177425 | { |
| 175208 | yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ | 177426 | yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/ |
| 175209 | } | 177427 | } |
| 175210 | break; | 177428 | break; |
| 175211 | case 309: /* wqlist ::= wqitem */ | 177429 | case 311: /* withnm ::= nm */ |
| 177430 | {pParse->bHasWith = 1;} | ||
| 177431 | break; | ||
| 177432 | case 312: /* wqlist ::= wqitem */ | ||
| 175212 | { | 177433 | { |
| 175213 | yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ | 177434 | yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/ |
| 175214 | } | 177435 | } |
| 175215 | break; | 177436 | break; |
| 175216 | case 310: /* wqlist ::= wqlist COMMA wqitem */ | 177437 | case 313: /* wqlist ::= wqlist COMMA wqitem */ |
| 175217 | { | 177438 | { |
| 175218 | yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); | 177439 | yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67); |
| 175219 | } | 177440 | } |
| 175220 | break; | 177441 | break; |
| 175221 | case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ | 177442 | case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 175222 | { | 177443 | { |
| 175223 | assert( yymsp[0].minor.yy41!=0 ); | 177444 | assert( yymsp[0].minor.yy211!=0 ); |
| 175224 | sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); | 177445 | sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211); |
| 175225 | yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; | 177446 | yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211; |
| 175226 | yylhsminor.yy41 = yymsp[0].minor.yy41; | 177447 | yylhsminor.yy211 = yymsp[0].minor.yy211; |
| 175227 | } | 177448 | } |
| 175228 | yymsp[-2].minor.yy41 = yylhsminor.yy41; | 177449 | yymsp[-2].minor.yy211 = yylhsminor.yy211; |
| 175229 | break; | 177450 | break; |
| 175230 | case 312: /* windowdefn ::= nm AS LP window RP */ | 177451 | case 315: /* windowdefn ::= nm AS LP window RP */ |
| 175231 | { | 177452 | { |
| 175232 | if( ALWAYS(yymsp[-1].minor.yy41) ){ | 177453 | if( ALWAYS(yymsp[-1].minor.yy211) ){ |
| 175233 | yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); | 177454 | yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); |
| 175234 | } | 177455 | } |
| 175235 | yylhsminor.yy41 = yymsp[-1].minor.yy41; | 177456 | yylhsminor.yy211 = yymsp[-1].minor.yy211; |
| 175236 | } | 177457 | } |
| 175237 | yymsp[-4].minor.yy41 = yylhsminor.yy41; | 177458 | yymsp[-4].minor.yy211 = yylhsminor.yy211; |
| 175238 | break; | 177459 | break; |
| 175239 | case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 177460 | case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 175240 | { | 177461 | { |
| 175241 | yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); | 177462 | yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0); |
| 175242 | } | 177463 | } |
| 175243 | break; | 177464 | break; |
| 175244 | case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 177465 | case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 175245 | { | 177466 | { |
| 175246 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); | 177467 | yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0); |
| 175247 | } | 177468 | } |
| 175248 | yymsp[-5].minor.yy41 = yylhsminor.yy41; | 177469 | yymsp[-5].minor.yy211 = yylhsminor.yy211; |
| 175249 | break; | 177470 | break; |
| 175250 | case 315: /* window ::= ORDER BY sortlist frame_opt */ | 177471 | case 318: /* window ::= ORDER BY sortlist frame_opt */ |
| 175251 | { | 177472 | { |
| 175252 | yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); | 177473 | yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0); |
| 175253 | } | 177474 | } |
| 175254 | break; | 177475 | break; |
| 175255 | case 316: /* window ::= nm ORDER BY sortlist frame_opt */ | 177476 | case 319: /* window ::= nm ORDER BY sortlist frame_opt */ |
| 175256 | { | 177477 | { |
| 175257 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); | 177478 | yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); |
| 175258 | } | 177479 | } |
| 175259 | yymsp[-4].minor.yy41 = yylhsminor.yy41; | 177480 | yymsp[-4].minor.yy211 = yylhsminor.yy211; |
| 175260 | break; | 177481 | break; |
| 175261 | case 317: /* window ::= nm frame_opt */ | 177482 | case 320: /* window ::= nm frame_opt */ |
| 175262 | { | 177483 | { |
| 175263 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); | 177484 | yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0); |
| 175264 | } | 177485 | } |
| 175265 | yymsp[-1].minor.yy41 = yylhsminor.yy41; | 177486 | yymsp[-1].minor.yy211 = yylhsminor.yy211; |
| 175266 | break; | 177487 | break; |
| 175267 | case 318: /* frame_opt ::= */ | 177488 | case 321: /* frame_opt ::= */ |
| 175268 | { | 177489 | { |
| 175269 | yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); | 177490 | yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); |
| 175270 | } | 177491 | } |
| 175271 | break; | 177492 | break; |
| 175272 | case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 177493 | case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 175273 | { | 177494 | { |
| 175274 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); | 177495 | yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462); |
| 175275 | } | 177496 | } |
| 175276 | yymsp[-2].minor.yy41 = yylhsminor.yy41; | 177497 | yymsp[-2].minor.yy211 = yylhsminor.yy211; |
| 175277 | break; | 177498 | break; |
| 175278 | case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 177499 | case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 175279 | { | 177500 | { |
| 175280 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); | 177501 | yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462); |
| 175281 | } | 177502 | } |
| 175282 | yymsp[-5].minor.yy41 = yylhsminor.yy41; | 177503 | yymsp[-5].minor.yy211 = yylhsminor.yy211; |
| 175283 | break; | 177504 | break; |
| 175284 | case 322: /* frame_bound_s ::= frame_bound */ | 177505 | case 325: /* frame_bound_s ::= frame_bound */ |
| 175285 | case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); | 177506 | case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327); |
| 175286 | {yylhsminor.yy595 = yymsp[0].minor.yy595;} | 177507 | {yylhsminor.yy509 = yymsp[0].minor.yy509;} |
| 175287 | yymsp[0].minor.yy595 = yylhsminor.yy595; | 177508 | yymsp[0].minor.yy509 = yylhsminor.yy509; |
| 175288 | break; | 177509 | break; |
| 175289 | case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ | 177510 | case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 175290 | case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); | 177511 | case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328); |
| 175291 | case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); | 177512 | case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330); |
| 175292 | {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} | 177513 | {yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;} |
| 175293 | yymsp[-1].minor.yy595 = yylhsminor.yy595; | 177514 | yymsp[-1].minor.yy509 = yylhsminor.yy509; |
| 175294 | break; | 177515 | break; |
| 175295 | case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ | 177516 | case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 175296 | {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} | 177517 | {yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;} |
| 175297 | yymsp[-1].minor.yy595 = yylhsminor.yy595; | 177518 | yymsp[-1].minor.yy509 = yylhsminor.yy509; |
| 175298 | break; | 177519 | break; |
| 175299 | case 328: /* frame_exclude_opt ::= */ | 177520 | case 331: /* frame_exclude_opt ::= */ |
| 175300 | {yymsp[1].minor.yy516 = 0;} | 177521 | {yymsp[1].minor.yy462 = 0;} |
| 175301 | break; | 177522 | break; |
| 175302 | case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ | 177523 | case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 175303 | {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} | 177524 | {yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;} |
| 175304 | break; | 177525 | break; |
| 175305 | case 330: /* frame_exclude ::= NO OTHERS */ | 177526 | case 333: /* frame_exclude ::= NO OTHERS */ |
| 175306 | case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); | 177527 | case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334); |
| 175307 | {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} | 177528 | {yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/} |
| 175308 | break; | 177529 | break; |
| 175309 | case 332: /* frame_exclude ::= GROUP|TIES */ | 177530 | case 335: /* frame_exclude ::= GROUP|TIES */ |
| 175310 | {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} | 177531 | {yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/} |
| 175311 | break; | 177532 | break; |
| 175312 | case 333: /* window_clause ::= WINDOW windowdefn_list */ | 177533 | case 336: /* window_clause ::= WINDOW windowdefn_list */ |
| 175313 | { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } | 177534 | { yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; } |
| 175314 | break; | 177535 | break; |
| 175315 | case 334: /* filter_over ::= filter_clause over_clause */ | 177536 | case 337: /* filter_over ::= filter_clause over_clause */ |
| 175316 | { | 177537 | { |
| 175317 | if( yymsp[0].minor.yy41 ){ | 177538 | if( yymsp[0].minor.yy211 ){ |
| 175318 | yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; | 177539 | yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454; |
| 175319 | }else{ | 177540 | }else{ |
| 175320 | sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); | 177541 | sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); |
| 175321 | } | 177542 | } |
| 175322 | yylhsminor.yy41 = yymsp[0].minor.yy41; | 177543 | yylhsminor.yy211 = yymsp[0].minor.yy211; |
| 175323 | } | 177544 | } |
| 175324 | yymsp[-1].minor.yy41 = yylhsminor.yy41; | 177545 | yymsp[-1].minor.yy211 = yylhsminor.yy211; |
| 175325 | break; | 177546 | break; |
| 175326 | case 335: /* filter_over ::= over_clause */ | 177547 | case 338: /* filter_over ::= over_clause */ |
| 175327 | { | 177548 | { |
| 175328 | yylhsminor.yy41 = yymsp[0].minor.yy41; | 177549 | yylhsminor.yy211 = yymsp[0].minor.yy211; |
| 175329 | } | 177550 | } |
| 175330 | yymsp[0].minor.yy41 = yylhsminor.yy41; | 177551 | yymsp[0].minor.yy211 = yylhsminor.yy211; |
| 175331 | break; | 177552 | break; |
| 175332 | case 336: /* filter_over ::= filter_clause */ | 177553 | case 339: /* filter_over ::= filter_clause */ |
| 175333 | { | 177554 | { |
| 175334 | yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); | 177555 | yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); |
| 175335 | if( yylhsminor.yy41 ){ | 177556 | if( yylhsminor.yy211 ){ |
| 175336 | yylhsminor.yy41->eFrmType = TK_FILTER; | 177557 | yylhsminor.yy211->eFrmType = TK_FILTER; |
| 175337 | yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; | 177558 | yylhsminor.yy211->pFilter = yymsp[0].minor.yy454; |
| 175338 | }else{ | 177559 | }else{ |
| 175339 | sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); | 177560 | sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454); |
| 175340 | } | 177561 | } |
| 175341 | } | 177562 | } |
| 175342 | yymsp[0].minor.yy41 = yylhsminor.yy41; | 177563 | yymsp[0].minor.yy211 = yylhsminor.yy211; |
| 175343 | break; | 177564 | break; |
| 175344 | case 337: /* over_clause ::= OVER LP window RP */ | 177565 | case 340: /* over_clause ::= OVER LP window RP */ |
| 175345 | { | 177566 | { |
| 175346 | yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; | 177567 | yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211; |
| 175347 | assert( yymsp[-3].minor.yy41!=0 ); | 177568 | assert( yymsp[-3].minor.yy211!=0 ); |
| 175348 | } | 177569 | } |
| 175349 | break; | 177570 | break; |
| 175350 | case 338: /* over_clause ::= OVER nm */ | 177571 | case 341: /* over_clause ::= OVER nm */ |
| 175351 | { | 177572 | { |
| 175352 | yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); | 177573 | yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); |
| 175353 | if( yymsp[-1].minor.yy41 ){ | 177574 | if( yymsp[-1].minor.yy211 ){ |
| 175354 | yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); | 177575 | yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); |
| 175355 | } | 177576 | } |
| 175356 | } | 177577 | } |
| 175357 | break; | 177578 | break; |
| 175358 | case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ | 177579 | case 342: /* filter_clause ::= FILTER LP WHERE expr RP */ |
| 175359 | { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } | 177580 | { yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; } |
| 177581 | break; | ||
| 177582 | case 343: /* term ::= QNUMBER */ | ||
| 177583 | { | ||
| 177584 | yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); | ||
| 177585 | sqlite3DequoteNumber(pParse, yylhsminor.yy454); | ||
| 177586 | } | ||
| 177587 | yymsp[0].minor.yy454 = yylhsminor.yy454; | ||
| 175360 | break; | 177588 | break; |
| 175361 | default: | 177589 | default: |
| 175362 | /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); | 177590 | /* (344) input ::= cmdlist */ yytestcase(yyruleno==344); |
| 175363 | /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); | 177591 | /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345); |
| 175364 | /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); | 177592 | /* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346); |
| 175365 | /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); | 177593 | /* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347); |
| 175366 | /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); | 177594 | /* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348); |
| 175367 | /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); | 177595 | /* (349) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=349); |
| 175368 | /* (346) trans_opt ::= */ yytestcase(yyruleno==346); | 177596 | /* (350) trans_opt ::= */ yytestcase(yyruleno==350); |
| 175369 | /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); | 177597 | /* (351) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==351); |
| 175370 | /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); | 177598 | /* (352) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==352); |
| 175371 | /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); | 177599 | /* (353) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==353); |
| 175372 | /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); | 177600 | /* (354) savepoint_opt ::= */ yytestcase(yyruleno==354); |
| 175373 | /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); | 177601 | /* (355) cmd ::= create_table create_table_args */ yytestcase(yyruleno==355); |
| 175374 | /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); | 177602 | /* (356) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=356); |
| 175375 | /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); | 177603 | /* (357) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==357); |
| 175376 | /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); | 177604 | /* (358) columnlist ::= columnname carglist */ yytestcase(yyruleno==358); |
| 175377 | /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355); | 177605 | /* (359) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==359); |
| 175378 | /* (356) nm ::= STRING */ yytestcase(yyruleno==356); | 177606 | /* (360) nm ::= STRING */ yytestcase(yyruleno==360); |
| 175379 | /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); | 177607 | /* (361) typetoken ::= typename */ yytestcase(yyruleno==361); |
| 175380 | /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); | 177608 | /* (362) typename ::= ID|STRING */ yytestcase(yyruleno==362); |
| 175381 | /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); | 177609 | /* (363) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); |
| 175382 | /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); | 177610 | /* (364) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); |
| 175383 | /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); | 177611 | /* (365) carglist ::= carglist ccons */ yytestcase(yyruleno==365); |
| 175384 | /* (362) carglist ::= */ yytestcase(yyruleno==362); | 177612 | /* (366) carglist ::= */ yytestcase(yyruleno==366); |
| 175385 | /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); | 177613 | /* (367) ccons ::= NULL onconf */ yytestcase(yyruleno==367); |
| 175386 | /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); | 177614 | /* (368) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==368); |
| 175387 | /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); | 177615 | /* (369) ccons ::= AS generated */ yytestcase(yyruleno==369); |
| 175388 | /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); | 177616 | /* (370) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==370); |
| 175389 | /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); | 177617 | /* (371) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==371); |
| 175390 | /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); | 177618 | /* (372) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=372); |
| 175391 | /* (369) tconscomma ::= */ yytestcase(yyruleno==369); | 177619 | /* (373) tconscomma ::= */ yytestcase(yyruleno==373); |
| 175392 | /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); | 177620 | /* (374) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=374); |
| 175393 | /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); | 177621 | /* (375) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=375); |
| 175394 | /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); | 177622 | /* (376) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=376); |
| 175395 | /* (373) oneselect ::= values */ yytestcase(yyruleno==373); | 177623 | /* (377) oneselect ::= values */ yytestcase(yyruleno==377); |
| 175396 | /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); | 177624 | /* (378) sclp ::= selcollist COMMA */ yytestcase(yyruleno==378); |
| 175397 | /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); | 177625 | /* (379) as ::= ID|STRING */ yytestcase(yyruleno==379); |
| 175398 | /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376); | 177626 | /* (380) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=380); |
| 175399 | /* (377) returning ::= */ yytestcase(yyruleno==377); | 177627 | /* (381) returning ::= */ yytestcase(yyruleno==381); |
| 175400 | /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); | 177628 | /* (382) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=382); |
| 175401 | /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); | 177629 | /* (383) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==383); |
| 175402 | /* (380) case_operand ::= expr */ yytestcase(yyruleno==380); | 177630 | /* (384) case_operand ::= expr */ yytestcase(yyruleno==384); |
| 175403 | /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); | 177631 | /* (385) exprlist ::= nexprlist */ yytestcase(yyruleno==385); |
| 175404 | /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); | 177632 | /* (386) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=386); |
| 175405 | /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); | 177633 | /* (387) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=387); |
| 175406 | /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); | 177634 | /* (388) nmnum ::= ON */ yytestcase(yyruleno==388); |
| 175407 | /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); | 177635 | /* (389) nmnum ::= DELETE */ yytestcase(yyruleno==389); |
| 175408 | /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); | 177636 | /* (390) nmnum ::= DEFAULT */ yytestcase(yyruleno==390); |
| 175409 | /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); | 177637 | /* (391) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==391); |
| 175410 | /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); | 177638 | /* (392) foreach_clause ::= */ yytestcase(yyruleno==392); |
| 175411 | /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); | 177639 | /* (393) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==393); |
| 175412 | /* (390) trnm ::= nm */ yytestcase(yyruleno==390); | 177640 | /* (394) trnm ::= nm */ yytestcase(yyruleno==394); |
| 175413 | /* (391) tridxby ::= */ yytestcase(yyruleno==391); | 177641 | /* (395) tridxby ::= */ yytestcase(yyruleno==395); |
| 175414 | /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); | 177642 | /* (396) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==396); |
| 175415 | /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); | 177643 | /* (397) database_kw_opt ::= */ yytestcase(yyruleno==397); |
| 175416 | /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); | 177644 | /* (398) kwcolumn_opt ::= */ yytestcase(yyruleno==398); |
| 175417 | /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); | 177645 | /* (399) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==399); |
| 175418 | /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); | 177646 | /* (400) vtabarglist ::= vtabarg */ yytestcase(yyruleno==400); |
| 175419 | /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); | 177647 | /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==401); |
| 175420 | /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); | 177648 | /* (402) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==402); |
| 175421 | /* (399) anylist ::= */ yytestcase(yyruleno==399); | 177649 | /* (403) anylist ::= */ yytestcase(yyruleno==403); |
| 175422 | /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); | 177650 | /* (404) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==404); |
| 175423 | /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); | 177651 | /* (405) anylist ::= anylist ANY */ yytestcase(yyruleno==405); |
| 175424 | /* (402) with ::= */ yytestcase(yyruleno==402); | 177652 | /* (406) with ::= */ yytestcase(yyruleno==406); |
| 175425 | /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403); | 177653 | /* (407) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=407); |
| 175426 | /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404); | 177654 | /* (408) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=408); |
| 175427 | break; | 177655 | break; |
| 175428 | /********** End reduce actions ************************************************/ | 177656 | /********** End reduce actions ************************************************/ |
| 175429 | }; | 177657 | }; |
| @@ -175610,19 +177838,12 @@ SQLITE_PRIVATE void sqlite3Parser( | |||
| 175610 | (int)(yypParser->yytos - yypParser->yystack)); | 177838 | (int)(yypParser->yytos - yypParser->yystack)); |
| 175611 | } | 177839 | } |
| 175612 | #endif | 177840 | #endif |
| 175613 | #if YYSTACKDEPTH>0 | ||
| 175614 | if( yypParser->yytos>=yypParser->yystackEnd ){ | 177841 | if( yypParser->yytos>=yypParser->yystackEnd ){ |
| 175615 | yyStackOverflow(yypParser); | ||
| 175616 | break; | ||
| 175617 | } | ||
| 175618 | #else | ||
| 175619 | if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ | ||
| 175620 | if( yyGrowStack(yypParser) ){ | 177842 | if( yyGrowStack(yypParser) ){ |
| 175621 | yyStackOverflow(yypParser); | 177843 | yyStackOverflow(yypParser); |
| 175622 | break; | 177844 | break; |
| 175623 | } | 177845 | } |
| 175624 | } | 177846 | } |
| 175625 | #endif | ||
| 175626 | } | 177847 | } |
| 175627 | yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); | 177848 | yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); |
| 175628 | }else if( yyact <= YY_MAX_SHIFTREDUCE ){ | 177849 | }else if( yyact <= YY_MAX_SHIFTREDUCE ){ |
| @@ -176693,27 +178914,58 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ | |||
| 176693 | *tokenType = TK_INTEGER; | 178914 | *tokenType = TK_INTEGER; |
| 176694 | #ifndef SQLITE_OMIT_HEX_INTEGER | 178915 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 176695 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ | 178916 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ |
| 176696 | for(i=3; sqlite3Isxdigit(z[i]); i++){} | 178917 | for(i=3; 1; i++){ |
| 176697 | return i; | 178918 | if( sqlite3Isxdigit(z[i])==0 ){ |
| 176698 | } | 178919 | if( z[i]==SQLITE_DIGIT_SEPARATOR ){ |
| 178920 | *tokenType = TK_QNUMBER; | ||
| 178921 | }else{ | ||
| 178922 | break; | ||
| 178923 | } | ||
| 178924 | } | ||
| 178925 | } | ||
| 178926 | }else | ||
| 176699 | #endif | 178927 | #endif |
| 176700 | for(i=0; sqlite3Isdigit(z[i]); i++){} | 178928 | { |
| 178929 | for(i=0; 1; i++){ | ||
| 178930 | if( sqlite3Isdigit(z[i])==0 ){ | ||
| 178931 | if( z[i]==SQLITE_DIGIT_SEPARATOR ){ | ||
| 178932 | *tokenType = TK_QNUMBER; | ||
| 178933 | }else{ | ||
| 178934 | break; | ||
| 178935 | } | ||
| 178936 | } | ||
| 178937 | } | ||
| 176701 | #ifndef SQLITE_OMIT_FLOATING_POINT | 178938 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 176702 | if( z[i]=='.' ){ | 178939 | if( z[i]=='.' ){ |
| 176703 | i++; | 178940 | if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; |
| 176704 | while( sqlite3Isdigit(z[i]) ){ i++; } | 178941 | for(i++; 1; i++){ |
| 176705 | *tokenType = TK_FLOAT; | 178942 | if( sqlite3Isdigit(z[i])==0 ){ |
| 176706 | } | 178943 | if( z[i]==SQLITE_DIGIT_SEPARATOR ){ |
| 176707 | if( (z[i]=='e' || z[i]=='E') && | 178944 | *tokenType = TK_QNUMBER; |
| 176708 | ( sqlite3Isdigit(z[i+1]) | 178945 | }else{ |
| 176709 | || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) | 178946 | break; |
| 176710 | ) | 178947 | } |
| 176711 | ){ | 178948 | } |
| 176712 | i += 2; | 178949 | } |
| 176713 | while( sqlite3Isdigit(z[i]) ){ i++; } | 178950 | } |
| 176714 | *tokenType = TK_FLOAT; | 178951 | if( (z[i]=='e' || z[i]=='E') && |
| 176715 | } | 178952 | ( sqlite3Isdigit(z[i+1]) |
| 178953 | || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) | ||
| 178954 | ) | ||
| 178955 | ){ | ||
| 178956 | if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; | ||
| 178957 | for(i+=2; 1; i++){ | ||
| 178958 | if( sqlite3Isdigit(z[i])==0 ){ | ||
| 178959 | if( z[i]==SQLITE_DIGIT_SEPARATOR ){ | ||
| 178960 | *tokenType = TK_QNUMBER; | ||
| 178961 | }else{ | ||
| 178962 | break; | ||
| 178963 | } | ||
| 178964 | } | ||
| 178965 | } | ||
| 178966 | } | ||
| 176716 | #endif | 178967 | #endif |
| 178968 | } | ||
| 176717 | while( IdChar(z[i]) ){ | 178969 | while( IdChar(z[i]) ){ |
| 176718 | *tokenType = TK_ILLEGAL; | 178970 | *tokenType = TK_ILLEGAL; |
| 176719 | i++; | 178971 | i++; |
| @@ -176878,10 +179130,13 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ | |||
| 176878 | if( tokenType>=TK_WINDOW ){ | 179130 | if( tokenType>=TK_WINDOW ){ |
| 176879 | assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER | 179131 | assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER |
| 176880 | || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW | 179132 | || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW |
| 179133 | || tokenType==TK_QNUMBER | ||
| 176881 | ); | 179134 | ); |
| 176882 | #else | 179135 | #else |
| 176883 | if( tokenType>=TK_SPACE ){ | 179136 | if( tokenType>=TK_SPACE ){ |
| 176884 | assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); | 179137 | assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL |
| 179138 | || tokenType==TK_QNUMBER | ||
| 179139 | ); | ||
| 176885 | #endif /* SQLITE_OMIT_WINDOWFUNC */ | 179140 | #endif /* SQLITE_OMIT_WINDOWFUNC */ |
| 176886 | if( AtomicLoad(&db->u1.isInterrupted) ){ | 179141 | if( AtomicLoad(&db->u1.isInterrupted) ){ |
| 176887 | pParse->rc = SQLITE_INTERRUPT; | 179142 | pParse->rc = SQLITE_INTERRUPT; |
| @@ -176914,7 +179169,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ | |||
| 176914 | assert( n==6 ); | 179169 | assert( n==6 ); |
| 176915 | tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); | 179170 | tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); |
| 176916 | #endif /* SQLITE_OMIT_WINDOWFUNC */ | 179171 | #endif /* SQLITE_OMIT_WINDOWFUNC */ |
| 176917 | }else{ | 179172 | }else if( tokenType!=TK_QNUMBER ){ |
| 176918 | Token x; | 179173 | Token x; |
| 176919 | x.z = zSql; | 179174 | x.z = zSql; |
| 176920 | x.n = n; | 179175 | x.n = n; |
| @@ -178265,6 +180520,18 @@ SQLITE_API int sqlite3_config(int op, ...){ | |||
| 178265 | } | 180520 | } |
| 178266 | #endif /* SQLITE_OMIT_DESERIALIZE */ | 180521 | #endif /* SQLITE_OMIT_DESERIALIZE */ |
| 178267 | 180522 | ||
| 180523 | case SQLITE_CONFIG_ROWID_IN_VIEW: { | ||
| 180524 | int *pVal = va_arg(ap,int*); | ||
| 180525 | #ifdef SQLITE_ALLOW_ROWID_IN_VIEW | ||
| 180526 | if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid; | ||
| 180527 | if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0; | ||
| 180528 | *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0); | ||
| 180529 | #else | ||
| 180530 | *pVal = 0; | ||
| 180531 | #endif | ||
| 180532 | break; | ||
| 180533 | } | ||
| 180534 | |||
| 178268 | default: { | 180535 | default: { |
| 178269 | rc = SQLITE_ERROR; | 180536 | rc = SQLITE_ERROR; |
| 178270 | break; | 180537 | break; |
| @@ -179414,7 +181681,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( | |||
| 179414 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); | 181681 | assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); |
| 179415 | assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); | 181682 | assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); |
| 179416 | extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| | 181683 | extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| |
| 179417 | SQLITE_SUBTYPE|SQLITE_INNOCUOUS); | 181684 | SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); |
| 179418 | enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); | 181685 | enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); |
| 179419 | 181686 | ||
| 179420 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But | 181687 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But |
| @@ -182159,6 +184426,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 182159 | break; | 184426 | break; |
| 182160 | } | 184427 | } |
| 182161 | #endif | 184428 | #endif |
| 184429 | |||
| 184430 | /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); | ||
| 184431 | ** | ||
| 184432 | ** Activate or deactivate validation of JSONB that is generated from | ||
| 184433 | ** text. Off by default, as the validation is slow. Validation is | ||
| 184434 | ** only available if compiled using SQLITE_DEBUG. | ||
| 184435 | ** | ||
| 184436 | ** If onOff is initially 1, then turn it on. If onOff is initially | ||
| 184437 | ** off, turn it off. If onOff is initially -1, then change onOff | ||
| 184438 | ** to be the current setting. | ||
| 184439 | */ | ||
| 184440 | case SQLITE_TESTCTRL_JSON_SELFCHECK: { | ||
| 184441 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) | ||
| 184442 | int *pOnOff = va_arg(ap, int*); | ||
| 184443 | if( *pOnOff<0 ){ | ||
| 184444 | *pOnOff = sqlite3Config.bJsonSelfcheck; | ||
| 184445 | }else{ | ||
| 184446 | sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); | ||
| 184447 | } | ||
| 184448 | #endif | ||
| 184449 | break; | ||
| 184450 | } | ||
| 182162 | } | 184451 | } |
| 182163 | va_end(ap); | 184452 | va_end(ap); |
| 182164 | #endif /* SQLITE_UNTESTABLE */ | 184453 | #endif /* SQLITE_UNTESTABLE */ |
| @@ -184143,6 +186432,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); | |||
| 184143 | 186432 | ||
| 184144 | SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); | 186433 | SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); |
| 184145 | 186434 | ||
| 186435 | SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); | ||
| 186436 | |||
| 184146 | #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ | 186437 | #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ |
| 184147 | #endif /* _FTSINT_H */ | 186438 | #endif /* _FTSINT_H */ |
| 184148 | 186439 | ||
| @@ -187865,7 +190156,7 @@ static int fts3ShadowName(const char *zName){ | |||
| 187865 | ** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual | 190156 | ** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual |
| 187866 | ** table. | 190157 | ** table. |
| 187867 | */ | 190158 | */ |
| 187868 | static int fts3Integrity( | 190159 | static int fts3IntegrityMethod( |
| 187869 | sqlite3_vtab *pVtab, /* The virtual table to be checked */ | 190160 | sqlite3_vtab *pVtab, /* The virtual table to be checked */ |
| 187870 | const char *zSchema, /* Name of schema in which pVtab lives */ | 190161 | const char *zSchema, /* Name of schema in which pVtab lives */ |
| 187871 | const char *zTabname, /* Name of the pVTab table */ | 190162 | const char *zTabname, /* Name of the pVTab table */ |
| @@ -187873,31 +190164,24 @@ static int fts3Integrity( | |||
| 187873 | char **pzErr /* Write error message here */ | 190164 | char **pzErr /* Write error message here */ |
| 187874 | ){ | 190165 | ){ |
| 187875 | Fts3Table *p = (Fts3Table*)pVtab; | 190166 | Fts3Table *p = (Fts3Table*)pVtab; |
| 187876 | char *zSql; | 190167 | int rc = SQLITE_OK; |
| 187877 | int rc; | 190168 | int bOk = 0; |
| 187878 | char *zErr = 0; | ||
| 187879 | 190169 | ||
| 187880 | assert( pzErr!=0 ); | ||
| 187881 | assert( *pzErr==0 ); | ||
| 187882 | UNUSED_PARAMETER(isQuick); | 190170 | UNUSED_PARAMETER(isQuick); |
| 187883 | zSql = sqlite3_mprintf( | 190171 | rc = sqlite3Fts3IntegrityCheck(p, &bOk); |
| 187884 | "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", | 190172 | assert( rc!=SQLITE_CORRUPT_VTAB ); |
| 187885 | zSchema, zTabname, zTabname); | 190173 | if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ |
| 187886 | if( zSql==0 ){ | ||
| 187887 | return SQLITE_NOMEM; | ||
| 187888 | } | ||
| 187889 | rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); | ||
| 187890 | sqlite3_free(zSql); | ||
| 187891 | if( (rc&0xff)==SQLITE_CORRUPT ){ | ||
| 187892 | *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", | ||
| 187893 | p->bFts4 ? 4 : 3, zSchema, zTabname); | ||
| 187894 | }else if( rc!=SQLITE_OK ){ | ||
| 187895 | *pzErr = sqlite3_mprintf("unable to validate the inverted index for" | 190174 | *pzErr = sqlite3_mprintf("unable to validate the inverted index for" |
| 187896 | " FTS%d table %s.%s: %s", | 190175 | " FTS%d table %s.%s: %s", |
| 187897 | p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); | 190176 | p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); |
| 190177 | if( *pzErr ) rc = SQLITE_OK; | ||
| 190178 | }else if( rc==SQLITE_OK && bOk==0 ){ | ||
| 190179 | *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", | ||
| 190180 | p->bFts4 ? 4 : 3, zSchema, zTabname); | ||
| 190181 | if( *pzErr==0 ) rc = SQLITE_NOMEM; | ||
| 187898 | } | 190182 | } |
| 187899 | sqlite3_free(zErr); | 190183 | sqlite3Fts3SegmentsClose(p); |
| 187900 | return SQLITE_OK; | 190184 | return rc; |
| 187901 | } | 190185 | } |
| 187902 | 190186 | ||
| 187903 | 190187 | ||
| @@ -187927,7 +190211,7 @@ static const sqlite3_module fts3Module = { | |||
| 187927 | /* xRelease */ fts3ReleaseMethod, | 190211 | /* xRelease */ fts3ReleaseMethod, |
| 187928 | /* xRollbackTo */ fts3RollbackToMethod, | 190212 | /* xRollbackTo */ fts3RollbackToMethod, |
| 187929 | /* xShadowName */ fts3ShadowName, | 190213 | /* xShadowName */ fts3ShadowName, |
| 187930 | /* xIntegrity */ fts3Integrity, | 190214 | /* xIntegrity */ fts3IntegrityMethod, |
| 187931 | }; | 190215 | }; |
| 187932 | 190216 | ||
| 187933 | /* | 190217 | /* |
| @@ -199481,7 +201765,7 @@ static u64 fts3ChecksumIndex( | |||
| 199481 | ** If an error occurs (e.g. an OOM or IO error), return an SQLite error | 201765 | ** If an error occurs (e.g. an OOM or IO error), return an SQLite error |
| 199482 | ** code. The final value of *pbOk is undefined in this case. | 201766 | ** code. The final value of *pbOk is undefined in this case. |
| 199483 | */ | 201767 | */ |
| 199484 | static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ | 201768 | SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ |
| 199485 | int rc = SQLITE_OK; /* Return code */ | 201769 | int rc = SQLITE_OK; /* Return code */ |
| 199486 | u64 cksum1 = 0; /* Checksum based on FTS index contents */ | 201770 | u64 cksum1 = 0; /* Checksum based on FTS index contents */ |
| 199487 | u64 cksum2 = 0; /* Checksum based on %_content contents */ | 201771 | u64 cksum2 = 0; /* Checksum based on %_content contents */ |
| @@ -199559,7 +201843,12 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ | |||
| 199559 | sqlite3_finalize(pStmt); | 201843 | sqlite3_finalize(pStmt); |
| 199560 | } | 201844 | } |
| 199561 | 201845 | ||
| 199562 | *pbOk = (cksum1==cksum2); | 201846 | if( rc==SQLITE_CORRUPT_VTAB ){ |
| 201847 | rc = SQLITE_OK; | ||
| 201848 | *pbOk = 0; | ||
| 201849 | }else{ | ||
| 201850 | *pbOk = (rc==SQLITE_OK && cksum1==cksum2); | ||
| 201851 | } | ||
| 199563 | return rc; | 201852 | return rc; |
| 199564 | } | 201853 | } |
| 199565 | 201854 | ||
| @@ -199599,7 +201888,7 @@ static int fts3DoIntegrityCheck( | |||
| 199599 | ){ | 201888 | ){ |
| 199600 | int rc; | 201889 | int rc; |
| 199601 | int bOk = 0; | 201890 | int bOk = 0; |
| 199602 | rc = fts3IntegrityCheck(p, &bOk); | 201891 | rc = sqlite3Fts3IntegrityCheck(p, &bOk); |
| 199603 | if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; | 201892 | if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; |
| 199604 | return rc; | 201893 | return rc; |
| 199605 | } | 201894 | } |
| @@ -200465,7 +202754,7 @@ static void fts3SnippetDetails( | |||
| 200465 | } | 202754 | } |
| 200466 | mCover |= mPhrase; | 202755 | mCover |= mPhrase; |
| 200467 | 202756 | ||
| 200468 | for(j=0; j<pPhrase->nToken; j++){ | 202757 | for(j=0; j<pPhrase->nToken && j<pIter->nSnippet; j++){ |
| 200469 | mHighlight |= (mPos>>j); | 202758 | mHighlight |= (mPos>>j); |
| 200470 | } | 202759 | } |
| 200471 | 202760 | ||
| @@ -202573,24 +204862,145 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ | |||
| 202573 | ** | 204862 | ** |
| 202574 | ****************************************************************************** | 204863 | ****************************************************************************** |
| 202575 | ** | 204864 | ** |
| 202576 | ** This SQLite JSON functions. | 204865 | ** SQLite JSON functions. |
| 202577 | ** | 204866 | ** |
| 202578 | ** This file began as an extension in ext/misc/json1.c in 2015. That | 204867 | ** This file began as an extension in ext/misc/json1.c in 2015. That |
| 202579 | ** extension proved so useful that it has now been moved into the core. | 204868 | ** extension proved so useful that it has now been moved into the core. |
| 202580 | ** | 204869 | ** |
| 202581 | ** For the time being, all JSON is stored as pure text. (We might add | 204870 | ** The original design stored all JSON as pure text, canonical RFC-8259. |
| 202582 | ** a JSONB type in the future which stores a binary encoding of JSON in | 204871 | ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). |
| 202583 | ** a BLOB, but there is no support for JSONB in the current implementation. | 204872 | ** All generated JSON text still conforms strictly to RFC-8259, but text |
| 202584 | ** This implementation parses JSON text at 250 MB/s, so it is hard to see | 204873 | ** with JSON-5 extensions is accepted as input. |
| 202585 | ** how JSONB might improve on that.) | 204874 | ** |
| 204875 | ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also | ||
| 204876 | ** accept BLOB values that have JSON encoded using a binary representation | ||
| 204877 | ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk | ||
| 204878 | ** format SQLite JSONB is completely different and incompatible with | ||
| 204879 | ** PostgreSQL JSONB. | ||
| 204880 | ** | ||
| 204881 | ** Decoding and interpreting JSONB is still O(N) where N is the size of | ||
| 204882 | ** the input, the same as text JSON. However, the constant of proportionality | ||
| 204883 | ** for JSONB is much smaller due to faster parsing. The size of each | ||
| 204884 | ** element in JSONB is encoded in its header, so there is no need to search | ||
| 204885 | ** for delimiters using persnickety syntax rules. JSONB seems to be about | ||
| 204886 | ** 3x faster than text JSON as a result. JSONB is also tends to be slightly | ||
| 204887 | ** smaller than text JSON, by 5% or 10%, but there are corner cases where | ||
| 204888 | ** JSONB can be slightly larger. So you are not far mistaken to say that | ||
| 204889 | ** a JSONB blob is the same size as the equivalent RFC-8259 text. | ||
| 204890 | ** | ||
| 204891 | ** | ||
| 204892 | ** THE JSONB ENCODING: | ||
| 204893 | ** | ||
| 204894 | ** Every JSON element is encoded in JSONB as a header and a payload. | ||
| 204895 | ** The header is between 1 and 9 bytes in size. The payload is zero | ||
| 204896 | ** or more bytes. | ||
| 204897 | ** | ||
| 204898 | ** The lower 4 bits of the first byte of the header determines the | ||
| 204899 | ** element type: | ||
| 204900 | ** | ||
| 204901 | ** 0: NULL | ||
| 204902 | ** 1: TRUE | ||
| 204903 | ** 2: FALSE | ||
| 204904 | ** 3: INT -- RFC-8259 integer literal | ||
| 204905 | ** 4: INT5 -- JSON5 integer literal | ||
| 204906 | ** 5: FLOAT -- RFC-8259 floating point literal | ||
| 204907 | ** 6: FLOAT5 -- JSON5 floating point literal | ||
| 204908 | ** 7: TEXT -- Text literal acceptable to both SQL and JSON | ||
| 204909 | ** 8: TEXTJ -- Text containing RFC-8259 escapes | ||
| 204910 | ** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes | ||
| 204911 | ** 10: TEXTRAW -- Text containing unescaped syntax characters | ||
| 204912 | ** 11: ARRAY | ||
| 204913 | ** 12: OBJECT | ||
| 204914 | ** | ||
| 204915 | ** The other three possible values (13-15) are reserved for future | ||
| 204916 | ** enhancements. | ||
| 204917 | ** | ||
| 204918 | ** The upper 4 bits of the first byte determine the size of the header | ||
| 204919 | ** and sometimes also the size of the payload. If X is the first byte | ||
| 204920 | ** of the element and if X>>4 is between 0 and 11, then the payload | ||
| 204921 | ** will be that many bytes in size and the header is exactly one byte | ||
| 204922 | ** in size. Other four values for X>>4 (12-15) indicate that the header | ||
| 204923 | ** is more than one byte in size and that the payload size is determined | ||
| 204924 | ** by the remainder of the header, interpreted as a unsigned big-endian | ||
| 204925 | ** integer. | ||
| 204926 | ** | ||
| 204927 | ** Value of X>>4 Size integer Total header size | ||
| 204928 | ** ------------- -------------------- ----------------- | ||
| 204929 | ** 12 1 byte (0-255) 2 | ||
| 204930 | ** 13 2 byte (0-65535) 3 | ||
| 204931 | ** 14 4 byte (0-4294967295) 5 | ||
| 204932 | ** 15 8 byte (0-1.8e19) 9 | ||
| 204933 | ** | ||
| 204934 | ** The payload size need not be expressed in its minimal form. For example, | ||
| 204935 | ** if the payload size is 10, the size can be expressed in any of 5 different | ||
| 204936 | ** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, | ||
| 204937 | ** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by | ||
| 204938 | ** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and | ||
| 204939 | ** a single byte of 0x0a. The shorter forms are preferred, of course, but | ||
| 204940 | ** sometimes when generating JSONB, the payload size is not known in advance | ||
| 204941 | ** and it is convenient to reserve sufficient header space to cover the | ||
| 204942 | ** largest possible payload size and then come back later and patch up | ||
| 204943 | ** the size when it becomes known, resulting in a non-minimal encoding. | ||
| 204944 | ** | ||
| 204945 | ** The value (X>>4)==15 is not actually used in the current implementation | ||
| 204946 | ** (as SQLite is currently unable handle BLOBs larger than about 2GB) | ||
| 204947 | ** but is included in the design to allow for future enhancements. | ||
| 204948 | ** | ||
| 204949 | ** The payload follows the header. NULL, TRUE, and FALSE have no payload and | ||
| 204950 | ** their payload size must always be zero. The payload for INT, INT5, | ||
| 204951 | ** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the | ||
| 204952 | ** "..." or '...' delimiters are omitted from the various text encodings. | ||
| 204953 | ** The payload for ARRAY and OBJECT is a list of additional elements that | ||
| 204954 | ** are the content for the array or object. The payload for an OBJECT | ||
| 204955 | ** must be an even number of elements. The first element of each pair is | ||
| 204956 | ** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. | ||
| 204957 | ** | ||
| 204958 | ** A valid JSONB blob consists of a single element, as described above. | ||
| 204959 | ** Usually this will be an ARRAY or OBJECT element which has many more | ||
| 204960 | ** elements as its content. But the overall blob is just a single element. | ||
| 204961 | ** | ||
| 204962 | ** Input validation for JSONB blobs simply checks that the element type | ||
| 204963 | ** code is between 0 and 12 and that the total size of the element | ||
| 204964 | ** (header plus payload) is the same as the size of the BLOB. If those | ||
| 204965 | ** checks are true, the BLOB is assumed to be JSONB and processing continues. | ||
| 204966 | ** Errors are only raised if some other miscoding is discovered during | ||
| 204967 | ** processing. | ||
| 204968 | ** | ||
| 204969 | ** Additional information can be found in the doc/jsonb.md file of the | ||
| 204970 | ** canonical SQLite source tree. | ||
| 202586 | */ | 204971 | */ |
| 202587 | #ifndef SQLITE_OMIT_JSON | 204972 | #ifndef SQLITE_OMIT_JSON |
| 202588 | /* #include "sqliteInt.h" */ | 204973 | /* #include "sqliteInt.h" */ |
| 202589 | 204974 | ||
| 204975 | /* JSONB element types | ||
| 204976 | */ | ||
| 204977 | #define JSONB_NULL 0 /* "null" */ | ||
| 204978 | #define JSONB_TRUE 1 /* "true" */ | ||
| 204979 | #define JSONB_FALSE 2 /* "false" */ | ||
| 204980 | #define JSONB_INT 3 /* integer acceptable to JSON and SQL */ | ||
| 204981 | #define JSONB_INT5 4 /* integer in 0x000 notation */ | ||
| 204982 | #define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ | ||
| 204983 | #define JSONB_FLOAT5 6 /* float with JSON5 extensions */ | ||
| 204984 | #define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ | ||
| 204985 | #define JSONB_TEXTJ 8 /* Text with JSON escapes */ | ||
| 204986 | #define JSONB_TEXT5 9 /* Text with JSON-5 escape */ | ||
| 204987 | #define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ | ||
| 204988 | #define JSONB_ARRAY 11 /* An array */ | ||
| 204989 | #define JSONB_OBJECT 12 /* An object */ | ||
| 204990 | |||
| 204991 | /* Human-readable names for the JSONB values. The index for each | ||
| 204992 | ** string must correspond to the JSONB_* integer above. | ||
| 204993 | */ | ||
| 204994 | static const char * const jsonbType[] = { | ||
| 204995 | "null", "true", "false", "integer", "integer", | ||
| 204996 | "real", "real", "text", "text", "text", | ||
| 204997 | "text", "array", "object", "", "", "", "" | ||
| 204998 | }; | ||
| 204999 | |||
| 202590 | /* | 205000 | /* |
| 202591 | ** Growing our own isspace() routine this way is twice as fast as | 205001 | ** Growing our own isspace() routine this way is twice as fast as |
| 202592 | ** the library isspace() function, resulting in a 7% overall performance | 205002 | ** the library isspace() function, resulting in a 7% overall performance |
| 202593 | ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). | 205003 | ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). |
| 202594 | */ | 205004 | */ |
| 202595 | static const char jsonIsSpace[] = { | 205005 | static const char jsonIsSpace[] = { |
| 202596 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, | 205006 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, |
| @@ -202611,11 +205021,19 @@ static const char jsonIsSpace[] = { | |||
| 202611 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 205021 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 202612 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 205022 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 202613 | }; | 205023 | }; |
| 202614 | #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) | 205024 | #define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) |
| 205025 | |||
| 205026 | /* | ||
| 205027 | ** The set of all space characters recognized by jsonIsspace(). | ||
| 205028 | ** Useful as the second argument to strspn(). | ||
| 205029 | */ | ||
| 205030 | static const char jsonSpaces[] = "\011\012\015\040"; | ||
| 202615 | 205031 | ||
| 202616 | /* | 205032 | /* |
| 202617 | ** Characters that are special to JSON. Control charaters, | 205033 | ** Characters that are special to JSON. Control characters, |
| 202618 | ** '"' and '\\'. | 205034 | ** '"' and '\\' and '\''. Actually, '\'' is not special to |
| 205035 | ** canonical JSON, but it is special in JSON-5, so we include | ||
| 205036 | ** it in the set of special characters. | ||
| 202619 | */ | 205037 | */ |
| 202620 | static const char jsonIsOk[256] = { | 205038 | static const char jsonIsOk[256] = { |
| 202621 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 205039 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| @@ -202637,22 +205055,49 @@ static const char jsonIsOk[256] = { | |||
| 202637 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 | 205055 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 |
| 202638 | }; | 205056 | }; |
| 202639 | 205057 | ||
| 202640 | |||
| 202641 | #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) | ||
| 202642 | # define VVA(X) | ||
| 202643 | #else | ||
| 202644 | # define VVA(X) X | ||
| 202645 | #endif | ||
| 202646 | |||
| 202647 | /* Objects */ | 205058 | /* Objects */ |
| 205059 | typedef struct JsonCache JsonCache; | ||
| 202648 | typedef struct JsonString JsonString; | 205060 | typedef struct JsonString JsonString; |
| 202649 | typedef struct JsonNode JsonNode; | ||
| 202650 | typedef struct JsonParse JsonParse; | 205061 | typedef struct JsonParse JsonParse; |
| 202651 | typedef struct JsonCleanup JsonCleanup; | 205062 | |
| 205063 | /* | ||
| 205064 | ** Magic number used for the JSON parse cache in sqlite3_get_auxdata() | ||
| 205065 | */ | ||
| 205066 | #define JSON_CACHE_ID (-429938) /* Cache entry */ | ||
| 205067 | #define JSON_CACHE_SIZE 4 /* Max number of cache entries */ | ||
| 205068 | |||
| 205069 | /* | ||
| 205070 | ** jsonUnescapeOneChar() returns this invalid code point if it encounters | ||
| 205071 | ** a syntax error. | ||
| 205072 | */ | ||
| 205073 | #define JSON_INVALID_CHAR 0x99999 | ||
| 205074 | |||
| 205075 | /* A cache mapping JSON text into JSONB blobs. | ||
| 205076 | ** | ||
| 205077 | ** Each cache entry is a JsonParse object with the following restrictions: | ||
| 205078 | ** | ||
| 205079 | ** * The bReadOnly flag must be set | ||
| 205080 | ** | ||
| 205081 | ** * The aBlob[] array must be owned by the JsonParse object. In other | ||
| 205082 | ** words, nBlobAlloc must be non-zero. | ||
| 205083 | ** | ||
| 205084 | ** * eEdit and delta must be zero. | ||
| 205085 | ** | ||
| 205086 | ** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. | ||
| 205087 | */ | ||
| 205088 | struct JsonCache { | ||
| 205089 | sqlite3 *db; /* Database connection */ | ||
| 205090 | int nUsed; /* Number of active entries in the cache */ | ||
| 205091 | JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ | ||
| 205092 | }; | ||
| 202652 | 205093 | ||
| 202653 | /* An instance of this object represents a JSON string | 205094 | /* An instance of this object represents a JSON string |
| 202654 | ** under construction. Really, this is a generic string accumulator | 205095 | ** under construction. Really, this is a generic string accumulator |
| 202655 | ** that can be and is used to create strings other than JSON. | 205096 | ** that can be and is used to create strings other than JSON. |
| 205097 | ** | ||
| 205098 | ** If the generated string is longer than will fit into the zSpace[] buffer, | ||
| 205099 | ** then it will be an RCStr string. This aids with caching of large | ||
| 205100 | ** JSON strings. | ||
| 202656 | */ | 205101 | */ |
| 202657 | struct JsonString { | 205102 | struct JsonString { |
| 202658 | sqlite3_context *pCtx; /* Function context - put error messages here */ | 205103 | sqlite3_context *pCtx; /* Function context - put error messages here */ |
| @@ -202660,121 +205105,75 @@ struct JsonString { | |||
| 202660 | u64 nAlloc; /* Bytes of storage available in zBuf[] */ | 205105 | u64 nAlloc; /* Bytes of storage available in zBuf[] */ |
| 202661 | u64 nUsed; /* Bytes of zBuf[] currently used */ | 205106 | u64 nUsed; /* Bytes of zBuf[] currently used */ |
| 202662 | u8 bStatic; /* True if zBuf is static space */ | 205107 | u8 bStatic; /* True if zBuf is static space */ |
| 202663 | u8 bErr; /* True if an error has been encountered */ | 205108 | u8 eErr; /* True if an error has been encountered */ |
| 202664 | char zSpace[100]; /* Initial static space */ | 205109 | char zSpace[100]; /* Initial static space */ |
| 202665 | }; | 205110 | }; |
| 202666 | 205111 | ||
| 202667 | /* A deferred cleanup task. A list of JsonCleanup objects might be | 205112 | /* Allowed values for JsonString.eErr */ |
| 202668 | ** run when the JsonParse object is destroyed. | 205113 | #define JSTRING_OOM 0x01 /* Out of memory */ |
| 202669 | */ | 205114 | #define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ |
| 202670 | struct JsonCleanup { | 205115 | #define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ |
| 202671 | JsonCleanup *pJCNext; /* Next in a list */ | ||
| 202672 | void (*xOp)(void*); /* Routine to run */ | ||
| 202673 | void *pArg; /* Argument to xOp() */ | ||
| 202674 | }; | ||
| 202675 | 205116 | ||
| 202676 | /* JSON type values | 205117 | /* The "subtype" set for text JSON values passed through using |
| 205118 | ** sqlite3_result_subtype() and sqlite3_value_subtype(). | ||
| 202677 | */ | 205119 | */ |
| 202678 | #define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ | ||
| 202679 | #define JSON_NULL 1 | ||
| 202680 | #define JSON_TRUE 2 | ||
| 202681 | #define JSON_FALSE 3 | ||
| 202682 | #define JSON_INT 4 | ||
| 202683 | #define JSON_REAL 5 | ||
| 202684 | #define JSON_STRING 6 | ||
| 202685 | #define JSON_ARRAY 7 | ||
| 202686 | #define JSON_OBJECT 8 | ||
| 202687 | |||
| 202688 | /* The "subtype" set for JSON values */ | ||
| 202689 | #define JSON_SUBTYPE 74 /* Ascii for "J" */ | 205120 | #define JSON_SUBTYPE 74 /* Ascii for "J" */ |
| 202690 | 205121 | ||
| 202691 | /* | 205122 | /* |
| 202692 | ** Names of the various JSON types: | 205123 | ** Bit values for the flags passed into various SQL function implementations |
| 202693 | */ | 205124 | ** via the sqlite3_user_data() value. |
| 202694 | static const char * const jsonType[] = { | ||
| 202695 | "subst", | ||
| 202696 | "null", "true", "false", "integer", "real", "text", "array", "object" | ||
| 202697 | }; | ||
| 202698 | |||
| 202699 | /* Bit values for the JsonNode.jnFlag field | ||
| 202700 | */ | 205125 | */ |
| 202701 | #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ | 205126 | #define JSON_JSON 0x01 /* Result is always JSON */ |
| 202702 | #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ | 205127 | #define JSON_SQL 0x02 /* Result is always SQL */ |
| 202703 | #define JNODE_REMOVE 0x04 /* Do not output */ | 205128 | #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ |
| 202704 | #define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ | 205129 | #define JSON_ISSET 0x04 /* json_set(), not json_insert() */ |
| 202705 | #define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ | 205130 | #define JSON_BLOB 0x08 /* Use the BLOB output format */ |
| 202706 | #define JNODE_LABEL 0x20 /* Is a label of an object */ | ||
| 202707 | #define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ | ||
| 202708 | |||
| 202709 | |||
| 202710 | /* A single node of parsed JSON. An array of these nodes describes | ||
| 202711 | ** a parse of JSON + edits. | ||
| 202712 | ** | ||
| 202713 | ** Use the json_parse() SQL function (available when compiled with | ||
| 202714 | ** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including | ||
| 202715 | ** a complete listing and decoding of the array of JsonNodes. | ||
| 202716 | */ | ||
| 202717 | struct JsonNode { | ||
| 202718 | u8 eType; /* One of the JSON_ type values */ | ||
| 202719 | u8 jnFlags; /* JNODE flags */ | ||
| 202720 | u8 eU; /* Which union element to use */ | ||
| 202721 | u32 n; /* Bytes of content for INT, REAL or STRING | ||
| 202722 | ** Number of sub-nodes for ARRAY and OBJECT | ||
| 202723 | ** Node that SUBST applies to */ | ||
| 202724 | union { | ||
| 202725 | const char *zJContent; /* 1: Content for INT, REAL, and STRING */ | ||
| 202726 | u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ | ||
| 202727 | u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ | ||
| 202728 | u32 iPrev; /* 4: Previous SUBST node, or 0 */ | ||
| 202729 | } u; | ||
| 202730 | }; | ||
| 202731 | 205131 | ||
| 202732 | 205132 | ||
| 202733 | /* A parsed and possibly edited JSON string. Lifecycle: | 205133 | /* A parsed JSON value. Lifecycle: |
| 202734 | ** | 205134 | ** |
| 202735 | ** 1. JSON comes in and is parsed into an array aNode[]. The original | 205135 | ** 1. JSON comes in and is parsed into a JSONB value in aBlob. The |
| 202736 | ** JSON text is stored in zJson. | 205136 | ** original text is stored in zJson. This step is skipped if the |
| 205137 | ** input is JSONB instead of text JSON. | ||
| 202737 | ** | 205138 | ** |
| 202738 | ** 2. Zero or more changes are made (via json_remove() or json_replace() | 205139 | ** 2. The aBlob[] array is searched using the JSON path notation, if needed. |
| 202739 | ** or similar) to the aNode[] array. | ||
| 202740 | ** | 205140 | ** |
| 202741 | ** 3. A new, edited and mimified JSON string is generated from aNode | 205141 | ** 3. Zero or more changes are made to aBlob[] (via json_remove() or |
| 202742 | ** and stored in zAlt. The JsonParse object always owns zAlt. | 205142 | ** json_replace() or json_patch() or similar). |
| 202743 | ** | 205143 | ** |
| 202744 | ** Step 1 always happens. Step 2 and 3 may or may not happen, depending | 205144 | ** 4. New JSON text is generated from the aBlob[] for output. This step |
| 202745 | ** on the operation. | 205145 | ** is skipped if the function is one of the jsonb_* functions that |
| 202746 | ** | 205146 | ** returns JSONB instead of text JSON. |
| 202747 | ** aNode[].u.zJContent entries typically point into zJson. Hence zJson | ||
| 202748 | ** must remain valid for the lifespan of the parse. For edits, | ||
| 202749 | ** aNode[].u.zJContent might point to malloced space other than zJson. | ||
| 202750 | ** Entries in pClup are responsible for freeing that extra malloced space. | ||
| 202751 | ** | ||
| 202752 | ** When walking the parse tree in aNode[], edits are ignored if useMod is | ||
| 202753 | ** false. | ||
| 202754 | */ | 205147 | */ |
| 202755 | struct JsonParse { | 205148 | struct JsonParse { |
| 202756 | u32 nNode; /* Number of slots of aNode[] used */ | 205149 | u8 *aBlob; /* JSONB representation of JSON value */ |
| 202757 | u32 nAlloc; /* Number of slots of aNode[] allocated */ | 205150 | u32 nBlob; /* Bytes of aBlob[] actually used */ |
| 202758 | JsonNode *aNode; /* Array of nodes containing the parse */ | 205151 | u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ |
| 202759 | char *zJson; /* Original JSON string (before edits) */ | 205152 | char *zJson; /* Json text used for parsing */ |
| 202760 | char *zAlt; /* Revised and/or mimified JSON */ | 205153 | sqlite3 *db; /* The database connection to which this object belongs */ |
| 202761 | u32 *aUp; /* Index of parent of each node */ | 205154 | int nJson; /* Length of the zJson string in bytes */ |
| 202762 | JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ | 205155 | u32 nJPRef; /* Number of references to this object */ |
| 205156 | u32 iErr; /* Error location in zJson[] */ | ||
| 202763 | u16 iDepth; /* Nesting depth */ | 205157 | u16 iDepth; /* Nesting depth */ |
| 202764 | u8 nErr; /* Number of errors seen */ | 205158 | u8 nErr; /* Number of errors seen */ |
| 202765 | u8 oom; /* Set to true if out of memory */ | 205159 | u8 oom; /* Set to true if out of memory */ |
| 202766 | u8 bJsonIsRCStr; /* True if zJson is an RCStr */ | 205160 | u8 bJsonIsRCStr; /* True if zJson is an RCStr */ |
| 202767 | u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ | 205161 | u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ |
| 202768 | u8 useMod; /* Actually use the edits contain inside aNode */ | 205162 | u8 bReadOnly; /* Do not modify. */ |
| 202769 | u8 hasMod; /* aNode contains edits from the original zJson */ | 205163 | /* Search and edit information. See jsonLookupStep() */ |
| 202770 | u32 nJPRef; /* Number of references to this object */ | 205164 | u8 eEdit; /* Edit operation to apply */ |
| 202771 | int nJson; /* Length of the zJson string in bytes */ | 205165 | int delta; /* Size change due to the edit */ |
| 202772 | int nAlt; /* Length of alternative JSON string zAlt, in bytes */ | 205166 | u32 nIns; /* Number of bytes to insert */ |
| 202773 | u32 iErr; /* Error location in zJson[] */ | 205167 | u32 iLabel; /* Location of label if search landed on an object value */ |
| 202774 | u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ | 205168 | u8 *aIns; /* Content to be inserted */ |
| 202775 | u32 iHold; /* Age of this entry in the cache for LRU replacement */ | ||
| 202776 | }; | 205169 | }; |
| 202777 | 205170 | ||
| 205171 | /* Allowed values for JsonParse.eEdit */ | ||
| 205172 | #define JEDIT_DEL 1 /* Delete if exists */ | ||
| 205173 | #define JEDIT_REPL 2 /* Overwrite if exists */ | ||
| 205174 | #define JEDIT_INS 3 /* Insert if not exists */ | ||
| 205175 | #define JEDIT_SET 4 /* Insert or overwrite */ | ||
| 205176 | |||
| 202778 | /* | 205177 | /* |
| 202779 | ** Maximum nesting depth of JSON for this implementation. | 205178 | ** Maximum nesting depth of JSON for this implementation. |
| 202780 | ** | 205179 | ** |
| @@ -202782,15 +205181,151 @@ struct JsonParse { | |||
| 202782 | ** descent parser. A depth of 1000 is far deeper than any sane JSON | 205181 | ** descent parser. A depth of 1000 is far deeper than any sane JSON |
| 202783 | ** should go. Historical note: This limit was 2000 prior to version 3.42.0 | 205182 | ** should go. Historical note: This limit was 2000 prior to version 3.42.0 |
| 202784 | */ | 205183 | */ |
| 202785 | #define JSON_MAX_DEPTH 1000 | 205184 | #ifndef SQLITE_JSON_MAX_DEPTH |
| 205185 | # define JSON_MAX_DEPTH 1000 | ||
| 205186 | #else | ||
| 205187 | # define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH | ||
| 205188 | #endif | ||
| 205189 | |||
| 205190 | /* | ||
| 205191 | ** Allowed values for the flgs argument to jsonParseFuncArg(); | ||
| 205192 | */ | ||
| 205193 | #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ | ||
| 205194 | #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ | ||
| 205195 | |||
| 205196 | /************************************************************************** | ||
| 205197 | ** Forward references | ||
| 205198 | **************************************************************************/ | ||
| 205199 | static void jsonReturnStringAsBlob(JsonString*); | ||
| 205200 | static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); | ||
| 205201 | static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); | ||
| 205202 | static void jsonReturnParse(sqlite3_context*,JsonParse*); | ||
| 205203 | static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); | ||
| 205204 | static void jsonParseFree(JsonParse*); | ||
| 205205 | static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); | ||
| 205206 | static u32 jsonUnescapeOneChar(const char*, u32, u32*); | ||
| 205207 | |||
| 205208 | /************************************************************************** | ||
| 205209 | ** Utility routines for dealing with JsonCache objects | ||
| 205210 | **************************************************************************/ | ||
| 205211 | |||
| 205212 | /* | ||
| 205213 | ** Free a JsonCache object. | ||
| 205214 | */ | ||
| 205215 | static void jsonCacheDelete(JsonCache *p){ | ||
| 205216 | int i; | ||
| 205217 | for(i=0; i<p->nUsed; i++){ | ||
| 205218 | jsonParseFree(p->a[i]); | ||
| 205219 | } | ||
| 205220 | sqlite3DbFree(p->db, p); | ||
| 205221 | } | ||
| 205222 | static void jsonCacheDeleteGeneric(void *p){ | ||
| 205223 | jsonCacheDelete((JsonCache*)p); | ||
| 205224 | } | ||
| 205225 | |||
| 205226 | /* | ||
| 205227 | ** Insert a new entry into the cache. If the cache is full, expel | ||
| 205228 | ** the least recently used entry. Return SQLITE_OK on success or a | ||
| 205229 | ** result code otherwise. | ||
| 205230 | ** | ||
| 205231 | ** Cache entries are stored in age order, oldest first. | ||
| 205232 | */ | ||
| 205233 | static int jsonCacheInsert( | ||
| 205234 | sqlite3_context *ctx, /* The SQL statement context holding the cache */ | ||
| 205235 | JsonParse *pParse /* The parse object to be added to the cache */ | ||
| 205236 | ){ | ||
| 205237 | JsonCache *p; | ||
| 205238 | |||
| 205239 | assert( pParse->zJson!=0 ); | ||
| 205240 | assert( pParse->bJsonIsRCStr ); | ||
| 205241 | assert( pParse->delta==0 ); | ||
| 205242 | p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); | ||
| 205243 | if( p==0 ){ | ||
| 205244 | sqlite3 *db = sqlite3_context_db_handle(ctx); | ||
| 205245 | p = sqlite3DbMallocZero(db, sizeof(*p)); | ||
| 205246 | if( p==0 ) return SQLITE_NOMEM; | ||
| 205247 | p->db = db; | ||
| 205248 | sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); | ||
| 205249 | p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); | ||
| 205250 | if( p==0 ) return SQLITE_NOMEM; | ||
| 205251 | } | ||
| 205252 | if( p->nUsed >= JSON_CACHE_SIZE ){ | ||
| 205253 | jsonParseFree(p->a[0]); | ||
| 205254 | memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); | ||
| 205255 | p->nUsed = JSON_CACHE_SIZE-1; | ||
| 205256 | } | ||
| 205257 | assert( pParse->nBlobAlloc>0 ); | ||
| 205258 | pParse->eEdit = 0; | ||
| 205259 | pParse->nJPRef++; | ||
| 205260 | pParse->bReadOnly = 1; | ||
| 205261 | p->a[p->nUsed] = pParse; | ||
| 205262 | p->nUsed++; | ||
| 205263 | return SQLITE_OK; | ||
| 205264 | } | ||
| 205265 | |||
| 205266 | /* | ||
| 205267 | ** Search for a cached translation the json text supplied by pArg. Return | ||
| 205268 | ** the JsonParse object if found. Return NULL if not found. | ||
| 205269 | ** | ||
| 205270 | ** When a match if found, the matching entry is moved to become the | ||
| 205271 | ** most-recently used entry if it isn't so already. | ||
| 205272 | ** | ||
| 205273 | ** The JsonParse object returned still belongs to the Cache and might | ||
| 205274 | ** be deleted at any moment. If the caller whants the JsonParse to | ||
| 205275 | ** linger, it needs to increment the nPJRef reference counter. | ||
| 205276 | */ | ||
| 205277 | static JsonParse *jsonCacheSearch( | ||
| 205278 | sqlite3_context *ctx, /* The SQL statement context holding the cache */ | ||
| 205279 | sqlite3_value *pArg /* Function argument containing SQL text */ | ||
| 205280 | ){ | ||
| 205281 | JsonCache *p; | ||
| 205282 | int i; | ||
| 205283 | const char *zJson; | ||
| 205284 | int nJson; | ||
| 205285 | |||
| 205286 | if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ | ||
| 205287 | return 0; | ||
| 205288 | } | ||
| 205289 | zJson = (const char*)sqlite3_value_text(pArg); | ||
| 205290 | if( zJson==0 ) return 0; | ||
| 205291 | nJson = sqlite3_value_bytes(pArg); | ||
| 205292 | |||
| 205293 | p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); | ||
| 205294 | if( p==0 ){ | ||
| 205295 | return 0; | ||
| 205296 | } | ||
| 205297 | for(i=0; i<p->nUsed; i++){ | ||
| 205298 | if( p->a[i]->zJson==zJson ) break; | ||
| 205299 | } | ||
| 205300 | if( i>=p->nUsed ){ | ||
| 205301 | for(i=0; i<p->nUsed; i++){ | ||
| 205302 | if( p->a[i]->nJson!=nJson ) continue; | ||
| 205303 | if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; | ||
| 205304 | } | ||
| 205305 | } | ||
| 205306 | if( i<p->nUsed ){ | ||
| 205307 | if( i<p->nUsed-1 ){ | ||
| 205308 | /* Make the matching entry the most recently used entry */ | ||
| 205309 | JsonParse *tmp = p->a[i]; | ||
| 205310 | memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); | ||
| 205311 | p->a[p->nUsed-1] = tmp; | ||
| 205312 | i = p->nUsed - 1; | ||
| 205313 | } | ||
| 205314 | assert( p->a[i]->delta==0 ); | ||
| 205315 | return p->a[i]; | ||
| 205316 | }else{ | ||
| 205317 | return 0; | ||
| 205318 | } | ||
| 205319 | } | ||
| 202786 | 205320 | ||
| 202787 | /************************************************************************** | 205321 | /************************************************************************** |
| 202788 | ** Utility routines for dealing with JsonString objects | 205322 | ** Utility routines for dealing with JsonString objects |
| 202789 | **************************************************************************/ | 205323 | **************************************************************************/ |
| 202790 | 205324 | ||
| 202791 | /* Set the JsonString object to an empty string | 205325 | /* Turn uninitialized bulk memory into a valid JsonString object |
| 205326 | ** holding a zero-length string. | ||
| 202792 | */ | 205327 | */ |
| 202793 | static void jsonZero(JsonString *p){ | 205328 | static void jsonStringZero(JsonString *p){ |
| 202794 | p->zBuf = p->zSpace; | 205329 | p->zBuf = p->zSpace; |
| 202795 | p->nAlloc = sizeof(p->zSpace); | 205330 | p->nAlloc = sizeof(p->zSpace); |
| 202796 | p->nUsed = 0; | 205331 | p->nUsed = 0; |
| @@ -202799,39 +205334,39 @@ static void jsonZero(JsonString *p){ | |||
| 202799 | 205334 | ||
| 202800 | /* Initialize the JsonString object | 205335 | /* Initialize the JsonString object |
| 202801 | */ | 205336 | */ |
| 202802 | static void jsonInit(JsonString *p, sqlite3_context *pCtx){ | 205337 | static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ |
| 202803 | p->pCtx = pCtx; | 205338 | p->pCtx = pCtx; |
| 202804 | p->bErr = 0; | 205339 | p->eErr = 0; |
| 202805 | jsonZero(p); | 205340 | jsonStringZero(p); |
| 202806 | } | 205341 | } |
| 202807 | 205342 | ||
| 202808 | /* Free all allocated memory and reset the JsonString object back to its | 205343 | /* Free all allocated memory and reset the JsonString object back to its |
| 202809 | ** initial state. | 205344 | ** initial state. |
| 202810 | */ | 205345 | */ |
| 202811 | static void jsonReset(JsonString *p){ | 205346 | static void jsonStringReset(JsonString *p){ |
| 202812 | if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); | 205347 | if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); |
| 202813 | jsonZero(p); | 205348 | jsonStringZero(p); |
| 202814 | } | 205349 | } |
| 202815 | 205350 | ||
| 202816 | /* Report an out-of-memory (OOM) condition | 205351 | /* Report an out-of-memory (OOM) condition |
| 202817 | */ | 205352 | */ |
| 202818 | static void jsonOom(JsonString *p){ | 205353 | static void jsonStringOom(JsonString *p){ |
| 202819 | p->bErr = 1; | 205354 | p->eErr |= JSTRING_OOM; |
| 202820 | sqlite3_result_error_nomem(p->pCtx); | 205355 | if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); |
| 202821 | jsonReset(p); | 205356 | jsonStringReset(p); |
| 202822 | } | 205357 | } |
| 202823 | 205358 | ||
| 202824 | /* Enlarge pJson->zBuf so that it can hold at least N more bytes. | 205359 | /* Enlarge pJson->zBuf so that it can hold at least N more bytes. |
| 202825 | ** Return zero on success. Return non-zero on an OOM error | 205360 | ** Return zero on success. Return non-zero on an OOM error |
| 202826 | */ | 205361 | */ |
| 202827 | static int jsonGrow(JsonString *p, u32 N){ | 205362 | static int jsonStringGrow(JsonString *p, u32 N){ |
| 202828 | u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; | 205363 | u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10; |
| 202829 | char *zNew; | 205364 | char *zNew; |
| 202830 | if( p->bStatic ){ | 205365 | if( p->bStatic ){ |
| 202831 | if( p->bErr ) return 1; | 205366 | if( p->eErr ) return 1; |
| 202832 | zNew = sqlite3RCStrNew(nTotal); | 205367 | zNew = sqlite3RCStrNew(nTotal); |
| 202833 | if( zNew==0 ){ | 205368 | if( zNew==0 ){ |
| 202834 | jsonOom(p); | 205369 | jsonStringOom(p); |
| 202835 | return SQLITE_NOMEM; | 205370 | return SQLITE_NOMEM; |
| 202836 | } | 205371 | } |
| 202837 | memcpy(zNew, p->zBuf, (size_t)p->nUsed); | 205372 | memcpy(zNew, p->zBuf, (size_t)p->nUsed); |
| @@ -202840,8 +205375,8 @@ static int jsonGrow(JsonString *p, u32 N){ | |||
| 202840 | }else{ | 205375 | }else{ |
| 202841 | p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); | 205376 | p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); |
| 202842 | if( p->zBuf==0 ){ | 205377 | if( p->zBuf==0 ){ |
| 202843 | p->bErr = 1; | 205378 | p->eErr |= JSTRING_OOM; |
| 202844 | jsonZero(p); | 205379 | jsonStringZero(p); |
| 202845 | return SQLITE_NOMEM; | 205380 | return SQLITE_NOMEM; |
| 202846 | } | 205381 | } |
| 202847 | } | 205382 | } |
| @@ -202851,20 +205386,20 @@ static int jsonGrow(JsonString *p, u32 N){ | |||
| 202851 | 205386 | ||
| 202852 | /* Append N bytes from zIn onto the end of the JsonString string. | 205387 | /* Append N bytes from zIn onto the end of the JsonString string. |
| 202853 | */ | 205388 | */ |
| 202854 | static SQLITE_NOINLINE void jsonAppendExpand( | 205389 | static SQLITE_NOINLINE void jsonStringExpandAndAppend( |
| 202855 | JsonString *p, | 205390 | JsonString *p, |
| 202856 | const char *zIn, | 205391 | const char *zIn, |
| 202857 | u32 N | 205392 | u32 N |
| 202858 | ){ | 205393 | ){ |
| 202859 | assert( N>0 ); | 205394 | assert( N>0 ); |
| 202860 | if( jsonGrow(p,N) ) return; | 205395 | if( jsonStringGrow(p,N) ) return; |
| 202861 | memcpy(p->zBuf+p->nUsed, zIn, N); | 205396 | memcpy(p->zBuf+p->nUsed, zIn, N); |
| 202862 | p->nUsed += N; | 205397 | p->nUsed += N; |
| 202863 | } | 205398 | } |
| 202864 | static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ | 205399 | static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ |
| 202865 | if( N==0 ) return; | 205400 | if( N==0 ) return; |
| 202866 | if( N+p->nUsed >= p->nAlloc ){ | 205401 | if( N+p->nUsed >= p->nAlloc ){ |
| 202867 | jsonAppendExpand(p,zIn,N); | 205402 | jsonStringExpandAndAppend(p,zIn,N); |
| 202868 | }else{ | 205403 | }else{ |
| 202869 | memcpy(p->zBuf+p->nUsed, zIn, N); | 205404 | memcpy(p->zBuf+p->nUsed, zIn, N); |
| 202870 | p->nUsed += N; | 205405 | p->nUsed += N; |
| @@ -202873,19 +205408,18 @@ static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ | |||
| 202873 | static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ | 205408 | static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ |
| 202874 | assert( N>0 ); | 205409 | assert( N>0 ); |
| 202875 | if( N+p->nUsed >= p->nAlloc ){ | 205410 | if( N+p->nUsed >= p->nAlloc ){ |
| 202876 | jsonAppendExpand(p,zIn,N); | 205411 | jsonStringExpandAndAppend(p,zIn,N); |
| 202877 | }else{ | 205412 | }else{ |
| 202878 | memcpy(p->zBuf+p->nUsed, zIn, N); | 205413 | memcpy(p->zBuf+p->nUsed, zIn, N); |
| 202879 | p->nUsed += N; | 205414 | p->nUsed += N; |
| 202880 | } | 205415 | } |
| 202881 | } | 205416 | } |
| 202882 | 205417 | ||
| 202883 | |||
| 202884 | /* Append formatted text (not to exceed N bytes) to the JsonString. | 205418 | /* Append formatted text (not to exceed N bytes) to the JsonString. |
| 202885 | */ | 205419 | */ |
| 202886 | static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ | 205420 | static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ |
| 202887 | va_list ap; | 205421 | va_list ap; |
| 202888 | if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; | 205422 | if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; |
| 202889 | va_start(ap, zFormat); | 205423 | va_start(ap, zFormat); |
| 202890 | sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); | 205424 | sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); |
| 202891 | va_end(ap); | 205425 | va_end(ap); |
| @@ -202895,7 +205429,7 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ | |||
| 202895 | /* Append a single character | 205429 | /* Append a single character |
| 202896 | */ | 205430 | */ |
| 202897 | static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ | 205431 | static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ |
| 202898 | if( jsonGrow(p,1) ) return; | 205432 | if( jsonStringGrow(p,1) ) return; |
| 202899 | p->zBuf[p->nUsed++] = c; | 205433 | p->zBuf[p->nUsed++] = c; |
| 202900 | } | 205434 | } |
| 202901 | static void jsonAppendChar(JsonString *p, char c){ | 205435 | static void jsonAppendChar(JsonString *p, char c){ |
| @@ -202906,24 +205440,27 @@ static void jsonAppendChar(JsonString *p, char c){ | |||
| 202906 | } | 205440 | } |
| 202907 | } | 205441 | } |
| 202908 | 205442 | ||
| 202909 | /* Try to force the string to be a zero-terminated RCStr string. | 205443 | /* Remove a single character from the end of the string |
| 205444 | */ | ||
| 205445 | static void jsonStringTrimOneChar(JsonString *p){ | ||
| 205446 | if( p->eErr==0 ){ | ||
| 205447 | assert( p->nUsed>0 ); | ||
| 205448 | p->nUsed--; | ||
| 205449 | } | ||
| 205450 | } | ||
| 205451 | |||
| 205452 | |||
| 205453 | /* Make sure there is a zero terminator on p->zBuf[] | ||
| 202910 | ** | 205454 | ** |
| 202911 | ** Return true on success. Return false if an OOM prevents this | 205455 | ** Return true on success. Return false if an OOM prevents this |
| 202912 | ** from happening. | 205456 | ** from happening. |
| 202913 | */ | 205457 | */ |
| 202914 | static int jsonForceRCStr(JsonString *p){ | 205458 | static int jsonStringTerminate(JsonString *p){ |
| 202915 | jsonAppendChar(p, 0); | 205459 | jsonAppendChar(p, 0); |
| 202916 | if( p->bErr ) return 0; | 205460 | jsonStringTrimOneChar(p); |
| 202917 | p->nUsed--; | 205461 | return p->eErr==0; |
| 202918 | if( p->bStatic==0 ) return 1; | ||
| 202919 | p->nAlloc = 0; | ||
| 202920 | p->nUsed++; | ||
| 202921 | jsonGrow(p, p->nUsed); | ||
| 202922 | p->nUsed--; | ||
| 202923 | return p->bStatic==0; | ||
| 202924 | } | 205462 | } |
| 202925 | 205463 | ||
| 202926 | |||
| 202927 | /* Append a comma separator to the output buffer, if the previous | 205464 | /* Append a comma separator to the output buffer, if the previous |
| 202928 | ** character is not '[' or '{'. | 205465 | ** character is not '[' or '{'. |
| 202929 | */ | 205466 | */ |
| @@ -202935,184 +205472,120 @@ static void jsonAppendSeparator(JsonString *p){ | |||
| 202935 | jsonAppendChar(p, ','); | 205472 | jsonAppendChar(p, ','); |
| 202936 | } | 205473 | } |
| 202937 | 205474 | ||
| 202938 | /* Append the N-byte string in zIn to the end of the JsonString string | 205475 | /* c is a control character. Append the canonical JSON representation |
| 202939 | ** under construction. Enclose the string in "..." and escape | 205476 | ** of that control character to p. |
| 202940 | ** any double-quotes or backslash characters contained within the | 205477 | ** |
| 202941 | ** string. | 205478 | ** This routine assumes that the output buffer has already been enlarged |
| 205479 | ** sufficiently to hold the worst-case encoding plus a nul terminator. | ||
| 202942 | */ | 205480 | */ |
| 202943 | static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ | 205481 | static void jsonAppendControlChar(JsonString *p, u8 c){ |
| 202944 | u32 i; | 205482 | static const char aSpecial[] = { |
| 202945 | if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return; | 205483 | 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, |
| 202946 | p->zBuf[p->nUsed++] = '"'; | 205484 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 202947 | for(i=0; i<N; i++){ | 205485 | }; |
| 202948 | unsigned char c = ((unsigned const char*)zIn)[i]; | 205486 | assert( sizeof(aSpecial)==32 ); |
| 202949 | if( jsonIsOk[c] ){ | 205487 | assert( aSpecial['\b']=='b' ); |
| 202950 | p->zBuf[p->nUsed++] = c; | 205488 | assert( aSpecial['\f']=='f' ); |
| 202951 | }else if( c=='"' || c=='\\' ){ | 205489 | assert( aSpecial['\n']=='n' ); |
| 202952 | json_simple_escape: | 205490 | assert( aSpecial['\r']=='r' ); |
| 202953 | if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; | 205491 | assert( aSpecial['\t']=='t' ); |
| 202954 | p->zBuf[p->nUsed++] = '\\'; | 205492 | assert( c>=0 && c<sizeof(aSpecial) ); |
| 202955 | p->zBuf[p->nUsed++] = c; | 205493 | assert( p->nUsed+7 <= p->nAlloc ); |
| 202956 | }else if( c=='\'' ){ | 205494 | if( aSpecial[c] ){ |
| 202957 | p->zBuf[p->nUsed++] = c; | 205495 | p->zBuf[p->nUsed] = '\\'; |
| 202958 | }else{ | 205496 | p->zBuf[p->nUsed+1] = aSpecial[c]; |
| 202959 | static const char aSpecial[] = { | 205497 | p->nUsed += 2; |
| 202960 | 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, | 205498 | }else{ |
| 202961 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 205499 | p->zBuf[p->nUsed] = '\\'; |
| 202962 | }; | 205500 | p->zBuf[p->nUsed+1] = 'u'; |
| 202963 | assert( sizeof(aSpecial)==32 ); | 205501 | p->zBuf[p->nUsed+2] = '0'; |
| 202964 | assert( aSpecial['\b']=='b' ); | 205502 | p->zBuf[p->nUsed+3] = '0'; |
| 202965 | assert( aSpecial['\f']=='f' ); | 205503 | p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4]; |
| 202966 | assert( aSpecial['\n']=='n' ); | 205504 | p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf]; |
| 202967 | assert( aSpecial['\r']=='r' ); | 205505 | p->nUsed += 6; |
| 202968 | assert( aSpecial['\t']=='t' ); | ||
| 202969 | assert( c>=0 && c<sizeof(aSpecial) ); | ||
| 202970 | if( aSpecial[c] ){ | ||
| 202971 | c = aSpecial[c]; | ||
| 202972 | goto json_simple_escape; | ||
| 202973 | } | ||
| 202974 | if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; | ||
| 202975 | p->zBuf[p->nUsed++] = '\\'; | ||
| 202976 | p->zBuf[p->nUsed++] = 'u'; | ||
| 202977 | p->zBuf[p->nUsed++] = '0'; | ||
| 202978 | p->zBuf[p->nUsed++] = '0'; | ||
| 202979 | p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; | ||
| 202980 | p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; | ||
| 202981 | } | ||
| 202982 | } | 205506 | } |
| 202983 | p->zBuf[p->nUsed++] = '"'; | ||
| 202984 | assert( p->nUsed<p->nAlloc ); | ||
| 202985 | } | 205507 | } |
| 202986 | 205508 | ||
| 202987 | /* | 205509 | /* Append the N-byte string in zIn to the end of the JsonString string |
| 202988 | ** The zIn[0..N] string is a JSON5 string literal. Append to p a translation | 205510 | ** under construction. Enclose the string in double-quotes ("...") and |
| 202989 | ** of the string literal that standard JSON and that omits all JSON5 | 205511 | ** escape any double-quotes or backslash characters contained within the |
| 202990 | ** features. | 205512 | ** string. |
| 205513 | ** | ||
| 205514 | ** This routine is a high-runner. There is a measurable performance | ||
| 205515 | ** increase associated with unwinding the jsonIsOk[] loop. | ||
| 202991 | */ | 205516 | */ |
| 202992 | static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ | 205517 | static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ |
| 202993 | u32 i; | 205518 | u32 k; |
| 202994 | jsonAppendChar(p, '"'); | 205519 | u8 c; |
| 202995 | zIn++; | 205520 | const u8 *z = (const u8*)zIn; |
| 202996 | N -= 2; | 205521 | if( z==0 ) return; |
| 202997 | while( N>0 ){ | 205522 | if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; |
| 202998 | for(i=0; i<N && zIn[i]!='\\'; i++){} | 205523 | p->zBuf[p->nUsed++] = '"'; |
| 202999 | if( i>0 ){ | 205524 | while( 1 /*exit-by-break*/ ){ |
| 203000 | jsonAppendRawNZ(p, zIn, i); | 205525 | k = 0; |
| 203001 | zIn += i; | 205526 | /* The following while() is the 4-way unwound equivalent of |
| 203002 | N -= i; | 205527 | ** |
| 203003 | if( N==0 ) break; | 205528 | ** while( k<N && jsonIsOk[z[k]] ){ k++; } |
| 203004 | } | 205529 | */ |
| 203005 | assert( zIn[0]=='\\' ); | 205530 | while( 1 /* Exit by break */ ){ |
| 203006 | switch( (u8)zIn[1] ){ | 205531 | if( k+3>=N ){ |
| 203007 | case '\'': | 205532 | while( k<N && jsonIsOk[z[k]] ){ k++; } |
| 203008 | jsonAppendChar(p, '\''); | ||
| 203009 | break; | ||
| 203010 | case 'v': | ||
| 203011 | jsonAppendRawNZ(p, "\\u0009", 6); | ||
| 203012 | break; | ||
| 203013 | case 'x': | ||
| 203014 | jsonAppendRawNZ(p, "\\u00", 4); | ||
| 203015 | jsonAppendRawNZ(p, &zIn[2], 2); | ||
| 203016 | zIn += 2; | ||
| 203017 | N -= 2; | ||
| 203018 | break; | ||
| 203019 | case '0': | ||
| 203020 | jsonAppendRawNZ(p, "\\u0000", 6); | ||
| 203021 | break; | 205533 | break; |
| 203022 | case '\r': | 205534 | } |
| 203023 | if( zIn[2]=='\n' ){ | 205535 | if( !jsonIsOk[z[k]] ){ |
| 203024 | zIn++; | ||
| 203025 | N--; | ||
| 203026 | } | ||
| 203027 | break; | 205536 | break; |
| 203028 | case '\n': | 205537 | } |
| 205538 | if( !jsonIsOk[z[k+1]] ){ | ||
| 205539 | k += 1; | ||
| 203029 | break; | 205540 | break; |
| 203030 | case 0xe2: | 205541 | } |
| 203031 | assert( N>=4 ); | 205542 | if( !jsonIsOk[z[k+2]] ){ |
| 203032 | assert( 0x80==(u8)zIn[2] ); | 205543 | k += 2; |
| 203033 | assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); | ||
| 203034 | zIn += 2; | ||
| 203035 | N -= 2; | ||
| 203036 | break; | 205544 | break; |
| 203037 | default: | 205545 | } |
| 203038 | jsonAppendRawNZ(p, zIn, 2); | 205546 | if( !jsonIsOk[z[k+3]] ){ |
| 205547 | k += 3; | ||
| 203039 | break; | 205548 | break; |
| 205549 | }else{ | ||
| 205550 | k += 4; | ||
| 205551 | } | ||
| 203040 | } | 205552 | } |
| 203041 | zIn += 2; | 205553 | if( k>=N ){ |
| 203042 | N -= 2; | 205554 | if( k>0 ){ |
| 203043 | } | 205555 | memcpy(&p->zBuf[p->nUsed], z, k); |
| 203044 | jsonAppendChar(p, '"'); | 205556 | p->nUsed += k; |
| 203045 | } | 205557 | } |
| 203046 | 205558 | break; | |
| 203047 | /* | 205559 | } |
| 203048 | ** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation | 205560 | if( k>0 ){ |
| 203049 | ** of the string literal that standard JSON and that omits all JSON5 | 205561 | memcpy(&p->zBuf[p->nUsed], z, k); |
| 203050 | ** features. | 205562 | p->nUsed += k; |
| 203051 | */ | 205563 | z += k; |
| 203052 | static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ | 205564 | N -= k; |
| 203053 | if( zIn[0]=='+' ){ | 205565 | } |
| 203054 | zIn++; | 205566 | c = z[0]; |
| 203055 | N--; | 205567 | if( c=='"' || c=='\\' ){ |
| 203056 | }else if( zIn[0]=='-' ){ | 205568 | if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; |
| 203057 | jsonAppendChar(p, '-'); | 205569 | p->zBuf[p->nUsed++] = '\\'; |
| 203058 | zIn++; | 205570 | p->zBuf[p->nUsed++] = c; |
| 203059 | N--; | 205571 | }else if( c=='\'' ){ |
| 203060 | } | 205572 | p->zBuf[p->nUsed++] = c; |
| 203061 | if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ | ||
| 203062 | sqlite3_int64 i = 0; | ||
| 203063 | int rc = sqlite3DecOrHexToI64(zIn, &i); | ||
| 203064 | if( rc<=1 ){ | ||
| 203065 | jsonPrintf(100,p,"%lld",i); | ||
| 203066 | }else{ | 205573 | }else{ |
| 203067 | assert( rc==2 ); | 205574 | if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; |
| 203068 | jsonAppendRawNZ(p, "9.0e999", 7); | 205575 | jsonAppendControlChar(p, c); |
| 203069 | } | 205576 | } |
| 203070 | return; | 205577 | z++; |
| 203071 | } | ||
| 203072 | assert( N>0 ); | ||
| 203073 | jsonAppendRawNZ(p, zIn, N); | ||
| 203074 | } | ||
| 203075 | |||
| 203076 | /* | ||
| 203077 | ** The zIn[0..N] string is a JSON5 real literal. Append to p a translation | ||
| 203078 | ** of the string literal that standard JSON and that omits all JSON5 | ||
| 203079 | ** features. | ||
| 203080 | */ | ||
| 203081 | static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ | ||
| 203082 | u32 i; | ||
| 203083 | if( zIn[0]=='+' ){ | ||
| 203084 | zIn++; | ||
| 203085 | N--; | ||
| 203086 | }else if( zIn[0]=='-' ){ | ||
| 203087 | jsonAppendChar(p, '-'); | ||
| 203088 | zIn++; | ||
| 203089 | N--; | 205578 | N--; |
| 203090 | } | 205579 | } |
| 203091 | if( zIn[0]=='.' ){ | 205580 | p->zBuf[p->nUsed++] = '"'; |
| 203092 | jsonAppendChar(p, '0'); | 205581 | assert( p->nUsed<p->nAlloc ); |
| 203093 | } | ||
| 203094 | for(i=0; i<N; i++){ | ||
| 203095 | if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){ | ||
| 203096 | i++; | ||
| 203097 | jsonAppendRaw(p, zIn, i); | ||
| 203098 | zIn += i; | ||
| 203099 | N -= i; | ||
| 203100 | jsonAppendChar(p, '0'); | ||
| 203101 | break; | ||
| 203102 | } | ||
| 203103 | } | ||
| 203104 | if( N>0 ){ | ||
| 203105 | jsonAppendRawNZ(p, zIn, N); | ||
| 203106 | } | ||
| 203107 | } | 205582 | } |
| 203108 | 205583 | ||
| 203109 | |||
| 203110 | |||
| 203111 | /* | 205584 | /* |
| 203112 | ** Append a function parameter value to the JSON string under | 205585 | ** Append an sqlite3_value (such as a function parameter) to the JSON |
| 203113 | ** construction. | 205586 | ** string under construction in p. |
| 203114 | */ | 205587 | */ |
| 203115 | static void jsonAppendValue( | 205588 | static void jsonAppendSqlValue( |
| 203116 | JsonString *p, /* Append to this JSON string */ | 205589 | JsonString *p, /* Append to this JSON string */ |
| 203117 | sqlite3_value *pValue /* Value to append */ | 205590 | sqlite3_value *pValue /* Value to append */ |
| 203118 | ){ | 205591 | ){ |
| @@ -203142,290 +205615,127 @@ static void jsonAppendValue( | |||
| 203142 | break; | 205615 | break; |
| 203143 | } | 205616 | } |
| 203144 | default: { | 205617 | default: { |
| 203145 | if( p->bErr==0 ){ | 205618 | if( jsonFuncArgMightBeBinary(pValue) ){ |
| 205619 | JsonParse px; | ||
| 205620 | memset(&px, 0, sizeof(px)); | ||
| 205621 | px.aBlob = (u8*)sqlite3_value_blob(pValue); | ||
| 205622 | px.nBlob = sqlite3_value_bytes(pValue); | ||
| 205623 | jsonTranslateBlobToText(&px, 0, p); | ||
| 205624 | }else if( p->eErr==0 ){ | ||
| 203146 | sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); | 205625 | sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); |
| 203147 | p->bErr = 2; | 205626 | p->eErr = JSTRING_ERR; |
| 203148 | jsonReset(p); | 205627 | jsonStringReset(p); |
| 203149 | } | 205628 | } |
| 203150 | break; | 205629 | break; |
| 203151 | } | 205630 | } |
| 203152 | } | 205631 | } |
| 203153 | } | 205632 | } |
| 203154 | 205633 | ||
| 203155 | 205634 | /* Make the text in p (which is probably a generated JSON text string) | |
| 203156 | /* Make the JSON in p the result of the SQL function. | 205635 | ** the result of the SQL function. |
| 205636 | ** | ||
| 205637 | ** The JsonString is reset. | ||
| 203157 | ** | 205638 | ** |
| 203158 | ** The JSON string is reset. | 205639 | ** If pParse and ctx are both non-NULL, then the SQL string in p is |
| 205640 | ** loaded into the zJson field of the pParse object as a RCStr and the | ||
| 205641 | ** pParse is added to the cache. | ||
| 203159 | */ | 205642 | */ |
| 203160 | static void jsonResult(JsonString *p){ | 205643 | static void jsonReturnString( |
| 203161 | if( p->bErr==0 ){ | 205644 | JsonString *p, /* String to return */ |
| 203162 | if( p->bStatic ){ | 205645 | JsonParse *pParse, /* JSONB source or NULL */ |
| 205646 | sqlite3_context *ctx /* Where to cache */ | ||
| 205647 | ){ | ||
| 205648 | assert( (pParse!=0)==(ctx!=0) ); | ||
| 205649 | assert( ctx==0 || ctx==p->pCtx ); | ||
| 205650 | if( p->eErr==0 ){ | ||
| 205651 | int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); | ||
| 205652 | if( flags & JSON_BLOB ){ | ||
| 205653 | jsonReturnStringAsBlob(p); | ||
| 205654 | }else if( p->bStatic ){ | ||
| 203163 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, | 205655 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, |
| 203164 | SQLITE_TRANSIENT, SQLITE_UTF8); | 205656 | SQLITE_TRANSIENT, SQLITE_UTF8); |
| 203165 | }else if( jsonForceRCStr(p) ){ | 205657 | }else if( jsonStringTerminate(p) ){ |
| 203166 | sqlite3RCStrRef(p->zBuf); | 205658 | if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ |
| 203167 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, | 205659 | int rc; |
| 205660 | pParse->zJson = sqlite3RCStrRef(p->zBuf); | ||
| 205661 | pParse->nJson = p->nUsed; | ||
| 205662 | pParse->bJsonIsRCStr = 1; | ||
| 205663 | rc = jsonCacheInsert(ctx, pParse); | ||
| 205664 | if( rc==SQLITE_NOMEM ){ | ||
| 205665 | sqlite3_result_error_nomem(ctx); | ||
| 205666 | jsonStringReset(p); | ||
| 205667 | return; | ||
| 205668 | } | ||
| 205669 | } | ||
| 205670 | sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, | ||
| 203168 | sqlite3RCStrUnref, | 205671 | sqlite3RCStrUnref, |
| 203169 | SQLITE_UTF8); | 205672 | SQLITE_UTF8); |
| 205673 | }else{ | ||
| 205674 | sqlite3_result_error_nomem(p->pCtx); | ||
| 203170 | } | 205675 | } |
| 203171 | } | 205676 | }else if( p->eErr & JSTRING_OOM ){ |
| 203172 | if( p->bErr==1 ){ | ||
| 203173 | sqlite3_result_error_nomem(p->pCtx); | 205677 | sqlite3_result_error_nomem(p->pCtx); |
| 205678 | }else if( p->eErr & JSTRING_MALFORMED ){ | ||
| 205679 | sqlite3_result_error(p->pCtx, "malformed JSON", -1); | ||
| 203174 | } | 205680 | } |
| 203175 | jsonReset(p); | 205681 | jsonStringReset(p); |
| 203176 | } | 205682 | } |
| 203177 | 205683 | ||
| 203178 | /************************************************************************** | 205684 | /************************************************************************** |
| 203179 | ** Utility routines for dealing with JsonNode and JsonParse objects | 205685 | ** Utility routines for dealing with JsonParse objects |
| 203180 | **************************************************************************/ | 205686 | **************************************************************************/ |
| 203181 | 205687 | ||
| 203182 | /* | 205688 | /* |
| 203183 | ** Return the number of consecutive JsonNode slots need to represent | ||
| 203184 | ** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and | ||
| 203185 | ** OBJECT types, the number might be larger. | ||
| 203186 | ** | ||
| 203187 | ** Appended elements are not counted. The value returned is the number | ||
| 203188 | ** by which the JsonNode counter should increment in order to go to the | ||
| 203189 | ** next peer value. | ||
| 203190 | */ | ||
| 203191 | static u32 jsonNodeSize(JsonNode *pNode){ | ||
| 203192 | return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; | ||
| 203193 | } | ||
| 203194 | |||
| 203195 | /* | ||
| 203196 | ** Reclaim all memory allocated by a JsonParse object. But do not | 205689 | ** Reclaim all memory allocated by a JsonParse object. But do not |
| 203197 | ** delete the JsonParse object itself. | 205690 | ** delete the JsonParse object itself. |
| 203198 | */ | 205691 | */ |
| 203199 | static void jsonParseReset(JsonParse *pParse){ | 205692 | static void jsonParseReset(JsonParse *pParse){ |
| 203200 | while( pParse->pClup ){ | ||
| 203201 | JsonCleanup *pTask = pParse->pClup; | ||
| 203202 | pParse->pClup = pTask->pJCNext; | ||
| 203203 | pTask->xOp(pTask->pArg); | ||
| 203204 | sqlite3_free(pTask); | ||
| 203205 | } | ||
| 203206 | assert( pParse->nJPRef<=1 ); | 205693 | assert( pParse->nJPRef<=1 ); |
| 203207 | if( pParse->aNode ){ | ||
| 203208 | sqlite3_free(pParse->aNode); | ||
| 203209 | pParse->aNode = 0; | ||
| 203210 | } | ||
| 203211 | pParse->nNode = 0; | ||
| 203212 | pParse->nAlloc = 0; | ||
| 203213 | if( pParse->aUp ){ | ||
| 203214 | sqlite3_free(pParse->aUp); | ||
| 203215 | pParse->aUp = 0; | ||
| 203216 | } | ||
| 203217 | if( pParse->bJsonIsRCStr ){ | 205694 | if( pParse->bJsonIsRCStr ){ |
| 203218 | sqlite3RCStrUnref(pParse->zJson); | 205695 | sqlite3RCStrUnref(pParse->zJson); |
| 203219 | pParse->zJson = 0; | 205696 | pParse->zJson = 0; |
| 205697 | pParse->nJson = 0; | ||
| 203220 | pParse->bJsonIsRCStr = 0; | 205698 | pParse->bJsonIsRCStr = 0; |
| 203221 | } | 205699 | } |
| 203222 | if( pParse->zAlt ){ | 205700 | if( pParse->nBlobAlloc ){ |
| 203223 | sqlite3RCStrUnref(pParse->zAlt); | 205701 | sqlite3DbFree(pParse->db, pParse->aBlob); |
| 203224 | pParse->zAlt = 0; | 205702 | pParse->aBlob = 0; |
| 205703 | pParse->nBlob = 0; | ||
| 205704 | pParse->nBlobAlloc = 0; | ||
| 203225 | } | 205705 | } |
| 203226 | } | 205706 | } |
| 203227 | 205707 | ||
| 203228 | /* | 205708 | /* |
| 203229 | ** Free a JsonParse object that was obtained from sqlite3_malloc(). | 205709 | ** Decrement the reference count on the JsonParse object. When the |
| 203230 | ** | 205710 | ** count reaches zero, free the object. |
| 203231 | ** Note that destroying JsonParse might call sqlite3RCStrUnref() to | ||
| 203232 | ** destroy the zJson value. The RCStr object might recursively invoke | ||
| 203233 | ** JsonParse to destroy this pParse object again. Take care to ensure | ||
| 203234 | ** that this recursive destructor sequence terminates harmlessly. | ||
| 203235 | */ | 205711 | */ |
| 203236 | static void jsonParseFree(JsonParse *pParse){ | 205712 | static void jsonParseFree(JsonParse *pParse){ |
| 203237 | if( pParse->nJPRef>1 ){ | 205713 | if( pParse ){ |
| 203238 | pParse->nJPRef--; | 205714 | if( pParse->nJPRef>1 ){ |
| 203239 | }else{ | 205715 | pParse->nJPRef--; |
| 203240 | jsonParseReset(pParse); | 205716 | }else{ |
| 203241 | sqlite3_free(pParse); | 205717 | jsonParseReset(pParse); |
| 203242 | } | 205718 | sqlite3DbFree(pParse->db, pParse); |
| 203243 | } | ||
| 203244 | |||
| 203245 | /* | ||
| 203246 | ** Add a cleanup task to the JsonParse object. | ||
| 203247 | ** | ||
| 203248 | ** If an OOM occurs, the cleanup operation happens immediately | ||
| 203249 | ** and this function returns SQLITE_NOMEM. | ||
| 203250 | */ | ||
| 203251 | static int jsonParseAddCleanup( | ||
| 203252 | JsonParse *pParse, /* Add the cleanup task to this parser */ | ||
| 203253 | void(*xOp)(void*), /* The cleanup task */ | ||
| 203254 | void *pArg /* Argument to the cleanup */ | ||
| 203255 | ){ | ||
| 203256 | JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); | ||
| 203257 | if( pTask==0 ){ | ||
| 203258 | pParse->oom = 1; | ||
| 203259 | xOp(pArg); | ||
| 203260 | return SQLITE_ERROR; | ||
| 203261 | } | ||
| 203262 | pTask->pJCNext = pParse->pClup; | ||
| 203263 | pParse->pClup = pTask; | ||
| 203264 | pTask->xOp = xOp; | ||
| 203265 | pTask->pArg = pArg; | ||
| 203266 | return SQLITE_OK; | ||
| 203267 | } | ||
| 203268 | |||
| 203269 | /* | ||
| 203270 | ** Convert the JsonNode pNode into a pure JSON string and | ||
| 203271 | ** append to pOut. Subsubstructure is also included. Return | ||
| 203272 | ** the number of JsonNode objects that are encoded. | ||
| 203273 | */ | ||
| 203274 | static void jsonRenderNode( | ||
| 203275 | JsonParse *pParse, /* the complete parse of the JSON */ | ||
| 203276 | JsonNode *pNode, /* The node to render */ | ||
| 203277 | JsonString *pOut /* Write JSON here */ | ||
| 203278 | ){ | ||
| 203279 | assert( pNode!=0 ); | ||
| 203280 | while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ | ||
| 203281 | u32 idx = (u32)(pNode - pParse->aNode); | ||
| 203282 | u32 i = pParse->iSubst; | ||
| 203283 | while( 1 /*exit-by-break*/ ){ | ||
| 203284 | assert( i<pParse->nNode ); | ||
| 203285 | assert( pParse->aNode[i].eType==JSON_SUBST ); | ||
| 203286 | assert( pParse->aNode[i].eU==4 ); | ||
| 203287 | assert( pParse->aNode[i].u.iPrev<i ); | ||
| 203288 | if( pParse->aNode[i].n==idx ){ | ||
| 203289 | pNode = &pParse->aNode[i+1]; | ||
| 203290 | break; | ||
| 203291 | } | ||
| 203292 | i = pParse->aNode[i].u.iPrev; | ||
| 203293 | } | ||
| 203294 | } | ||
| 203295 | switch( pNode->eType ){ | ||
| 203296 | default: { | ||
| 203297 | assert( pNode->eType==JSON_NULL ); | ||
| 203298 | jsonAppendRawNZ(pOut, "null", 4); | ||
| 203299 | break; | ||
| 203300 | } | ||
| 203301 | case JSON_TRUE: { | ||
| 203302 | jsonAppendRawNZ(pOut, "true", 4); | ||
| 203303 | break; | ||
| 203304 | } | ||
| 203305 | case JSON_FALSE: { | ||
| 203306 | jsonAppendRawNZ(pOut, "false", 5); | ||
| 203307 | break; | ||
| 203308 | } | ||
| 203309 | case JSON_STRING: { | ||
| 203310 | assert( pNode->eU==1 ); | ||
| 203311 | if( pNode->jnFlags & JNODE_RAW ){ | ||
| 203312 | if( pNode->jnFlags & JNODE_LABEL ){ | ||
| 203313 | jsonAppendChar(pOut, '"'); | ||
| 203314 | jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); | ||
| 203315 | jsonAppendChar(pOut, '"'); | ||
| 203316 | }else{ | ||
| 203317 | jsonAppendString(pOut, pNode->u.zJContent, pNode->n); | ||
| 203318 | } | ||
| 203319 | }else if( pNode->jnFlags & JNODE_JSON5 ){ | ||
| 203320 | jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); | ||
| 203321 | }else{ | ||
| 203322 | assert( pNode->n>0 ); | ||
| 203323 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 203324 | } | ||
| 203325 | break; | ||
| 203326 | } | ||
| 203327 | case JSON_REAL: { | ||
| 203328 | assert( pNode->eU==1 ); | ||
| 203329 | if( pNode->jnFlags & JNODE_JSON5 ){ | ||
| 203330 | jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); | ||
| 203331 | }else{ | ||
| 203332 | assert( pNode->n>0 ); | ||
| 203333 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 203334 | } | ||
| 203335 | break; | ||
| 203336 | } | ||
| 203337 | case JSON_INT: { | ||
| 203338 | assert( pNode->eU==1 ); | ||
| 203339 | if( pNode->jnFlags & JNODE_JSON5 ){ | ||
| 203340 | jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); | ||
| 203341 | }else{ | ||
| 203342 | assert( pNode->n>0 ); | ||
| 203343 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 203344 | } | ||
| 203345 | break; | ||
| 203346 | } | ||
| 203347 | case JSON_ARRAY: { | ||
| 203348 | u32 j = 1; | ||
| 203349 | jsonAppendChar(pOut, '['); | ||
| 203350 | for(;;){ | ||
| 203351 | while( j<=pNode->n ){ | ||
| 203352 | if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ | ||
| 203353 | jsonAppendSeparator(pOut); | ||
| 203354 | jsonRenderNode(pParse, &pNode[j], pOut); | ||
| 203355 | } | ||
| 203356 | j += jsonNodeSize(&pNode[j]); | ||
| 203357 | } | ||
| 203358 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | ||
| 203359 | if( pParse->useMod==0 ) break; | ||
| 203360 | assert( pNode->eU==2 ); | ||
| 203361 | pNode = &pParse->aNode[pNode->u.iAppend]; | ||
| 203362 | j = 1; | ||
| 203363 | } | ||
| 203364 | jsonAppendChar(pOut, ']'); | ||
| 203365 | break; | ||
| 203366 | } | ||
| 203367 | case JSON_OBJECT: { | ||
| 203368 | u32 j = 1; | ||
| 203369 | jsonAppendChar(pOut, '{'); | ||
| 203370 | for(;;){ | ||
| 203371 | while( j<=pNode->n ){ | ||
| 203372 | if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ | ||
| 203373 | jsonAppendSeparator(pOut); | ||
| 203374 | jsonRenderNode(pParse, &pNode[j], pOut); | ||
| 203375 | jsonAppendChar(pOut, ':'); | ||
| 203376 | jsonRenderNode(pParse, &pNode[j+1], pOut); | ||
| 203377 | } | ||
| 203378 | j += 1 + jsonNodeSize(&pNode[j+1]); | ||
| 203379 | } | ||
| 203380 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | ||
| 203381 | if( pParse->useMod==0 ) break; | ||
| 203382 | assert( pNode->eU==2 ); | ||
| 203383 | pNode = &pParse->aNode[pNode->u.iAppend]; | ||
| 203384 | j = 1; | ||
| 203385 | } | ||
| 203386 | jsonAppendChar(pOut, '}'); | ||
| 203387 | break; | ||
| 203388 | } | 205719 | } |
| 203389 | } | 205720 | } |
| 203390 | } | 205721 | } |
| 203391 | 205722 | ||
| 203392 | /* | 205723 | /************************************************************************** |
| 203393 | ** Return a JsonNode and all its descendants as a JSON string. | 205724 | ** Utility routines for the JSON text parser |
| 203394 | */ | 205725 | **************************************************************************/ |
| 203395 | static void jsonReturnJson( | ||
| 203396 | JsonParse *pParse, /* The complete JSON */ | ||
| 203397 | JsonNode *pNode, /* Node to return */ | ||
| 203398 | sqlite3_context *pCtx, /* Return value for this function */ | ||
| 203399 | int bGenerateAlt /* Also store the rendered text in zAlt */ | ||
| 203400 | ){ | ||
| 203401 | JsonString s; | ||
| 203402 | if( pParse->oom ){ | ||
| 203403 | sqlite3_result_error_nomem(pCtx); | ||
| 203404 | return; | ||
| 203405 | } | ||
| 203406 | if( pParse->nErr==0 ){ | ||
| 203407 | jsonInit(&s, pCtx); | ||
| 203408 | jsonRenderNode(pParse, pNode, &s); | ||
| 203409 | if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ | ||
| 203410 | pParse->zAlt = sqlite3RCStrRef(s.zBuf); | ||
| 203411 | pParse->nAlt = s.nUsed; | ||
| 203412 | } | ||
| 203413 | jsonResult(&s); | ||
| 203414 | sqlite3_result_subtype(pCtx, JSON_SUBTYPE); | ||
| 203415 | } | ||
| 203416 | } | ||
| 203417 | 205726 | ||
| 203418 | /* | 205727 | /* |
| 203419 | ** Translate a single byte of Hex into an integer. | 205728 | ** Translate a single byte of Hex into an integer. |
| 203420 | ** This routine only works if h really is a valid hexadecimal | 205729 | ** This routine only gives a correct answer if h really is a valid hexadecimal |
| 203421 | ** character: 0..9a..fA..F | 205730 | ** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not |
| 205731 | ** assert() if the digit is not hex. | ||
| 203422 | */ | 205732 | */ |
| 203423 | static u8 jsonHexToInt(int h){ | 205733 | static u8 jsonHexToInt(int h){ |
| 203424 | assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); | 205734 | #ifdef SQLITE_ASCII |
| 205735 | h += 9*(1&(h>>6)); | ||
| 205736 | #endif | ||
| 203425 | #ifdef SQLITE_EBCDIC | 205737 | #ifdef SQLITE_EBCDIC |
| 203426 | h += 9*(1&~(h>>4)); | 205738 | h += 9*(1&~(h>>4)); |
| 203427 | #else | ||
| 203428 | h += 9*(1&(h>>6)); | ||
| 203429 | #endif | 205739 | #endif |
| 203430 | return (u8)(h & 0xf); | 205740 | return (u8)(h & 0xf); |
| 203431 | } | 205741 | } |
| @@ -203435,10 +205745,6 @@ static u8 jsonHexToInt(int h){ | |||
| 203435 | */ | 205745 | */ |
| 203436 | static u32 jsonHexToInt4(const char *z){ | 205746 | static u32 jsonHexToInt4(const char *z){ |
| 203437 | u32 v; | 205747 | u32 v; |
| 203438 | assert( sqlite3Isxdigit(z[0]) ); | ||
| 203439 | assert( sqlite3Isxdigit(z[1]) ); | ||
| 203440 | assert( sqlite3Isxdigit(z[2]) ); | ||
| 203441 | assert( sqlite3Isxdigit(z[3]) ); | ||
| 203442 | v = (jsonHexToInt(z[0])<<12) | 205748 | v = (jsonHexToInt(z[0])<<12) |
| 203443 | + (jsonHexToInt(z[1])<<8) | 205749 | + (jsonHexToInt(z[1])<<8) |
| 203444 | + (jsonHexToInt(z[2])<<4) | 205750 | + (jsonHexToInt(z[2])<<4) |
| @@ -203447,281 +205753,6 @@ static u32 jsonHexToInt4(const char *z){ | |||
| 203447 | } | 205753 | } |
| 203448 | 205754 | ||
| 203449 | /* | 205755 | /* |
| 203450 | ** Make the JsonNode the return value of the function. | ||
| 203451 | */ | ||
| 203452 | static void jsonReturn( | ||
| 203453 | JsonParse *pParse, /* Complete JSON parse tree */ | ||
| 203454 | JsonNode *pNode, /* Node to return */ | ||
| 203455 | sqlite3_context *pCtx /* Return value for this function */ | ||
| 203456 | ){ | ||
| 203457 | switch( pNode->eType ){ | ||
| 203458 | default: { | ||
| 203459 | assert( pNode->eType==JSON_NULL ); | ||
| 203460 | sqlite3_result_null(pCtx); | ||
| 203461 | break; | ||
| 203462 | } | ||
| 203463 | case JSON_TRUE: { | ||
| 203464 | sqlite3_result_int(pCtx, 1); | ||
| 203465 | break; | ||
| 203466 | } | ||
| 203467 | case JSON_FALSE: { | ||
| 203468 | sqlite3_result_int(pCtx, 0); | ||
| 203469 | break; | ||
| 203470 | } | ||
| 203471 | case JSON_INT: { | ||
| 203472 | sqlite3_int64 i = 0; | ||
| 203473 | int rc; | ||
| 203474 | int bNeg = 0; | ||
| 203475 | const char *z; | ||
| 203476 | |||
| 203477 | assert( pNode->eU==1 ); | ||
| 203478 | z = pNode->u.zJContent; | ||
| 203479 | if( z[0]=='-' ){ z++; bNeg = 1; } | ||
| 203480 | else if( z[0]=='+' ){ z++; } | ||
| 203481 | rc = sqlite3DecOrHexToI64(z, &i); | ||
| 203482 | if( rc<=1 ){ | ||
| 203483 | sqlite3_result_int64(pCtx, bNeg ? -i : i); | ||
| 203484 | }else if( rc==3 && bNeg ){ | ||
| 203485 | sqlite3_result_int64(pCtx, SMALLEST_INT64); | ||
| 203486 | }else{ | ||
| 203487 | goto to_double; | ||
| 203488 | } | ||
| 203489 | break; | ||
| 203490 | } | ||
| 203491 | case JSON_REAL: { | ||
| 203492 | double r; | ||
| 203493 | const char *z; | ||
| 203494 | assert( pNode->eU==1 ); | ||
| 203495 | to_double: | ||
| 203496 | z = pNode->u.zJContent; | ||
| 203497 | sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); | ||
| 203498 | sqlite3_result_double(pCtx, r); | ||
| 203499 | break; | ||
| 203500 | } | ||
| 203501 | case JSON_STRING: { | ||
| 203502 | if( pNode->jnFlags & JNODE_RAW ){ | ||
| 203503 | assert( pNode->eU==1 ); | ||
| 203504 | sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, | ||
| 203505 | SQLITE_TRANSIENT); | ||
| 203506 | }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ | ||
| 203507 | /* JSON formatted without any backslash-escapes */ | ||
| 203508 | assert( pNode->eU==1 ); | ||
| 203509 | sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, | ||
| 203510 | SQLITE_TRANSIENT); | ||
| 203511 | }else{ | ||
| 203512 | /* Translate JSON formatted string into raw text */ | ||
| 203513 | u32 i; | ||
| 203514 | u32 n = pNode->n; | ||
| 203515 | const char *z; | ||
| 203516 | char *zOut; | ||
| 203517 | u32 j; | ||
| 203518 | u32 nOut = n; | ||
| 203519 | assert( pNode->eU==1 ); | ||
| 203520 | z = pNode->u.zJContent; | ||
| 203521 | zOut = sqlite3_malloc( nOut+1 ); | ||
| 203522 | if( zOut==0 ){ | ||
| 203523 | sqlite3_result_error_nomem(pCtx); | ||
| 203524 | break; | ||
| 203525 | } | ||
| 203526 | for(i=1, j=0; i<n-1; i++){ | ||
| 203527 | char c = z[i]; | ||
| 203528 | if( c=='\\' ){ | ||
| 203529 | c = z[++i]; | ||
| 203530 | if( c=='u' ){ | ||
| 203531 | u32 v = jsonHexToInt4(z+i+1); | ||
| 203532 | i += 4; | ||
| 203533 | if( v==0 ) break; | ||
| 203534 | if( v<=0x7f ){ | ||
| 203535 | zOut[j++] = (char)v; | ||
| 203536 | }else if( v<=0x7ff ){ | ||
| 203537 | zOut[j++] = (char)(0xc0 | (v>>6)); | ||
| 203538 | zOut[j++] = 0x80 | (v&0x3f); | ||
| 203539 | }else{ | ||
| 203540 | u32 vlo; | ||
| 203541 | if( (v&0xfc00)==0xd800 | ||
| 203542 | && i<n-6 | ||
| 203543 | && z[i+1]=='\\' | ||
| 203544 | && z[i+2]=='u' | ||
| 203545 | && ((vlo = jsonHexToInt4(z+i+3))&0xfc00)==0xdc00 | ||
| 203546 | ){ | ||
| 203547 | /* We have a surrogate pair */ | ||
| 203548 | v = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; | ||
| 203549 | i += 6; | ||
| 203550 | zOut[j++] = 0xf0 | (v>>18); | ||
| 203551 | zOut[j++] = 0x80 | ((v>>12)&0x3f); | ||
| 203552 | zOut[j++] = 0x80 | ((v>>6)&0x3f); | ||
| 203553 | zOut[j++] = 0x80 | (v&0x3f); | ||
| 203554 | }else{ | ||
| 203555 | zOut[j++] = 0xe0 | (v>>12); | ||
| 203556 | zOut[j++] = 0x80 | ((v>>6)&0x3f); | ||
| 203557 | zOut[j++] = 0x80 | (v&0x3f); | ||
| 203558 | } | ||
| 203559 | } | ||
| 203560 | continue; | ||
| 203561 | }else if( c=='b' ){ | ||
| 203562 | c = '\b'; | ||
| 203563 | }else if( c=='f' ){ | ||
| 203564 | c = '\f'; | ||
| 203565 | }else if( c=='n' ){ | ||
| 203566 | c = '\n'; | ||
| 203567 | }else if( c=='r' ){ | ||
| 203568 | c = '\r'; | ||
| 203569 | }else if( c=='t' ){ | ||
| 203570 | c = '\t'; | ||
| 203571 | }else if( c=='v' ){ | ||
| 203572 | c = '\v'; | ||
| 203573 | }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){ | ||
| 203574 | /* pass through unchanged */ | ||
| 203575 | }else if( c=='0' ){ | ||
| 203576 | c = 0; | ||
| 203577 | }else if( c=='x' ){ | ||
| 203578 | c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]); | ||
| 203579 | i += 2; | ||
| 203580 | }else if( c=='\r' && z[i+1]=='\n' ){ | ||
| 203581 | i++; | ||
| 203582 | continue; | ||
| 203583 | }else if( 0xe2==(u8)c ){ | ||
| 203584 | assert( 0x80==(u8)z[i+1] ); | ||
| 203585 | assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] ); | ||
| 203586 | i += 2; | ||
| 203587 | continue; | ||
| 203588 | }else{ | ||
| 203589 | continue; | ||
| 203590 | } | ||
| 203591 | } /* end if( c=='\\' ) */ | ||
| 203592 | zOut[j++] = c; | ||
| 203593 | } /* end for() */ | ||
| 203594 | zOut[j] = 0; | ||
| 203595 | sqlite3_result_text(pCtx, zOut, j, sqlite3_free); | ||
| 203596 | } | ||
| 203597 | break; | ||
| 203598 | } | ||
| 203599 | case JSON_ARRAY: | ||
| 203600 | case JSON_OBJECT: { | ||
| 203601 | jsonReturnJson(pParse, pNode, pCtx, 0); | ||
| 203602 | break; | ||
| 203603 | } | ||
| 203604 | } | ||
| 203605 | } | ||
| 203606 | |||
| 203607 | /* Forward reference */ | ||
| 203608 | static int jsonParseAddNode(JsonParse*,u32,u32,const char*); | ||
| 203609 | |||
| 203610 | /* | ||
| 203611 | ** A macro to hint to the compiler that a function should not be | ||
| 203612 | ** inlined. | ||
| 203613 | */ | ||
| 203614 | #if defined(__GNUC__) | ||
| 203615 | # define JSON_NOINLINE __attribute__((noinline)) | ||
| 203616 | #elif defined(_MSC_VER) && _MSC_VER>=1310 | ||
| 203617 | # define JSON_NOINLINE __declspec(noinline) | ||
| 203618 | #else | ||
| 203619 | # define JSON_NOINLINE | ||
| 203620 | #endif | ||
| 203621 | |||
| 203622 | |||
| 203623 | /* | ||
| 203624 | ** Add a single node to pParse->aNode after first expanding the | ||
| 203625 | ** size of the aNode array. Return the index of the new node. | ||
| 203626 | ** | ||
| 203627 | ** If an OOM error occurs, set pParse->oom and return -1. | ||
| 203628 | */ | ||
| 203629 | static JSON_NOINLINE int jsonParseAddNodeExpand( | ||
| 203630 | JsonParse *pParse, /* Append the node to this object */ | ||
| 203631 | u32 eType, /* Node type */ | ||
| 203632 | u32 n, /* Content size or sub-node count */ | ||
| 203633 | const char *zContent /* Content */ | ||
| 203634 | ){ | ||
| 203635 | u32 nNew; | ||
| 203636 | JsonNode *pNew; | ||
| 203637 | assert( pParse->nNode>=pParse->nAlloc ); | ||
| 203638 | if( pParse->oom ) return -1; | ||
| 203639 | nNew = pParse->nAlloc*2 + 10; | ||
| 203640 | pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); | ||
| 203641 | if( pNew==0 ){ | ||
| 203642 | pParse->oom = 1; | ||
| 203643 | return -1; | ||
| 203644 | } | ||
| 203645 | pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); | ||
| 203646 | pParse->aNode = pNew; | ||
| 203647 | assert( pParse->nNode<pParse->nAlloc ); | ||
| 203648 | return jsonParseAddNode(pParse, eType, n, zContent); | ||
| 203649 | } | ||
| 203650 | |||
| 203651 | /* | ||
| 203652 | ** Create a new JsonNode instance based on the arguments and append that | ||
| 203653 | ** instance to the JsonParse. Return the index in pParse->aNode[] of the | ||
| 203654 | ** new node, or -1 if a memory allocation fails. | ||
| 203655 | */ | ||
| 203656 | static int jsonParseAddNode( | ||
| 203657 | JsonParse *pParse, /* Append the node to this object */ | ||
| 203658 | u32 eType, /* Node type */ | ||
| 203659 | u32 n, /* Content size or sub-node count */ | ||
| 203660 | const char *zContent /* Content */ | ||
| 203661 | ){ | ||
| 203662 | JsonNode *p; | ||
| 203663 | assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); | ||
| 203664 | if( pParse->nNode>=pParse->nAlloc ){ | ||
| 203665 | return jsonParseAddNodeExpand(pParse, eType, n, zContent); | ||
| 203666 | } | ||
| 203667 | assert( pParse->aNode!=0 ); | ||
| 203668 | p = &pParse->aNode[pParse->nNode]; | ||
| 203669 | assert( p!=0 ); | ||
| 203670 | p->eType = (u8)(eType & 0xff); | ||
| 203671 | p->jnFlags = (u8)(eType >> 8); | ||
| 203672 | VVA( p->eU = zContent ? 1 : 0 ); | ||
| 203673 | p->n = n; | ||
| 203674 | p->u.zJContent = zContent; | ||
| 203675 | return pParse->nNode++; | ||
| 203676 | } | ||
| 203677 | |||
| 203678 | /* | ||
| 203679 | ** Add an array of new nodes to the current pParse->aNode array. | ||
| 203680 | ** Return the index of the first node added. | ||
| 203681 | ** | ||
| 203682 | ** If an OOM error occurs, set pParse->oom. | ||
| 203683 | */ | ||
| 203684 | static void jsonParseAddNodeArray( | ||
| 203685 | JsonParse *pParse, /* Append the node to this object */ | ||
| 203686 | JsonNode *aNode, /* Array of nodes to add */ | ||
| 203687 | u32 nNode /* Number of elements in aNew */ | ||
| 203688 | ){ | ||
| 203689 | assert( aNode!=0 ); | ||
| 203690 | assert( nNode>=1 ); | ||
| 203691 | if( pParse->nNode + nNode > pParse->nAlloc ){ | ||
| 203692 | u32 nNew = pParse->nNode + nNode; | ||
| 203693 | JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); | ||
| 203694 | if( aNew==0 ){ | ||
| 203695 | pParse->oom = 1; | ||
| 203696 | return; | ||
| 203697 | } | ||
| 203698 | pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); | ||
| 203699 | pParse->aNode = aNew; | ||
| 203700 | } | ||
| 203701 | memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); | ||
| 203702 | pParse->nNode += nNode; | ||
| 203703 | } | ||
| 203704 | |||
| 203705 | /* | ||
| 203706 | ** Add a new JSON_SUBST node. The node immediately following | ||
| 203707 | ** this new node will be the substitute content for iNode. | ||
| 203708 | */ | ||
| 203709 | static int jsonParseAddSubstNode( | ||
| 203710 | JsonParse *pParse, /* Add the JSON_SUBST here */ | ||
| 203711 | u32 iNode /* References this node */ | ||
| 203712 | ){ | ||
| 203713 | int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); | ||
| 203714 | if( pParse->oom ) return -1; | ||
| 203715 | pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; | ||
| 203716 | pParse->aNode[idx].eU = 4; | ||
| 203717 | pParse->aNode[idx].u.iPrev = pParse->iSubst; | ||
| 203718 | pParse->iSubst = idx; | ||
| 203719 | pParse->hasMod = 1; | ||
| 203720 | pParse->useMod = 1; | ||
| 203721 | return idx; | ||
| 203722 | } | ||
| 203723 | |||
| 203724 | /* | ||
| 203725 | ** Return true if z[] begins with 2 (or more) hexadecimal digits | 205756 | ** Return true if z[] begins with 2 (or more) hexadecimal digits |
| 203726 | */ | 205757 | */ |
| 203727 | static int jsonIs2Hex(const char *z){ | 205758 | static int jsonIs2Hex(const char *z){ |
| @@ -203874,63 +205905,503 @@ static const struct NanInfName { | |||
| 203874 | char *zMatch; | 205905 | char *zMatch; |
| 203875 | char *zRepl; | 205906 | char *zRepl; |
| 203876 | } aNanInfName[] = { | 205907 | } aNanInfName[] = { |
| 203877 | { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, | 205908 | { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, |
| 203878 | { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, | 205909 | { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, |
| 203879 | { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, | 205910 | { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, |
| 203880 | { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, | 205911 | { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, |
| 203881 | { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, | 205912 | { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, |
| 203882 | }; | 205913 | }; |
| 203883 | 205914 | ||
| 205915 | |||
| 205916 | /* | ||
| 205917 | ** Report the wrong number of arguments for json_insert(), json_replace() | ||
| 205918 | ** or json_set(). | ||
| 205919 | */ | ||
| 205920 | static void jsonWrongNumArgs( | ||
| 205921 | sqlite3_context *pCtx, | ||
| 205922 | const char *zFuncName | ||
| 205923 | ){ | ||
| 205924 | char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", | ||
| 205925 | zFuncName); | ||
| 205926 | sqlite3_result_error(pCtx, zMsg, -1); | ||
| 205927 | sqlite3_free(zMsg); | ||
| 205928 | } | ||
| 205929 | |||
| 205930 | /**************************************************************************** | ||
| 205931 | ** Utility routines for dealing with the binary BLOB representation of JSON | ||
| 205932 | ****************************************************************************/ | ||
| 205933 | |||
| 205934 | /* | ||
| 205935 | ** Expand pParse->aBlob so that it holds at least N bytes. | ||
| 205936 | ** | ||
| 205937 | ** Return the number of errors. | ||
| 205938 | */ | ||
| 205939 | static int jsonBlobExpand(JsonParse *pParse, u32 N){ | ||
| 205940 | u8 *aNew; | ||
| 205941 | u32 t; | ||
| 205942 | assert( N>pParse->nBlobAlloc ); | ||
| 205943 | if( pParse->nBlobAlloc==0 ){ | ||
| 205944 | t = 100; | ||
| 205945 | }else{ | ||
| 205946 | t = pParse->nBlobAlloc*2; | ||
| 205947 | } | ||
| 205948 | if( t<N ) t = N+100; | ||
| 205949 | aNew = sqlite3DbRealloc(pParse->db, pParse->aBlob, t); | ||
| 205950 | if( aNew==0 ){ pParse->oom = 1; return 1; } | ||
| 205951 | pParse->aBlob = aNew; | ||
| 205952 | pParse->nBlobAlloc = t; | ||
| 205953 | return 0; | ||
| 205954 | } | ||
| 205955 | |||
| 205956 | /* | ||
| 205957 | ** If pParse->aBlob is not previously editable (because it is taken | ||
| 205958 | ** from sqlite3_value_blob(), as indicated by the fact that | ||
| 205959 | ** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable | ||
| 205960 | ** by making a copy into space obtained from malloc. | ||
| 205961 | ** | ||
| 205962 | ** Return true on success. Return false on OOM. | ||
| 205963 | */ | ||
| 205964 | static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ | ||
| 205965 | u8 *aOld; | ||
| 205966 | u32 nSize; | ||
| 205967 | assert( !pParse->bReadOnly ); | ||
| 205968 | if( pParse->oom ) return 0; | ||
| 205969 | if( pParse->nBlobAlloc>0 ) return 1; | ||
| 205970 | aOld = pParse->aBlob; | ||
| 205971 | nSize = pParse->nBlob + nExtra; | ||
| 205972 | pParse->aBlob = 0; | ||
| 205973 | if( jsonBlobExpand(pParse, nSize) ){ | ||
| 205974 | return 0; | ||
| 205975 | } | ||
| 205976 | assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); | ||
| 205977 | memcpy(pParse->aBlob, aOld, pParse->nBlob); | ||
| 205978 | return 1; | ||
| 205979 | } | ||
| 205980 | |||
| 205981 | /* Expand pParse->aBlob and append one bytes. | ||
| 205982 | */ | ||
| 205983 | static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( | ||
| 205984 | JsonParse *pParse, | ||
| 205985 | u8 c | ||
| 205986 | ){ | ||
| 205987 | jsonBlobExpand(pParse, pParse->nBlob+1); | ||
| 205988 | if( pParse->oom==0 ){ | ||
| 205989 | assert( pParse->nBlob+1<=pParse->nBlobAlloc ); | ||
| 205990 | pParse->aBlob[pParse->nBlob++] = c; | ||
| 205991 | } | ||
| 205992 | } | ||
| 205993 | |||
| 205994 | /* Append a single character. | ||
| 205995 | */ | ||
| 205996 | static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ | ||
| 205997 | if( pParse->nBlob >= pParse->nBlobAlloc ){ | ||
| 205998 | jsonBlobExpandAndAppendOneByte(pParse, c); | ||
| 205999 | }else{ | ||
| 206000 | pParse->aBlob[pParse->nBlob++] = c; | ||
| 206001 | } | ||
| 206002 | } | ||
| 206003 | |||
| 206004 | /* Slow version of jsonBlobAppendNode() that first resizes the | ||
| 206005 | ** pParse->aBlob structure. | ||
| 206006 | */ | ||
| 206007 | static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); | ||
| 206008 | static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( | ||
| 206009 | JsonParse *pParse, | ||
| 206010 | u8 eType, | ||
| 206011 | u32 szPayload, | ||
| 206012 | const void *aPayload | ||
| 206013 | ){ | ||
| 206014 | if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; | ||
| 206015 | jsonBlobAppendNode(pParse, eType, szPayload, aPayload); | ||
| 206016 | } | ||
| 206017 | |||
| 206018 | |||
| 206019 | /* Append an node type byte together with the payload size and | ||
| 206020 | ** possibly also the payload. | ||
| 206021 | ** | ||
| 206022 | ** If aPayload is not NULL, then it is a pointer to the payload which | ||
| 206023 | ** is also appended. If aPayload is NULL, the pParse->aBlob[] array | ||
| 206024 | ** is resized (if necessary) so that it is big enough to hold the | ||
| 206025 | ** payload, but the payload is not appended and pParse->nBlob is left | ||
| 206026 | ** pointing to where the first byte of payload will eventually be. | ||
| 206027 | */ | ||
| 206028 | static void jsonBlobAppendNode( | ||
| 206029 | JsonParse *pParse, /* The JsonParse object under construction */ | ||
| 206030 | u8 eType, /* Node type. One of JSONB_* */ | ||
| 206031 | u32 szPayload, /* Number of bytes of payload */ | ||
| 206032 | const void *aPayload /* The payload. Might be NULL */ | ||
| 206033 | ){ | ||
| 206034 | u8 *a; | ||
| 206035 | if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ | ||
| 206036 | jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); | ||
| 206037 | return; | ||
| 206038 | } | ||
| 206039 | assert( pParse->aBlob!=0 ); | ||
| 206040 | a = &pParse->aBlob[pParse->nBlob]; | ||
| 206041 | if( szPayload<=11 ){ | ||
| 206042 | a[0] = eType | (szPayload<<4); | ||
| 206043 | pParse->nBlob += 1; | ||
| 206044 | }else if( szPayload<=0xff ){ | ||
| 206045 | a[0] = eType | 0xc0; | ||
| 206046 | a[1] = szPayload & 0xff; | ||
| 206047 | pParse->nBlob += 2; | ||
| 206048 | }else if( szPayload<=0xffff ){ | ||
| 206049 | a[0] = eType | 0xd0; | ||
| 206050 | a[1] = (szPayload >> 8) & 0xff; | ||
| 206051 | a[2] = szPayload & 0xff; | ||
| 206052 | pParse->nBlob += 3; | ||
| 206053 | }else{ | ||
| 206054 | a[0] = eType | 0xe0; | ||
| 206055 | a[1] = (szPayload >> 24) & 0xff; | ||
| 206056 | a[2] = (szPayload >> 16) & 0xff; | ||
| 206057 | a[3] = (szPayload >> 8) & 0xff; | ||
| 206058 | a[4] = szPayload & 0xff; | ||
| 206059 | pParse->nBlob += 5; | ||
| 206060 | } | ||
| 206061 | if( aPayload ){ | ||
| 206062 | pParse->nBlob += szPayload; | ||
| 206063 | memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); | ||
| 206064 | } | ||
| 206065 | } | ||
| 206066 | |||
| 206067 | /* Change the payload size for the node at index i to be szPayload. | ||
| 206068 | */ | ||
| 206069 | static int jsonBlobChangePayloadSize( | ||
| 206070 | JsonParse *pParse, | ||
| 206071 | u32 i, | ||
| 206072 | u32 szPayload | ||
| 206073 | ){ | ||
| 206074 | u8 *a; | ||
| 206075 | u8 szType; | ||
| 206076 | u8 nExtra; | ||
| 206077 | u8 nNeeded; | ||
| 206078 | int delta; | ||
| 206079 | if( pParse->oom ) return 0; | ||
| 206080 | a = &pParse->aBlob[i]; | ||
| 206081 | szType = a[0]>>4; | ||
| 206082 | if( szType<=11 ){ | ||
| 206083 | nExtra = 0; | ||
| 206084 | }else if( szType==12 ){ | ||
| 206085 | nExtra = 1; | ||
| 206086 | }else if( szType==13 ){ | ||
| 206087 | nExtra = 2; | ||
| 206088 | }else{ | ||
| 206089 | nExtra = 4; | ||
| 206090 | } | ||
| 206091 | if( szPayload<=11 ){ | ||
| 206092 | nNeeded = 0; | ||
| 206093 | }else if( szPayload<=0xff ){ | ||
| 206094 | nNeeded = 1; | ||
| 206095 | }else if( szPayload<=0xffff ){ | ||
| 206096 | nNeeded = 2; | ||
| 206097 | }else{ | ||
| 206098 | nNeeded = 4; | ||
| 206099 | } | ||
| 206100 | delta = nNeeded - nExtra; | ||
| 206101 | if( delta ){ | ||
| 206102 | u32 newSize = pParse->nBlob + delta; | ||
| 206103 | if( delta>0 ){ | ||
| 206104 | if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ | ||
| 206105 | return 0; /* OOM error. Error state recorded in pParse->oom. */ | ||
| 206106 | } | ||
| 206107 | a = &pParse->aBlob[i]; | ||
| 206108 | memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); | ||
| 206109 | }else{ | ||
| 206110 | memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); | ||
| 206111 | } | ||
| 206112 | pParse->nBlob = newSize; | ||
| 206113 | } | ||
| 206114 | if( nNeeded==0 ){ | ||
| 206115 | a[0] = (a[0] & 0x0f) | (szPayload<<4); | ||
| 206116 | }else if( nNeeded==1 ){ | ||
| 206117 | a[0] = (a[0] & 0x0f) | 0xc0; | ||
| 206118 | a[1] = szPayload & 0xff; | ||
| 206119 | }else if( nNeeded==2 ){ | ||
| 206120 | a[0] = (a[0] & 0x0f) | 0xd0; | ||
| 206121 | a[1] = (szPayload >> 8) & 0xff; | ||
| 206122 | a[2] = szPayload & 0xff; | ||
| 206123 | }else{ | ||
| 206124 | a[0] = (a[0] & 0x0f) | 0xe0; | ||
| 206125 | a[1] = (szPayload >> 24) & 0xff; | ||
| 206126 | a[2] = (szPayload >> 16) & 0xff; | ||
| 206127 | a[3] = (szPayload >> 8) & 0xff; | ||
| 206128 | a[4] = szPayload & 0xff; | ||
| 206129 | } | ||
| 206130 | return delta; | ||
| 206131 | } | ||
| 206132 | |||
| 206133 | /* | ||
| 206134 | ** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, | ||
| 206135 | ** then set *pOp to JSONB_TEXTJ and return true. If not, do not make | ||
| 206136 | ** any changes to *pOp and return false. | ||
| 206137 | */ | ||
| 206138 | static int jsonIs4HexB(const char *z, int *pOp){ | ||
| 206139 | if( z[0]!='u' ) return 0; | ||
| 206140 | if( !jsonIs4Hex(&z[1]) ) return 0; | ||
| 206141 | *pOp = JSONB_TEXTJ; | ||
| 206142 | return 1; | ||
| 206143 | } | ||
| 206144 | |||
| 206145 | /* | ||
| 206146 | ** Check a single element of the JSONB in pParse for validity. | ||
| 206147 | ** | ||
| 206148 | ** The element to be checked starts at offset i and must end at on the | ||
| 206149 | ** last byte before iEnd. | ||
| 206150 | ** | ||
| 206151 | ** Return 0 if everything is correct. Return the 1-based byte offset of the | ||
| 206152 | ** error if a problem is detected. (In other words, if the error is at offset | ||
| 206153 | ** 0, return 1). | ||
| 206154 | */ | ||
| 206155 | static u32 jsonbValidityCheck( | ||
| 206156 | const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ | ||
| 206157 | u32 i, /* Start of element as pParse->aBlob[i] */ | ||
| 206158 | u32 iEnd, /* One more than the last byte of the element */ | ||
| 206159 | u32 iDepth /* Current nesting depth */ | ||
| 206160 | ){ | ||
| 206161 | u32 n, sz, j, k; | ||
| 206162 | const u8 *z; | ||
| 206163 | u8 x; | ||
| 206164 | if( iDepth>JSON_MAX_DEPTH ) return i+1; | ||
| 206165 | sz = 0; | ||
| 206166 | n = jsonbPayloadSize(pParse, i, &sz); | ||
| 206167 | if( NEVER(n==0) ) return i+1; /* Checked by caller */ | ||
| 206168 | if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ | ||
| 206169 | z = pParse->aBlob; | ||
| 206170 | x = z[i] & 0x0f; | ||
| 206171 | switch( x ){ | ||
| 206172 | case JSONB_NULL: | ||
| 206173 | case JSONB_TRUE: | ||
| 206174 | case JSONB_FALSE: { | ||
| 206175 | return n+sz==1 ? 0 : i+1; | ||
| 206176 | } | ||
| 206177 | case JSONB_INT: { | ||
| 206178 | if( sz<1 ) return i+1; | ||
| 206179 | j = i+n; | ||
| 206180 | if( z[j]=='-' ){ | ||
| 206181 | j++; | ||
| 206182 | if( sz<2 ) return i+1; | ||
| 206183 | } | ||
| 206184 | k = i+n+sz; | ||
| 206185 | while( j<k ){ | ||
| 206186 | if( sqlite3Isdigit(z[j]) ){ | ||
| 206187 | j++; | ||
| 206188 | }else{ | ||
| 206189 | return j+1; | ||
| 206190 | } | ||
| 206191 | } | ||
| 206192 | return 0; | ||
| 206193 | } | ||
| 206194 | case JSONB_INT5: { | ||
| 206195 | if( sz<3 ) return i+1; | ||
| 206196 | j = i+n; | ||
| 206197 | if( z[j]=='-' ){ | ||
| 206198 | if( sz<4 ) return i+1; | ||
| 206199 | j++; | ||
| 206200 | } | ||
| 206201 | if( z[j]!='0' ) return i+1; | ||
| 206202 | if( z[j+1]!='x' && z[j+1]!='X' ) return j+2; | ||
| 206203 | j += 2; | ||
| 206204 | k = i+n+sz; | ||
| 206205 | while( j<k ){ | ||
| 206206 | if( sqlite3Isxdigit(z[j]) ){ | ||
| 206207 | j++; | ||
| 206208 | }else{ | ||
| 206209 | return j+1; | ||
| 206210 | } | ||
| 206211 | } | ||
| 206212 | return 0; | ||
| 206213 | } | ||
| 206214 | case JSONB_FLOAT: | ||
| 206215 | case JSONB_FLOAT5: { | ||
| 206216 | u8 seen = 0; /* 0: initial. 1: '.' seen 2: 'e' seen */ | ||
| 206217 | if( sz<2 ) return i+1; | ||
| 206218 | j = i+n; | ||
| 206219 | k = j+sz; | ||
| 206220 | if( z[j]=='-' ){ | ||
| 206221 | j++; | ||
| 206222 | if( sz<3 ) return i+1; | ||
| 206223 | } | ||
| 206224 | if( z[j]=='.' ){ | ||
| 206225 | if( x==JSONB_FLOAT ) return j+1; | ||
| 206226 | if( !sqlite3Isdigit(z[j+1]) ) return j+1; | ||
| 206227 | j += 2; | ||
| 206228 | seen = 1; | ||
| 206229 | }else if( z[j]=='0' && x==JSONB_FLOAT ){ | ||
| 206230 | if( j+3>k ) return j+1; | ||
| 206231 | if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; | ||
| 206232 | j++; | ||
| 206233 | } | ||
| 206234 | for(; j<k; j++){ | ||
| 206235 | if( sqlite3Isdigit(z[j]) ) continue; | ||
| 206236 | if( z[j]=='.' ){ | ||
| 206237 | if( seen>0 ) return j+1; | ||
| 206238 | if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ | ||
| 206239 | return j+1; | ||
| 206240 | } | ||
| 206241 | seen = 1; | ||
| 206242 | continue; | ||
| 206243 | } | ||
| 206244 | if( z[j]=='e' || z[j]=='E' ){ | ||
| 206245 | if( seen==2 ) return j+1; | ||
| 206246 | if( j==k-1 ) return j+1; | ||
| 206247 | if( z[j+1]=='+' || z[j+1]=='-' ){ | ||
| 206248 | j++; | ||
| 206249 | if( j==k-1 ) return j+1; | ||
| 206250 | } | ||
| 206251 | seen = 2; | ||
| 206252 | continue; | ||
| 206253 | } | ||
| 206254 | return j+1; | ||
| 206255 | } | ||
| 206256 | if( seen==0 ) return i+1; | ||
| 206257 | return 0; | ||
| 206258 | } | ||
| 206259 | case JSONB_TEXT: { | ||
| 206260 | j = i+n; | ||
| 206261 | k = j+sz; | ||
| 206262 | while( j<k ){ | ||
| 206263 | if( !jsonIsOk[z[j]] && z[j]!='\'' ) return j+1; | ||
| 206264 | j++; | ||
| 206265 | } | ||
| 206266 | return 0; | ||
| 206267 | } | ||
| 206268 | case JSONB_TEXTJ: | ||
| 206269 | case JSONB_TEXT5: { | ||
| 206270 | j = i+n; | ||
| 206271 | k = j+sz; | ||
| 206272 | while( j<k ){ | ||
| 206273 | if( !jsonIsOk[z[j]] && z[j]!='\'' ){ | ||
| 206274 | if( z[j]=='"' ){ | ||
| 206275 | if( x==JSONB_TEXTJ ) return j+1; | ||
| 206276 | }else if( z[j]<=0x1f ){ | ||
| 206277 | /* Control characters in JSON5 string literals are ok */ | ||
| 206278 | if( x==JSONB_TEXTJ ) return j+1; | ||
| 206279 | }else if( NEVER(z[j]!='\\') || j+1>=k ){ | ||
| 206280 | return j+1; | ||
| 206281 | }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ | ||
| 206282 | j++; | ||
| 206283 | }else if( z[j+1]=='u' ){ | ||
| 206284 | if( j+5>=k ) return j+1; | ||
| 206285 | if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; | ||
| 206286 | j++; | ||
| 206287 | }else if( x!=JSONB_TEXT5 ){ | ||
| 206288 | return j+1; | ||
| 206289 | }else{ | ||
| 206290 | u32 c = 0; | ||
| 206291 | u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); | ||
| 206292 | if( c==JSON_INVALID_CHAR ) return j+1; | ||
| 206293 | j += szC - 1; | ||
| 206294 | } | ||
| 206295 | } | ||
| 206296 | j++; | ||
| 206297 | } | ||
| 206298 | return 0; | ||
| 206299 | } | ||
| 206300 | case JSONB_TEXTRAW: { | ||
| 206301 | return 0; | ||
| 206302 | } | ||
| 206303 | case JSONB_ARRAY: { | ||
| 206304 | u32 sub; | ||
| 206305 | j = i+n; | ||
| 206306 | k = j+sz; | ||
| 206307 | while( j<k ){ | ||
| 206308 | sz = 0; | ||
| 206309 | n = jsonbPayloadSize(pParse, j, &sz); | ||
| 206310 | if( n==0 ) return j+1; | ||
| 206311 | if( j+n+sz>k ) return j+1; | ||
| 206312 | sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); | ||
| 206313 | if( sub ) return sub; | ||
| 206314 | j += n + sz; | ||
| 206315 | } | ||
| 206316 | assert( j==k ); | ||
| 206317 | return 0; | ||
| 206318 | } | ||
| 206319 | case JSONB_OBJECT: { | ||
| 206320 | u32 cnt = 0; | ||
| 206321 | u32 sub; | ||
| 206322 | j = i+n; | ||
| 206323 | k = j+sz; | ||
| 206324 | while( j<k ){ | ||
| 206325 | sz = 0; | ||
| 206326 | n = jsonbPayloadSize(pParse, j, &sz); | ||
| 206327 | if( n==0 ) return j+1; | ||
| 206328 | if( j+n+sz>k ) return j+1; | ||
| 206329 | if( (cnt & 1)==0 ){ | ||
| 206330 | x = z[j] & 0x0f; | ||
| 206331 | if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return j+1; | ||
| 206332 | } | ||
| 206333 | sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); | ||
| 206334 | if( sub ) return sub; | ||
| 206335 | cnt++; | ||
| 206336 | j += n + sz; | ||
| 206337 | } | ||
| 206338 | assert( j==k ); | ||
| 206339 | if( (cnt & 1)!=0 ) return j+1; | ||
| 206340 | return 0; | ||
| 206341 | } | ||
| 206342 | default: { | ||
| 206343 | return i+1; | ||
| 206344 | } | ||
| 206345 | } | ||
| 206346 | } | ||
| 206347 | |||
| 203884 | /* | 206348 | /* |
| 203885 | ** Parse a single JSON value which begins at pParse->zJson[i]. Return the | 206349 | ** Translate a single element of JSON text at pParse->zJson[i] into |
| 203886 | ** index of the first character past the end of the value parsed. | 206350 | ** its equivalent binary JSONB representation. Append the translation into |
| 206351 | ** pParse->aBlob[] beginning at pParse->nBlob. The size of | ||
| 206352 | ** pParse->aBlob[] is increased as necessary. | ||
| 203887 | ** | 206353 | ** |
| 203888 | ** Special return values: | 206354 | ** Return the index of the first character past the end of the element parsed, |
| 206355 | ** or one of the following special result codes: | ||
| 203889 | ** | 206356 | ** |
| 203890 | ** 0 End of input | 206357 | ** 0 End of input |
| 203891 | ** -1 Syntax error | 206358 | ** -1 Syntax error or OOM |
| 203892 | ** -2 '}' seen | 206359 | ** -2 '}' seen \ |
| 203893 | ** -3 ']' seen | 206360 | ** -3 ']' seen \___ For these returns, pParse->iErr is set to |
| 203894 | ** -4 ',' seen | 206361 | ** -4 ',' seen / the index in zJson[] of the seen character |
| 203895 | ** -5 ':' seen | 206362 | ** -5 ':' seen / |
| 203896 | */ | 206363 | */ |
| 203897 | static int jsonParseValue(JsonParse *pParse, u32 i){ | 206364 | static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ |
| 203898 | char c; | 206365 | char c; |
| 203899 | u32 j; | 206366 | u32 j; |
| 203900 | int iThis; | 206367 | u32 iThis, iStart; |
| 203901 | int x; | 206368 | int x; |
| 203902 | JsonNode *pNode; | 206369 | u8 t; |
| 203903 | const char *z = pParse->zJson; | 206370 | const char *z = pParse->zJson; |
| 203904 | json_parse_restart: | 206371 | json_parse_restart: |
| 203905 | switch( (u8)z[i] ){ | 206372 | switch( (u8)z[i] ){ |
| 203906 | case '{': { | 206373 | case '{': { |
| 203907 | /* Parse object */ | 206374 | /* Parse object */ |
| 203908 | iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); | 206375 | iThis = pParse->nBlob; |
| 203909 | if( iThis<0 ) return -1; | 206376 | jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); |
| 203910 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ | 206377 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ |
| 203911 | pParse->iErr = i; | 206378 | pParse->iErr = i; |
| 203912 | return -1; | 206379 | return -1; |
| 203913 | } | 206380 | } |
| 206381 | iStart = pParse->nBlob; | ||
| 203914 | for(j=i+1;;j++){ | 206382 | for(j=i+1;;j++){ |
| 203915 | u32 nNode = pParse->nNode; | 206383 | u32 iBlob = pParse->nBlob; |
| 203916 | x = jsonParseValue(pParse, j); | 206384 | x = jsonTranslateTextToBlob(pParse, j); |
| 203917 | if( x<=0 ){ | 206385 | if( x<=0 ){ |
| 206386 | int op; | ||
| 203918 | if( x==(-2) ){ | 206387 | if( x==(-2) ){ |
| 203919 | j = pParse->iErr; | 206388 | j = pParse->iErr; |
| 203920 | if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; | 206389 | if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; |
| 203921 | break; | 206390 | break; |
| 203922 | } | 206391 | } |
| 203923 | j += json5Whitespace(&z[j]); | 206392 | j += json5Whitespace(&z[j]); |
| 206393 | op = JSONB_TEXT; | ||
| 203924 | if( sqlite3JsonId1(z[j]) | 206394 | if( sqlite3JsonId1(z[j]) |
| 203925 | || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) | 206395 | || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) |
| 203926 | ){ | 206396 | ){ |
| 203927 | int k = j+1; | 206397 | int k = j+1; |
| 203928 | while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) | 206398 | while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) |
| 203929 | || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) | 206399 | || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) |
| 203930 | ){ | 206400 | ){ |
| 203931 | k++; | 206401 | k++; |
| 203932 | } | 206402 | } |
| 203933 | jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); | 206403 | assert( iBlob==pParse->nBlob ); |
| 206404 | jsonBlobAppendNode(pParse, op, k-j, &z[j]); | ||
| 203934 | pParse->hasNonstd = 1; | 206405 | pParse->hasNonstd = 1; |
| 203935 | x = k; | 206406 | x = k; |
| 203936 | }else{ | 206407 | }else{ |
| @@ -203939,24 +206410,24 @@ json_parse_restart: | |||
| 203939 | } | 206410 | } |
| 203940 | } | 206411 | } |
| 203941 | if( pParse->oom ) return -1; | 206412 | if( pParse->oom ) return -1; |
| 203942 | pNode = &pParse->aNode[nNode]; | 206413 | t = pParse->aBlob[iBlob] & 0x0f; |
| 203943 | if( pNode->eType!=JSON_STRING ){ | 206414 | if( t<JSONB_TEXT || t>JSONB_TEXTRAW ){ |
| 203944 | pParse->iErr = j; | 206415 | pParse->iErr = j; |
| 203945 | return -1; | 206416 | return -1; |
| 203946 | } | 206417 | } |
| 203947 | pNode->jnFlags |= JNODE_LABEL; | ||
| 203948 | j = x; | 206418 | j = x; |
| 203949 | if( z[j]==':' ){ | 206419 | if( z[j]==':' ){ |
| 203950 | j++; | 206420 | j++; |
| 203951 | }else{ | 206421 | }else{ |
| 203952 | if( fast_isspace(z[j]) ){ | 206422 | if( jsonIsspace(z[j]) ){ |
| 203953 | do{ j++; }while( fast_isspace(z[j]) ); | 206423 | /* strspn() is not helpful here */ |
| 206424 | do{ j++; }while( jsonIsspace(z[j]) ); | ||
| 203954 | if( z[j]==':' ){ | 206425 | if( z[j]==':' ){ |
| 203955 | j++; | 206426 | j++; |
| 203956 | goto parse_object_value; | 206427 | goto parse_object_value; |
| 203957 | } | 206428 | } |
| 203958 | } | 206429 | } |
| 203959 | x = jsonParseValue(pParse, j); | 206430 | x = jsonTranslateTextToBlob(pParse, j); |
| 203960 | if( x!=(-5) ){ | 206431 | if( x!=(-5) ){ |
| 203961 | if( x!=(-1) ) pParse->iErr = j; | 206432 | if( x!=(-1) ) pParse->iErr = j; |
| 203962 | return -1; | 206433 | return -1; |
| @@ -203964,7 +206435,7 @@ json_parse_restart: | |||
| 203964 | j = pParse->iErr+1; | 206435 | j = pParse->iErr+1; |
| 203965 | } | 206436 | } |
| 203966 | parse_object_value: | 206437 | parse_object_value: |
| 203967 | x = jsonParseValue(pParse, j); | 206438 | x = jsonTranslateTextToBlob(pParse, j); |
| 203968 | if( x<=0 ){ | 206439 | if( x<=0 ){ |
| 203969 | if( x!=(-1) ) pParse->iErr = j; | 206440 | if( x!=(-1) ) pParse->iErr = j; |
| 203970 | return -1; | 206441 | return -1; |
| @@ -203975,15 +206446,15 @@ json_parse_restart: | |||
| 203975 | }else if( z[j]=='}' ){ | 206446 | }else if( z[j]=='}' ){ |
| 203976 | break; | 206447 | break; |
| 203977 | }else{ | 206448 | }else{ |
| 203978 | if( fast_isspace(z[j]) ){ | 206449 | if( jsonIsspace(z[j]) ){ |
| 203979 | do{ j++; }while( fast_isspace(z[j]) ); | 206450 | j += 1 + (u32)strspn(&z[j+1], jsonSpaces); |
| 203980 | if( z[j]==',' ){ | 206451 | if( z[j]==',' ){ |
| 203981 | continue; | 206452 | continue; |
| 203982 | }else if( z[j]=='}' ){ | 206453 | }else if( z[j]=='}' ){ |
| 203983 | break; | 206454 | break; |
| 203984 | } | 206455 | } |
| 203985 | } | 206456 | } |
| 203986 | x = jsonParseValue(pParse, j); | 206457 | x = jsonTranslateTextToBlob(pParse, j); |
| 203987 | if( x==(-4) ){ | 206458 | if( x==(-4) ){ |
| 203988 | j = pParse->iErr; | 206459 | j = pParse->iErr; |
| 203989 | continue; | 206460 | continue; |
| @@ -203996,25 +206467,27 @@ json_parse_restart: | |||
| 203996 | pParse->iErr = j; | 206467 | pParse->iErr = j; |
| 203997 | return -1; | 206468 | return -1; |
| 203998 | } | 206469 | } |
| 203999 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; | 206470 | jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); |
| 204000 | pParse->iDepth--; | 206471 | pParse->iDepth--; |
| 204001 | return j+1; | 206472 | return j+1; |
| 204002 | } | 206473 | } |
| 204003 | case '[': { | 206474 | case '[': { |
| 204004 | /* Parse array */ | 206475 | /* Parse array */ |
| 204005 | iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); | 206476 | iThis = pParse->nBlob; |
| 204006 | if( iThis<0 ) return -1; | 206477 | assert( i<=(u32)pParse->nJson ); |
| 206478 | jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); | ||
| 206479 | iStart = pParse->nBlob; | ||
| 206480 | if( pParse->oom ) return -1; | ||
| 204007 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ | 206481 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ |
| 204008 | pParse->iErr = i; | 206482 | pParse->iErr = i; |
| 204009 | return -1; | 206483 | return -1; |
| 204010 | } | 206484 | } |
| 204011 | memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); | ||
| 204012 | for(j=i+1;;j++){ | 206485 | for(j=i+1;;j++){ |
| 204013 | x = jsonParseValue(pParse, j); | 206486 | x = jsonTranslateTextToBlob(pParse, j); |
| 204014 | if( x<=0 ){ | 206487 | if( x<=0 ){ |
| 204015 | if( x==(-3) ){ | 206488 | if( x==(-3) ){ |
| 204016 | j = pParse->iErr; | 206489 | j = pParse->iErr; |
| 204017 | if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; | 206490 | if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; |
| 204018 | break; | 206491 | break; |
| 204019 | } | 206492 | } |
| 204020 | if( x!=(-1) ) pParse->iErr = j; | 206493 | if( x!=(-1) ) pParse->iErr = j; |
| @@ -204026,15 +206499,15 @@ json_parse_restart: | |||
| 204026 | }else if( z[j]==']' ){ | 206499 | }else if( z[j]==']' ){ |
| 204027 | break; | 206500 | break; |
| 204028 | }else{ | 206501 | }else{ |
| 204029 | if( fast_isspace(z[j]) ){ | 206502 | if( jsonIsspace(z[j]) ){ |
| 204030 | do{ j++; }while( fast_isspace(z[j]) ); | 206503 | j += 1 + (u32)strspn(&z[j+1], jsonSpaces); |
| 204031 | if( z[j]==',' ){ | 206504 | if( z[j]==',' ){ |
| 204032 | continue; | 206505 | continue; |
| 204033 | }else if( z[j]==']' ){ | 206506 | }else if( z[j]==']' ){ |
| 204034 | break; | 206507 | break; |
| 204035 | } | 206508 | } |
| 204036 | } | 206509 | } |
| 204037 | x = jsonParseValue(pParse, j); | 206510 | x = jsonTranslateTextToBlob(pParse, j); |
| 204038 | if( x==(-4) ){ | 206511 | if( x==(-4) ){ |
| 204039 | j = pParse->iErr; | 206512 | j = pParse->iErr; |
| 204040 | continue; | 206513 | continue; |
| @@ -204047,23 +206520,33 @@ json_parse_restart: | |||
| 204047 | pParse->iErr = j; | 206520 | pParse->iErr = j; |
| 204048 | return -1; | 206521 | return -1; |
| 204049 | } | 206522 | } |
| 204050 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; | 206523 | jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); |
| 204051 | pParse->iDepth--; | 206524 | pParse->iDepth--; |
| 204052 | return j+1; | 206525 | return j+1; |
| 204053 | } | 206526 | } |
| 204054 | case '\'': { | 206527 | case '\'': { |
| 204055 | u8 jnFlags; | 206528 | u8 opcode; |
| 204056 | char cDelim; | 206529 | char cDelim; |
| 204057 | pParse->hasNonstd = 1; | 206530 | pParse->hasNonstd = 1; |
| 204058 | jnFlags = JNODE_JSON5; | 206531 | opcode = JSONB_TEXT; |
| 204059 | goto parse_string; | 206532 | goto parse_string; |
| 204060 | case '"': | 206533 | case '"': |
| 204061 | /* Parse string */ | 206534 | /* Parse string */ |
| 204062 | jnFlags = 0; | 206535 | opcode = JSONB_TEXT; |
| 204063 | parse_string: | 206536 | parse_string: |
| 204064 | cDelim = z[i]; | 206537 | cDelim = z[i]; |
| 204065 | for(j=i+1; 1; j++){ | 206538 | j = i+1; |
| 204066 | if( jsonIsOk[(unsigned char)z[j]] ) continue; | 206539 | while( 1 /*exit-by-break*/ ){ |
| 206540 | if( jsonIsOk[(u8)z[j]] ){ | ||
| 206541 | if( !jsonIsOk[(u8)z[j+1]] ){ | ||
| 206542 | j += 1; | ||
| 206543 | }else if( !jsonIsOk[(u8)z[j+2]] ){ | ||
| 206544 | j += 2; | ||
| 206545 | }else{ | ||
| 206546 | j += 3; | ||
| 206547 | continue; | ||
| 206548 | } | ||
| 206549 | } | ||
| 204067 | c = z[j]; | 206550 | c = z[j]; |
| 204068 | if( c==cDelim ){ | 206551 | if( c==cDelim ){ |
| 204069 | break; | 206552 | break; |
| @@ -204072,33 +206555,41 @@ json_parse_restart: | |||
| 204072 | if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' | 206555 | if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' |
| 204073 | || c=='n' || c=='r' || c=='t' | 206556 | || c=='n' || c=='r' || c=='t' |
| 204074 | || (c=='u' && jsonIs4Hex(&z[j+1])) ){ | 206557 | || (c=='u' && jsonIs4Hex(&z[j+1])) ){ |
| 204075 | jnFlags |= JNODE_ESCAPE; | 206558 | if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; |
| 204076 | }else if( c=='\'' || c=='0' || c=='v' || c=='\n' | 206559 | }else if( c=='\'' || c=='0' || c=='v' || c=='\n' |
| 204077 | || (0xe2==(u8)c && 0x80==(u8)z[j+1] | 206560 | || (0xe2==(u8)c && 0x80==(u8)z[j+1] |
| 204078 | && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) | 206561 | && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) |
| 204079 | || (c=='x' && jsonIs2Hex(&z[j+1])) ){ | 206562 | || (c=='x' && jsonIs2Hex(&z[j+1])) ){ |
| 204080 | jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); | 206563 | opcode = JSONB_TEXT5; |
| 204081 | pParse->hasNonstd = 1; | 206564 | pParse->hasNonstd = 1; |
| 204082 | }else if( c=='\r' ){ | 206565 | }else if( c=='\r' ){ |
| 204083 | if( z[j+1]=='\n' ) j++; | 206566 | if( z[j+1]=='\n' ) j++; |
| 204084 | jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); | 206567 | opcode = JSONB_TEXT5; |
| 204085 | pParse->hasNonstd = 1; | 206568 | pParse->hasNonstd = 1; |
| 204086 | }else{ | 206569 | }else{ |
| 204087 | pParse->iErr = j; | 206570 | pParse->iErr = j; |
| 204088 | return -1; | 206571 | return -1; |
| 204089 | } | 206572 | } |
| 204090 | }else if( c<=0x1f ){ | 206573 | }else if( c<=0x1f ){ |
| 204091 | /* Control characters are not allowed in strings */ | 206574 | if( c==0 ){ |
| 204092 | pParse->iErr = j; | 206575 | pParse->iErr = j; |
| 204093 | return -1; | 206576 | return -1; |
| 206577 | } | ||
| 206578 | /* Control characters are not allowed in canonical JSON string | ||
| 206579 | ** literals, but are allowed in JSON5 string literals. */ | ||
| 206580 | opcode = JSONB_TEXT5; | ||
| 206581 | pParse->hasNonstd = 1; | ||
| 206582 | }else if( c=='"' ){ | ||
| 206583 | opcode = JSONB_TEXT5; | ||
| 204094 | } | 206584 | } |
| 206585 | j++; | ||
| 204095 | } | 206586 | } |
| 204096 | jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); | 206587 | jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); |
| 204097 | return j+1; | 206588 | return j+1; |
| 204098 | } | 206589 | } |
| 204099 | case 't': { | 206590 | case 't': { |
| 204100 | if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ | 206591 | if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ |
| 204101 | jsonParseAddNode(pParse, JSON_TRUE, 0, 0); | 206592 | jsonBlobAppendOneByte(pParse, JSONB_TRUE); |
| 204102 | return i+4; | 206593 | return i+4; |
| 204103 | } | 206594 | } |
| 204104 | pParse->iErr = i; | 206595 | pParse->iErr = i; |
| @@ -204106,23 +206597,22 @@ json_parse_restart: | |||
| 204106 | } | 206597 | } |
| 204107 | case 'f': { | 206598 | case 'f': { |
| 204108 | if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ | 206599 | if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ |
| 204109 | jsonParseAddNode(pParse, JSON_FALSE, 0, 0); | 206600 | jsonBlobAppendOneByte(pParse, JSONB_FALSE); |
| 204110 | return i+5; | 206601 | return i+5; |
| 204111 | } | 206602 | } |
| 204112 | pParse->iErr = i; | 206603 | pParse->iErr = i; |
| 204113 | return -1; | 206604 | return -1; |
| 204114 | } | 206605 | } |
| 204115 | case '+': { | 206606 | case '+': { |
| 204116 | u8 seenDP, seenE, jnFlags; | 206607 | u8 seenE; |
| 204117 | pParse->hasNonstd = 1; | 206608 | pParse->hasNonstd = 1; |
| 204118 | jnFlags = JNODE_JSON5; | 206609 | t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ |
| 204119 | goto parse_number; | 206610 | goto parse_number; |
| 204120 | case '.': | 206611 | case '.': |
| 204121 | if( sqlite3Isdigit(z[i+1]) ){ | 206612 | if( sqlite3Isdigit(z[i+1]) ){ |
| 204122 | pParse->hasNonstd = 1; | 206613 | pParse->hasNonstd = 1; |
| 204123 | jnFlags = JNODE_JSON5; | 206614 | t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ |
| 204124 | seenE = 0; | 206615 | seenE = 0; |
| 204125 | seenDP = JSON_REAL; | ||
| 204126 | goto parse_number_2; | 206616 | goto parse_number_2; |
| 204127 | } | 206617 | } |
| 204128 | pParse->iErr = i; | 206618 | pParse->iErr = i; |
| @@ -204139,9 +206629,8 @@ json_parse_restart: | |||
| 204139 | case '8': | 206629 | case '8': |
| 204140 | case '9': | 206630 | case '9': |
| 204141 | /* Parse number */ | 206631 | /* Parse number */ |
| 204142 | jnFlags = 0; | 206632 | t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ |
| 204143 | parse_number: | 206633 | parse_number: |
| 204144 | seenDP = JSON_INT; | ||
| 204145 | seenE = 0; | 206634 | seenE = 0; |
| 204146 | assert( '-' < '0' ); | 206635 | assert( '-' < '0' ); |
| 204147 | assert( '+' < '0' ); | 206636 | assert( '+' < '0' ); |
| @@ -204151,9 +206640,9 @@ json_parse_restart: | |||
| 204151 | if( c<='0' ){ | 206640 | if( c<='0' ){ |
| 204152 | if( c=='0' ){ | 206641 | if( c=='0' ){ |
| 204153 | if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ | 206642 | if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ |
| 204154 | assert( seenDP==JSON_INT ); | 206643 | assert( t==0x00 ); |
| 204155 | pParse->hasNonstd = 1; | 206644 | pParse->hasNonstd = 1; |
| 204156 | jnFlags |= JNODE_JSON5; | 206645 | t = 0x01; |
| 204157 | for(j=i+3; sqlite3Isxdigit(z[j]); j++){} | 206646 | for(j=i+3; sqlite3Isxdigit(z[j]); j++){} |
| 204158 | goto parse_number_finish; | 206647 | goto parse_number_finish; |
| 204159 | }else if( sqlite3Isdigit(z[i+1]) ){ | 206648 | }else if( sqlite3Isdigit(z[i+1]) ){ |
| @@ -204170,15 +206659,15 @@ json_parse_restart: | |||
| 204170 | ){ | 206659 | ){ |
| 204171 | pParse->hasNonstd = 1; | 206660 | pParse->hasNonstd = 1; |
| 204172 | if( z[i]=='-' ){ | 206661 | if( z[i]=='-' ){ |
| 204173 | jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); | 206662 | jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); |
| 204174 | }else{ | 206663 | }else{ |
| 204175 | jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); | 206664 | jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); |
| 204176 | } | 206665 | } |
| 204177 | return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); | 206666 | return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); |
| 204178 | } | 206667 | } |
| 204179 | if( z[i+1]=='.' ){ | 206668 | if( z[i+1]=='.' ){ |
| 204180 | pParse->hasNonstd = 1; | 206669 | pParse->hasNonstd = 1; |
| 204181 | jnFlags |= JNODE_JSON5; | 206670 | t |= 0x01; |
| 204182 | goto parse_number_2; | 206671 | goto parse_number_2; |
| 204183 | } | 206672 | } |
| 204184 | pParse->iErr = i; | 206673 | pParse->iErr = i; |
| @@ -204190,30 +206679,31 @@ json_parse_restart: | |||
| 204190 | return -1; | 206679 | return -1; |
| 204191 | }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ | 206680 | }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ |
| 204192 | pParse->hasNonstd = 1; | 206681 | pParse->hasNonstd = 1; |
| 204193 | jnFlags |= JNODE_JSON5; | 206682 | t |= 0x01; |
| 204194 | for(j=i+4; sqlite3Isxdigit(z[j]); j++){} | 206683 | for(j=i+4; sqlite3Isxdigit(z[j]); j++){} |
| 204195 | goto parse_number_finish; | 206684 | goto parse_number_finish; |
| 204196 | } | 206685 | } |
| 204197 | } | 206686 | } |
| 204198 | } | 206687 | } |
| 204199 | } | 206688 | } |
| 206689 | |||
| 204200 | parse_number_2: | 206690 | parse_number_2: |
| 204201 | for(j=i+1;; j++){ | 206691 | for(j=i+1;; j++){ |
| 204202 | c = z[j]; | 206692 | c = z[j]; |
| 204203 | if( sqlite3Isdigit(c) ) continue; | 206693 | if( sqlite3Isdigit(c) ) continue; |
| 204204 | if( c=='.' ){ | 206694 | if( c=='.' ){ |
| 204205 | if( seenDP==JSON_REAL ){ | 206695 | if( (t & 0x02)!=0 ){ |
| 204206 | pParse->iErr = j; | 206696 | pParse->iErr = j; |
| 204207 | return -1; | 206697 | return -1; |
| 204208 | } | 206698 | } |
| 204209 | seenDP = JSON_REAL; | 206699 | t |= 0x02; |
| 204210 | continue; | 206700 | continue; |
| 204211 | } | 206701 | } |
| 204212 | if( c=='e' || c=='E' ){ | 206702 | if( c=='e' || c=='E' ){ |
| 204213 | if( z[j-1]<'0' ){ | 206703 | if( z[j-1]<'0' ){ |
| 204214 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ | 206704 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ |
| 204215 | pParse->hasNonstd = 1; | 206705 | pParse->hasNonstd = 1; |
| 204216 | jnFlags |= JNODE_JSON5; | 206706 | t |= 0x01; |
| 204217 | }else{ | 206707 | }else{ |
| 204218 | pParse->iErr = j; | 206708 | pParse->iErr = j; |
| 204219 | return -1; | 206709 | return -1; |
| @@ -204223,7 +206713,7 @@ json_parse_restart: | |||
| 204223 | pParse->iErr = j; | 206713 | pParse->iErr = j; |
| 204224 | return -1; | 206714 | return -1; |
| 204225 | } | 206715 | } |
| 204226 | seenDP = JSON_REAL; | 206716 | t |= 0x02; |
| 204227 | seenE = 1; | 206717 | seenE = 1; |
| 204228 | c = z[j+1]; | 206718 | c = z[j+1]; |
| 204229 | if( c=='+' || c=='-' ){ | 206719 | if( c=='+' || c=='-' ){ |
| @@ -204241,14 +206731,18 @@ json_parse_restart: | |||
| 204241 | if( z[j-1]<'0' ){ | 206731 | if( z[j-1]<'0' ){ |
| 204242 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ | 206732 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ |
| 204243 | pParse->hasNonstd = 1; | 206733 | pParse->hasNonstd = 1; |
| 204244 | jnFlags |= JNODE_JSON5; | 206734 | t |= 0x01; |
| 204245 | }else{ | 206735 | }else{ |
| 204246 | pParse->iErr = j; | 206736 | pParse->iErr = j; |
| 204247 | return -1; | 206737 | return -1; |
| 204248 | } | 206738 | } |
| 204249 | } | 206739 | } |
| 204250 | parse_number_finish: | 206740 | parse_number_finish: |
| 204251 | jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); | 206741 | assert( JSONB_INT+0x01==JSONB_INT5 ); |
| 206742 | assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); | ||
| 206743 | assert( JSONB_INT+0x02==JSONB_FLOAT ); | ||
| 206744 | if( z[i]=='+' ) i++; | ||
| 206745 | jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); | ||
| 204252 | return j; | 206746 | return j; |
| 204253 | } | 206747 | } |
| 204254 | case '}': { | 206748 | case '}': { |
| @@ -204274,9 +206768,7 @@ json_parse_restart: | |||
| 204274 | case 0x0a: | 206768 | case 0x0a: |
| 204275 | case 0x0d: | 206769 | case 0x0d: |
| 204276 | case 0x20: { | 206770 | case 0x20: { |
| 204277 | do{ | 206771 | i += 1 + (u32)strspn(&z[i+1], jsonSpaces); |
| 204278 | i++; | ||
| 204279 | }while( fast_isspace(z[i]) ); | ||
| 204280 | goto json_parse_restart; | 206772 | goto json_parse_restart; |
| 204281 | } | 206773 | } |
| 204282 | case 0x0b: | 206774 | case 0x0b: |
| @@ -204298,10 +206790,11 @@ json_parse_restart: | |||
| 204298 | } | 206790 | } |
| 204299 | case 'n': { | 206791 | case 'n': { |
| 204300 | if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ | 206792 | if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ |
| 204301 | jsonParseAddNode(pParse, JSON_NULL, 0, 0); | 206793 | jsonBlobAppendOneByte(pParse, JSONB_NULL); |
| 204302 | return i+4; | 206794 | return i+4; |
| 204303 | } | 206795 | } |
| 204304 | /* fall-through into the default case that checks for NaN */ | 206796 | /* fall-through into the default case that checks for NaN */ |
| 206797 | /* no break */ deliberate_fall_through | ||
| 204305 | } | 206798 | } |
| 204306 | default: { | 206799 | default: { |
| 204307 | u32 k; | 206800 | u32 k; |
| @@ -204314,8 +206807,11 @@ json_parse_restart: | |||
| 204314 | continue; | 206807 | continue; |
| 204315 | } | 206808 | } |
| 204316 | if( sqlite3Isalnum(z[i+nn]) ) continue; | 206809 | if( sqlite3Isalnum(z[i+nn]) ) continue; |
| 204317 | jsonParseAddNode(pParse, aNanInfName[k].eType, | 206810 | if( aNanInfName[k].eType==JSONB_FLOAT ){ |
| 204318 | aNanInfName[k].nRepl, aNanInfName[k].zRepl); | 206811 | jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); |
| 206812 | }else{ | ||
| 206813 | jsonBlobAppendOneByte(pParse, JSONB_NULL); | ||
| 206814 | } | ||
| 204319 | pParse->hasNonstd = 1; | 206815 | pParse->hasNonstd = 1; |
| 204320 | return i + nn; | 206816 | return i + nn; |
| 204321 | } | 206817 | } |
| @@ -204325,6 +206821,7 @@ json_parse_restart: | |||
| 204325 | } /* End switch(z[i]) */ | 206821 | } /* End switch(z[i]) */ |
| 204326 | } | 206822 | } |
| 204327 | 206823 | ||
| 206824 | |||
| 204328 | /* | 206825 | /* |
| 204329 | ** Parse a complete JSON string. Return 0 on success or non-zero if there | 206826 | ** Parse a complete JSON string. Return 0 on success or non-zero if there |
| 204330 | ** are any errors. If an error occurs, free all memory held by pParse, | 206827 | ** are any errors. If an error occurs, free all memory held by pParse, |
| @@ -204333,20 +206830,26 @@ json_parse_restart: | |||
| 204333 | ** pParse must be initialized to an empty parse object prior to calling | 206830 | ** pParse must be initialized to an empty parse object prior to calling |
| 204334 | ** this routine. | 206831 | ** this routine. |
| 204335 | */ | 206832 | */ |
| 204336 | static int jsonParse( | 206833 | static int jsonConvertTextToBlob( |
| 204337 | JsonParse *pParse, /* Initialize and fill this JsonParse object */ | 206834 | JsonParse *pParse, /* Initialize and fill this JsonParse object */ |
| 204338 | sqlite3_context *pCtx /* Report errors here */ | 206835 | sqlite3_context *pCtx /* Report errors here */ |
| 204339 | ){ | 206836 | ){ |
| 204340 | int i; | 206837 | int i; |
| 204341 | const char *zJson = pParse->zJson; | 206838 | const char *zJson = pParse->zJson; |
| 204342 | i = jsonParseValue(pParse, 0); | 206839 | i = jsonTranslateTextToBlob(pParse, 0); |
| 204343 | if( pParse->oom ) i = -1; | 206840 | if( pParse->oom ) i = -1; |
| 204344 | if( i>0 ){ | 206841 | if( i>0 ){ |
| 206842 | #ifdef SQLITE_DEBUG | ||
| 204345 | assert( pParse->iDepth==0 ); | 206843 | assert( pParse->iDepth==0 ); |
| 204346 | while( fast_isspace(zJson[i]) ) i++; | 206844 | if( sqlite3Config.bJsonSelfcheck ){ |
| 206845 | assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); | ||
| 206846 | } | ||
| 206847 | #endif | ||
| 206848 | while( jsonIsspace(zJson[i]) ) i++; | ||
| 204347 | if( zJson[i] ){ | 206849 | if( zJson[i] ){ |
| 204348 | i += json5Whitespace(&zJson[i]); | 206850 | i += json5Whitespace(&zJson[i]); |
| 204349 | if( zJson[i] ){ | 206851 | if( zJson[i] ){ |
| 206852 | if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); | ||
| 204350 | jsonParseReset(pParse); | 206853 | jsonParseReset(pParse); |
| 204351 | return 1; | 206854 | return 1; |
| 204352 | } | 206855 | } |
| @@ -204367,248 +206870,832 @@ static int jsonParse( | |||
| 204367 | return 0; | 206870 | return 0; |
| 204368 | } | 206871 | } |
| 204369 | 206872 | ||
| 206873 | /* | ||
| 206874 | ** The input string pStr is a well-formed JSON text string. Convert | ||
| 206875 | ** this into the JSONB format and make it the return value of the | ||
| 206876 | ** SQL function. | ||
| 206877 | */ | ||
| 206878 | static void jsonReturnStringAsBlob(JsonString *pStr){ | ||
| 206879 | JsonParse px; | ||
| 206880 | memset(&px, 0, sizeof(px)); | ||
| 206881 | jsonStringTerminate(pStr); | ||
| 206882 | if( pStr->eErr ){ | ||
| 206883 | sqlite3_result_error_nomem(pStr->pCtx); | ||
| 206884 | return; | ||
| 206885 | } | ||
| 206886 | px.zJson = pStr->zBuf; | ||
| 206887 | px.nJson = pStr->nUsed; | ||
| 206888 | px.db = sqlite3_context_db_handle(pStr->pCtx); | ||
| 206889 | (void)jsonTranslateTextToBlob(&px, 0); | ||
| 206890 | if( px.oom ){ | ||
| 206891 | sqlite3DbFree(px.db, px.aBlob); | ||
| 206892 | sqlite3_result_error_nomem(pStr->pCtx); | ||
| 206893 | }else{ | ||
| 206894 | assert( px.nBlobAlloc>0 ); | ||
| 206895 | assert( !px.bReadOnly ); | ||
| 206896 | sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); | ||
| 206897 | } | ||
| 206898 | } | ||
| 204370 | 206899 | ||
| 204371 | /* Mark node i of pParse as being a child of iParent. Call recursively | 206900 | /* The byte at index i is a node type-code. This routine |
| 204372 | ** to fill in all the descendants of node i. | 206901 | ** determines the payload size for that node and writes that |
| 206902 | ** payload size in to *pSz. It returns the offset from i to the | ||
| 206903 | ** beginning of the payload. Return 0 on error. | ||
| 204373 | */ | 206904 | */ |
| 204374 | static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ | 206905 | static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ |
| 204375 | JsonNode *pNode = &pParse->aNode[i]; | 206906 | u8 x; |
| 204376 | u32 j; | 206907 | u32 sz; |
| 204377 | pParse->aUp[i] = iParent; | 206908 | u32 n; |
| 204378 | switch( pNode->eType ){ | 206909 | if( NEVER(i>pParse->nBlob) ){ |
| 204379 | case JSON_ARRAY: { | 206910 | *pSz = 0; |
| 204380 | for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ | 206911 | return 0; |
| 204381 | jsonParseFillInParentage(pParse, i+j, i); | 206912 | } |
| 206913 | x = pParse->aBlob[i]>>4; | ||
| 206914 | if( x<=11 ){ | ||
| 206915 | sz = x; | ||
| 206916 | n = 1; | ||
| 206917 | }else if( x==12 ){ | ||
| 206918 | if( i+1>=pParse->nBlob ){ | ||
| 206919 | *pSz = 0; | ||
| 206920 | return 0; | ||
| 206921 | } | ||
| 206922 | sz = pParse->aBlob[i+1]; | ||
| 206923 | n = 2; | ||
| 206924 | }else if( x==13 ){ | ||
| 206925 | if( i+2>=pParse->nBlob ){ | ||
| 206926 | *pSz = 0; | ||
| 206927 | return 0; | ||
| 206928 | } | ||
| 206929 | sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; | ||
| 206930 | n = 3; | ||
| 206931 | }else if( x==14 ){ | ||
| 206932 | if( i+4>=pParse->nBlob ){ | ||
| 206933 | *pSz = 0; | ||
| 206934 | return 0; | ||
| 206935 | } | ||
| 206936 | sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + | ||
| 206937 | (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; | ||
| 206938 | n = 5; | ||
| 206939 | }else{ | ||
| 206940 | if( i+8>=pParse->nBlob | ||
| 206941 | || pParse->aBlob[i+1]!=0 | ||
| 206942 | || pParse->aBlob[i+2]!=0 | ||
| 206943 | || pParse->aBlob[i+3]!=0 | ||
| 206944 | || pParse->aBlob[i+4]!=0 | ||
| 206945 | ){ | ||
| 206946 | *pSz = 0; | ||
| 206947 | return 0; | ||
| 206948 | } | ||
| 206949 | sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + | ||
| 206950 | (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; | ||
| 206951 | n = 9; | ||
| 206952 | } | ||
| 206953 | if( (i64)i+sz+n > pParse->nBlob | ||
| 206954 | && (i64)i+sz+n > pParse->nBlob-pParse->delta | ||
| 206955 | ){ | ||
| 206956 | sz = 0; | ||
| 206957 | n = 0; | ||
| 206958 | } | ||
| 206959 | *pSz = sz; | ||
| 206960 | return n; | ||
| 206961 | } | ||
| 206962 | |||
| 206963 | |||
| 206964 | /* | ||
| 206965 | ** Translate the binary JSONB representation of JSON beginning at | ||
| 206966 | ** pParse->aBlob[i] into a JSON text string. Append the JSON | ||
| 206967 | ** text onto the end of pOut. Return the index in pParse->aBlob[] | ||
| 206968 | ** of the first byte past the end of the element that is translated. | ||
| 206969 | ** | ||
| 206970 | ** If an error is detected in the BLOB input, the pOut->eErr flag | ||
| 206971 | ** might get set to JSTRING_MALFORMED. But not all BLOB input errors | ||
| 206972 | ** are detected. So a malformed JSONB input might either result | ||
| 206973 | ** in an error, or in incorrect JSON. | ||
| 206974 | ** | ||
| 206975 | ** The pOut->eErr JSTRING_OOM flag is set on a OOM. | ||
| 206976 | */ | ||
| 206977 | static u32 jsonTranslateBlobToText( | ||
| 206978 | const JsonParse *pParse, /* the complete parse of the JSON */ | ||
| 206979 | u32 i, /* Start rendering at this index */ | ||
| 206980 | JsonString *pOut /* Write JSON here */ | ||
| 206981 | ){ | ||
| 206982 | u32 sz, n, j, iEnd; | ||
| 206983 | |||
| 206984 | n = jsonbPayloadSize(pParse, i, &sz); | ||
| 206985 | if( n==0 ){ | ||
| 206986 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 206987 | return pParse->nBlob+1; | ||
| 206988 | } | ||
| 206989 | switch( pParse->aBlob[i] & 0x0f ){ | ||
| 206990 | case JSONB_NULL: { | ||
| 206991 | jsonAppendRawNZ(pOut, "null", 4); | ||
| 206992 | return i+1; | ||
| 206993 | } | ||
| 206994 | case JSONB_TRUE: { | ||
| 206995 | jsonAppendRawNZ(pOut, "true", 4); | ||
| 206996 | return i+1; | ||
| 206997 | } | ||
| 206998 | case JSONB_FALSE: { | ||
| 206999 | jsonAppendRawNZ(pOut, "false", 5); | ||
| 207000 | return i+1; | ||
| 207001 | } | ||
| 207002 | case JSONB_INT: | ||
| 207003 | case JSONB_FLOAT: { | ||
| 207004 | if( sz==0 ) goto malformed_jsonb; | ||
| 207005 | jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); | ||
| 207006 | break; | ||
| 207007 | } | ||
| 207008 | case JSONB_INT5: { /* Integer literal in hexadecimal notation */ | ||
| 207009 | u32 k = 2; | ||
| 207010 | sqlite3_uint64 u = 0; | ||
| 207011 | const char *zIn = (const char*)&pParse->aBlob[i+n]; | ||
| 207012 | int bOverflow = 0; | ||
| 207013 | if( sz==0 ) goto malformed_jsonb; | ||
| 207014 | if( zIn[0]=='-' ){ | ||
| 207015 | jsonAppendChar(pOut, '-'); | ||
| 207016 | k++; | ||
| 207017 | }else if( zIn[0]=='+' ){ | ||
| 207018 | k++; | ||
| 207019 | } | ||
| 207020 | for(; k<sz; k++){ | ||
| 207021 | if( !sqlite3Isxdigit(zIn[k]) ){ | ||
| 207022 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207023 | break; | ||
| 207024 | }else if( (u>>60)!=0 ){ | ||
| 207025 | bOverflow = 1; | ||
| 207026 | }else{ | ||
| 207027 | u = u*16 + sqlite3HexToInt(zIn[k]); | ||
| 207028 | } | ||
| 204382 | } | 207029 | } |
| 207030 | jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); | ||
| 204383 | break; | 207031 | break; |
| 204384 | } | 207032 | } |
| 204385 | case JSON_OBJECT: { | 207033 | case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ |
| 204386 | for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ | 207034 | u32 k = 0; |
| 204387 | pParse->aUp[i+j] = i; | 207035 | const char *zIn = (const char*)&pParse->aBlob[i+n]; |
| 204388 | jsonParseFillInParentage(pParse, i+j+1, i); | 207036 | if( sz==0 ) goto malformed_jsonb; |
| 207037 | if( zIn[0]=='-' ){ | ||
| 207038 | jsonAppendChar(pOut, '-'); | ||
| 207039 | k++; | ||
| 204389 | } | 207040 | } |
| 207041 | if( zIn[k]=='.' ){ | ||
| 207042 | jsonAppendChar(pOut, '0'); | ||
| 207043 | } | ||
| 207044 | for(; k<sz; k++){ | ||
| 207045 | jsonAppendChar(pOut, zIn[k]); | ||
| 207046 | if( zIn[k]=='.' && (k+1==sz || !sqlite3Isdigit(zIn[k+1])) ){ | ||
| 207047 | jsonAppendChar(pOut, '0'); | ||
| 207048 | } | ||
| 207049 | } | ||
| 207050 | break; | ||
| 207051 | } | ||
| 207052 | case JSONB_TEXT: | ||
| 207053 | case JSONB_TEXTJ: { | ||
| 207054 | jsonAppendChar(pOut, '"'); | ||
| 207055 | jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); | ||
| 207056 | jsonAppendChar(pOut, '"'); | ||
| 204390 | break; | 207057 | break; |
| 204391 | } | 207058 | } |
| 207059 | case JSONB_TEXT5: { | ||
| 207060 | const char *zIn; | ||
| 207061 | u32 k; | ||
| 207062 | u32 sz2 = sz; | ||
| 207063 | zIn = (const char*)&pParse->aBlob[i+n]; | ||
| 207064 | jsonAppendChar(pOut, '"'); | ||
| 207065 | while( sz2>0 ){ | ||
| 207066 | for(k=0; k<sz2 && (jsonIsOk[(u8)zIn[k]] || zIn[k]=='\''); k++){} | ||
| 207067 | if( k>0 ){ | ||
| 207068 | jsonAppendRawNZ(pOut, zIn, k); | ||
| 207069 | if( k>=sz2 ){ | ||
| 207070 | break; | ||
| 207071 | } | ||
| 207072 | zIn += k; | ||
| 207073 | sz2 -= k; | ||
| 207074 | } | ||
| 207075 | if( zIn[0]=='"' ){ | ||
| 207076 | jsonAppendRawNZ(pOut, "\\\"", 2); | ||
| 207077 | zIn++; | ||
| 207078 | sz2--; | ||
| 207079 | continue; | ||
| 207080 | } | ||
| 207081 | if( zIn[0]<=0x1f ){ | ||
| 207082 | if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break; | ||
| 207083 | jsonAppendControlChar(pOut, zIn[0]); | ||
| 207084 | zIn++; | ||
| 207085 | sz2--; | ||
| 207086 | continue; | ||
| 207087 | } | ||
| 207088 | assert( zIn[0]=='\\' ); | ||
| 207089 | assert( sz2>=1 ); | ||
| 207090 | if( sz2<2 ){ | ||
| 207091 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207092 | break; | ||
| 207093 | } | ||
| 207094 | switch( (u8)zIn[1] ){ | ||
| 207095 | case '\'': | ||
| 207096 | jsonAppendChar(pOut, '\''); | ||
| 207097 | break; | ||
| 207098 | case 'v': | ||
| 207099 | jsonAppendRawNZ(pOut, "\\u0009", 6); | ||
| 207100 | break; | ||
| 207101 | case 'x': | ||
| 207102 | if( sz2<4 ){ | ||
| 207103 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207104 | sz2 = 2; | ||
| 207105 | break; | ||
| 207106 | } | ||
| 207107 | jsonAppendRawNZ(pOut, "\\u00", 4); | ||
| 207108 | jsonAppendRawNZ(pOut, &zIn[2], 2); | ||
| 207109 | zIn += 2; | ||
| 207110 | sz2 -= 2; | ||
| 207111 | break; | ||
| 207112 | case '0': | ||
| 207113 | jsonAppendRawNZ(pOut, "\\u0000", 6); | ||
| 207114 | break; | ||
| 207115 | case '\r': | ||
| 207116 | if( sz2>2 && zIn[2]=='\n' ){ | ||
| 207117 | zIn++; | ||
| 207118 | sz2--; | ||
| 207119 | } | ||
| 207120 | break; | ||
| 207121 | case '\n': | ||
| 207122 | break; | ||
| 207123 | case 0xe2: | ||
| 207124 | /* '\' followed by either U+2028 or U+2029 is ignored as | ||
| 207125 | ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. | ||
| 207126 | ** U+2029 is the same except for the last byte */ | ||
| 207127 | if( sz2<4 | ||
| 207128 | || 0x80!=(u8)zIn[2] | ||
| 207129 | || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) | ||
| 207130 | ){ | ||
| 207131 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207132 | sz2 = 2; | ||
| 207133 | break; | ||
| 207134 | } | ||
| 207135 | zIn += 2; | ||
| 207136 | sz2 -= 2; | ||
| 207137 | break; | ||
| 207138 | default: | ||
| 207139 | jsonAppendRawNZ(pOut, zIn, 2); | ||
| 207140 | break; | ||
| 207141 | } | ||
| 207142 | assert( sz2>=2 ); | ||
| 207143 | zIn += 2; | ||
| 207144 | sz2 -= 2; | ||
| 207145 | } | ||
| 207146 | jsonAppendChar(pOut, '"'); | ||
| 207147 | break; | ||
| 207148 | } | ||
| 207149 | case JSONB_TEXTRAW: { | ||
| 207150 | jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); | ||
| 207151 | break; | ||
| 207152 | } | ||
| 207153 | case JSONB_ARRAY: { | ||
| 207154 | jsonAppendChar(pOut, '['); | ||
| 207155 | j = i+n; | ||
| 207156 | iEnd = j+sz; | ||
| 207157 | while( j<iEnd && pOut->eErr==0 ){ | ||
| 207158 | j = jsonTranslateBlobToText(pParse, j, pOut); | ||
| 207159 | jsonAppendChar(pOut, ','); | ||
| 207160 | } | ||
| 207161 | if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; | ||
| 207162 | if( sz>0 ) jsonStringTrimOneChar(pOut); | ||
| 207163 | jsonAppendChar(pOut, ']'); | ||
| 207164 | break; | ||
| 207165 | } | ||
| 207166 | case JSONB_OBJECT: { | ||
| 207167 | int x = 0; | ||
| 207168 | jsonAppendChar(pOut, '{'); | ||
| 207169 | j = i+n; | ||
| 207170 | iEnd = j+sz; | ||
| 207171 | while( j<iEnd && pOut->eErr==0 ){ | ||
| 207172 | j = jsonTranslateBlobToText(pParse, j, pOut); | ||
| 207173 | jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); | ||
| 207174 | } | ||
| 207175 | if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; | ||
| 207176 | if( sz>0 ) jsonStringTrimOneChar(pOut); | ||
| 207177 | jsonAppendChar(pOut, '}'); | ||
| 207178 | break; | ||
| 207179 | } | ||
| 207180 | |||
| 204392 | default: { | 207181 | default: { |
| 207182 | malformed_jsonb: | ||
| 207183 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 204393 | break; | 207184 | break; |
| 204394 | } | 207185 | } |
| 204395 | } | 207186 | } |
| 207187 | return i+n+sz; | ||
| 207188 | } | ||
| 207189 | |||
| 207190 | /* Context for recursion of json_pretty() | ||
| 207191 | */ | ||
| 207192 | typedef struct JsonPretty JsonPretty; | ||
| 207193 | struct JsonPretty { | ||
| 207194 | JsonParse *pParse; /* The BLOB being rendered */ | ||
| 207195 | JsonString *pOut; /* Generate pretty output into this string */ | ||
| 207196 | const char *zIndent; /* Use this text for indentation */ | ||
| 207197 | u32 szIndent; /* Bytes in zIndent[] */ | ||
| 207198 | u32 nIndent; /* Current level of indentation */ | ||
| 207199 | }; | ||
| 207200 | |||
| 207201 | /* Append indentation to the pretty JSON under construction */ | ||
| 207202 | static void jsonPrettyIndent(JsonPretty *pPretty){ | ||
| 207203 | u32 jj; | ||
| 207204 | for(jj=0; jj<pPretty->nIndent; jj++){ | ||
| 207205 | jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent); | ||
| 207206 | } | ||
| 204396 | } | 207207 | } |
| 204397 | 207208 | ||
| 204398 | /* | 207209 | /* |
| 204399 | ** Compute the parentage of all nodes in a completed parse. | 207210 | ** Translate the binary JSONB representation of JSON beginning at |
| 207211 | ** pParse->aBlob[i] into a JSON text string. Append the JSON | ||
| 207212 | ** text onto the end of pOut. Return the index in pParse->aBlob[] | ||
| 207213 | ** of the first byte past the end of the element that is translated. | ||
| 207214 | ** | ||
| 207215 | ** This is a variant of jsonTranslateBlobToText() that "pretty-prints" | ||
| 207216 | ** the output. Extra whitespace is inserted to make the JSON easier | ||
| 207217 | ** for humans to read. | ||
| 207218 | ** | ||
| 207219 | ** If an error is detected in the BLOB input, the pOut->eErr flag | ||
| 207220 | ** might get set to JSTRING_MALFORMED. But not all BLOB input errors | ||
| 207221 | ** are detected. So a malformed JSONB input might either result | ||
| 207222 | ** in an error, or in incorrect JSON. | ||
| 207223 | ** | ||
| 207224 | ** The pOut->eErr JSTRING_OOM flag is set on a OOM. | ||
| 204400 | */ | 207225 | */ |
| 204401 | static int jsonParseFindParents(JsonParse *pParse){ | 207226 | static u32 jsonTranslateBlobToPrettyText( |
| 204402 | u32 *aUp; | 207227 | JsonPretty *pPretty, /* Pretty-printing context */ |
| 204403 | assert( pParse->aUp==0 ); | 207228 | u32 i /* Start rendering at this index */ |
| 204404 | aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); | 207229 | ){ |
| 204405 | if( aUp==0 ){ | 207230 | u32 sz, n, j, iEnd; |
| 204406 | pParse->oom = 1; | 207231 | const JsonParse *pParse = pPretty->pParse; |
| 204407 | return SQLITE_NOMEM; | 207232 | JsonString *pOut = pPretty->pOut; |
| 207233 | n = jsonbPayloadSize(pParse, i, &sz); | ||
| 207234 | if( n==0 ){ | ||
| 207235 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207236 | return pParse->nBlob+1; | ||
| 204408 | } | 207237 | } |
| 204409 | jsonParseFillInParentage(pParse, 0, 0); | 207238 | switch( pParse->aBlob[i] & 0x0f ){ |
| 204410 | return SQLITE_OK; | 207239 | case JSONB_ARRAY: { |
| 207240 | j = i+n; | ||
| 207241 | iEnd = j+sz; | ||
| 207242 | jsonAppendChar(pOut, '['); | ||
| 207243 | if( j<iEnd ){ | ||
| 207244 | jsonAppendChar(pOut, '\n'); | ||
| 207245 | pPretty->nIndent++; | ||
| 207246 | while( pOut->eErr==0 ){ | ||
| 207247 | jsonPrettyIndent(pPretty); | ||
| 207248 | j = jsonTranslateBlobToPrettyText(pPretty, j); | ||
| 207249 | if( j>=iEnd ) break; | ||
| 207250 | jsonAppendRawNZ(pOut, ",\n", 2); | ||
| 207251 | } | ||
| 207252 | jsonAppendChar(pOut, '\n'); | ||
| 207253 | pPretty->nIndent--; | ||
| 207254 | jsonPrettyIndent(pPretty); | ||
| 207255 | } | ||
| 207256 | jsonAppendChar(pOut, ']'); | ||
| 207257 | i = iEnd; | ||
| 207258 | break; | ||
| 207259 | } | ||
| 207260 | case JSONB_OBJECT: { | ||
| 207261 | j = i+n; | ||
| 207262 | iEnd = j+sz; | ||
| 207263 | jsonAppendChar(pOut, '{'); | ||
| 207264 | if( j<iEnd ){ | ||
| 207265 | jsonAppendChar(pOut, '\n'); | ||
| 207266 | pPretty->nIndent++; | ||
| 207267 | while( pOut->eErr==0 ){ | ||
| 207268 | jsonPrettyIndent(pPretty); | ||
| 207269 | j = jsonTranslateBlobToText(pParse, j, pOut); | ||
| 207270 | if( j>iEnd ){ | ||
| 207271 | pOut->eErr |= JSTRING_MALFORMED; | ||
| 207272 | break; | ||
| 207273 | } | ||
| 207274 | jsonAppendRawNZ(pOut, ": ", 2); | ||
| 207275 | j = jsonTranslateBlobToPrettyText(pPretty, j); | ||
| 207276 | if( j>=iEnd ) break; | ||
| 207277 | jsonAppendRawNZ(pOut, ",\n", 2); | ||
| 207278 | } | ||
| 207279 | jsonAppendChar(pOut, '\n'); | ||
| 207280 | pPretty->nIndent--; | ||
| 207281 | jsonPrettyIndent(pPretty); | ||
| 207282 | } | ||
| 207283 | jsonAppendChar(pOut, '}'); | ||
| 207284 | i = iEnd; | ||
| 207285 | break; | ||
| 207286 | } | ||
| 207287 | default: { | ||
| 207288 | i = jsonTranslateBlobToText(pParse, i, pOut); | ||
| 207289 | break; | ||
| 207290 | } | ||
| 207291 | } | ||
| 207292 | return i; | ||
| 207293 | } | ||
| 207294 | |||
| 207295 | |||
| 207296 | /* Return true if the input pJson | ||
| 207297 | ** | ||
| 207298 | ** For performance reasons, this routine does not do a detailed check of the | ||
| 207299 | ** input BLOB to ensure that it is well-formed. Hence, false positives are | ||
| 207300 | ** possible. False negatives should never occur, however. | ||
| 207301 | */ | ||
| 207302 | static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ | ||
| 207303 | u32 sz, n; | ||
| 207304 | const u8 *aBlob; | ||
| 207305 | int nBlob; | ||
| 207306 | JsonParse s; | ||
| 207307 | if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; | ||
| 207308 | aBlob = sqlite3_value_blob(pJson); | ||
| 207309 | nBlob = sqlite3_value_bytes(pJson); | ||
| 207310 | if( nBlob<1 ) return 0; | ||
| 207311 | if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; | ||
| 207312 | memset(&s, 0, sizeof(s)); | ||
| 207313 | s.aBlob = (u8*)aBlob; | ||
| 207314 | s.nBlob = nBlob; | ||
| 207315 | n = jsonbPayloadSize(&s, 0, &sz); | ||
| 207316 | if( n==0 ) return 0; | ||
| 207317 | if( sz+n!=(u32)nBlob ) return 0; | ||
| 207318 | if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; | ||
| 207319 | return sz+n==(u32)nBlob; | ||
| 204411 | } | 207320 | } |
| 204412 | 207321 | ||
| 204413 | /* | 207322 | /* |
| 204414 | ** Magic number used for the JSON parse cache in sqlite3_get_auxdata() | 207323 | ** Given that a JSONB_ARRAY object starts at offset i, return |
| 207324 | ** the number of entries in that array. | ||
| 204415 | */ | 207325 | */ |
| 204416 | #define JSON_CACHE_ID (-429938) /* First cache entry */ | 207326 | static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ |
| 204417 | #define JSON_CACHE_SZ 4 /* Max number of cache entries */ | 207327 | u32 n, sz, i, iEnd; |
| 207328 | u32 k = 0; | ||
| 207329 | n = jsonbPayloadSize(pParse, iRoot, &sz); | ||
| 207330 | iEnd = iRoot+n+sz; | ||
| 207331 | for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){ | ||
| 207332 | n = jsonbPayloadSize(pParse, i, &sz); | ||
| 207333 | } | ||
| 207334 | return k; | ||
| 207335 | } | ||
| 204418 | 207336 | ||
| 204419 | /* | 207337 | /* |
| 204420 | ** Obtain a complete parse of the JSON found in the pJson argument | 207338 | ** Edit the payload size of the element at iRoot by the amount in |
| 204421 | ** | 207339 | ** pParse->delta. |
| 204422 | ** Use the sqlite3_get_auxdata() cache to find a preexisting parse | 207340 | */ |
| 204423 | ** if it is available. If the cache is not available or if it | 207341 | static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ |
| 204424 | ** is no longer valid, parse the JSON again and return the new parse. | 207342 | u32 sz = 0; |
| 204425 | ** Also register the new parse so that it will be available for | 207343 | u32 nBlob; |
| 204426 | ** future sqlite3_get_auxdata() calls. | 207344 | assert( pParse->delta!=0 ); |
| 204427 | ** | 207345 | assert( pParse->nBlobAlloc >= pParse->nBlob ); |
| 204428 | ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx | 207346 | nBlob = pParse->nBlob; |
| 204429 | ** and return NULL. | 207347 | pParse->nBlob = pParse->nBlobAlloc; |
| 204430 | ** | 207348 | (void)jsonbPayloadSize(pParse, iRoot, &sz); |
| 204431 | ** The returned pointer (if it is not NULL) is owned by the cache in | 207349 | pParse->nBlob = nBlob; |
| 204432 | ** most cases, not the caller. The caller does NOT need to invoke | 207350 | sz += pParse->delta; |
| 204433 | ** jsonParseFree(), in most cases. | 207351 | pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); |
| 207352 | } | ||
| 207353 | |||
| 207354 | /* | ||
| 207355 | ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of | ||
| 207356 | ** content beginning at iDel, and replacing them with nIns bytes of | ||
| 207357 | ** content given by aIns. | ||
| 204434 | ** | 207358 | ** |
| 204435 | ** Except, if an error occurs and pErrCtx==0 then return the JsonParse | 207359 | ** nDel may be zero, in which case no bytes are removed. But iDel is |
| 204436 | ** object with JsonParse.nErr non-zero and the caller will own the JsonParse | 207360 | ** still important as new bytes will be insert beginning at iDel. |
| 204437 | ** object. In that case, it will be the responsibility of the caller to | ||
| 204438 | ** invoke jsonParseFree(). To summarize: | ||
| 204439 | ** | 207361 | ** |
| 204440 | ** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the | 207362 | ** aIns may be zero, in which case space is created to hold nIns bytes |
| 204441 | ** cache. Call does not need to | 207363 | ** beginning at iDel, but that space is uninitialized. |
| 204442 | ** free it. | ||
| 204443 | ** | 207364 | ** |
| 204444 | ** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller | 207365 | ** Set pParse->oom if an OOM occurs. |
| 204445 | ** and so the caller must free it. | ||
| 204446 | */ | 207366 | */ |
| 204447 | static JsonParse *jsonParseCached( | 207367 | static void jsonBlobEdit( |
| 204448 | sqlite3_context *pCtx, /* Context to use for cache search */ | 207368 | JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ |
| 204449 | sqlite3_value *pJson, /* Function param containing JSON text */ | 207369 | u32 iDel, /* First byte to be removed */ |
| 204450 | sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ | 207370 | u32 nDel, /* Number of bytes to remove */ |
| 204451 | int bUnedited /* No prior edits allowed */ | 207371 | const u8 *aIns, /* Content to insert */ |
| 207372 | u32 nIns /* Bytes of content to insert */ | ||
| 204452 | ){ | 207373 | ){ |
| 204453 | char *zJson = (char*)sqlite3_value_text(pJson); | 207374 | i64 d = (i64)nIns - (i64)nDel; |
| 204454 | int nJson = sqlite3_value_bytes(pJson); | 207375 | if( d!=0 ){ |
| 204455 | JsonParse *p; | 207376 | if( pParse->nBlob + d > pParse->nBlobAlloc ){ |
| 204456 | JsonParse *pMatch = 0; | 207377 | jsonBlobExpand(pParse, pParse->nBlob+d); |
| 204457 | int iKey; | 207378 | if( pParse->oom ) return; |
| 204458 | int iMinKey = 0; | 207379 | } |
| 204459 | u32 iMinHold = 0xffffffff; | 207380 | memmove(&pParse->aBlob[iDel+nIns], |
| 204460 | u32 iMaxHold = 0; | 207381 | &pParse->aBlob[iDel+nDel], |
| 204461 | int bJsonRCStr; | 207382 | pParse->nBlob - (iDel+nDel)); |
| 207383 | pParse->nBlob += d; | ||
| 207384 | pParse->delta += d; | ||
| 207385 | } | ||
| 207386 | if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); | ||
| 207387 | } | ||
| 204462 | 207388 | ||
| 204463 | if( zJson==0 ) return 0; | 207389 | /* |
| 204464 | for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ | 207390 | ** Return the number of escaped newlines to be ignored. |
| 204465 | p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); | 207391 | ** An escaped newline is a one of the following byte sequences: |
| 204466 | if( p==0 ){ | 207392 | ** |
| 204467 | iMinKey = iKey; | 207393 | ** 0x5c 0x0a |
| 204468 | break; | 207394 | ** 0x5c 0x0d |
| 207395 | ** 0x5c 0x0d 0x0a | ||
| 207396 | ** 0x5c 0xe2 0x80 0xa8 | ||
| 207397 | ** 0x5c 0xe2 0x80 0xa9 | ||
| 207398 | */ | ||
| 207399 | static u32 jsonBytesToBypass(const char *z, u32 n){ | ||
| 207400 | u32 i = 0; | ||
| 207401 | while( i+1<n ){ | ||
| 207402 | if( z[i]!='\\' ) return i; | ||
| 207403 | if( z[i+1]=='\n' ){ | ||
| 207404 | i += 2; | ||
| 207405 | continue; | ||
| 204469 | } | 207406 | } |
| 204470 | if( pMatch==0 | 207407 | if( z[i+1]=='\r' ){ |
| 204471 | && p->nJson==nJson | 207408 | if( i+2<n && z[i+2]=='\n' ){ |
| 204472 | && (p->hasMod==0 || bUnedited==0) | 207409 | i += 3; |
| 204473 | && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) | 207410 | }else{ |
| 204474 | ){ | 207411 | i += 2; |
| 204475 | p->nErr = 0; | 207412 | } |
| 204476 | p->useMod = 0; | 207413 | continue; |
| 204477 | pMatch = p; | ||
| 204478 | }else | ||
| 204479 | if( pMatch==0 | ||
| 204480 | && p->zAlt!=0 | ||
| 204481 | && bUnedited==0 | ||
| 204482 | && p->nAlt==nJson | ||
| 204483 | && memcmp(p->zAlt, zJson, nJson)==0 | ||
| 204484 | ){ | ||
| 204485 | p->nErr = 0; | ||
| 204486 | p->useMod = 1; | ||
| 204487 | pMatch = p; | ||
| 204488 | }else if( p->iHold<iMinHold ){ | ||
| 204489 | iMinHold = p->iHold; | ||
| 204490 | iMinKey = iKey; | ||
| 204491 | } | 207414 | } |
| 204492 | if( p->iHold>iMaxHold ){ | 207415 | if( 0xe2==(u8)z[i+1] |
| 204493 | iMaxHold = p->iHold; | 207416 | && i+3<n |
| 207417 | && 0x80==(u8)z[i+2] | ||
| 207418 | && (0xa8==(u8)z[i+3] || 0xa9==(u8)z[i+3]) | ||
| 207419 | ){ | ||
| 207420 | i += 4; | ||
| 207421 | continue; | ||
| 204494 | } | 207422 | } |
| 207423 | break; | ||
| 204495 | } | 207424 | } |
| 204496 | if( pMatch ){ | 207425 | return i; |
| 204497 | /* The input JSON text was found in the cache. Use the preexisting | 207426 | } |
| 204498 | ** parse of this JSON */ | ||
| 204499 | pMatch->nErr = 0; | ||
| 204500 | pMatch->iHold = iMaxHold+1; | ||
| 204501 | assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ | ||
| 204502 | return pMatch; | ||
| 204503 | } | ||
| 204504 | 207427 | ||
| 204505 | /* The input JSON was not found anywhere in the cache. We will need | 207428 | /* |
| 204506 | ** to parse it ourselves and generate a new JsonParse object. | 207429 | ** Input z[0..n] defines JSON escape sequence including the leading '\\'. |
| 204507 | */ | 207430 | ** Decode that escape sequence into a single character. Write that |
| 204508 | bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); | 207431 | ** character into *piOut. Return the number of bytes in the escape sequence. |
| 204509 | p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); | 207432 | ** |
| 204510 | if( p==0 ){ | 207433 | ** If there is a syntax error of some kind (for example too few characters |
| 204511 | sqlite3_result_error_nomem(pCtx); | 207434 | ** after the '\\' to complete the encoding) then *piOut is set to |
| 204512 | return 0; | 207435 | ** JSON_INVALID_CHAR. |
| 207436 | */ | ||
| 207437 | static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){ | ||
| 207438 | assert( n>0 ); | ||
| 207439 | assert( z[0]=='\\' ); | ||
| 207440 | if( n<2 ){ | ||
| 207441 | *piOut = JSON_INVALID_CHAR; | ||
| 207442 | return n; | ||
| 204513 | } | 207443 | } |
| 204514 | memset(p, 0, sizeof(*p)); | 207444 | switch( (u8)z[1] ){ |
| 204515 | if( bJsonRCStr ){ | 207445 | case 'u': { |
| 204516 | p->zJson = sqlite3RCStrRef(zJson); | 207446 | u32 v, vlo; |
| 204517 | p->bJsonIsRCStr = 1; | 207447 | if( n<6 ){ |
| 204518 | }else{ | 207448 | *piOut = JSON_INVALID_CHAR; |
| 204519 | p->zJson = (char*)&p[1]; | 207449 | return n; |
| 204520 | memcpy(p->zJson, zJson, nJson+1); | 207450 | } |
| 207451 | v = jsonHexToInt4(&z[2]); | ||
| 207452 | if( (v & 0xfc00)==0xd800 | ||
| 207453 | && n>=12 | ||
| 207454 | && z[6]=='\\' | ||
| 207455 | && z[7]=='u' | ||
| 207456 | && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 | ||
| 207457 | ){ | ||
| 207458 | *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; | ||
| 207459 | return 12; | ||
| 207460 | }else{ | ||
| 207461 | *piOut = v; | ||
| 207462 | return 6; | ||
| 207463 | } | ||
| 207464 | } | ||
| 207465 | case 'b': { *piOut = '\b'; return 2; } | ||
| 207466 | case 'f': { *piOut = '\f'; return 2; } | ||
| 207467 | case 'n': { *piOut = '\n'; return 2; } | ||
| 207468 | case 'r': { *piOut = '\r'; return 2; } | ||
| 207469 | case 't': { *piOut = '\t'; return 2; } | ||
| 207470 | case 'v': { *piOut = '\v'; return 2; } | ||
| 207471 | case '0': { *piOut = 0; return 2; } | ||
| 207472 | case '\'': | ||
| 207473 | case '"': | ||
| 207474 | case '/': | ||
| 207475 | case '\\':{ *piOut = z[1]; return 2; } | ||
| 207476 | case 'x': { | ||
| 207477 | if( n<4 ){ | ||
| 207478 | *piOut = JSON_INVALID_CHAR; | ||
| 207479 | return n; | ||
| 207480 | } | ||
| 207481 | *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); | ||
| 207482 | return 4; | ||
| 207483 | } | ||
| 207484 | case 0xe2: | ||
| 207485 | case '\r': | ||
| 207486 | case '\n': { | ||
| 207487 | u32 nSkip = jsonBytesToBypass(z, n); | ||
| 207488 | if( nSkip==0 ){ | ||
| 207489 | *piOut = JSON_INVALID_CHAR; | ||
| 207490 | return n; | ||
| 207491 | }else if( nSkip==n ){ | ||
| 207492 | *piOut = 0; | ||
| 207493 | return n; | ||
| 207494 | }else if( z[nSkip]=='\\' ){ | ||
| 207495 | return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); | ||
| 207496 | }else{ | ||
| 207497 | int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); | ||
| 207498 | return nSkip + sz; | ||
| 207499 | } | ||
| 207500 | } | ||
| 207501 | default: { | ||
| 207502 | *piOut = JSON_INVALID_CHAR; | ||
| 207503 | return 2; | ||
| 207504 | } | ||
| 204521 | } | 207505 | } |
| 204522 | p->nJPRef = 1; | 207506 | } |
| 204523 | if( jsonParse(p, pErrCtx) ){ | 207507 | |
| 204524 | if( pErrCtx==0 ){ | 207508 | |
| 204525 | p->nErr = 1; | 207509 | /* |
| 204526 | assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ | 207510 | ** Compare two object labels. Return 1 if they are equal and |
| 204527 | return p; | 207511 | ** 0 if they differ. |
| 207512 | ** | ||
| 207513 | ** In this version, we know that one or the other or both of the | ||
| 207514 | ** two comparands contains an escape sequence. | ||
| 207515 | */ | ||
| 207516 | static SQLITE_NOINLINE int jsonLabelCompareEscaped( | ||
| 207517 | const char *zLeft, /* The left label */ | ||
| 207518 | u32 nLeft, /* Size of the left label in bytes */ | ||
| 207519 | int rawLeft, /* True if zLeft contains no escapes */ | ||
| 207520 | const char *zRight, /* The right label */ | ||
| 207521 | u32 nRight, /* Size of the right label in bytes */ | ||
| 207522 | int rawRight /* True if zRight is escape-free */ | ||
| 207523 | ){ | ||
| 207524 | u32 cLeft, cRight; | ||
| 207525 | assert( rawLeft==0 || rawRight==0 ); | ||
| 207526 | while( 1 /*exit-by-return*/ ){ | ||
| 207527 | if( nLeft==0 ){ | ||
| 207528 | cLeft = 0; | ||
| 207529 | }else if( rawLeft || zLeft[0]!='\\' ){ | ||
| 207530 | cLeft = ((u8*)zLeft)[0]; | ||
| 207531 | if( cLeft>=0xc0 ){ | ||
| 207532 | int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); | ||
| 207533 | zLeft += sz; | ||
| 207534 | nLeft -= sz; | ||
| 207535 | }else{ | ||
| 207536 | zLeft++; | ||
| 207537 | nLeft--; | ||
| 207538 | } | ||
| 207539 | }else{ | ||
| 207540 | u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); | ||
| 207541 | zLeft += n; | ||
| 207542 | assert( n<=nLeft ); | ||
| 207543 | nLeft -= n; | ||
| 207544 | } | ||
| 207545 | if( nRight==0 ){ | ||
| 207546 | cRight = 0; | ||
| 207547 | }else if( rawRight || zRight[0]!='\\' ){ | ||
| 207548 | cRight = ((u8*)zRight)[0]; | ||
| 207549 | if( cRight>=0xc0 ){ | ||
| 207550 | int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); | ||
| 207551 | zRight += sz; | ||
| 207552 | nRight -= sz; | ||
| 207553 | }else{ | ||
| 207554 | zRight++; | ||
| 207555 | nRight--; | ||
| 207556 | } | ||
| 207557 | }else{ | ||
| 207558 | u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); | ||
| 207559 | zRight += n; | ||
| 207560 | assert( n<=nRight ); | ||
| 207561 | nRight -= n; | ||
| 204528 | } | 207562 | } |
| 204529 | jsonParseFree(p); | 207563 | if( cLeft!=cRight ) return 0; |
| 204530 | return 0; | 207564 | if( cLeft==0 ) return 1; |
| 204531 | } | 207565 | } |
| 204532 | p->nJson = nJson; | ||
| 204533 | p->iHold = iMaxHold+1; | ||
| 204534 | /* Transfer ownership of the new JsonParse to the cache */ | ||
| 204535 | sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, | ||
| 204536 | (void(*)(void*))jsonParseFree); | ||
| 204537 | return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); | ||
| 204538 | } | 207566 | } |
| 204539 | 207567 | ||
| 204540 | /* | 207568 | /* |
| 204541 | ** Compare the OBJECT label at pNode against zKey,nKey. Return true on | 207569 | ** Compare two object labels. Return 1 if they are equal and |
| 204542 | ** a match. | 207570 | ** 0 if they differ. Return -1 if an OOM occurs. |
| 204543 | */ | 207571 | */ |
| 204544 | static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ | 207572 | static int jsonLabelCompare( |
| 204545 | assert( pNode->eU==1 ); | 207573 | const char *zLeft, /* The left label */ |
| 204546 | if( pNode->jnFlags & JNODE_RAW ){ | 207574 | u32 nLeft, /* Size of the left label in bytes */ |
| 204547 | if( pNode->n!=nKey ) return 0; | 207575 | int rawLeft, /* True if zLeft contains no escapes */ |
| 204548 | return strncmp(pNode->u.zJContent, zKey, nKey)==0; | 207576 | const char *zRight, /* The right label */ |
| 207577 | u32 nRight, /* Size of the right label in bytes */ | ||
| 207578 | int rawRight /* True if zRight is escape-free */ | ||
| 207579 | ){ | ||
| 207580 | if( rawLeft && rawRight ){ | ||
| 207581 | /* Simpliest case: Neither label contains escapes. A simple | ||
| 207582 | ** memcmp() is sufficient. */ | ||
| 207583 | if( nLeft!=nRight ) return 0; | ||
| 207584 | return memcmp(zLeft, zRight, nLeft)==0; | ||
| 204549 | }else{ | 207585 | }else{ |
| 204550 | if( pNode->n!=nKey+2 ) return 0; | 207586 | return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, |
| 204551 | return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; | 207587 | zRight, nRight, rawRight); |
| 204552 | } | 207588 | } |
| 204553 | } | 207589 | } |
| 204554 | static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ | 207590 | |
| 204555 | if( p1->jnFlags & JNODE_RAW ){ | 207591 | /* |
| 204556 | return jsonLabelCompare(p2, p1->u.zJContent, p1->n); | 207592 | ** Error returns from jsonLookupStep() |
| 204557 | }else if( p2->jnFlags & JNODE_RAW ){ | 207593 | */ |
| 204558 | return jsonLabelCompare(p1, p2->u.zJContent, p2->n); | 207594 | #define JSON_LOOKUP_ERROR 0xffffffff |
| 207595 | #define JSON_LOOKUP_NOTFOUND 0xfffffffe | ||
| 207596 | #define JSON_LOOKUP_PATHERROR 0xfffffffd | ||
| 207597 | #define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) | ||
| 207598 | |||
| 207599 | /* Forward declaration */ | ||
| 207600 | static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); | ||
| 207601 | |||
| 207602 | |||
| 207603 | /* This helper routine for jsonLookupStep() populates pIns with | ||
| 207604 | ** binary data that is to be inserted into pParse. | ||
| 207605 | ** | ||
| 207606 | ** In the common case, pIns just points to pParse->aIns and pParse->nIns. | ||
| 207607 | ** But if the zPath of the original edit operation includes path elements | ||
| 207608 | ** that go deeper, additional substructure must be created. | ||
| 207609 | ** | ||
| 207610 | ** For example: | ||
| 207611 | ** | ||
| 207612 | ** json_insert('{}', '$.a.b.c', 123); | ||
| 207613 | ** | ||
| 207614 | ** The search stops at '$.a' But additional substructure must be | ||
| 207615 | ** created for the ".b.c" part of the patch so that the final result | ||
| 207616 | ** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with | ||
| 207617 | ** the binary equivalent of {"b":{"c":123}} so that it can be inserted. | ||
| 207618 | ** | ||
| 207619 | ** The caller is responsible for resetting pIns when it has finished | ||
| 207620 | ** using the substructure. | ||
| 207621 | */ | ||
| 207622 | static u32 jsonCreateEditSubstructure( | ||
| 207623 | JsonParse *pParse, /* The original JSONB that is being edited */ | ||
| 207624 | JsonParse *pIns, /* Populate this with the blob data to insert */ | ||
| 207625 | const char *zTail /* Tail of the path that determins substructure */ | ||
| 207626 | ){ | ||
| 207627 | static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; | ||
| 207628 | int rc; | ||
| 207629 | memset(pIns, 0, sizeof(*pIns)); | ||
| 207630 | pIns->db = pParse->db; | ||
| 207631 | if( zTail[0]==0 ){ | ||
| 207632 | /* No substructure. Just insert what is given in pParse. */ | ||
| 207633 | pIns->aBlob = pParse->aIns; | ||
| 207634 | pIns->nBlob = pParse->nIns; | ||
| 207635 | rc = 0; | ||
| 204559 | }else{ | 207636 | }else{ |
| 204560 | return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; | 207637 | /* Construct the binary substructure */ |
| 207638 | pIns->nBlob = 1; | ||
| 207639 | pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; | ||
| 207640 | pIns->eEdit = pParse->eEdit; | ||
| 207641 | pIns->nIns = pParse->nIns; | ||
| 207642 | pIns->aIns = pParse->aIns; | ||
| 207643 | rc = jsonLookupStep(pIns, 0, zTail, 0); | ||
| 207644 | pParse->oom |= pIns->oom; | ||
| 204561 | } | 207645 | } |
| 207646 | return rc; /* Error code only */ | ||
| 204562 | } | 207647 | } |
| 204563 | 207648 | ||
| 204564 | /* forward declaration */ | ||
| 204565 | static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); | ||
| 204566 | |||
| 204567 | /* | 207649 | /* |
| 204568 | ** Search along zPath to find the node specified. Return a pointer | 207650 | ** Search along zPath to find the Json element specified. Return an |
| 204569 | ** to that node, or NULL if zPath is malformed or if there is no such | 207651 | ** index into pParse->aBlob[] for the start of that element's value. |
| 204570 | ** node. | 207652 | ** |
| 207653 | ** If the value found by this routine is the value half of label/value pair | ||
| 207654 | ** within an object, then set pPath->iLabel to the start of the corresponding | ||
| 207655 | ** label, before returning. | ||
| 204571 | ** | 207656 | ** |
| 204572 | ** If pApnd!=0, then try to append new nodes to complete zPath if it is | 207657 | ** Return one of the JSON_LOOKUP error codes if problems are seen. |
| 204573 | ** possible to do so and if no existing node corresponds to zPath. If | 207658 | ** |
| 204574 | ** new nodes are appended *pApnd is set to 1. | 207659 | ** This routine will also modify the blob. If pParse->eEdit is one of |
| 207660 | ** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be | ||
| 207661 | ** made to the selected value. If an edit is performed, then the return | ||
| 207662 | ** value does not necessarily point to the select element. If an edit | ||
| 207663 | ** is performed, the return value is only useful for detecting error | ||
| 207664 | ** conditions. | ||
| 204575 | */ | 207665 | */ |
| 204576 | static JsonNode *jsonLookupStep( | 207666 | static u32 jsonLookupStep( |
| 204577 | JsonParse *pParse, /* The JSON to search */ | 207667 | JsonParse *pParse, /* The JSON to search */ |
| 204578 | u32 iRoot, /* Begin the search at this node */ | 207668 | u32 iRoot, /* Begin the search at this element of aBlob[] */ |
| 204579 | const char *zPath, /* The path to search */ | 207669 | const char *zPath, /* The path to search */ |
| 204580 | int *pApnd, /* Append nodes to complete path if not NULL */ | 207670 | u32 iLabel /* Label if iRoot is a value of in an object */ |
| 204581 | const char **pzErr /* Make *pzErr point to any syntax error in zPath */ | ||
| 204582 | ){ | 207671 | ){ |
| 204583 | u32 i, j, nKey; | 207672 | u32 i, j, k, nKey, sz, n, iEnd, rc; |
| 204584 | const char *zKey; | 207673 | const char *zKey; |
| 204585 | JsonNode *pRoot; | 207674 | u8 x; |
| 204586 | if( pParse->oom ) return 0; | 207675 | |
| 204587 | pRoot = &pParse->aNode[iRoot]; | 207676 | if( zPath[0]==0 ){ |
| 204588 | if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ | 207677 | if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ |
| 204589 | while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ | 207678 | n = jsonbPayloadSize(pParse, iRoot, &sz); |
| 204590 | u32 idx = (u32)(pRoot - pParse->aNode); | 207679 | sz += n; |
| 204591 | i = pParse->iSubst; | 207680 | if( pParse->eEdit==JEDIT_DEL ){ |
| 204592 | while( 1 /*exit-by-break*/ ){ | 207681 | if( iLabel>0 ){ |
| 204593 | assert( i<pParse->nNode ); | 207682 | sz += iRoot - iLabel; |
| 204594 | assert( pParse->aNode[i].eType==JSON_SUBST ); | 207683 | iRoot = iLabel; |
| 204595 | assert( pParse->aNode[i].eU==4 ); | 207684 | } |
| 204596 | assert( pParse->aNode[i].u.iPrev<i ); | 207685 | jsonBlobEdit(pParse, iRoot, sz, 0, 0); |
| 204597 | if( pParse->aNode[i].n==idx ){ | 207686 | }else if( pParse->eEdit==JEDIT_INS ){ |
| 204598 | pRoot = &pParse->aNode[i+1]; | 207687 | /* Already exists, so json_insert() is a no-op */ |
| 204599 | iRoot = i+1; | 207688 | }else{ |
| 204600 | break; | 207689 | /* json_set() or json_replace() */ |
| 204601 | } | 207690 | jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); |
| 204602 | i = pParse->aNode[i].u.iPrev; | ||
| 204603 | } | 207691 | } |
| 204604 | } | 207692 | } |
| 204605 | if( pRoot->jnFlags & JNODE_REMOVE ){ | 207693 | pParse->iLabel = iLabel; |
| 204606 | return 0; | 207694 | return iRoot; |
| 204607 | } | ||
| 204608 | } | 207695 | } |
| 204609 | if( zPath[0]==0 ) return pRoot; | ||
| 204610 | if( zPath[0]=='.' ){ | 207696 | if( zPath[0]=='.' ){ |
| 204611 | if( pRoot->eType!=JSON_OBJECT ) return 0; | 207697 | int rawKey = 1; |
| 207698 | x = pParse->aBlob[iRoot]; | ||
| 204612 | zPath++; | 207699 | zPath++; |
| 204613 | if( zPath[0]=='"' ){ | 207700 | if( zPath[0]=='"' ){ |
| 204614 | zKey = zPath + 1; | 207701 | zKey = zPath + 1; |
| @@ -204617,251 +207704,705 @@ static JsonNode *jsonLookupStep( | |||
| 204617 | if( zPath[i] ){ | 207704 | if( zPath[i] ){ |
| 204618 | i++; | 207705 | i++; |
| 204619 | }else{ | 207706 | }else{ |
| 204620 | *pzErr = zPath; | 207707 | return JSON_LOOKUP_PATHERROR; |
| 204621 | return 0; | ||
| 204622 | } | 207708 | } |
| 204623 | testcase( nKey==0 ); | 207709 | testcase( nKey==0 ); |
| 207710 | rawKey = memchr(zKey, '\\', nKey)==0; | ||
| 204624 | }else{ | 207711 | }else{ |
| 204625 | zKey = zPath; | 207712 | zKey = zPath; |
| 204626 | for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} | 207713 | for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} |
| 204627 | nKey = i; | 207714 | nKey = i; |
| 204628 | if( nKey==0 ){ | 207715 | if( nKey==0 ){ |
| 204629 | *pzErr = zPath; | 207716 | return JSON_LOOKUP_PATHERROR; |
| 204630 | return 0; | 207717 | } |
| 204631 | } | 207718 | } |
| 204632 | } | 207719 | if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; |
| 204633 | j = 1; | 207720 | n = jsonbPayloadSize(pParse, iRoot, &sz); |
| 204634 | for(;;){ | 207721 | j = iRoot + n; /* j is the index of a label */ |
| 204635 | while( j<=pRoot->n ){ | 207722 | iEnd = j+sz; |
| 204636 | if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ | 207723 | while( j<iEnd ){ |
| 204637 | return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); | 207724 | int rawLabel; |
| 204638 | } | 207725 | const char *zLabel; |
| 204639 | j++; | 207726 | x = pParse->aBlob[j] & 0x0f; |
| 204640 | j += jsonNodeSize(&pRoot[j]); | 207727 | if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; |
| 207728 | n = jsonbPayloadSize(pParse, j, &sz); | ||
| 207729 | if( n==0 ) return JSON_LOOKUP_ERROR; | ||
| 207730 | k = j+n; /* k is the index of the label text */ | ||
| 207731 | if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; | ||
| 207732 | zLabel = (const char*)&pParse->aBlob[k]; | ||
| 207733 | rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; | ||
| 207734 | if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ | ||
| 207735 | u32 v = k+sz; /* v is the index of the value */ | ||
| 207736 | if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; | ||
| 207737 | n = jsonbPayloadSize(pParse, v, &sz); | ||
| 207738 | if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; | ||
| 207739 | assert( j>0 ); | ||
| 207740 | rc = jsonLookupStep(pParse, v, &zPath[i], j); | ||
| 207741 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); | ||
| 207742 | return rc; | ||
| 204641 | } | 207743 | } |
| 204642 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; | 207744 | j = k+sz; |
| 204643 | if( pParse->useMod==0 ) break; | 207745 | if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; |
| 204644 | assert( pRoot->eU==2 ); | 207746 | n = jsonbPayloadSize(pParse, j, &sz); |
| 204645 | iRoot = pRoot->u.iAppend; | 207747 | if( n==0 ) return JSON_LOOKUP_ERROR; |
| 204646 | pRoot = &pParse->aNode[iRoot]; | 207748 | j += n+sz; |
| 204647 | j = 1; | 207749 | } |
| 204648 | } | 207750 | if( j>iEnd ) return JSON_LOOKUP_ERROR; |
| 204649 | if( pApnd ){ | 207751 | if( pParse->eEdit>=JEDIT_INS ){ |
| 204650 | u32 iStart, iLabel; | 207752 | u32 nIns; /* Total bytes to insert (label+value) */ |
| 204651 | JsonNode *pNode; | 207753 | JsonParse v; /* BLOB encoding of the value to be inserted */ |
| 204652 | assert( pParse->useMod ); | 207754 | JsonParse ix; /* Header of the label to be inserted */ |
| 204653 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); | 207755 | testcase( pParse->eEdit==JEDIT_INS ); |
| 204654 | iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); | 207756 | testcase( pParse->eEdit==JEDIT_SET ); |
| 204655 | zPath += i; | 207757 | memset(&ix, 0, sizeof(ix)); |
| 204656 | pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); | 207758 | ix.db = pParse->db; |
| 204657 | if( pParse->oom ) return 0; | 207759 | jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); |
| 204658 | if( pNode ){ | 207760 | pParse->oom |= ix.oom; |
| 204659 | pRoot = &pParse->aNode[iRoot]; | 207761 | rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); |
| 204660 | assert( pRoot->eU==0 ); | 207762 | if( !JSON_LOOKUP_ISERROR(rc) |
| 204661 | pRoot->u.iAppend = iStart; | 207763 | && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) |
| 204662 | pRoot->jnFlags |= JNODE_APPEND; | 207764 | ){ |
| 204663 | VVA( pRoot->eU = 2 ); | 207765 | assert( !pParse->oom ); |
| 204664 | pParse->aNode[iLabel].jnFlags |= JNODE_RAW; | 207766 | nIns = ix.nBlob + nKey + v.nBlob; |
| 204665 | } | 207767 | jsonBlobEdit(pParse, j, 0, 0, nIns); |
| 204666 | return pNode; | 207768 | if( !pParse->oom ){ |
| 207769 | assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ | ||
| 207770 | assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ | ||
| 207771 | memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); | ||
| 207772 | k = j + ix.nBlob; | ||
| 207773 | memcpy(&pParse->aBlob[k], zKey, nKey); | ||
| 207774 | k += nKey; | ||
| 207775 | memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); | ||
| 207776 | if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); | ||
| 207777 | } | ||
| 207778 | } | ||
| 207779 | jsonParseReset(&v); | ||
| 207780 | jsonParseReset(&ix); | ||
| 207781 | return rc; | ||
| 204667 | } | 207782 | } |
| 204668 | }else if( zPath[0]=='[' ){ | 207783 | }else if( zPath[0]=='[' ){ |
| 204669 | i = 0; | 207784 | x = pParse->aBlob[iRoot] & 0x0f; |
| 204670 | j = 1; | 207785 | if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; |
| 204671 | while( sqlite3Isdigit(zPath[j]) ){ | 207786 | n = jsonbPayloadSize(pParse, iRoot, &sz); |
| 204672 | i = i*10 + zPath[j] - '0'; | 207787 | k = 0; |
| 204673 | j++; | 207788 | i = 1; |
| 207789 | while( sqlite3Isdigit(zPath[i]) ){ | ||
| 207790 | k = k*10 + zPath[i] - '0'; | ||
| 207791 | i++; | ||
| 204674 | } | 207792 | } |
| 204675 | if( j<2 || zPath[j]!=']' ){ | 207793 | if( i<2 || zPath[i]!=']' ){ |
| 204676 | if( zPath[1]=='#' ){ | 207794 | if( zPath[1]=='#' ){ |
| 204677 | JsonNode *pBase = pRoot; | 207795 | k = jsonbArrayCount(pParse, iRoot); |
| 204678 | int iBase = iRoot; | 207796 | i = 2; |
| 204679 | if( pRoot->eType!=JSON_ARRAY ) return 0; | ||
| 204680 | for(;;){ | ||
| 204681 | while( j<=pBase->n ){ | ||
| 204682 | if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; | ||
| 204683 | j += jsonNodeSize(&pBase[j]); | ||
| 204684 | } | ||
| 204685 | if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; | ||
| 204686 | if( pParse->useMod==0 ) break; | ||
| 204687 | assert( pBase->eU==2 ); | ||
| 204688 | iBase = pBase->u.iAppend; | ||
| 204689 | pBase = &pParse->aNode[iBase]; | ||
| 204690 | j = 1; | ||
| 204691 | } | ||
| 204692 | j = 2; | ||
| 204693 | if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ | 207797 | if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ |
| 204694 | unsigned int x = 0; | 207798 | unsigned int nn = 0; |
| 204695 | j = 3; | 207799 | i = 3; |
| 204696 | do{ | 207800 | do{ |
| 204697 | x = x*10 + zPath[j] - '0'; | 207801 | nn = nn*10 + zPath[i] - '0'; |
| 204698 | j++; | 207802 | i++; |
| 204699 | }while( sqlite3Isdigit(zPath[j]) ); | 207803 | }while( sqlite3Isdigit(zPath[i]) ); |
| 204700 | if( x>i ) return 0; | 207804 | if( nn>k ) return JSON_LOOKUP_NOTFOUND; |
| 204701 | i -= x; | 207805 | k -= nn; |
| 204702 | } | 207806 | } |
| 204703 | if( zPath[j]!=']' ){ | 207807 | if( zPath[i]!=']' ){ |
| 204704 | *pzErr = zPath; | 207808 | return JSON_LOOKUP_PATHERROR; |
| 204705 | return 0; | ||
| 204706 | } | 207809 | } |
| 204707 | }else{ | 207810 | }else{ |
| 204708 | *pzErr = zPath; | 207811 | return JSON_LOOKUP_PATHERROR; |
| 204709 | return 0; | ||
| 204710 | } | 207812 | } |
| 204711 | } | 207813 | } |
| 204712 | if( pRoot->eType!=JSON_ARRAY ) return 0; | 207814 | j = iRoot+n; |
| 204713 | zPath += j + 1; | 207815 | iEnd = j+sz; |
| 204714 | j = 1; | 207816 | while( j<iEnd ){ |
| 204715 | for(;;){ | 207817 | if( k==0 ){ |
| 204716 | while( j<=pRoot->n | 207818 | rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); |
| 204717 | && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) | 207819 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); |
| 207820 | return rc; | ||
| 207821 | } | ||
| 207822 | k--; | ||
| 207823 | n = jsonbPayloadSize(pParse, j, &sz); | ||
| 207824 | if( n==0 ) return JSON_LOOKUP_ERROR; | ||
| 207825 | j += n+sz; | ||
| 207826 | } | ||
| 207827 | if( j>iEnd ) return JSON_LOOKUP_ERROR; | ||
| 207828 | if( k>0 ) return JSON_LOOKUP_NOTFOUND; | ||
| 207829 | if( pParse->eEdit>=JEDIT_INS ){ | ||
| 207830 | JsonParse v; | ||
| 207831 | testcase( pParse->eEdit==JEDIT_INS ); | ||
| 207832 | testcase( pParse->eEdit==JEDIT_SET ); | ||
| 207833 | rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); | ||
| 207834 | if( !JSON_LOOKUP_ISERROR(rc) | ||
| 207835 | && jsonBlobMakeEditable(pParse, v.nBlob) | ||
| 204718 | ){ | 207836 | ){ |
| 204719 | if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; | 207837 | assert( !pParse->oom ); |
| 204720 | j += jsonNodeSize(&pRoot[j]); | 207838 | jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); |
| 204721 | } | ||
| 204722 | if( i==0 && j<=pRoot->n ) break; | ||
| 204723 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; | ||
| 204724 | if( pParse->useMod==0 ) break; | ||
| 204725 | assert( pRoot->eU==2 ); | ||
| 204726 | iRoot = pRoot->u.iAppend; | ||
| 204727 | pRoot = &pParse->aNode[iRoot]; | ||
| 204728 | j = 1; | ||
| 204729 | } | ||
| 204730 | if( j<=pRoot->n ){ | ||
| 204731 | return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); | ||
| 204732 | } | ||
| 204733 | if( i==0 && pApnd ){ | ||
| 204734 | u32 iStart; | ||
| 204735 | JsonNode *pNode; | ||
| 204736 | assert( pParse->useMod ); | ||
| 204737 | iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); | ||
| 204738 | pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); | ||
| 204739 | if( pParse->oom ) return 0; | ||
| 204740 | if( pNode ){ | ||
| 204741 | pRoot = &pParse->aNode[iRoot]; | ||
| 204742 | assert( pRoot->eU==0 ); | ||
| 204743 | pRoot->u.iAppend = iStart; | ||
| 204744 | pRoot->jnFlags |= JNODE_APPEND; | ||
| 204745 | VVA( pRoot->eU = 2 ); | ||
| 204746 | } | 207839 | } |
| 204747 | return pNode; | 207840 | jsonParseReset(&v); |
| 207841 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); | ||
| 207842 | return rc; | ||
| 204748 | } | 207843 | } |
| 204749 | }else{ | 207844 | }else{ |
| 204750 | *pzErr = zPath; | 207845 | return JSON_LOOKUP_PATHERROR; |
| 204751 | } | 207846 | } |
| 204752 | return 0; | 207847 | return JSON_LOOKUP_NOTFOUND; |
| 204753 | } | 207848 | } |
| 204754 | 207849 | ||
| 204755 | /* | 207850 | /* |
| 204756 | ** Append content to pParse that will complete zPath. Return a pointer | 207851 | ** Convert a JSON BLOB into text and make that text the return value |
| 204757 | ** to the inserted node, or return NULL if the append fails. | 207852 | ** of an SQL function. |
| 204758 | */ | 207853 | */ |
| 204759 | static JsonNode *jsonLookupAppend( | 207854 | static void jsonReturnTextJsonFromBlob( |
| 204760 | JsonParse *pParse, /* Append content to the JSON parse */ | 207855 | sqlite3_context *ctx, |
| 204761 | const char *zPath, /* Description of content to append */ | 207856 | const u8 *aBlob, |
| 204762 | int *pApnd, /* Set this flag to 1 */ | 207857 | u32 nBlob |
| 204763 | const char **pzErr /* Make this point to any syntax error */ | ||
| 204764 | ){ | 207858 | ){ |
| 204765 | *pApnd = 1; | 207859 | JsonParse x; |
| 204766 | if( zPath[0]==0 ){ | 207860 | JsonString s; |
| 204767 | jsonParseAddNode(pParse, JSON_NULL, 0, 0); | 207861 | |
| 204768 | return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; | 207862 | if( NEVER(aBlob==0) ) return; |
| 204769 | } | 207863 | memset(&x, 0, sizeof(x)); |
| 204770 | if( zPath[0]=='.' ){ | 207864 | x.aBlob = (u8*)aBlob; |
| 204771 | jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); | 207865 | x.nBlob = nBlob; |
| 204772 | }else if( strncmp(zPath,"[0]",3)==0 ){ | 207866 | jsonStringInit(&s, ctx); |
| 204773 | jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); | 207867 | jsonTranslateBlobToText(&x, 0, &s); |
| 204774 | }else{ | 207868 | jsonReturnString(&s, 0, 0); |
| 204775 | return 0; | ||
| 204776 | } | ||
| 204777 | if( pParse->oom ) return 0; | ||
| 204778 | return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); | ||
| 204779 | } | 207869 | } |
| 204780 | 207870 | ||
| 207871 | |||
| 204781 | /* | 207872 | /* |
| 204782 | ** Return the text of a syntax error message on a JSON path. Space is | 207873 | ** Return the value of the BLOB node at index i. |
| 204783 | ** obtained from sqlite3_malloc(). | 207874 | ** |
| 207875 | ** If the value is a primitive, return it as an SQL value. | ||
| 207876 | ** If the value is an array or object, return it as either | ||
| 207877 | ** JSON text or the BLOB encoding, depending on the JSON_B flag | ||
| 207878 | ** on the userdata. | ||
| 204784 | */ | 207879 | */ |
| 204785 | static char *jsonPathSyntaxError(const char *zErr){ | 207880 | static void jsonReturnFromBlob( |
| 204786 | return sqlite3_mprintf("JSON path error near '%q'", zErr); | 207881 | JsonParse *pParse, /* Complete JSON parse tree */ |
| 207882 | u32 i, /* Index of the node */ | ||
| 207883 | sqlite3_context *pCtx, /* Return value for this function */ | ||
| 207884 | int textOnly /* return text JSON. Disregard user-data */ | ||
| 207885 | ){ | ||
| 207886 | u32 n, sz; | ||
| 207887 | int rc; | ||
| 207888 | sqlite3 *db = sqlite3_context_db_handle(pCtx); | ||
| 207889 | |||
| 207890 | n = jsonbPayloadSize(pParse, i, &sz); | ||
| 207891 | if( n==0 ){ | ||
| 207892 | sqlite3_result_error(pCtx, "malformed JSON", -1); | ||
| 207893 | return; | ||
| 207894 | } | ||
| 207895 | switch( pParse->aBlob[i] & 0x0f ){ | ||
| 207896 | case JSONB_NULL: { | ||
| 207897 | if( sz ) goto returnfromblob_malformed; | ||
| 207898 | sqlite3_result_null(pCtx); | ||
| 207899 | break; | ||
| 207900 | } | ||
| 207901 | case JSONB_TRUE: { | ||
| 207902 | if( sz ) goto returnfromblob_malformed; | ||
| 207903 | sqlite3_result_int(pCtx, 1); | ||
| 207904 | break; | ||
| 207905 | } | ||
| 207906 | case JSONB_FALSE: { | ||
| 207907 | if( sz ) goto returnfromblob_malformed; | ||
| 207908 | sqlite3_result_int(pCtx, 0); | ||
| 207909 | break; | ||
| 207910 | } | ||
| 207911 | case JSONB_INT5: | ||
| 207912 | case JSONB_INT: { | ||
| 207913 | sqlite3_int64 iRes = 0; | ||
| 207914 | char *z; | ||
| 207915 | int bNeg = 0; | ||
| 207916 | char x; | ||
| 207917 | if( sz==0 ) goto returnfromblob_malformed; | ||
| 207918 | x = (char)pParse->aBlob[i+n]; | ||
| 207919 | if( x=='-' ){ | ||
| 207920 | if( sz<2 ) goto returnfromblob_malformed; | ||
| 207921 | n++; | ||
| 207922 | sz--; | ||
| 207923 | bNeg = 1; | ||
| 207924 | } | ||
| 207925 | z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); | ||
| 207926 | if( z==0 ) goto returnfromblob_oom; | ||
| 207927 | rc = sqlite3DecOrHexToI64(z, &iRes); | ||
| 207928 | sqlite3DbFree(db, z); | ||
| 207929 | if( rc==0 ){ | ||
| 207930 | sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); | ||
| 207931 | }else if( rc==3 && bNeg ){ | ||
| 207932 | sqlite3_result_int64(pCtx, SMALLEST_INT64); | ||
| 207933 | }else if( rc==1 ){ | ||
| 207934 | goto returnfromblob_malformed; | ||
| 207935 | }else{ | ||
| 207936 | if( bNeg ){ n--; sz++; } | ||
| 207937 | goto to_double; | ||
| 207938 | } | ||
| 207939 | break; | ||
| 207940 | } | ||
| 207941 | case JSONB_FLOAT5: | ||
| 207942 | case JSONB_FLOAT: { | ||
| 207943 | double r; | ||
| 207944 | char *z; | ||
| 207945 | if( sz==0 ) goto returnfromblob_malformed; | ||
| 207946 | to_double: | ||
| 207947 | z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); | ||
| 207948 | if( z==0 ) goto returnfromblob_oom; | ||
| 207949 | rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); | ||
| 207950 | sqlite3DbFree(db, z); | ||
| 207951 | if( rc<=0 ) goto returnfromblob_malformed; | ||
| 207952 | sqlite3_result_double(pCtx, r); | ||
| 207953 | break; | ||
| 207954 | } | ||
| 207955 | case JSONB_TEXTRAW: | ||
| 207956 | case JSONB_TEXT: { | ||
| 207957 | sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, | ||
| 207958 | SQLITE_TRANSIENT); | ||
| 207959 | break; | ||
| 207960 | } | ||
| 207961 | case JSONB_TEXT5: | ||
| 207962 | case JSONB_TEXTJ: { | ||
| 207963 | /* Translate JSON formatted string into raw text */ | ||
| 207964 | u32 iIn, iOut; | ||
| 207965 | const char *z; | ||
| 207966 | char *zOut; | ||
| 207967 | u32 nOut = sz; | ||
| 207968 | z = (const char*)&pParse->aBlob[i+n]; | ||
| 207969 | zOut = sqlite3DbMallocRaw(db, nOut+1); | ||
| 207970 | if( zOut==0 ) goto returnfromblob_oom; | ||
| 207971 | for(iIn=iOut=0; iIn<sz; iIn++){ | ||
| 207972 | char c = z[iIn]; | ||
| 207973 | if( c=='\\' ){ | ||
| 207974 | u32 v; | ||
| 207975 | u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v); | ||
| 207976 | if( v<=0x7f ){ | ||
| 207977 | zOut[iOut++] = (char)v; | ||
| 207978 | }else if( v<=0x7ff ){ | ||
| 207979 | assert( szEscape>=2 ); | ||
| 207980 | zOut[iOut++] = (char)(0xc0 | (v>>6)); | ||
| 207981 | zOut[iOut++] = 0x80 | (v&0x3f); | ||
| 207982 | }else if( v<0x10000 ){ | ||
| 207983 | assert( szEscape>=3 ); | ||
| 207984 | zOut[iOut++] = 0xe0 | (v>>12); | ||
| 207985 | zOut[iOut++] = 0x80 | ((v>>6)&0x3f); | ||
| 207986 | zOut[iOut++] = 0x80 | (v&0x3f); | ||
| 207987 | }else if( v==JSON_INVALID_CHAR ){ | ||
| 207988 | /* Silently ignore illegal unicode */ | ||
| 207989 | }else{ | ||
| 207990 | assert( szEscape>=4 ); | ||
| 207991 | zOut[iOut++] = 0xf0 | (v>>18); | ||
| 207992 | zOut[iOut++] = 0x80 | ((v>>12)&0x3f); | ||
| 207993 | zOut[iOut++] = 0x80 | ((v>>6)&0x3f); | ||
| 207994 | zOut[iOut++] = 0x80 | (v&0x3f); | ||
| 207995 | } | ||
| 207996 | iIn += szEscape - 1; | ||
| 207997 | }else{ | ||
| 207998 | zOut[iOut++] = c; | ||
| 207999 | } | ||
| 208000 | } /* end for() */ | ||
| 208001 | assert( iOut<=nOut ); | ||
| 208002 | zOut[iOut] = 0; | ||
| 208003 | sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); | ||
| 208004 | break; | ||
| 208005 | } | ||
| 208006 | case JSONB_ARRAY: | ||
| 208007 | case JSONB_OBJECT: { | ||
| 208008 | int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)); | ||
| 208009 | if( flags & JSON_BLOB ){ | ||
| 208010 | sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); | ||
| 208011 | }else{ | ||
| 208012 | jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); | ||
| 208013 | } | ||
| 208014 | break; | ||
| 208015 | } | ||
| 208016 | default: { | ||
| 208017 | goto returnfromblob_malformed; | ||
| 208018 | } | ||
| 208019 | } | ||
| 208020 | return; | ||
| 208021 | |||
| 208022 | returnfromblob_oom: | ||
| 208023 | sqlite3_result_error_nomem(pCtx); | ||
| 208024 | return; | ||
| 208025 | |||
| 208026 | returnfromblob_malformed: | ||
| 208027 | sqlite3_result_error(pCtx, "malformed JSON", -1); | ||
| 208028 | return; | ||
| 204787 | } | 208029 | } |
| 204788 | 208030 | ||
| 204789 | /* | 208031 | /* |
| 204790 | ** Do a node lookup using zPath. Return a pointer to the node on success. | 208032 | ** pArg is a function argument that might be an SQL value or a JSON |
| 204791 | ** Return NULL if not found or if there is an error. | 208033 | ** value. Figure out what it is and encode it as a JSONB blob. |
| 208034 | ** Return the results in pParse. | ||
| 204792 | ** | 208035 | ** |
| 204793 | ** On an error, write an error message into pCtx and increment the | 208036 | ** pParse is uninitialized upon entry. This routine will handle the |
| 204794 | ** pParse->nErr counter. | 208037 | ** initialization of pParse. The result will be contained in |
| 208038 | ** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically | ||
| 208039 | ** allocated (if pParse->nBlobAlloc is greater than zero) in which case | ||
| 208040 | ** the caller is responsible for freeing the space allocated to pParse->aBlob | ||
| 208041 | ** when it has finished with it. Or pParse->aBlob might be a static string | ||
| 208042 | ** or a value obtained from sqlite3_value_blob(pArg). | ||
| 204795 | ** | 208043 | ** |
| 204796 | ** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if | 208044 | ** If the argument is a BLOB that is clearly not a JSONB, then this |
| 204797 | ** nodes are appended. | 208045 | ** function might set an error message in ctx and return non-zero. |
| 208046 | ** It might also set an error message and return non-zero on an OOM error. | ||
| 204798 | */ | 208047 | */ |
| 204799 | static JsonNode *jsonLookup( | 208048 | static int jsonFunctionArgToBlob( |
| 204800 | JsonParse *pParse, /* The JSON to search */ | 208049 | sqlite3_context *ctx, |
| 204801 | const char *zPath, /* The path to search */ | 208050 | sqlite3_value *pArg, |
| 204802 | int *pApnd, /* Append nodes to complete path if not NULL */ | 208051 | JsonParse *pParse |
| 204803 | sqlite3_context *pCtx /* Report errors here, if not NULL */ | 208052 | ){ |
| 204804 | ){ | 208053 | int eType = sqlite3_value_type(pArg); |
| 204805 | const char *zErr = 0; | 208054 | static u8 aNull[] = { 0x00 }; |
| 204806 | JsonNode *pNode = 0; | 208055 | memset(pParse, 0, sizeof(pParse[0])); |
| 204807 | char *zMsg; | 208056 | pParse->db = sqlite3_context_db_handle(ctx); |
| 204808 | 208057 | switch( eType ){ | |
| 204809 | if( zPath==0 ) return 0; | 208058 | default: { |
| 204810 | if( zPath[0]!='$' ){ | 208059 | pParse->aBlob = aNull; |
| 204811 | zErr = zPath; | 208060 | pParse->nBlob = 1; |
| 204812 | goto lookup_err; | 208061 | return 0; |
| 208062 | } | ||
| 208063 | case SQLITE_BLOB: { | ||
| 208064 | if( jsonFuncArgMightBeBinary(pArg) ){ | ||
| 208065 | pParse->aBlob = (u8*)sqlite3_value_blob(pArg); | ||
| 208066 | pParse->nBlob = sqlite3_value_bytes(pArg); | ||
| 208067 | }else{ | ||
| 208068 | sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); | ||
| 208069 | return 1; | ||
| 208070 | } | ||
| 208071 | break; | ||
| 208072 | } | ||
| 208073 | case SQLITE_TEXT: { | ||
| 208074 | const char *zJson = (const char*)sqlite3_value_text(pArg); | ||
| 208075 | int nJson = sqlite3_value_bytes(pArg); | ||
| 208076 | if( zJson==0 ) return 1; | ||
| 208077 | if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ | ||
| 208078 | pParse->zJson = (char*)zJson; | ||
| 208079 | pParse->nJson = nJson; | ||
| 208080 | if( jsonConvertTextToBlob(pParse, ctx) ){ | ||
| 208081 | sqlite3_result_error(ctx, "malformed JSON", -1); | ||
| 208082 | sqlite3DbFree(pParse->db, pParse->aBlob); | ||
| 208083 | memset(pParse, 0, sizeof(pParse[0])); | ||
| 208084 | return 1; | ||
| 208085 | } | ||
| 208086 | }else{ | ||
| 208087 | jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); | ||
| 208088 | } | ||
| 208089 | break; | ||
| 208090 | } | ||
| 208091 | case SQLITE_FLOAT: { | ||
| 208092 | double r = sqlite3_value_double(pArg); | ||
| 208093 | if( NEVER(sqlite3IsNaN(r)) ){ | ||
| 208094 | jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); | ||
| 208095 | }else{ | ||
| 208096 | int n = sqlite3_value_bytes(pArg); | ||
| 208097 | const char *z = (const char*)sqlite3_value_text(pArg); | ||
| 208098 | if( z==0 ) return 1; | ||
| 208099 | if( z[0]=='I' ){ | ||
| 208100 | jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); | ||
| 208101 | }else if( z[0]=='-' && z[1]=='I' ){ | ||
| 208102 | jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); | ||
| 208103 | }else{ | ||
| 208104 | jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); | ||
| 208105 | } | ||
| 208106 | } | ||
| 208107 | break; | ||
| 208108 | } | ||
| 208109 | case SQLITE_INTEGER: { | ||
| 208110 | int n = sqlite3_value_bytes(pArg); | ||
| 208111 | const char *z = (const char*)sqlite3_value_text(pArg); | ||
| 208112 | if( z==0 ) return 1; | ||
| 208113 | jsonBlobAppendNode(pParse, JSONB_INT, n, z); | ||
| 208114 | break; | ||
| 208115 | } | ||
| 208116 | } | ||
| 208117 | if( pParse->oom ){ | ||
| 208118 | sqlite3_result_error_nomem(ctx); | ||
| 208119 | return 1; | ||
| 208120 | }else{ | ||
| 208121 | return 0; | ||
| 204813 | } | 208122 | } |
| 204814 | zPath++; | 208123 | } |
| 204815 | pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); | ||
| 204816 | if( zErr==0 ) return pNode; | ||
| 204817 | 208124 | ||
| 204818 | lookup_err: | 208125 | /* |
| 204819 | pParse->nErr++; | 208126 | ** Generate a bad path error. |
| 204820 | assert( zErr!=0 && pCtx!=0 ); | 208127 | ** |
| 204821 | zMsg = jsonPathSyntaxError(zErr); | 208128 | ** If ctx is not NULL then push the error message into ctx and return NULL. |
| 208129 | ** If ctx is NULL, then return the text of the error message. | ||
| 208130 | */ | ||
| 208131 | static char *jsonBadPathError( | ||
| 208132 | sqlite3_context *ctx, /* The function call containing the error */ | ||
| 208133 | const char *zPath /* The path with the problem */ | ||
| 208134 | ){ | ||
| 208135 | char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); | ||
| 208136 | if( ctx==0 ) return zMsg; | ||
| 204822 | if( zMsg ){ | 208137 | if( zMsg ){ |
| 204823 | sqlite3_result_error(pCtx, zMsg, -1); | 208138 | sqlite3_result_error(ctx, zMsg, -1); |
| 204824 | sqlite3_free(zMsg); | 208139 | sqlite3_free(zMsg); |
| 204825 | }else{ | 208140 | }else{ |
| 204826 | sqlite3_result_error_nomem(pCtx); | 208141 | sqlite3_result_error_nomem(ctx); |
| 204827 | } | 208142 | } |
| 204828 | return 0; | 208143 | return 0; |
| 204829 | } | 208144 | } |
| 204830 | 208145 | ||
| 208146 | /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent | ||
| 208147 | ** arguments come in parse where each pair contains a JSON path and | ||
| 208148 | ** content to insert or set at that patch. Do the updates | ||
| 208149 | ** and return the result. | ||
| 208150 | ** | ||
| 208151 | ** The specific operation is determined by eEdit, which can be one | ||
| 208152 | ** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. | ||
| 208153 | */ | ||
| 208154 | static void jsonInsertIntoBlob( | ||
| 208155 | sqlite3_context *ctx, | ||
| 208156 | int argc, | ||
| 208157 | sqlite3_value **argv, | ||
| 208158 | int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ | ||
| 208159 | ){ | ||
| 208160 | int i; | ||
| 208161 | u32 rc = 0; | ||
| 208162 | const char *zPath = 0; | ||
| 208163 | int flgs; | ||
| 208164 | JsonParse *p; | ||
| 208165 | JsonParse ax; | ||
| 208166 | |||
| 208167 | assert( (argc&1)==1 ); | ||
| 208168 | flgs = argc==1 ? 0 : JSON_EDITABLE; | ||
| 208169 | p = jsonParseFuncArg(ctx, argv[0], flgs); | ||
| 208170 | if( p==0 ) return; | ||
| 208171 | for(i=1; i<argc-1; i+=2){ | ||
| 208172 | if( sqlite3_value_type(argv[i])==SQLITE_NULL ) continue; | ||
| 208173 | zPath = (const char*)sqlite3_value_text(argv[i]); | ||
| 208174 | if( zPath==0 ){ | ||
| 208175 | sqlite3_result_error_nomem(ctx); | ||
| 208176 | jsonParseFree(p); | ||
| 208177 | return; | ||
| 208178 | } | ||
| 208179 | if( zPath[0]!='$' ) goto jsonInsertIntoBlob_patherror; | ||
| 208180 | if( jsonFunctionArgToBlob(ctx, argv[i+1], &ax) ){ | ||
| 208181 | jsonParseReset(&ax); | ||
| 208182 | jsonParseFree(p); | ||
| 208183 | return; | ||
| 208184 | } | ||
| 208185 | if( zPath[1]==0 ){ | ||
| 208186 | if( eEdit==JEDIT_REPL || eEdit==JEDIT_SET ){ | ||
| 208187 | jsonBlobEdit(p, 0, p->nBlob, ax.aBlob, ax.nBlob); | ||
| 208188 | } | ||
| 208189 | rc = 0; | ||
| 208190 | }else{ | ||
| 208191 | p->eEdit = eEdit; | ||
| 208192 | p->nIns = ax.nBlob; | ||
| 208193 | p->aIns = ax.aBlob; | ||
| 208194 | p->delta = 0; | ||
| 208195 | rc = jsonLookupStep(p, 0, zPath+1, 0); | ||
| 208196 | } | ||
| 208197 | jsonParseReset(&ax); | ||
| 208198 | if( rc==JSON_LOOKUP_NOTFOUND ) continue; | ||
| 208199 | if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; | ||
| 208200 | } | ||
| 208201 | jsonReturnParse(ctx, p); | ||
| 208202 | jsonParseFree(p); | ||
| 208203 | return; | ||
| 208204 | |||
| 208205 | jsonInsertIntoBlob_patherror: | ||
| 208206 | jsonParseFree(p); | ||
| 208207 | if( rc==JSON_LOOKUP_ERROR ){ | ||
| 208208 | sqlite3_result_error(ctx, "malformed JSON", -1); | ||
| 208209 | }else{ | ||
| 208210 | jsonBadPathError(ctx, zPath); | ||
| 208211 | } | ||
| 208212 | return; | ||
| 208213 | } | ||
| 204831 | 208214 | ||
| 204832 | /* | 208215 | /* |
| 204833 | ** Report the wrong number of arguments for json_insert(), json_replace() | 208216 | ** If pArg is a blob that seems like a JSONB blob, then initialize |
| 204834 | ** or json_set(). | 208217 | ** p to point to that JSONB and return TRUE. If pArg does not seem like |
| 208218 | ** a JSONB blob, then return FALSE; | ||
| 208219 | ** | ||
| 208220 | ** This routine is only called if it is already known that pArg is a | ||
| 208221 | ** blob. The only open question is whether or not the blob appears | ||
| 208222 | ** to be a JSONB blob. | ||
| 204835 | */ | 208223 | */ |
| 204836 | static void jsonWrongNumArgs( | 208224 | static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ |
| 204837 | sqlite3_context *pCtx, | 208225 | u32 n, sz = 0; |
| 204838 | const char *zFuncName | 208226 | p->aBlob = (u8*)sqlite3_value_blob(pArg); |
| 204839 | ){ | 208227 | p->nBlob = (u32)sqlite3_value_bytes(pArg); |
| 204840 | char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", | 208228 | if( p->nBlob==0 ){ |
| 204841 | zFuncName); | 208229 | p->aBlob = 0; |
| 204842 | sqlite3_result_error(pCtx, zMsg, -1); | 208230 | return 0; |
| 204843 | sqlite3_free(zMsg); | 208231 | } |
| 208232 | if( NEVER(p->aBlob==0) ){ | ||
| 208233 | return 0; | ||
| 208234 | } | ||
| 208235 | if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT | ||
| 208236 | && (n = jsonbPayloadSize(p, 0, &sz))>0 | ||
| 208237 | && sz+n==p->nBlob | ||
| 208238 | && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) | ||
| 208239 | ){ | ||
| 208240 | return 1; | ||
| 208241 | } | ||
| 208242 | p->aBlob = 0; | ||
| 208243 | p->nBlob = 0; | ||
| 208244 | return 0; | ||
| 204844 | } | 208245 | } |
| 204845 | 208246 | ||
| 204846 | /* | 208247 | /* |
| 204847 | ** Mark all NULL entries in the Object passed in as JNODE_REMOVE. | 208248 | ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, |
| 208249 | ** from the SQL function argument pArg. Return a pointer to the new | ||
| 208250 | ** JsonParse object. | ||
| 208251 | ** | ||
| 208252 | ** Ownership of the new JsonParse object is passed to the caller. The | ||
| 208253 | ** caller should invoke jsonParseFree() on the return value when it | ||
| 208254 | ** has finished using it. | ||
| 208255 | ** | ||
| 208256 | ** If any errors are detected, an appropriate error messages is set | ||
| 208257 | ** using sqlite3_result_error() or the equivalent and this routine | ||
| 208258 | ** returns NULL. This routine also returns NULL if the pArg argument | ||
| 208259 | ** is an SQL NULL value, but no error message is set in that case. This | ||
| 208260 | ** is so that SQL functions that are given NULL arguments will return | ||
| 208261 | ** a NULL value. | ||
| 204848 | */ | 208262 | */ |
| 204849 | static void jsonRemoveAllNulls(JsonNode *pNode){ | 208263 | static JsonParse *jsonParseFuncArg( |
| 204850 | int i, n; | 208264 | sqlite3_context *ctx, |
| 204851 | assert( pNode->eType==JSON_OBJECT ); | 208265 | sqlite3_value *pArg, |
| 204852 | n = pNode->n; | 208266 | u32 flgs |
| 204853 | for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ | 208267 | ){ |
| 204854 | switch( pNode[i].eType ){ | 208268 | int eType; /* Datatype of pArg */ |
| 204855 | case JSON_NULL: | 208269 | JsonParse *p = 0; /* Value to be returned */ |
| 204856 | pNode[i].jnFlags |= JNODE_REMOVE; | 208270 | JsonParse *pFromCache = 0; /* Value taken from cache */ |
| 204857 | break; | 208271 | sqlite3 *db; /* The database connection */ |
| 204858 | case JSON_OBJECT: | 208272 | |
| 204859 | jsonRemoveAllNulls(&pNode[i]); | 208273 | assert( ctx!=0 ); |
| 204860 | break; | 208274 | eType = sqlite3_value_type(pArg); |
| 208275 | if( eType==SQLITE_NULL ){ | ||
| 208276 | return 0; | ||
| 208277 | } | ||
| 208278 | pFromCache = jsonCacheSearch(ctx, pArg); | ||
| 208279 | if( pFromCache ){ | ||
| 208280 | pFromCache->nJPRef++; | ||
| 208281 | if( (flgs & JSON_EDITABLE)==0 ){ | ||
| 208282 | return pFromCache; | ||
| 208283 | } | ||
| 208284 | } | ||
| 208285 | db = sqlite3_context_db_handle(ctx); | ||
| 208286 | rebuild_from_cache: | ||
| 208287 | p = sqlite3DbMallocZero(db, sizeof(*p)); | ||
| 208288 | if( p==0 ) goto json_pfa_oom; | ||
| 208289 | memset(p, 0, sizeof(*p)); | ||
| 208290 | p->db = db; | ||
| 208291 | p->nJPRef = 1; | ||
| 208292 | if( pFromCache!=0 ){ | ||
| 208293 | u32 nBlob = pFromCache->nBlob; | ||
| 208294 | p->aBlob = sqlite3DbMallocRaw(db, nBlob); | ||
| 208295 | if( p->aBlob==0 ) goto json_pfa_oom; | ||
| 208296 | memcpy(p->aBlob, pFromCache->aBlob, nBlob); | ||
| 208297 | p->nBlobAlloc = p->nBlob = nBlob; | ||
| 208298 | p->hasNonstd = pFromCache->hasNonstd; | ||
| 208299 | jsonParseFree(pFromCache); | ||
| 208300 | return p; | ||
| 208301 | } | ||
| 208302 | if( eType==SQLITE_BLOB ){ | ||
| 208303 | if( jsonArgIsJsonb(pArg,p) ){ | ||
| 208304 | if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ | ||
| 208305 | goto json_pfa_oom; | ||
| 208306 | } | ||
| 208307 | return p; | ||
| 204861 | } | 208308 | } |
| 208309 | /* If the blob is not valid JSONB, fall through into trying to cast | ||
| 208310 | ** the blob into text which is then interpreted as JSON. (tag-20240123-a) | ||
| 208311 | ** | ||
| 208312 | ** This goes against all historical documentation about how the SQLite | ||
| 208313 | ** JSON functions were suppose to work. From the beginning, blob was | ||
| 208314 | ** reserved for expansion and a blob value should have raised an error. | ||
| 208315 | ** But it did not, due to a bug. And many applications came to depend | ||
| 208316 | ** upon this buggy behavior, espeically when using the CLI and reading | ||
| 208317 | ** JSON text using readfile(), which returns a blob. For this reason | ||
| 208318 | ** we will continue to support the bug moving forward. | ||
| 208319 | ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d | ||
| 208320 | */ | ||
| 204862 | } | 208321 | } |
| 208322 | p->zJson = (char*)sqlite3_value_text(pArg); | ||
| 208323 | p->nJson = sqlite3_value_bytes(pArg); | ||
| 208324 | if( db->mallocFailed ) goto json_pfa_oom; | ||
| 208325 | if( p->nJson==0 ) goto json_pfa_malformed; | ||
| 208326 | assert( p->zJson!=0 ); | ||
| 208327 | if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ | ||
| 208328 | if( flgs & JSON_KEEPERROR ){ | ||
| 208329 | p->nErr = 1; | ||
| 208330 | return p; | ||
| 208331 | }else{ | ||
| 208332 | jsonParseFree(p); | ||
| 208333 | return 0; | ||
| 208334 | } | ||
| 208335 | }else{ | ||
| 208336 | int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); | ||
| 208337 | int rc; | ||
| 208338 | if( !isRCStr ){ | ||
| 208339 | char *zNew = sqlite3RCStrNew( p->nJson ); | ||
| 208340 | if( zNew==0 ) goto json_pfa_oom; | ||
| 208341 | memcpy(zNew, p->zJson, p->nJson); | ||
| 208342 | p->zJson = zNew; | ||
| 208343 | p->zJson[p->nJson] = 0; | ||
| 208344 | }else{ | ||
| 208345 | sqlite3RCStrRef(p->zJson); | ||
| 208346 | } | ||
| 208347 | p->bJsonIsRCStr = 1; | ||
| 208348 | rc = jsonCacheInsert(ctx, p); | ||
| 208349 | if( rc==SQLITE_NOMEM ) goto json_pfa_oom; | ||
| 208350 | if( flgs & JSON_EDITABLE ){ | ||
| 208351 | pFromCache = p; | ||
| 208352 | p = 0; | ||
| 208353 | goto rebuild_from_cache; | ||
| 208354 | } | ||
| 208355 | } | ||
| 208356 | return p; | ||
| 208357 | |||
| 208358 | json_pfa_malformed: | ||
| 208359 | if( flgs & JSON_KEEPERROR ){ | ||
| 208360 | p->nErr = 1; | ||
| 208361 | return p; | ||
| 208362 | }else{ | ||
| 208363 | jsonParseFree(p); | ||
| 208364 | sqlite3_result_error(ctx, "malformed JSON", -1); | ||
| 208365 | return 0; | ||
| 208366 | } | ||
| 208367 | |||
| 208368 | json_pfa_oom: | ||
| 208369 | jsonParseFree(pFromCache); | ||
| 208370 | jsonParseFree(p); | ||
| 208371 | sqlite3_result_error_nomem(ctx); | ||
| 208372 | return 0; | ||
| 204863 | } | 208373 | } |
| 204864 | 208374 | ||
| 208375 | /* | ||
| 208376 | ** Make the return value of a JSON function either the raw JSONB blob | ||
| 208377 | ** or make it JSON text, depending on whether the JSON_BLOB flag is | ||
| 208378 | ** set on the function. | ||
| 208379 | */ | ||
| 208380 | static void jsonReturnParse( | ||
| 208381 | sqlite3_context *ctx, | ||
| 208382 | JsonParse *p | ||
| 208383 | ){ | ||
| 208384 | int flgs; | ||
| 208385 | if( p->oom ){ | ||
| 208386 | sqlite3_result_error_nomem(ctx); | ||
| 208387 | return; | ||
| 208388 | } | ||
| 208389 | flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); | ||
| 208390 | if( flgs & JSON_BLOB ){ | ||
| 208391 | if( p->nBlobAlloc>0 && !p->bReadOnly ){ | ||
| 208392 | sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); | ||
| 208393 | p->nBlobAlloc = 0; | ||
| 208394 | }else{ | ||
| 208395 | sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); | ||
| 208396 | } | ||
| 208397 | }else{ | ||
| 208398 | JsonString s; | ||
| 208399 | jsonStringInit(&s, ctx); | ||
| 208400 | p->delta = 0; | ||
| 208401 | jsonTranslateBlobToText(p, 0, &s); | ||
| 208402 | jsonReturnString(&s, p, ctx); | ||
| 208403 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | ||
| 208404 | } | ||
| 208405 | } | ||
| 204865 | 208406 | ||
| 204866 | /**************************************************************************** | 208407 | /**************************************************************************** |
| 204867 | ** SQL functions used for testing and debugging | 208408 | ** SQL functions used for testing and debugging |
| @@ -204869,63 +208410,124 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ | |||
| 204869 | 208410 | ||
| 204870 | #if SQLITE_DEBUG | 208411 | #if SQLITE_DEBUG |
| 204871 | /* | 208412 | /* |
| 204872 | ** Print N node entries. | 208413 | ** Decode JSONB bytes in aBlob[] starting at iStart through but not |
| 204873 | */ | 208414 | ** including iEnd. Indent the |
| 204874 | static void jsonDebugPrintNodeEntries( | 208415 | ** content by nIndent spaces. |
| 204875 | JsonNode *aNode, /* First node entry to print */ | 208416 | */ |
| 204876 | int N /* Number of node entries to print */ | 208417 | static void jsonDebugPrintBlob( |
| 204877 | ){ | 208418 | JsonParse *pParse, /* JSON content */ |
| 204878 | int i; | 208419 | u32 iStart, /* Start rendering here */ |
| 204879 | for(i=0; i<N; i++){ | 208420 | u32 iEnd, /* Do not render this byte or any byte after this one */ |
| 204880 | const char *zType; | 208421 | int nIndent, /* Indent by this many spaces */ |
| 204881 | if( aNode[i].jnFlags & JNODE_LABEL ){ | 208422 | sqlite3_str *pOut /* Generate output into this sqlite3_str object */ |
| 204882 | zType = "label"; | 208423 | ){ |
| 204883 | }else{ | 208424 | while( iStart<iEnd ){ |
| 204884 | zType = jsonType[aNode[i].eType]; | 208425 | u32 i, n, nn, sz = 0; |
| 208426 | int showContent = 1; | ||
| 208427 | u8 x = pParse->aBlob[iStart] & 0x0f; | ||
| 208428 | u32 savedNBlob = pParse->nBlob; | ||
| 208429 | sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); | ||
| 208430 | if( pParse->nBlobAlloc>pParse->nBlob ){ | ||
| 208431 | pParse->nBlob = pParse->nBlobAlloc; | ||
| 208432 | } | ||
| 208433 | nn = n = jsonbPayloadSize(pParse, iStart, &sz); | ||
| 208434 | if( nn==0 ) nn = 1; | ||
| 208435 | if( sz>0 && x<JSONB_ARRAY ){ | ||
| 208436 | nn += sz; | ||
| 208437 | } | ||
| 208438 | for(i=0; i<nn; i++){ | ||
| 208439 | sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]); | ||
| 208440 | } | ||
| 208441 | if( n==0 ){ | ||
| 208442 | sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); | ||
| 208443 | iStart = n==0 ? iStart+1 : iEnd; | ||
| 208444 | continue; | ||
| 204885 | } | 208445 | } |
| 204886 | printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n); | 208446 | pParse->nBlob = savedNBlob; |
| 204887 | if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){ | 208447 | if( iStart+n+sz>iEnd ){ |
| 204888 | u8 f = aNode[i].jnFlags; | 208448 | iEnd = iStart+n+sz; |
| 204889 | if( f & JNODE_RAW ) printf(" RAW"); | 208449 | if( iEnd>pParse->nBlob ){ |
| 204890 | if( f & JNODE_ESCAPE ) printf(" ESCAPE"); | 208450 | if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ |
| 204891 | if( f & JNODE_REMOVE ) printf(" REMOVE"); | 208451 | iEnd = pParse->nBlobAlloc; |
| 204892 | if( f & JNODE_REPLACE ) printf(" REPLACE"); | 208452 | }else{ |
| 204893 | if( f & JNODE_APPEND ) printf(" APPEND"); | 208453 | iEnd = pParse->nBlob; |
| 204894 | if( f & JNODE_JSON5 ) printf(" JSON5"); | 208454 | } |
| 208455 | } | ||
| 208456 | } | ||
| 208457 | sqlite3_str_appendall(pOut," <-- "); | ||
| 208458 | switch( x ){ | ||
| 208459 | case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; | ||
| 208460 | case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; | ||
| 208461 | case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; | ||
| 208462 | case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; | ||
| 208463 | case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; | ||
| 208464 | case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; | ||
| 208465 | case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; | ||
| 208466 | case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; | ||
| 208467 | case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; | ||
| 208468 | case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; | ||
| 208469 | case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; | ||
| 208470 | case JSONB_ARRAY: { | ||
| 208471 | sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); | ||
| 208472 | jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); | ||
| 208473 | showContent = 0; | ||
| 208474 | break; | ||
| 208475 | } | ||
| 208476 | case JSONB_OBJECT: { | ||
| 208477 | sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); | ||
| 208478 | jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); | ||
| 208479 | showContent = 0; | ||
| 208480 | break; | ||
| 208481 | } | ||
| 208482 | default: { | ||
| 208483 | sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); | ||
| 208484 | showContent = 0; | ||
| 208485 | break; | ||
| 208486 | } | ||
| 204895 | } | 208487 | } |
| 204896 | switch( aNode[i].eU ){ | 208488 | if( showContent ){ |
| 204897 | case 1: printf(" zJContent=[%.*s]\n", | 208489 | if( sz==0 && x<=JSONB_FALSE ){ |
| 204898 | aNode[i].n, aNode[i].u.zJContent); break; | 208490 | sqlite3_str_append(pOut, "\n", 1); |
| 204899 | case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break; | 208491 | }else{ |
| 204900 | case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break; | 208492 | u32 j; |
| 204901 | case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break; | 208493 | sqlite3_str_appendall(pOut, ": \""); |
| 204902 | default: printf("\n"); | 208494 | for(j=iStart+n; j<iStart+n+sz; j++){ |
| 208495 | u8 c = pParse->aBlob[j]; | ||
| 208496 | if( c<0x20 || c>=0x7f ) c = '.'; | ||
| 208497 | sqlite3_str_append(pOut, (char*)&c, 1); | ||
| 208498 | } | ||
| 208499 | sqlite3_str_append(pOut, "\"\n", 2); | ||
| 208500 | } | ||
| 204903 | } | 208501 | } |
| 208502 | iStart += n + sz; | ||
| 204904 | } | 208503 | } |
| 204905 | } | 208504 | } |
| 204906 | #endif /* SQLITE_DEBUG */ | 208505 | static void jsonShowParse(JsonParse *pParse){ |
| 204907 | 208506 | sqlite3_str out; | |
| 204908 | 208507 | char zBuf[1000]; | |
| 204909 | #if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */ | 208508 | if( pParse==0 ){ |
| 204910 | static void jsonDebugPrintParse(JsonParse *p){ | 208509 | printf("NULL pointer\n"); |
| 204911 | jsonDebugPrintNodeEntries(p->aNode, p->nNode); | 208510 | return; |
| 204912 | } | 208511 | }else{ |
| 204913 | static void jsonDebugPrintNode(JsonNode *pNode){ | 208512 | printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); |
| 204914 | jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); | 208513 | printf("nBlob = %u\n", pParse->nBlob); |
| 208514 | printf("delta = %d\n", pParse->delta); | ||
| 208515 | if( pParse->nBlob==0 ) return; | ||
| 208516 | printf("content (bytes 0..%u):\n", pParse->nBlob-1); | ||
| 208517 | } | ||
| 208518 | sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); | ||
| 208519 | jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); | ||
| 208520 | printf("%s", sqlite3_str_value(&out)); | ||
| 208521 | sqlite3_str_reset(&out); | ||
| 204915 | } | 208522 | } |
| 204916 | #else | 208523 | #endif /* SQLITE_DEBUG */ |
| 204917 | /* The usual case */ | ||
| 204918 | # define jsonDebugPrintNode(X) | ||
| 204919 | # define jsonDebugPrintParse(X) | ||
| 204920 | #endif | ||
| 204921 | 208524 | ||
| 204922 | #ifdef SQLITE_DEBUG | 208525 | #ifdef SQLITE_DEBUG |
| 204923 | /* | 208526 | /* |
| 204924 | ** SQL function: json_parse(JSON) | 208527 | ** SQL function: json_parse(JSON) |
| 204925 | ** | 208528 | ** |
| 204926 | ** Parse JSON using jsonParseCached(). Then print a dump of that | 208529 | ** Parse JSON using jsonParseFuncArg(). Return text that is a |
| 204927 | ** parse on standard output. Return the mimified JSON result, just | 208530 | ** human-readable dump of the binary JSONB for the input parameter. |
| 204928 | ** like the json() function. | ||
| 204929 | */ | 208531 | */ |
| 204930 | static void jsonParseFunc( | 208532 | static void jsonParseFunc( |
| 204931 | sqlite3_context *ctx, | 208533 | sqlite3_context *ctx, |
| @@ -204933,38 +208535,20 @@ static void jsonParseFunc( | |||
| 204933 | sqlite3_value **argv | 208535 | sqlite3_value **argv |
| 204934 | ){ | 208536 | ){ |
| 204935 | JsonParse *p; /* The parse */ | 208537 | JsonParse *p; /* The parse */ |
| 208538 | sqlite3_str out; | ||
| 204936 | 208539 | ||
| 204937 | assert( argc==1 ); | 208540 | assert( argc>=1 ); |
| 204938 | p = jsonParseCached(ctx, argv[0], ctx, 0); | 208541 | sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); |
| 208542 | p = jsonParseFuncArg(ctx, argv[0], 0); | ||
| 204939 | if( p==0 ) return; | 208543 | if( p==0 ) return; |
| 204940 | printf("nNode = %u\n", p->nNode); | 208544 | if( argc==1 ){ |
| 204941 | printf("nAlloc = %u\n", p->nAlloc); | 208545 | jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); |
| 204942 | printf("nJson = %d\n", p->nJson); | 208546 | sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8); |
| 204943 | printf("nAlt = %d\n", p->nAlt); | 208547 | }else{ |
| 204944 | printf("nErr = %u\n", p->nErr); | 208548 | jsonShowParse(p); |
| 204945 | printf("oom = %u\n", p->oom); | 208549 | } |
| 204946 | printf("hasNonstd = %u\n", p->hasNonstd); | 208550 | jsonParseFree(p); |
| 204947 | printf("useMod = %u\n", p->useMod); | 208551 | sqlite3_str_reset(&out); |
| 204948 | printf("hasMod = %u\n", p->hasMod); | ||
| 204949 | printf("nJPRef = %u\n", p->nJPRef); | ||
| 204950 | printf("iSubst = %u\n", p->iSubst); | ||
| 204951 | printf("iHold = %u\n", p->iHold); | ||
| 204952 | jsonDebugPrintNodeEntries(p->aNode, p->nNode); | ||
| 204953 | jsonReturnJson(p, p->aNode, ctx, 1); | ||
| 204954 | } | ||
| 204955 | |||
| 204956 | /* | ||
| 204957 | ** The json_test1(JSON) function return true (1) if the input is JSON | ||
| 204958 | ** text generated by another json function. It returns (0) if the input | ||
| 204959 | ** is not known to be JSON. | ||
| 204960 | */ | ||
| 204961 | static void jsonTest1Func( | ||
| 204962 | sqlite3_context *ctx, | ||
| 204963 | int argc, | ||
| 204964 | sqlite3_value **argv | ||
| 204965 | ){ | ||
| 204966 | UNUSED_PARAMETER(argc); | ||
| 204967 | sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); | ||
| 204968 | } | 208552 | } |
| 204969 | #endif /* SQLITE_DEBUG */ | 208553 | #endif /* SQLITE_DEBUG */ |
| 204970 | 208554 | ||
| @@ -204973,7 +208557,7 @@ static void jsonTest1Func( | |||
| 204973 | ****************************************************************************/ | 208557 | ****************************************************************************/ |
| 204974 | 208558 | ||
| 204975 | /* | 208559 | /* |
| 204976 | ** Implementation of the json_QUOTE(VALUE) function. Return a JSON value | 208560 | ** Implementation of the json_quote(VALUE) function. Return a JSON value |
| 204977 | ** corresponding to the SQL value input. Mostly this means putting | 208561 | ** corresponding to the SQL value input. Mostly this means putting |
| 204978 | ** double-quotes around strings and returning the unquoted string "null" | 208562 | ** double-quotes around strings and returning the unquoted string "null" |
| 204979 | ** when given a NULL input. | 208563 | ** when given a NULL input. |
| @@ -204986,9 +208570,9 @@ static void jsonQuoteFunc( | |||
| 204986 | JsonString jx; | 208570 | JsonString jx; |
| 204987 | UNUSED_PARAMETER(argc); | 208571 | UNUSED_PARAMETER(argc); |
| 204988 | 208572 | ||
| 204989 | jsonInit(&jx, ctx); | 208573 | jsonStringInit(&jx, ctx); |
| 204990 | jsonAppendValue(&jx, argv[0]); | 208574 | jsonAppendSqlValue(&jx, argv[0]); |
| 204991 | jsonResult(&jx); | 208575 | jsonReturnString(&jx, 0, 0); |
| 204992 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | 208576 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 204993 | } | 208577 | } |
| 204994 | 208578 | ||
| @@ -205005,18 +208589,17 @@ static void jsonArrayFunc( | |||
| 205005 | int i; | 208589 | int i; |
| 205006 | JsonString jx; | 208590 | JsonString jx; |
| 205007 | 208591 | ||
| 205008 | jsonInit(&jx, ctx); | 208592 | jsonStringInit(&jx, ctx); |
| 205009 | jsonAppendChar(&jx, '['); | 208593 | jsonAppendChar(&jx, '['); |
| 205010 | for(i=0; i<argc; i++){ | 208594 | for(i=0; i<argc; i++){ |
| 205011 | jsonAppendSeparator(&jx); | 208595 | jsonAppendSeparator(&jx); |
| 205012 | jsonAppendValue(&jx, argv[i]); | 208596 | jsonAppendSqlValue(&jx, argv[i]); |
| 205013 | } | 208597 | } |
| 205014 | jsonAppendChar(&jx, ']'); | 208598 | jsonAppendChar(&jx, ']'); |
| 205015 | jsonResult(&jx); | 208599 | jsonReturnString(&jx, 0, 0); |
| 205016 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | 208600 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 205017 | } | 208601 | } |
| 205018 | 208602 | ||
| 205019 | |||
| 205020 | /* | 208603 | /* |
| 205021 | ** json_array_length(JSON) | 208604 | ** json_array_length(JSON) |
| 205022 | ** json_array_length(JSON, PATH) | 208605 | ** json_array_length(JSON, PATH) |
| @@ -205030,46 +208613,46 @@ static void jsonArrayLengthFunc( | |||
| 205030 | sqlite3_value **argv | 208613 | sqlite3_value **argv |
| 205031 | ){ | 208614 | ){ |
| 205032 | JsonParse *p; /* The parse */ | 208615 | JsonParse *p; /* The parse */ |
| 205033 | sqlite3_int64 n = 0; | 208616 | sqlite3_int64 cnt = 0; |
| 205034 | u32 i; | 208617 | u32 i; |
| 205035 | JsonNode *pNode; | 208618 | u8 eErr = 0; |
| 205036 | 208619 | ||
| 205037 | p = jsonParseCached(ctx, argv[0], ctx, 0); | 208620 | p = jsonParseFuncArg(ctx, argv[0], 0); |
| 205038 | if( p==0 ) return; | 208621 | if( p==0 ) return; |
| 205039 | assert( p->nNode ); | ||
| 205040 | if( argc==2 ){ | 208622 | if( argc==2 ){ |
| 205041 | const char *zPath = (const char*)sqlite3_value_text(argv[1]); | 208623 | const char *zPath = (const char*)sqlite3_value_text(argv[1]); |
| 205042 | pNode = jsonLookup(p, zPath, 0, ctx); | 208624 | if( zPath==0 ){ |
| 205043 | }else{ | 208625 | jsonParseFree(p); |
| 205044 | pNode = p->aNode; | 208626 | return; |
| 205045 | } | 208627 | } |
| 205046 | if( pNode==0 ){ | 208628 | i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0); |
| 205047 | return; | 208629 | if( JSON_LOOKUP_ISERROR(i) ){ |
| 205048 | } | 208630 | if( i==JSON_LOOKUP_NOTFOUND ){ |
| 205049 | if( pNode->eType==JSON_ARRAY ){ | 208631 | /* no-op */ |
| 205050 | while( 1 /*exit-by-break*/ ){ | 208632 | }else if( i==JSON_LOOKUP_PATHERROR ){ |
| 205051 | i = 1; | 208633 | jsonBadPathError(ctx, zPath); |
| 205052 | while( i<=pNode->n ){ | 208634 | }else{ |
| 205053 | if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++; | 208635 | sqlite3_result_error(ctx, "malformed JSON", -1); |
| 205054 | i += jsonNodeSize(&pNode[i]); | ||
| 205055 | } | 208636 | } |
| 205056 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | 208637 | eErr = 1; |
| 205057 | if( p->useMod==0 ) break; | 208638 | i = 0; |
| 205058 | assert( pNode->eU==2 ); | ||
| 205059 | pNode = &p->aNode[pNode->u.iAppend]; | ||
| 205060 | } | 208639 | } |
| 208640 | }else{ | ||
| 208641 | i = 0; | ||
| 208642 | } | ||
| 208643 | if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){ | ||
| 208644 | cnt = jsonbArrayCount(p, i); | ||
| 205061 | } | 208645 | } |
| 205062 | sqlite3_result_int64(ctx, n); | 208646 | if( !eErr ) sqlite3_result_int64(ctx, cnt); |
| 208647 | jsonParseFree(p); | ||
| 205063 | } | 208648 | } |
| 205064 | 208649 | ||
| 205065 | /* | 208650 | /* True if the string is all alphanumerics and underscores */ |
| 205066 | ** Bit values for the flags passed into jsonExtractFunc() or | 208651 | static int jsonAllAlphanum(const char *z, int n){ |
| 205067 | ** jsonSetFunc() via the user-data value. | 208652 | int i; |
| 205068 | */ | 208653 | for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){} |
| 205069 | #define JSON_JSON 0x01 /* Result is always JSON */ | 208654 | return i==n; |
| 205070 | #define JSON_SQL 0x02 /* Result is always SQL */ | 208655 | } |
| 205071 | #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ | ||
| 205072 | #define JSON_ISSET 0x04 /* json_set(), not json_insert() */ | ||
| 205073 | 208656 | ||
| 205074 | /* | 208657 | /* |
| 205075 | ** json_extract(JSON, PATH, ...) | 208658 | ** json_extract(JSON, PATH, ...) |
| @@ -205096,152 +208679,307 @@ static void jsonExtractFunc( | |||
| 205096 | int argc, | 208679 | int argc, |
| 205097 | sqlite3_value **argv | 208680 | sqlite3_value **argv |
| 205098 | ){ | 208681 | ){ |
| 205099 | JsonParse *p; /* The parse */ | 208682 | JsonParse *p = 0; /* The parse */ |
| 205100 | JsonNode *pNode; | 208683 | int flags; /* Flags associated with the function */ |
| 205101 | const char *zPath; | 208684 | int i; /* Loop counter */ |
| 205102 | int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); | 208685 | JsonString jx; /* String for array result */ |
| 205103 | JsonString jx; | ||
| 205104 | 208686 | ||
| 205105 | if( argc<2 ) return; | 208687 | if( argc<2 ) return; |
| 205106 | p = jsonParseCached(ctx, argv[0], ctx, 0); | 208688 | p = jsonParseFuncArg(ctx, argv[0], 0); |
| 205107 | if( p==0 ) return; | 208689 | if( p==0 ) return; |
| 205108 | if( argc==2 ){ | 208690 | flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); |
| 208691 | jsonStringInit(&jx, ctx); | ||
| 208692 | if( argc>2 ){ | ||
| 208693 | jsonAppendChar(&jx, '['); | ||
| 208694 | } | ||
| 208695 | for(i=1; i<argc; i++){ | ||
| 205109 | /* With a single PATH argument */ | 208696 | /* With a single PATH argument */ |
| 205110 | zPath = (const char*)sqlite3_value_text(argv[1]); | 208697 | const char *zPath = (const char*)sqlite3_value_text(argv[i]); |
| 205111 | if( zPath==0 ) return; | 208698 | int nPath; |
| 205112 | if( flags & JSON_ABPATH ){ | 208699 | u32 j; |
| 205113 | if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){ | 208700 | if( zPath==0 ) goto json_extract_error; |
| 205114 | /* The -> and ->> operators accept abbreviated PATH arguments. This | 208701 | nPath = sqlite3Strlen30(zPath); |
| 205115 | ** is mostly for compatibility with PostgreSQL, but also for | 208702 | if( zPath[0]=='$' ){ |
| 205116 | ** convenience. | 208703 | j = jsonLookupStep(p, 0, zPath+1, 0); |
| 205117 | ** | 208704 | }else if( (flags & JSON_ABPATH) ){ |
| 205118 | ** NUMBER ==> $[NUMBER] // PG compatible | 208705 | /* The -> and ->> operators accept abbreviated PATH arguments. This |
| 205119 | ** LABEL ==> $.LABEL // PG compatible | 208706 | ** is mostly for compatibility with PostgreSQL, but also for |
| 205120 | ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience | 208707 | ** convenience. |
| 205121 | */ | 208708 | ** |
| 205122 | jsonInit(&jx, ctx); | 208709 | ** NUMBER ==> $[NUMBER] // PG compatible |
| 205123 | if( sqlite3Isdigit(zPath[0]) ){ | 208710 | ** LABEL ==> $.LABEL // PG compatible |
| 205124 | jsonAppendRawNZ(&jx, "$[", 2); | 208711 | ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience |
| 205125 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); | 208712 | */ |
| 205126 | jsonAppendRawNZ(&jx, "]", 2); | 208713 | jsonStringInit(&jx, ctx); |
| 205127 | }else{ | 208714 | if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ |
| 205128 | jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); | 208715 | jsonAppendRawNZ(&jx, "[", 1); |
| 205129 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); | 208716 | jsonAppendRaw(&jx, zPath, nPath); |
| 205130 | jsonAppendChar(&jx, 0); | 208717 | jsonAppendRawNZ(&jx, "]", 2); |
| 205131 | } | 208718 | }else if( jsonAllAlphanum(zPath, nPath) ){ |
| 205132 | pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); | 208719 | jsonAppendRawNZ(&jx, ".", 1); |
| 205133 | jsonReset(&jx); | 208720 | jsonAppendRaw(&jx, zPath, nPath); |
| 208721 | }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ | ||
| 208722 | jsonAppendRaw(&jx, zPath, nPath); | ||
| 205134 | }else{ | 208723 | }else{ |
| 205135 | pNode = jsonLookup(p, zPath, 0, ctx); | 208724 | jsonAppendRawNZ(&jx, ".\"", 2); |
| 208725 | jsonAppendRaw(&jx, zPath, nPath); | ||
| 208726 | jsonAppendRawNZ(&jx, "\"", 1); | ||
| 205136 | } | 208727 | } |
| 205137 | if( pNode ){ | 208728 | jsonStringTerminate(&jx); |
| 208729 | j = jsonLookupStep(p, 0, jx.zBuf, 0); | ||
| 208730 | jsonStringReset(&jx); | ||
| 208731 | }else{ | ||
| 208732 | jsonBadPathError(ctx, zPath); | ||
| 208733 | goto json_extract_error; | ||
| 208734 | } | ||
| 208735 | if( j<p->nBlob ){ | ||
| 208736 | if( argc==2 ){ | ||
| 205138 | if( flags & JSON_JSON ){ | 208737 | if( flags & JSON_JSON ){ |
| 205139 | jsonReturnJson(p, pNode, ctx, 0); | 208738 | jsonStringInit(&jx, ctx); |
| 208739 | jsonTranslateBlobToText(p, j, &jx); | ||
| 208740 | jsonReturnString(&jx, 0, 0); | ||
| 208741 | jsonStringReset(&jx); | ||
| 208742 | assert( (flags & JSON_BLOB)==0 ); | ||
| 208743 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | ||
| 205140 | }else{ | 208744 | }else{ |
| 205141 | jsonReturn(p, pNode, ctx); | 208745 | jsonReturnFromBlob(p, j, ctx, 0); |
| 205142 | sqlite3_result_subtype(ctx, 0); | 208746 | if( (flags & (JSON_SQL|JSON_BLOB))==0 |
| 208747 | && (p->aBlob[j]&0x0f)>=JSONB_ARRAY | ||
| 208748 | ){ | ||
| 208749 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | ||
| 208750 | } | ||
| 205143 | } | 208751 | } |
| 208752 | }else{ | ||
| 208753 | jsonAppendSeparator(&jx); | ||
| 208754 | jsonTranslateBlobToText(p, j, &jx); | ||
| 205144 | } | 208755 | } |
| 205145 | }else{ | 208756 | }else if( j==JSON_LOOKUP_NOTFOUND ){ |
| 205146 | pNode = jsonLookup(p, zPath, 0, ctx); | 208757 | if( argc==2 ){ |
| 205147 | if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx); | 208758 | goto json_extract_error; /* Return NULL if not found */ |
| 205148 | } | ||
| 205149 | }else{ | ||
| 205150 | /* Two or more PATH arguments results in a JSON array with each | ||
| 205151 | ** element of the array being the value selected by one of the PATHs */ | ||
| 205152 | int i; | ||
| 205153 | jsonInit(&jx, ctx); | ||
| 205154 | jsonAppendChar(&jx, '['); | ||
| 205155 | for(i=1; i<argc; i++){ | ||
| 205156 | zPath = (const char*)sqlite3_value_text(argv[i]); | ||
| 205157 | pNode = jsonLookup(p, zPath, 0, ctx); | ||
| 205158 | if( p->nErr ) break; | ||
| 205159 | jsonAppendSeparator(&jx); | ||
| 205160 | if( pNode ){ | ||
| 205161 | jsonRenderNode(p, pNode, &jx); | ||
| 205162 | }else{ | 208759 | }else{ |
| 208760 | jsonAppendSeparator(&jx); | ||
| 205163 | jsonAppendRawNZ(&jx, "null", 4); | 208761 | jsonAppendRawNZ(&jx, "null", 4); |
| 205164 | } | 208762 | } |
| 208763 | }else if( j==JSON_LOOKUP_ERROR ){ | ||
| 208764 | sqlite3_result_error(ctx, "malformed JSON", -1); | ||
| 208765 | goto json_extract_error; | ||
| 208766 | }else{ | ||
| 208767 | jsonBadPathError(ctx, zPath); | ||
| 208768 | goto json_extract_error; | ||
| 205165 | } | 208769 | } |
| 205166 | if( i==argc ){ | 208770 | } |
| 205167 | jsonAppendChar(&jx, ']'); | 208771 | if( argc>2 ){ |
| 205168 | jsonResult(&jx); | 208772 | jsonAppendChar(&jx, ']'); |
| 208773 | jsonReturnString(&jx, 0, 0); | ||
| 208774 | if( (flags & JSON_BLOB)==0 ){ | ||
| 205169 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | 208775 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 205170 | } | 208776 | } |
| 205171 | jsonReset(&jx); | ||
| 205172 | } | 208777 | } |
| 208778 | json_extract_error: | ||
| 208779 | jsonStringReset(&jx); | ||
| 208780 | jsonParseFree(p); | ||
| 208781 | return; | ||
| 205173 | } | 208782 | } |
| 205174 | 208783 | ||
| 205175 | /* This is the RFC 7396 MergePatch algorithm. | 208784 | /* |
| 205176 | */ | 208785 | ** Return codes for jsonMergePatch() |
| 205177 | static JsonNode *jsonMergePatch( | 208786 | */ |
| 205178 | JsonParse *pParse, /* The JSON parser that contains the TARGET */ | 208787 | #define JSON_MERGE_OK 0 /* Success */ |
| 205179 | u32 iTarget, /* Node of the TARGET in pParse */ | 208788 | #define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ |
| 205180 | JsonNode *pPatch /* The PATCH */ | 208789 | #define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ |
| 205181 | ){ | 208790 | #define JSON_MERGE_OOM 3 /* Out-of-memory condition */ |
| 205182 | u32 i, j; | 208791 | |
| 205183 | u32 iRoot; | 208792 | /* |
| 205184 | JsonNode *pTarget; | 208793 | ** RFC-7396 MergePatch for two JSONB blobs. |
| 205185 | if( pPatch->eType!=JSON_OBJECT ){ | 208794 | ** |
| 205186 | return pPatch; | 208795 | ** pTarget is the target. pPatch is the patch. The target is updated |
| 205187 | } | 208796 | ** in place. The patch is read-only. |
| 205188 | assert( iTarget<pParse->nNode ); | 208797 | ** |
| 205189 | pTarget = &pParse->aNode[iTarget]; | 208798 | ** The original RFC-7396 algorithm is this: |
| 205190 | assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); | 208799 | ** |
| 205191 | if( pTarget->eType!=JSON_OBJECT ){ | 208800 | ** define MergePatch(Target, Patch): |
| 205192 | jsonRemoveAllNulls(pPatch); | 208801 | ** if Patch is an Object: |
| 205193 | return pPatch; | 208802 | ** if Target is not an Object: |
| 205194 | } | 208803 | ** Target = {} # Ignore the contents and set it to an empty Object |
| 205195 | iRoot = iTarget; | 208804 | ** for each Name/Value pair in Patch: |
| 205196 | for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){ | 208805 | ** if Value is null: |
| 205197 | u32 nKey; | 208806 | ** if Name exists in Target: |
| 205198 | const char *zKey; | 208807 | ** remove the Name/Value pair from Target |
| 205199 | assert( pPatch[i].eType==JSON_STRING ); | 208808 | ** else: |
| 205200 | assert( pPatch[i].jnFlags & JNODE_LABEL ); | 208809 | ** Target[Name] = MergePatch(Target[Name], Value) |
| 205201 | assert( pPatch[i].eU==1 ); | 208810 | ** return Target |
| 205202 | nKey = pPatch[i].n; | 208811 | ** else: |
| 205203 | zKey = pPatch[i].u.zJContent; | 208812 | ** return Patch |
| 205204 | for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ | 208813 | ** |
| 205205 | assert( pTarget[j].eType==JSON_STRING ); | 208814 | ** Here is an equivalent algorithm restructured to show the actual |
| 205206 | assert( pTarget[j].jnFlags & JNODE_LABEL ); | 208815 | ** implementation: |
| 205207 | if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ | 208816 | ** |
| 205208 | if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; | 208817 | ** 01 define MergePatch(Target, Patch): |
| 205209 | if( pPatch[i+1].eType==JSON_NULL ){ | 208818 | ** 02 if Patch is not an Object: |
| 205210 | pTarget[j+1].jnFlags |= JNODE_REMOVE; | 208819 | ** 03 return Patch |
| 205211 | }else{ | 208820 | ** 04 else: // if Patch is an Object |
| 205212 | JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); | 208821 | ** 05 if Target is not an Object: |
| 205213 | if( pNew==0 ) return 0; | 208822 | ** 06 Target = {} |
| 205214 | if( pNew!=&pParse->aNode[iTarget+j+1] ){ | 208823 | ** 07 for each Name/Value pair in Patch: |
| 205215 | jsonParseAddSubstNode(pParse, iTarget+j+1); | 208824 | ** 08 if Name exists in Target: |
| 205216 | jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); | 208825 | ** 09 if Value is null: |
| 205217 | } | 208826 | ** 10 remove the Name/Value pair from Target |
| 205218 | pTarget = &pParse->aNode[iTarget]; | 208827 | ** 11 else |
| 205219 | } | 208828 | ** 12 Target[name] = MergePatch(Target[Name], Value) |
| 205220 | break; | 208829 | ** 13 else if Value is not NULL: |
| 208830 | ** 14 if Value is not an Object: | ||
| 208831 | ** 15 Target[name] = Value | ||
| 208832 | ** 16 else: | ||
| 208833 | ** 17 Target[name] = MergePatch('{}',value) | ||
| 208834 | ** 18 return Target | ||
| 208835 | ** | | ||
| 208836 | ** ^---- Line numbers referenced in comments in the implementation | ||
| 208837 | */ | ||
| 208838 | static int jsonMergePatch( | ||
| 208839 | JsonParse *pTarget, /* The JSON parser that contains the TARGET */ | ||
| 208840 | u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ | ||
| 208841 | const JsonParse *pPatch, /* The PATCH */ | ||
| 208842 | u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ | ||
| 208843 | ){ | ||
| 208844 | u8 x; /* Type of a single node */ | ||
| 208845 | u32 n, sz=0; /* Return values from jsonbPayloadSize() */ | ||
| 208846 | u32 iTCursor; /* Cursor position while scanning the target object */ | ||
| 208847 | u32 iTStart; /* First label in the target object */ | ||
| 208848 | u32 iTEndBE; /* Original first byte past end of target, before edit */ | ||
| 208849 | u32 iTEnd; /* Current first byte past end of target */ | ||
| 208850 | u8 eTLabel; /* Node type of the target label */ | ||
| 208851 | u32 iTLabel = 0; /* Index of the label */ | ||
| 208852 | u32 nTLabel = 0; /* Header size in bytes for the target label */ | ||
| 208853 | u32 szTLabel = 0; /* Size of the target label payload */ | ||
| 208854 | u32 iTValue = 0; /* Index of the target value */ | ||
| 208855 | u32 nTValue = 0; /* Header size of the target value */ | ||
| 208856 | u32 szTValue = 0; /* Payload size for the target value */ | ||
| 208857 | |||
| 208858 | u32 iPCursor; /* Cursor position while scanning the patch */ | ||
| 208859 | u32 iPEnd; /* First byte past the end of the patch */ | ||
| 208860 | u8 ePLabel; /* Node type of the patch label */ | ||
| 208861 | u32 iPLabel; /* Start of patch label */ | ||
| 208862 | u32 nPLabel; /* Size of header on the patch label */ | ||
| 208863 | u32 szPLabel; /* Payload size of the patch label */ | ||
| 208864 | u32 iPValue; /* Start of patch value */ | ||
| 208865 | u32 nPValue; /* Header size for the patch value */ | ||
| 208866 | u32 szPValue; /* Payload size of the patch value */ | ||
| 208867 | |||
| 208868 | assert( iTarget>=0 && iTarget<pTarget->nBlob ); | ||
| 208869 | assert( iPatch>=0 && iPatch<pPatch->nBlob ); | ||
| 208870 | x = pPatch->aBlob[iPatch] & 0x0f; | ||
| 208871 | if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ | ||
| 208872 | u32 szPatch; /* Total size of the patch, header+payload */ | ||
| 208873 | u32 szTarget; /* Total size of the target, header+payload */ | ||
| 208874 | n = jsonbPayloadSize(pPatch, iPatch, &sz); | ||
| 208875 | szPatch = n+sz; | ||
| 208876 | sz = 0; | ||
| 208877 | n = jsonbPayloadSize(pTarget, iTarget, &sz); | ||
| 208878 | szTarget = n+sz; | ||
| 208879 | jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); | ||
| 208880 | return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ | ||
| 208881 | } | ||
| 208882 | x = pTarget->aBlob[iTarget] & 0x0f; | ||
| 208883 | if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ | ||
| 208884 | n = jsonbPayloadSize(pTarget, iTarget, &sz); | ||
| 208885 | jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); | ||
| 208886 | x = pTarget->aBlob[iTarget]; | ||
| 208887 | pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; | ||
| 208888 | } | ||
| 208889 | n = jsonbPayloadSize(pPatch, iPatch, &sz); | ||
| 208890 | if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; | ||
| 208891 | iPCursor = iPatch+n; | ||
| 208892 | iPEnd = iPCursor+sz; | ||
| 208893 | n = jsonbPayloadSize(pTarget, iTarget, &sz); | ||
| 208894 | if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; | ||
| 208895 | iTStart = iTarget+n; | ||
| 208896 | iTEndBE = iTStart+sz; | ||
| 208897 | |||
| 208898 | while( iPCursor<iPEnd ){ /* Algorithm line 07 */ | ||
| 208899 | iPLabel = iPCursor; | ||
| 208900 | ePLabel = pPatch->aBlob[iPCursor] & 0x0f; | ||
| 208901 | if( ePLabel<JSONB_TEXT || ePLabel>JSONB_TEXTRAW ){ | ||
| 208902 | return JSON_MERGE_BADPATCH; | ||
| 208903 | } | ||
| 208904 | nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); | ||
| 208905 | if( nPLabel==0 ) return JSON_MERGE_BADPATCH; | ||
| 208906 | iPValue = iPCursor + nPLabel + szPLabel; | ||
| 208907 | if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; | ||
| 208908 | nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); | ||
| 208909 | if( nPValue==0 ) return JSON_MERGE_BADPATCH; | ||
| 208910 | iPCursor = iPValue + nPValue + szPValue; | ||
| 208911 | if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; | ||
| 208912 | |||
| 208913 | iTCursor = iTStart; | ||
| 208914 | iTEnd = iTEndBE + pTarget->delta; | ||
| 208915 | while( iTCursor<iTEnd ){ | ||
| 208916 | int isEqual; /* true if the patch and target labels match */ | ||
| 208917 | iTLabel = iTCursor; | ||
| 208918 | eTLabel = pTarget->aBlob[iTCursor] & 0x0f; | ||
| 208919 | if( eTLabel<JSONB_TEXT || eTLabel>JSONB_TEXTRAW ){ | ||
| 208920 | return JSON_MERGE_BADTARGET; | ||
| 208921 | } | ||
| 208922 | nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); | ||
| 208923 | if( nTLabel==0 ) return JSON_MERGE_BADTARGET; | ||
| 208924 | iTValue = iTLabel + nTLabel + szTLabel; | ||
| 208925 | if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; | ||
| 208926 | nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); | ||
| 208927 | if( nTValue==0 ) return JSON_MERGE_BADTARGET; | ||
| 208928 | if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; | ||
| 208929 | isEqual = jsonLabelCompare( | ||
| 208930 | (const char*)&pPatch->aBlob[iPLabel+nPLabel], | ||
| 208931 | szPLabel, | ||
| 208932 | (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), | ||
| 208933 | (const char*)&pTarget->aBlob[iTLabel+nTLabel], | ||
| 208934 | szTLabel, | ||
| 208935 | (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); | ||
| 208936 | if( isEqual ) break; | ||
| 208937 | iTCursor = iTValue + nTValue + szTValue; | ||
| 208938 | } | ||
| 208939 | x = pPatch->aBlob[iPValue] & 0x0f; | ||
| 208940 | if( iTCursor<iTEnd ){ | ||
| 208941 | /* A match was found. Algorithm line 08 */ | ||
| 208942 | if( x==0 ){ | ||
| 208943 | /* Patch value is NULL. Algorithm line 09 */ | ||
| 208944 | jsonBlobEdit(pTarget, iTLabel, nTLabel+szTLabel+nTValue+szTValue, 0,0); | ||
| 208945 | /* vvvvvv----- No OOM on a delete-only edit */ | ||
| 208946 | if( NEVER(pTarget->oom) ) return JSON_MERGE_OOM; | ||
| 208947 | }else{ | ||
| 208948 | /* Algorithm line 12 */ | ||
| 208949 | int rc, savedDelta = pTarget->delta; | ||
| 208950 | pTarget->delta = 0; | ||
| 208951 | rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); | ||
| 208952 | if( rc ) return rc; | ||
| 208953 | pTarget->delta += savedDelta; | ||
| 208954 | } | ||
| 208955 | }else if( x>0 ){ /* Algorithm line 13 */ | ||
| 208956 | /* No match and patch value is not NULL */ | ||
| 208957 | u32 szNew = szPLabel+nPLabel; | ||
| 208958 | if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ | ||
| 208959 | jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); | ||
| 208960 | if( pTarget->oom ) return JSON_MERGE_OOM; | ||
| 208961 | memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); | ||
| 208962 | memcpy(&pTarget->aBlob[iTEnd+szNew], | ||
| 208963 | &pPatch->aBlob[iPValue], szPValue+nPValue); | ||
| 208964 | }else{ | ||
| 208965 | int rc, savedDelta; | ||
| 208966 | jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); | ||
| 208967 | if( pTarget->oom ) return JSON_MERGE_OOM; | ||
| 208968 | memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); | ||
| 208969 | pTarget->aBlob[iTEnd+szNew] = 0x00; | ||
| 208970 | savedDelta = pTarget->delta; | ||
| 208971 | pTarget->delta = 0; | ||
| 208972 | rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); | ||
| 208973 | if( rc ) return rc; | ||
| 208974 | pTarget->delta += savedDelta; | ||
| 205221 | } | 208975 | } |
| 205222 | } | 208976 | } |
| 205223 | if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ | ||
| 205224 | int iStart; | ||
| 205225 | JsonNode *pApnd; | ||
| 205226 | u32 nApnd; | ||
| 205227 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); | ||
| 205228 | jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); | ||
| 205229 | pApnd = &pPatch[i+1]; | ||
| 205230 | if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); | ||
| 205231 | nApnd = jsonNodeSize(pApnd); | ||
| 205232 | jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); | ||
| 205233 | if( pParse->oom ) return 0; | ||
| 205234 | pParse->aNode[iStart].n = 1+nApnd; | ||
| 205235 | pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; | ||
| 205236 | pParse->aNode[iRoot].u.iAppend = iStart; | ||
| 205237 | VVA( pParse->aNode[iRoot].eU = 2 ); | ||
| 205238 | iRoot = iStart; | ||
| 205239 | pTarget = &pParse->aNode[iTarget]; | ||
| 205240 | } | ||
| 205241 | } | 208977 | } |
| 205242 | return pTarget; | 208978 | if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); |
| 208979 | return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; | ||
| 205243 | } | 208980 | } |
| 205244 | 208981 | ||
| 208982 | |||
| 205245 | /* | 208983 | /* |
| 205246 | ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON | 208984 | ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON |
| 205247 | ** object that is the result of running the RFC 7396 MergePatch() algorithm | 208985 | ** object that is the result of running the RFC 7396 MergePatch() algorithm |
| @@ -205252,28 +208990,27 @@ static void jsonPatchFunc( | |||
| 205252 | int argc, | 208990 | int argc, |
| 205253 | sqlite3_value **argv | 208991 | sqlite3_value **argv |
| 205254 | ){ | 208992 | ){ |
| 205255 | JsonParse *pX; /* The JSON that is being patched */ | 208993 | JsonParse *pTarget; /* The TARGET */ |
| 205256 | JsonParse *pY; /* The patch */ | 208994 | JsonParse *pPatch; /* The PATCH */ |
| 205257 | JsonNode *pResult; /* The result of the merge */ | 208995 | int rc; /* Result code */ |
| 205258 | 208996 | ||
| 205259 | UNUSED_PARAMETER(argc); | 208997 | UNUSED_PARAMETER(argc); |
| 205260 | pX = jsonParseCached(ctx, argv[0], ctx, 1); | 208998 | assert( argc==2 ); |
| 205261 | if( pX==0 ) return; | 208999 | pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); |
| 205262 | assert( pX->hasMod==0 ); | 209000 | if( pTarget==0 ) return; |
| 205263 | pX->hasMod = 1; | 209001 | pPatch = jsonParseFuncArg(ctx, argv[1], 0); |
| 205264 | pY = jsonParseCached(ctx, argv[1], ctx, 1); | 209002 | if( pPatch ){ |
| 205265 | if( pY==0 ) return; | 209003 | rc = jsonMergePatch(pTarget, 0, pPatch, 0); |
| 205266 | pX->useMod = 1; | 209004 | if( rc==JSON_MERGE_OK ){ |
| 205267 | pY->useMod = 1; | 209005 | jsonReturnParse(ctx, pTarget); |
| 205268 | pResult = jsonMergePatch(pX, 0, pY->aNode); | 209006 | }else if( rc==JSON_MERGE_OOM ){ |
| 205269 | assert( pResult!=0 || pX->oom ); | 209007 | sqlite3_result_error_nomem(ctx); |
| 205270 | if( pResult && pX->oom==0 ){ | 209008 | }else{ |
| 205271 | jsonDebugPrintParse(pX); | 209009 | sqlite3_result_error(ctx, "malformed JSON", -1); |
| 205272 | jsonDebugPrintNode(pResult); | 209010 | } |
| 205273 | jsonReturnJson(pX, pResult, ctx, 0); | 209011 | jsonParseFree(pPatch); |
| 205274 | }else{ | ||
| 205275 | sqlite3_result_error_nomem(ctx); | ||
| 205276 | } | 209012 | } |
| 209013 | jsonParseFree(pTarget); | ||
| 205277 | } | 209014 | } |
| 205278 | 209015 | ||
| 205279 | 209016 | ||
| @@ -205297,23 +209034,23 @@ static void jsonObjectFunc( | |||
| 205297 | "of arguments", -1); | 209034 | "of arguments", -1); |
| 205298 | return; | 209035 | return; |
| 205299 | } | 209036 | } |
| 205300 | jsonInit(&jx, ctx); | 209037 | jsonStringInit(&jx, ctx); |
| 205301 | jsonAppendChar(&jx, '{'); | 209038 | jsonAppendChar(&jx, '{'); |
| 205302 | for(i=0; i<argc; i+=2){ | 209039 | for(i=0; i<argc; i+=2){ |
| 205303 | if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ | 209040 | if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){ |
| 205304 | sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); | 209041 | sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1); |
| 205305 | jsonReset(&jx); | 209042 | jsonStringReset(&jx); |
| 205306 | return; | 209043 | return; |
| 205307 | } | 209044 | } |
| 205308 | jsonAppendSeparator(&jx); | 209045 | jsonAppendSeparator(&jx); |
| 205309 | z = (const char*)sqlite3_value_text(argv[i]); | 209046 | z = (const char*)sqlite3_value_text(argv[i]); |
| 205310 | n = (u32)sqlite3_value_bytes(argv[i]); | 209047 | n = sqlite3_value_bytes(argv[i]); |
| 205311 | jsonAppendString(&jx, z, n); | 209048 | jsonAppendString(&jx, z, n); |
| 205312 | jsonAppendChar(&jx, ':'); | 209049 | jsonAppendChar(&jx, ':'); |
| 205313 | jsonAppendValue(&jx, argv[i+1]); | 209050 | jsonAppendSqlValue(&jx, argv[i+1]); |
| 205314 | } | 209051 | } |
| 205315 | jsonAppendChar(&jx, '}'); | 209052 | jsonAppendChar(&jx, '}'); |
| 205316 | jsonResult(&jx); | 209053 | jsonReturnString(&jx, 0, 0); |
| 205317 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | 209054 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); |
| 205318 | } | 209055 | } |
| 205319 | 209056 | ||
| @@ -205329,120 +209066,50 @@ static void jsonRemoveFunc( | |||
| 205329 | int argc, | 209066 | int argc, |
| 205330 | sqlite3_value **argv | 209067 | sqlite3_value **argv |
| 205331 | ){ | 209068 | ){ |
| 205332 | JsonParse *pParse; /* The parse */ | 209069 | JsonParse *p; /* The parse */ |
| 205333 | JsonNode *pNode; | 209070 | const char *zPath = 0; /* Path of element to be removed */ |
| 205334 | const char *zPath; | 209071 | int i; /* Loop counter */ |
| 205335 | u32 i; | 209072 | u32 rc; /* Subroutine return code */ |
| 205336 | 209073 | ||
| 205337 | if( argc<1 ) return; | 209074 | if( argc<1 ) return; |
| 205338 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); | 209075 | p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0); |
| 205339 | if( pParse==0 ) return; | 209076 | if( p==0 ) return; |
| 205340 | for(i=1; i<(u32)argc; i++){ | 209077 | for(i=1; i<argc; i++){ |
| 205341 | zPath = (const char*)sqlite3_value_text(argv[i]); | 209078 | zPath = (const char*)sqlite3_value_text(argv[i]); |
| 205342 | if( zPath==0 ) goto remove_done; | 209079 | if( zPath==0 ){ |
| 205343 | pNode = jsonLookup(pParse, zPath, 0, ctx); | 209080 | goto json_remove_done; |
| 205344 | if( pParse->nErr ) goto remove_done; | 209081 | } |
| 205345 | if( pNode ){ | 209082 | if( zPath[0]!='$' ){ |
| 205346 | pNode->jnFlags |= JNODE_REMOVE; | 209083 | goto json_remove_patherror; |
| 205347 | pParse->hasMod = 1; | 209084 | } |
| 205348 | pParse->useMod = 1; | 209085 | if( zPath[1]==0 ){ |
| 205349 | } | 209086 | /* json_remove(j,'$') returns NULL */ |
| 205350 | } | 209087 | goto json_remove_done; |
| 205351 | if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ | 209088 | } |
| 205352 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); | 209089 | p->eEdit = JEDIT_DEL; |
| 205353 | } | 209090 | p->delta = 0; |
| 205354 | remove_done: | 209091 | rc = jsonLookupStep(p, 0, zPath+1, 0); |
| 205355 | jsonDebugPrintParse(p); | 209092 | if( JSON_LOOKUP_ISERROR(rc) ){ |
| 205356 | } | 209093 | if( rc==JSON_LOOKUP_NOTFOUND ){ |
| 205357 | 209094 | continue; /* No-op */ | |
| 205358 | /* | 209095 | }else if( rc==JSON_LOOKUP_PATHERROR ){ |
| 205359 | ** Substitute the value at iNode with the pValue parameter. | 209096 | jsonBadPathError(ctx, zPath); |
| 205360 | */ | ||
| 205361 | static void jsonReplaceNode( | ||
| 205362 | sqlite3_context *pCtx, | ||
| 205363 | JsonParse *p, | ||
| 205364 | int iNode, | ||
| 205365 | sqlite3_value *pValue | ||
| 205366 | ){ | ||
| 205367 | int idx = jsonParseAddSubstNode(p, iNode); | ||
| 205368 | if( idx<=0 ){ | ||
| 205369 | assert( p->oom ); | ||
| 205370 | return; | ||
| 205371 | } | ||
| 205372 | switch( sqlite3_value_type(pValue) ){ | ||
| 205373 | case SQLITE_NULL: { | ||
| 205374 | jsonParseAddNode(p, JSON_NULL, 0, 0); | ||
| 205375 | break; | ||
| 205376 | } | ||
| 205377 | case SQLITE_FLOAT: { | ||
| 205378 | char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); | ||
| 205379 | int n; | ||
| 205380 | if( z==0 ){ | ||
| 205381 | p->oom = 1; | ||
| 205382 | break; | ||
| 205383 | } | ||
| 205384 | n = sqlite3Strlen30(z); | ||
| 205385 | jsonParseAddNode(p, JSON_REAL, n, z); | ||
| 205386 | jsonParseAddCleanup(p, sqlite3_free, z); | ||
| 205387 | break; | ||
| 205388 | } | ||
| 205389 | case SQLITE_INTEGER: { | ||
| 205390 | char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); | ||
| 205391 | int n; | ||
| 205392 | if( z==0 ){ | ||
| 205393 | p->oom = 1; | ||
| 205394 | break; | ||
| 205395 | } | ||
| 205396 | n = sqlite3Strlen30(z); | ||
| 205397 | jsonParseAddNode(p, JSON_INT, n, z); | ||
| 205398 | jsonParseAddCleanup(p, sqlite3_free, z); | ||
| 205399 | |||
| 205400 | break; | ||
| 205401 | } | ||
| 205402 | case SQLITE_TEXT: { | ||
| 205403 | const char *z = (const char*)sqlite3_value_text(pValue); | ||
| 205404 | u32 n = (u32)sqlite3_value_bytes(pValue); | ||
| 205405 | if( z==0 ){ | ||
| 205406 | p->oom = 1; | ||
| 205407 | break; | ||
| 205408 | } | ||
| 205409 | if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ | ||
| 205410 | char *zCopy = sqlite3_malloc64( n+1 ); | ||
| 205411 | int k; | ||
| 205412 | if( zCopy ){ | ||
| 205413 | memcpy(zCopy, z, n); | ||
| 205414 | zCopy[n] = 0; | ||
| 205415 | jsonParseAddCleanup(p, sqlite3_free, zCopy); | ||
| 205416 | }else{ | ||
| 205417 | p->oom = 1; | ||
| 205418 | sqlite3_result_error_nomem(pCtx); | ||
| 205419 | } | ||
| 205420 | k = jsonParseAddNode(p, JSON_STRING, n, zCopy); | ||
| 205421 | assert( k>0 || p->oom ); | ||
| 205422 | if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; | ||
| 205423 | }else{ | 209097 | }else{ |
| 205424 | JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); | 209098 | sqlite3_result_error(ctx, "malformed JSON", -1); |
| 205425 | if( pPatch==0 ){ | ||
| 205426 | p->oom = 1; | ||
| 205427 | break; | ||
| 205428 | } | ||
| 205429 | jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); | ||
| 205430 | /* The nodes copied out of pPatch and into p likely contain | ||
| 205431 | ** u.zJContent pointers into pPatch->zJson. So preserve the | ||
| 205432 | ** content of pPatch until p is destroyed. */ | ||
| 205433 | assert( pPatch->nJPRef>=1 ); | ||
| 205434 | pPatch->nJPRef++; | ||
| 205435 | jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); | ||
| 205436 | } | 209099 | } |
| 205437 | break; | 209100 | goto json_remove_done; |
| 205438 | } | ||
| 205439 | default: { | ||
| 205440 | jsonParseAddNode(p, JSON_NULL, 0, 0); | ||
| 205441 | sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); | ||
| 205442 | p->nErr++; | ||
| 205443 | break; | ||
| 205444 | } | 209101 | } |
| 205445 | } | 209102 | } |
| 209103 | jsonReturnParse(ctx, p); | ||
| 209104 | jsonParseFree(p); | ||
| 209105 | return; | ||
| 209106 | |||
| 209107 | json_remove_patherror: | ||
| 209108 | jsonBadPathError(ctx, zPath); | ||
| 209109 | |||
| 209110 | json_remove_done: | ||
| 209111 | jsonParseFree(p); | ||
| 209112 | return; | ||
| 205446 | } | 209113 | } |
| 205447 | 209114 | ||
| 205448 | /* | 209115 | /* |
| @@ -205456,32 +209123,12 @@ static void jsonReplaceFunc( | |||
| 205456 | int argc, | 209123 | int argc, |
| 205457 | sqlite3_value **argv | 209124 | sqlite3_value **argv |
| 205458 | ){ | 209125 | ){ |
| 205459 | JsonParse *pParse; /* The parse */ | ||
| 205460 | JsonNode *pNode; | ||
| 205461 | const char *zPath; | ||
| 205462 | u32 i; | ||
| 205463 | |||
| 205464 | if( argc<1 ) return; | 209126 | if( argc<1 ) return; |
| 205465 | if( (argc&1)==0 ) { | 209127 | if( (argc&1)==0 ) { |
| 205466 | jsonWrongNumArgs(ctx, "replace"); | 209128 | jsonWrongNumArgs(ctx, "replace"); |
| 205467 | return; | 209129 | return; |
| 205468 | } | 209130 | } |
| 205469 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); | 209131 | jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); |
| 205470 | if( pParse==0 ) return; | ||
| 205471 | pParse->nJPRef++; | ||
| 205472 | for(i=1; i<(u32)argc; i+=2){ | ||
| 205473 | zPath = (const char*)sqlite3_value_text(argv[i]); | ||
| 205474 | pParse->useMod = 1; | ||
| 205475 | pNode = jsonLookup(pParse, zPath, 0, ctx); | ||
| 205476 | if( pParse->nErr ) goto replace_err; | ||
| 205477 | if( pNode ){ | ||
| 205478 | jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); | ||
| 205479 | } | ||
| 205480 | } | ||
| 205481 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); | ||
| 205482 | replace_err: | ||
| 205483 | jsonDebugPrintParse(pParse); | ||
| 205484 | jsonParseFree(pParse); | ||
| 205485 | } | 209132 | } |
| 205486 | 209133 | ||
| 205487 | 209134 | ||
| @@ -205502,39 +209149,16 @@ static void jsonSetFunc( | |||
| 205502 | int argc, | 209149 | int argc, |
| 205503 | sqlite3_value **argv | 209150 | sqlite3_value **argv |
| 205504 | ){ | 209151 | ){ |
| 205505 | JsonParse *pParse; /* The parse */ | 209152 | |
| 205506 | JsonNode *pNode; | 209153 | int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); |
| 205507 | const char *zPath; | 209154 | int bIsSet = (flags&JSON_ISSET)!=0; |
| 205508 | u32 i; | ||
| 205509 | int bApnd; | ||
| 205510 | int bIsSet = sqlite3_user_data(ctx)!=0; | ||
| 205511 | 209155 | ||
| 205512 | if( argc<1 ) return; | 209156 | if( argc<1 ) return; |
| 205513 | if( (argc&1)==0 ) { | 209157 | if( (argc&1)==0 ) { |
| 205514 | jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); | 209158 | jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); |
| 205515 | return; | 209159 | return; |
| 205516 | } | 209160 | } |
| 205517 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); | 209161 | jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); |
| 205518 | if( pParse==0 ) return; | ||
| 205519 | pParse->nJPRef++; | ||
| 205520 | for(i=1; i<(u32)argc; i+=2){ | ||
| 205521 | zPath = (const char*)sqlite3_value_text(argv[i]); | ||
| 205522 | bApnd = 0; | ||
| 205523 | pParse->useMod = 1; | ||
| 205524 | pNode = jsonLookup(pParse, zPath, &bApnd, ctx); | ||
| 205525 | if( pParse->oom ){ | ||
| 205526 | sqlite3_result_error_nomem(ctx); | ||
| 205527 | goto jsonSetDone; | ||
| 205528 | }else if( pParse->nErr ){ | ||
| 205529 | goto jsonSetDone; | ||
| 205530 | }else if( pNode && (bApnd || bIsSet) ){ | ||
| 205531 | jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); | ||
| 205532 | } | ||
| 205533 | } | ||
| 205534 | jsonDebugPrintParse(pParse); | ||
| 205535 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); | ||
| 205536 | jsonSetDone: | ||
| 205537 | jsonParseFree(pParse); | ||
| 205538 | } | 209162 | } |
| 205539 | 209163 | ||
| 205540 | /* | 209164 | /* |
| @@ -205550,27 +209174,127 @@ static void jsonTypeFunc( | |||
| 205550 | sqlite3_value **argv | 209174 | sqlite3_value **argv |
| 205551 | ){ | 209175 | ){ |
| 205552 | JsonParse *p; /* The parse */ | 209176 | JsonParse *p; /* The parse */ |
| 205553 | const char *zPath; | 209177 | const char *zPath = 0; |
| 205554 | JsonNode *pNode; | 209178 | u32 i; |
| 205555 | 209179 | ||
| 205556 | p = jsonParseCached(ctx, argv[0], ctx, 0); | 209180 | p = jsonParseFuncArg(ctx, argv[0], 0); |
| 205557 | if( p==0 ) return; | 209181 | if( p==0 ) return; |
| 205558 | if( argc==2 ){ | 209182 | if( argc==2 ){ |
| 205559 | zPath = (const char*)sqlite3_value_text(argv[1]); | 209183 | zPath = (const char*)sqlite3_value_text(argv[1]); |
| 205560 | pNode = jsonLookup(p, zPath, 0, ctx); | 209184 | if( zPath==0 ) goto json_type_done; |
| 209185 | if( zPath[0]!='$' ){ | ||
| 209186 | jsonBadPathError(ctx, zPath); | ||
| 209187 | goto json_type_done; | ||
| 209188 | } | ||
| 209189 | i = jsonLookupStep(p, 0, zPath+1, 0); | ||
| 209190 | if( JSON_LOOKUP_ISERROR(i) ){ | ||
| 209191 | if( i==JSON_LOOKUP_NOTFOUND ){ | ||
| 209192 | /* no-op */ | ||
| 209193 | }else if( i==JSON_LOOKUP_PATHERROR ){ | ||
| 209194 | jsonBadPathError(ctx, zPath); | ||
| 209195 | }else{ | ||
| 209196 | sqlite3_result_error(ctx, "malformed JSON", -1); | ||
| 209197 | } | ||
| 209198 | goto json_type_done; | ||
| 209199 | } | ||
| 205561 | }else{ | 209200 | }else{ |
| 205562 | pNode = p->aNode; | 209201 | i = 0; |
| 205563 | } | 209202 | } |
| 205564 | if( pNode ){ | 209203 | sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); |
| 205565 | sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); | 209204 | json_type_done: |
| 209205 | jsonParseFree(p); | ||
| 209206 | } | ||
| 209207 | |||
| 209208 | /* | ||
| 209209 | ** json_pretty(JSON) | ||
| 209210 | ** json_pretty(JSON, INDENT) | ||
| 209211 | ** | ||
| 209212 | ** Return text that is a pretty-printed rendering of the input JSON. | ||
| 209213 | ** If the argument is not valid JSON, return NULL. | ||
| 209214 | ** | ||
| 209215 | ** The INDENT argument is text that is used for indentation. If omitted, | ||
| 209216 | ** it defaults to four spaces (the same as PostgreSQL). | ||
| 209217 | */ | ||
| 209218 | static void jsonPrettyFunc( | ||
| 209219 | sqlite3_context *ctx, | ||
| 209220 | int argc, | ||
| 209221 | sqlite3_value **argv | ||
| 209222 | ){ | ||
| 209223 | JsonString s; /* The output string */ | ||
| 209224 | JsonPretty x; /* Pretty printing context */ | ||
| 209225 | |||
| 209226 | memset(&x, 0, sizeof(x)); | ||
| 209227 | x.pParse = jsonParseFuncArg(ctx, argv[0], 0); | ||
| 209228 | if( x.pParse==0 ) return; | ||
| 209229 | x.pOut = &s; | ||
| 209230 | jsonStringInit(&s, ctx); | ||
| 209231 | if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){ | ||
| 209232 | x.zIndent = " "; | ||
| 209233 | x.szIndent = 4; | ||
| 209234 | }else{ | ||
| 209235 | x.szIndent = (u32)strlen(x.zIndent); | ||
| 205566 | } | 209236 | } |
| 209237 | jsonTranslateBlobToPrettyText(&x, 0); | ||
| 209238 | jsonReturnString(&s, 0, 0); | ||
| 209239 | jsonParseFree(x.pParse); | ||
| 205567 | } | 209240 | } |
| 205568 | 209241 | ||
| 205569 | /* | 209242 | /* |
| 205570 | ** json_valid(JSON) | 209243 | ** json_valid(JSON) |
| 205571 | ** | 209244 | ** json_valid(JSON, FLAGS) |
| 205572 | ** Return 1 if JSON is a well-formed canonical JSON string according | 209245 | ** |
| 205573 | ** to RFC-7159. Return 0 otherwise. | 209246 | ** Check the JSON argument to see if it is well-formed. The FLAGS argument |
| 209247 | ** encodes the various constraints on what is meant by "well-formed": | ||
| 209248 | ** | ||
| 209249 | ** 0x01 Canonical RFC-8259 JSON text | ||
| 209250 | ** 0x02 JSON text with optional JSON-5 extensions | ||
| 209251 | ** 0x04 Superficially appears to be JSONB | ||
| 209252 | ** 0x08 Strictly well-formed JSONB | ||
| 209253 | ** | ||
| 209254 | ** If the FLAGS argument is omitted, it defaults to 1. Useful values for | ||
| 209255 | ** FLAGS include: | ||
| 209256 | ** | ||
| 209257 | ** 1 Strict canonical JSON text | ||
| 209258 | ** 2 JSON text perhaps with JSON-5 extensions | ||
| 209259 | ** 4 Superficially appears to be JSONB | ||
| 209260 | ** 5 Canonical JSON text or superficial JSONB | ||
| 209261 | ** 6 JSON-5 text or superficial JSONB | ||
| 209262 | ** 8 Strict JSONB | ||
| 209263 | ** 9 Canonical JSON text or strict JSONB | ||
| 209264 | ** 10 JSON-5 text or strict JSONB | ||
| 209265 | ** | ||
| 209266 | ** Other flag combinations are redundant. For example, every canonical | ||
| 209267 | ** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 | ||
| 209268 | ** are the same. Similarly, any input that passes a strict JSONB validation | ||
| 209269 | ** will also pass the superficial validation so 12 through 15 are the same | ||
| 209270 | ** as 8 through 11 respectively. | ||
| 209271 | ** | ||
| 209272 | ** This routine runs in linear time to validate text and when doing strict | ||
| 209273 | ** JSONB validation. Superficial JSONB validation is constant time, | ||
| 209274 | ** assuming the BLOB is already in memory. The performance advantage | ||
| 209275 | ** of superficial JSONB validation is why that option is provided. | ||
| 209276 | ** Application developers can choose to do fast superficial validation or | ||
| 209277 | ** slower strict validation, according to their specific needs. | ||
| 209278 | ** | ||
| 209279 | ** Only the lower four bits of the FLAGS argument are currently used. | ||
| 209280 | ** Higher bits are reserved for future expansion. To facilitate | ||
| 209281 | ** compatibility, the current implementation raises an error if any bit | ||
| 209282 | ** in FLAGS is set other than the lower four bits. | ||
| 209283 | ** | ||
| 209284 | ** The original circa 2015 implementation of the JSON routines in | ||
| 209285 | ** SQLite only supported canonical RFC-8259 JSON text and the json_valid() | ||
| 209286 | ** function only accepted one argument. That is why the default value | ||
| 209287 | ** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only | ||
| 209288 | ** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS | ||
| 209289 | ** argument was added when the JSON routines were extended to support | ||
| 209290 | ** JSON5-like extensions and binary JSONB stored in BLOBs. | ||
| 209291 | ** | ||
| 209292 | ** Return Values: | ||
| 209293 | ** | ||
| 209294 | ** * Raise an error if FLAGS is outside the range of 1 to 15. | ||
| 209295 | ** * Return NULL if the input is NULL | ||
| 209296 | ** * Return 1 if the input is well-formed. | ||
| 209297 | ** * Return 0 if the input is not well-formed. | ||
| 205574 | */ | 209298 | */ |
| 205575 | static void jsonValidFunc( | 209299 | static void jsonValidFunc( |
| 205576 | sqlite3_context *ctx, | 209300 | sqlite3_context *ctx, |
| @@ -205578,79 +209302,128 @@ static void jsonValidFunc( | |||
| 205578 | sqlite3_value **argv | 209302 | sqlite3_value **argv |
| 205579 | ){ | 209303 | ){ |
| 205580 | JsonParse *p; /* The parse */ | 209304 | JsonParse *p; /* The parse */ |
| 205581 | UNUSED_PARAMETER(argc); | 209305 | u8 flags = 1; |
| 205582 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ | 209306 | u8 res = 0; |
| 209307 | if( argc==2 ){ | ||
| 209308 | i64 f = sqlite3_value_int64(argv[1]); | ||
| 209309 | if( f<1 || f>15 ){ | ||
| 209310 | sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" | ||
| 209311 | " between 1 and 15", -1); | ||
| 209312 | return; | ||
| 209313 | } | ||
| 209314 | flags = f & 0x0f; | ||
| 209315 | } | ||
| 209316 | switch( sqlite3_value_type(argv[0]) ){ | ||
| 209317 | case SQLITE_NULL: { | ||
| 205583 | #ifdef SQLITE_LEGACY_JSON_VALID | 209318 | #ifdef SQLITE_LEGACY_JSON_VALID |
| 205584 | /* Incorrect legacy behavior was to return FALSE for a NULL input */ | 209319 | /* Incorrect legacy behavior was to return FALSE for a NULL input */ |
| 205585 | sqlite3_result_int(ctx, 0); | 209320 | sqlite3_result_int(ctx, 0); |
| 205586 | #endif | 209321 | #endif |
| 205587 | return; | 209322 | return; |
| 205588 | } | 209323 | } |
| 205589 | p = jsonParseCached(ctx, argv[0], 0, 0); | 209324 | case SQLITE_BLOB: { |
| 205590 | if( p==0 || p->oom ){ | 209325 | if( jsonFuncArgMightBeBinary(argv[0]) ){ |
| 205591 | sqlite3_result_error_nomem(ctx); | 209326 | if( flags & 0x04 ){ |
| 205592 | sqlite3_free(p); | 209327 | /* Superficial checking only - accomplished by the |
| 205593 | }else{ | 209328 | ** jsonFuncArgMightBeBinary() call above. */ |
| 205594 | sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); | 209329 | res = 1; |
| 205595 | if( p->nErr ) jsonParseFree(p); | 209330 | }else if( flags & 0x08 ){ |
| 209331 | /* Strict checking. Check by translating BLOB->TEXT->BLOB. If | ||
| 209332 | ** no errors occur, call that a "strict check". */ | ||
| 209333 | JsonParse px; | ||
| 209334 | u32 iErr; | ||
| 209335 | memset(&px, 0, sizeof(px)); | ||
| 209336 | px.aBlob = (u8*)sqlite3_value_blob(argv[0]); | ||
| 209337 | px.nBlob = sqlite3_value_bytes(argv[0]); | ||
| 209338 | iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); | ||
| 209339 | res = iErr==0; | ||
| 209340 | } | ||
| 209341 | break; | ||
| 209342 | } | ||
| 209343 | /* Fall through into interpreting the input as text. See note | ||
| 209344 | ** above at tag-20240123-a. */ | ||
| 209345 | /* no break */ deliberate_fall_through | ||
| 209346 | } | ||
| 209347 | default: { | ||
| 209348 | JsonParse px; | ||
| 209349 | if( (flags & 0x3)==0 ) break; | ||
| 209350 | memset(&px, 0, sizeof(px)); | ||
| 209351 | |||
| 209352 | p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); | ||
| 209353 | if( p ){ | ||
| 209354 | if( p->oom ){ | ||
| 209355 | sqlite3_result_error_nomem(ctx); | ||
| 209356 | }else if( p->nErr ){ | ||
| 209357 | /* no-op */ | ||
| 209358 | }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ | ||
| 209359 | res = 1; | ||
| 209360 | } | ||
| 209361 | jsonParseFree(p); | ||
| 209362 | }else{ | ||
| 209363 | sqlite3_result_error_nomem(ctx); | ||
| 209364 | } | ||
| 209365 | break; | ||
| 209366 | } | ||
| 205596 | } | 209367 | } |
| 209368 | sqlite3_result_int(ctx, res); | ||
| 205597 | } | 209369 | } |
| 205598 | 209370 | ||
| 205599 | /* | 209371 | /* |
| 205600 | ** json_error_position(JSON) | 209372 | ** json_error_position(JSON) |
| 205601 | ** | 209373 | ** |
| 205602 | ** If the argument is not an interpretable JSON string, then return the 1-based | 209374 | ** If the argument is NULL, return NULL |
| 205603 | ** character position at which the parser first recognized that the input | ||
| 205604 | ** was in error. The left-most character is 1. If the string is valid | ||
| 205605 | ** JSON, then return 0. | ||
| 205606 | ** | ||
| 205607 | ** Note that json_valid() is only true for strictly conforming canonical JSON. | ||
| 205608 | ** But this routine returns zero if the input contains extension. Thus: | ||
| 205609 | ** | ||
| 205610 | ** (1) If the input X is strictly conforming canonical JSON: | ||
| 205611 | ** | ||
| 205612 | ** json_valid(X) returns true | ||
| 205613 | ** json_error_position(X) returns 0 | ||
| 205614 | ** | 209375 | ** |
| 205615 | ** (2) If the input X is JSON but it includes extension (such as JSON5) that | 209376 | ** If the argument is BLOB, do a full validity check and return non-zero |
| 205616 | ** are not part of RFC-8259: | 209377 | ** if the check fails. The return value is the approximate 1-based offset |
| 209378 | ** to the byte of the element that contains the first error. | ||
| 205617 | ** | 209379 | ** |
| 205618 | ** json_valid(X) returns false | 209380 | ** Otherwise interpret the argument is TEXT (even if it is numeric) and |
| 205619 | ** json_error_position(X) return 0 | 209381 | ** return the 1-based character position for where the parser first recognized |
| 205620 | ** | 209382 | ** that the input was not valid JSON, or return 0 if the input text looks |
| 205621 | ** (3) If the input X cannot be interpreted as JSON even taking extensions | 209383 | ** ok. JSON-5 extensions are accepted. |
| 205622 | ** into account: | ||
| 205623 | ** | ||
| 205624 | ** json_valid(X) return false | ||
| 205625 | ** json_error_position(X) returns 1 or more | ||
| 205626 | */ | 209384 | */ |
| 205627 | static void jsonErrorFunc( | 209385 | static void jsonErrorFunc( |
| 205628 | sqlite3_context *ctx, | 209386 | sqlite3_context *ctx, |
| 205629 | int argc, | 209387 | int argc, |
| 205630 | sqlite3_value **argv | 209388 | sqlite3_value **argv |
| 205631 | ){ | 209389 | ){ |
| 205632 | JsonParse *p; /* The parse */ | 209390 | i64 iErrPos = 0; /* Error position to be returned */ |
| 209391 | JsonParse s; | ||
| 209392 | |||
| 209393 | assert( argc==1 ); | ||
| 205633 | UNUSED_PARAMETER(argc); | 209394 | UNUSED_PARAMETER(argc); |
| 205634 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; | 209395 | memset(&s, 0, sizeof(s)); |
| 205635 | p = jsonParseCached(ctx, argv[0], 0, 0); | 209396 | s.db = sqlite3_context_db_handle(ctx); |
| 205636 | if( p==0 || p->oom ){ | 209397 | if( jsonFuncArgMightBeBinary(argv[0]) ){ |
| 209398 | s.aBlob = (u8*)sqlite3_value_blob(argv[0]); | ||
| 209399 | s.nBlob = sqlite3_value_bytes(argv[0]); | ||
| 209400 | iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); | ||
| 209401 | }else{ | ||
| 209402 | s.zJson = (char*)sqlite3_value_text(argv[0]); | ||
| 209403 | if( s.zJson==0 ) return; /* NULL input or OOM */ | ||
| 209404 | s.nJson = sqlite3_value_bytes(argv[0]); | ||
| 209405 | if( jsonConvertTextToBlob(&s,0) ){ | ||
| 209406 | if( s.oom ){ | ||
| 209407 | iErrPos = -1; | ||
| 209408 | }else{ | ||
| 209409 | /* Convert byte-offset s.iErr into a character offset */ | ||
| 209410 | u32 k; | ||
| 209411 | assert( s.zJson!=0 ); /* Because s.oom is false */ | ||
| 209412 | for(k=0; k<s.iErr && ALWAYS(s.zJson[k]); k++){ | ||
| 209413 | if( (s.zJson[k] & 0xc0)!=0x80 ) iErrPos++; | ||
| 209414 | } | ||
| 209415 | iErrPos++; | ||
| 209416 | } | ||
| 209417 | } | ||
| 209418 | } | ||
| 209419 | jsonParseReset(&s); | ||
| 209420 | if( iErrPos<0 ){ | ||
| 205637 | sqlite3_result_error_nomem(ctx); | 209421 | sqlite3_result_error_nomem(ctx); |
| 205638 | sqlite3_free(p); | ||
| 205639 | }else if( p->nErr==0 ){ | ||
| 205640 | sqlite3_result_int(ctx, 0); | ||
| 205641 | }else{ | 209422 | }else{ |
| 205642 | int n = 1; | 209423 | sqlite3_result_int64(ctx, iErrPos); |
| 205643 | u32 i; | ||
| 205644 | const char *z = (const char*)sqlite3_value_text(argv[0]); | ||
| 205645 | for(i=0; i<p->iErr && ALWAYS(z[i]); i++){ | ||
| 205646 | if( (z[i]&0xc0)!=0x80 ) n++; | ||
| 205647 | } | ||
| 205648 | sqlite3_result_int(ctx, n); | ||
| 205649 | jsonParseFree(p); | ||
| 205650 | } | 209424 | } |
| 205651 | } | 209425 | } |
| 205652 | 209426 | ||
| 205653 | |||
| 205654 | /**************************************************************************** | 209427 | /**************************************************************************** |
| 205655 | ** Aggregate SQL function implementations | 209428 | ** Aggregate SQL function implementations |
| 205656 | ****************************************************************************/ | 209429 | ****************************************************************************/ |
| @@ -205669,24 +209442,34 @@ static void jsonArrayStep( | |||
| 205669 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); | 209442 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 205670 | if( pStr ){ | 209443 | if( pStr ){ |
| 205671 | if( pStr->zBuf==0 ){ | 209444 | if( pStr->zBuf==0 ){ |
| 205672 | jsonInit(pStr, ctx); | 209445 | jsonStringInit(pStr, ctx); |
| 205673 | jsonAppendChar(pStr, '['); | 209446 | jsonAppendChar(pStr, '['); |
| 205674 | }else if( pStr->nUsed>1 ){ | 209447 | }else if( pStr->nUsed>1 ){ |
| 205675 | jsonAppendChar(pStr, ','); | 209448 | jsonAppendChar(pStr, ','); |
| 205676 | } | 209449 | } |
| 205677 | pStr->pCtx = ctx; | 209450 | pStr->pCtx = ctx; |
| 205678 | jsonAppendValue(pStr, argv[0]); | 209451 | jsonAppendSqlValue(pStr, argv[0]); |
| 205679 | } | 209452 | } |
| 205680 | } | 209453 | } |
| 205681 | static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ | 209454 | static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ |
| 205682 | JsonString *pStr; | 209455 | JsonString *pStr; |
| 205683 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); | 209456 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 205684 | if( pStr ){ | 209457 | if( pStr ){ |
| 209458 | int flags; | ||
| 205685 | pStr->pCtx = ctx; | 209459 | pStr->pCtx = ctx; |
| 205686 | jsonAppendChar(pStr, ']'); | 209460 | jsonAppendChar(pStr, ']'); |
| 205687 | if( pStr->bErr ){ | 209461 | flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); |
| 205688 | if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); | 209462 | if( pStr->eErr ){ |
| 205689 | assert( pStr->bStatic ); | 209463 | jsonReturnString(pStr, 0, 0); |
| 209464 | return; | ||
| 209465 | }else if( flags & JSON_BLOB ){ | ||
| 209466 | jsonReturnStringAsBlob(pStr); | ||
| 209467 | if( isFinal ){ | ||
| 209468 | if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); | ||
| 209469 | }else{ | ||
| 209470 | jsonStringTrimOneChar(pStr); | ||
| 209471 | } | ||
| 209472 | return; | ||
| 205690 | }else if( isFinal ){ | 209473 | }else if( isFinal ){ |
| 205691 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, | 209474 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, |
| 205692 | pStr->bStatic ? SQLITE_TRANSIENT : | 209475 | pStr->bStatic ? SQLITE_TRANSIENT : |
| @@ -205694,7 +209477,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ | |||
| 205694 | pStr->bStatic = 1; | 209477 | pStr->bStatic = 1; |
| 205695 | }else{ | 209478 | }else{ |
| 205696 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); | 209479 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); |
| 205697 | pStr->nUsed--; | 209480 | jsonStringTrimOneChar(pStr); |
| 205698 | } | 209481 | } |
| 205699 | }else{ | 209482 | }else{ |
| 205700 | sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); | 209483 | sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); |
| @@ -205775,27 +209558,38 @@ static void jsonObjectStep( | |||
| 205775 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); | 209558 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 205776 | if( pStr ){ | 209559 | if( pStr ){ |
| 205777 | if( pStr->zBuf==0 ){ | 209560 | if( pStr->zBuf==0 ){ |
| 205778 | jsonInit(pStr, ctx); | 209561 | jsonStringInit(pStr, ctx); |
| 205779 | jsonAppendChar(pStr, '{'); | 209562 | jsonAppendChar(pStr, '{'); |
| 205780 | }else if( pStr->nUsed>1 ){ | 209563 | }else if( pStr->nUsed>1 ){ |
| 205781 | jsonAppendChar(pStr, ','); | 209564 | jsonAppendChar(pStr, ','); |
| 205782 | } | 209565 | } |
| 205783 | pStr->pCtx = ctx; | 209566 | pStr->pCtx = ctx; |
| 205784 | z = (const char*)sqlite3_value_text(argv[0]); | 209567 | z = (const char*)sqlite3_value_text(argv[0]); |
| 205785 | n = (u32)sqlite3_value_bytes(argv[0]); | 209568 | n = sqlite3Strlen30(z); |
| 205786 | jsonAppendString(pStr, z, n); | 209569 | jsonAppendString(pStr, z, n); |
| 205787 | jsonAppendChar(pStr, ':'); | 209570 | jsonAppendChar(pStr, ':'); |
| 205788 | jsonAppendValue(pStr, argv[1]); | 209571 | jsonAppendSqlValue(pStr, argv[1]); |
| 205789 | } | 209572 | } |
| 205790 | } | 209573 | } |
| 205791 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ | 209574 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 205792 | JsonString *pStr; | 209575 | JsonString *pStr; |
| 205793 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); | 209576 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 205794 | if( pStr ){ | 209577 | if( pStr ){ |
| 209578 | int flags; | ||
| 205795 | jsonAppendChar(pStr, '}'); | 209579 | jsonAppendChar(pStr, '}'); |
| 205796 | if( pStr->bErr ){ | 209580 | pStr->pCtx = ctx; |
| 205797 | if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); | 209581 | flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); |
| 205798 | assert( pStr->bStatic ); | 209582 | if( pStr->eErr ){ |
| 209583 | jsonReturnString(pStr, 0, 0); | ||
| 209584 | return; | ||
| 209585 | }else if( flags & JSON_BLOB ){ | ||
| 209586 | jsonReturnStringAsBlob(pStr); | ||
| 209587 | if( isFinal ){ | ||
| 209588 | if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); | ||
| 209589 | }else{ | ||
| 209590 | jsonStringTrimOneChar(pStr); | ||
| 209591 | } | ||
| 209592 | return; | ||
| 205799 | }else if( isFinal ){ | 209593 | }else if( isFinal ){ |
| 205800 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, | 209594 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, |
| 205801 | pStr->bStatic ? SQLITE_TRANSIENT : | 209595 | pStr->bStatic ? SQLITE_TRANSIENT : |
| @@ -205803,7 +209597,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ | |||
| 205803 | pStr->bStatic = 1; | 209597 | pStr->bStatic = 1; |
| 205804 | }else{ | 209598 | }else{ |
| 205805 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); | 209599 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); |
| 205806 | pStr->nUsed--; | 209600 | jsonStringTrimOneChar(pStr); |
| 205807 | } | 209601 | } |
| 205808 | }else{ | 209602 | }else{ |
| 205809 | sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); | 209603 | sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); |
| @@ -205823,19 +209617,37 @@ static void jsonObjectFinal(sqlite3_context *ctx){ | |||
| 205823 | /**************************************************************************** | 209617 | /**************************************************************************** |
| 205824 | ** The json_each virtual table | 209618 | ** The json_each virtual table |
| 205825 | ****************************************************************************/ | 209619 | ****************************************************************************/ |
| 209620 | typedef struct JsonParent JsonParent; | ||
| 209621 | struct JsonParent { | ||
| 209622 | u32 iHead; /* Start of object or array */ | ||
| 209623 | u32 iValue; /* Start of the value */ | ||
| 209624 | u32 iEnd; /* First byte past the end */ | ||
| 209625 | u32 nPath; /* Length of path */ | ||
| 209626 | i64 iKey; /* Key for JSONB_ARRAY */ | ||
| 209627 | }; | ||
| 209628 | |||
| 205826 | typedef struct JsonEachCursor JsonEachCursor; | 209629 | typedef struct JsonEachCursor JsonEachCursor; |
| 205827 | struct JsonEachCursor { | 209630 | struct JsonEachCursor { |
| 205828 | sqlite3_vtab_cursor base; /* Base class - must be first */ | 209631 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 205829 | u32 iRowid; /* The rowid */ | 209632 | u32 iRowid; /* The rowid */ |
| 205830 | u32 iBegin; /* The first node of the scan */ | 209633 | u32 i; /* Index in sParse.aBlob[] of current row */ |
| 205831 | u32 i; /* Index in sParse.aNode[] of current row */ | ||
| 205832 | u32 iEnd; /* EOF when i equals or exceeds this value */ | 209634 | u32 iEnd; /* EOF when i equals or exceeds this value */ |
| 205833 | u8 eType; /* Type of top-level element */ | 209635 | u32 nRoot; /* Size of the root path in bytes */ |
| 209636 | u8 eType; /* Type of the container for element i */ | ||
| 205834 | u8 bRecursive; /* True for json_tree(). False for json_each() */ | 209637 | u8 bRecursive; /* True for json_tree(). False for json_each() */ |
| 205835 | char *zJson; /* Input JSON */ | 209638 | u32 nParent; /* Current nesting depth */ |
| 205836 | char *zRoot; /* Path by which to filter zJson */ | 209639 | u32 nParentAlloc; /* Space allocated for aParent[] */ |
| 209640 | JsonParent *aParent; /* Parent elements of i */ | ||
| 209641 | sqlite3 *db; /* Database connection */ | ||
| 209642 | JsonString path; /* Current path */ | ||
| 205837 | JsonParse sParse; /* Parse of the input JSON */ | 209643 | JsonParse sParse; /* Parse of the input JSON */ |
| 205838 | }; | 209644 | }; |
| 209645 | typedef struct JsonEachConnection JsonEachConnection; | ||
| 209646 | struct JsonEachConnection { | ||
| 209647 | sqlite3_vtab base; /* Base class - must be first */ | ||
| 209648 | sqlite3 *db; /* Database connection */ | ||
| 209649 | }; | ||
| 209650 | |||
| 205839 | 209651 | ||
| 205840 | /* Constructor for the json_each virtual table */ | 209652 | /* Constructor for the json_each virtual table */ |
| 205841 | static int jsonEachConnect( | 209653 | static int jsonEachConnect( |
| @@ -205845,7 +209657,7 @@ static int jsonEachConnect( | |||
| 205845 | sqlite3_vtab **ppVtab, | 209657 | sqlite3_vtab **ppVtab, |
| 205846 | char **pzErr | 209658 | char **pzErr |
| 205847 | ){ | 209659 | ){ |
| 205848 | sqlite3_vtab *pNew; | 209660 | JsonEachConnection *pNew; |
| 205849 | int rc; | 209661 | int rc; |
| 205850 | 209662 | ||
| 205851 | /* Column numbers */ | 209663 | /* Column numbers */ |
| @@ -205871,28 +209683,32 @@ static int jsonEachConnect( | |||
| 205871 | "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," | 209683 | "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," |
| 205872 | "json HIDDEN,root HIDDEN)"); | 209684 | "json HIDDEN,root HIDDEN)"); |
| 205873 | if( rc==SQLITE_OK ){ | 209685 | if( rc==SQLITE_OK ){ |
| 205874 | pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); | 209686 | pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); |
| 209687 | *ppVtab = (sqlite3_vtab*)pNew; | ||
| 205875 | if( pNew==0 ) return SQLITE_NOMEM; | 209688 | if( pNew==0 ) return SQLITE_NOMEM; |
| 205876 | memset(pNew, 0, sizeof(*pNew)); | ||
| 205877 | sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); | 209689 | sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); |
| 209690 | pNew->db = db; | ||
| 205878 | } | 209691 | } |
| 205879 | return rc; | 209692 | return rc; |
| 205880 | } | 209693 | } |
| 205881 | 209694 | ||
| 205882 | /* destructor for json_each virtual table */ | 209695 | /* destructor for json_each virtual table */ |
| 205883 | static int jsonEachDisconnect(sqlite3_vtab *pVtab){ | 209696 | static int jsonEachDisconnect(sqlite3_vtab *pVtab){ |
| 205884 | sqlite3_free(pVtab); | 209697 | JsonEachConnection *p = (JsonEachConnection*)pVtab; |
| 209698 | sqlite3DbFree(p->db, pVtab); | ||
| 205885 | return SQLITE_OK; | 209699 | return SQLITE_OK; |
| 205886 | } | 209700 | } |
| 205887 | 209701 | ||
| 205888 | /* constructor for a JsonEachCursor object for json_each(). */ | 209702 | /* constructor for a JsonEachCursor object for json_each(). */ |
| 205889 | static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ | 209703 | static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
| 209704 | JsonEachConnection *pVtab = (JsonEachConnection*)p; | ||
| 205890 | JsonEachCursor *pCur; | 209705 | JsonEachCursor *pCur; |
| 205891 | 209706 | ||
| 205892 | UNUSED_PARAMETER(p); | 209707 | UNUSED_PARAMETER(p); |
| 205893 | pCur = sqlite3_malloc( sizeof(*pCur) ); | 209708 | pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); |
| 205894 | if( pCur==0 ) return SQLITE_NOMEM; | 209709 | if( pCur==0 ) return SQLITE_NOMEM; |
| 205895 | memset(pCur, 0, sizeof(*pCur)); | 209710 | pCur->db = pVtab->db; |
| 209711 | jsonStringZero(&pCur->path); | ||
| 205896 | *ppCursor = &pCur->base; | 209712 | *ppCursor = &pCur->base; |
| 205897 | return SQLITE_OK; | 209713 | return SQLITE_OK; |
| 205898 | } | 209714 | } |
| @@ -205910,21 +209726,24 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ | |||
| 205910 | /* Reset a JsonEachCursor back to its original state. Free any memory | 209726 | /* Reset a JsonEachCursor back to its original state. Free any memory |
| 205911 | ** held. */ | 209727 | ** held. */ |
| 205912 | static void jsonEachCursorReset(JsonEachCursor *p){ | 209728 | static void jsonEachCursorReset(JsonEachCursor *p){ |
| 205913 | sqlite3_free(p->zRoot); | ||
| 205914 | jsonParseReset(&p->sParse); | 209729 | jsonParseReset(&p->sParse); |
| 209730 | jsonStringReset(&p->path); | ||
| 209731 | sqlite3DbFree(p->db, p->aParent); | ||
| 205915 | p->iRowid = 0; | 209732 | p->iRowid = 0; |
| 205916 | p->i = 0; | 209733 | p->i = 0; |
| 209734 | p->aParent = 0; | ||
| 209735 | p->nParent = 0; | ||
| 209736 | p->nParentAlloc = 0; | ||
| 205917 | p->iEnd = 0; | 209737 | p->iEnd = 0; |
| 205918 | p->eType = 0; | 209738 | p->eType = 0; |
| 205919 | p->zJson = 0; | ||
| 205920 | p->zRoot = 0; | ||
| 205921 | } | 209739 | } |
| 205922 | 209740 | ||
| 205923 | /* Destructor for a jsonEachCursor object */ | 209741 | /* Destructor for a jsonEachCursor object */ |
| 205924 | static int jsonEachClose(sqlite3_vtab_cursor *cur){ | 209742 | static int jsonEachClose(sqlite3_vtab_cursor *cur){ |
| 205925 | JsonEachCursor *p = (JsonEachCursor*)cur; | 209743 | JsonEachCursor *p = (JsonEachCursor*)cur; |
| 205926 | jsonEachCursorReset(p); | 209744 | jsonEachCursorReset(p); |
| 205927 | sqlite3_free(cur); | 209745 | |
| 209746 | sqlite3DbFree(p->db, cur); | ||
| 205928 | return SQLITE_OK; | 209747 | return SQLITE_OK; |
| 205929 | } | 209748 | } |
| 205930 | 209749 | ||
| @@ -205935,200 +209754,233 @@ static int jsonEachEof(sqlite3_vtab_cursor *cur){ | |||
| 205935 | return p->i >= p->iEnd; | 209754 | return p->i >= p->iEnd; |
| 205936 | } | 209755 | } |
| 205937 | 209756 | ||
| 205938 | /* Advance the cursor to the next element for json_tree() */ | 209757 | /* |
| 205939 | static int jsonEachNext(sqlite3_vtab_cursor *cur){ | 209758 | ** If the cursor is currently pointing at the label of a object entry, |
| 205940 | JsonEachCursor *p = (JsonEachCursor*)cur; | 209759 | ** then return the index of the value. For all other cases, return the |
| 205941 | if( p->bRecursive ){ | 209760 | ** current pointer position, which is the value. |
| 205942 | if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; | 209761 | */ |
| 205943 | p->i++; | 209762 | static int jsonSkipLabel(JsonEachCursor *p){ |
| 205944 | p->iRowid++; | 209763 | if( p->eType==JSONB_OBJECT ){ |
| 205945 | if( p->i<p->iEnd ){ | 209764 | u32 sz = 0; |
| 205946 | u32 iUp = p->sParse.aUp[p->i]; | 209765 | u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); |
| 205947 | JsonNode *pUp = &p->sParse.aNode[iUp]; | 209766 | return p->i + n + sz; |
| 205948 | p->eType = pUp->eType; | 209767 | }else{ |
| 205949 | if( pUp->eType==JSON_ARRAY ){ | 209768 | return p->i; |
| 205950 | assert( pUp->eU==0 || pUp->eU==3 ); | 209769 | } |
| 205951 | testcase( pUp->eU==3 ); | 209770 | } |
| 205952 | VVA( pUp->eU = 3 ); | 209771 | |
| 205953 | if( iUp==p->i-1 ){ | 209772 | /* |
| 205954 | pUp->u.iKey = 0; | 209773 | ** Append the path name for the current element. |
| 205955 | }else{ | 209774 | */ |
| 205956 | pUp->u.iKey++; | 209775 | static void jsonAppendPathName(JsonEachCursor *p){ |
| 209776 | assert( p->nParent>0 ); | ||
| 209777 | assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); | ||
| 209778 | if( p->eType==JSONB_ARRAY ){ | ||
| 209779 | jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); | ||
| 209780 | }else{ | ||
| 209781 | u32 n, sz = 0, k, i; | ||
| 209782 | const char *z; | ||
| 209783 | int needQuote = 0; | ||
| 209784 | n = jsonbPayloadSize(&p->sParse, p->i, &sz); | ||
| 209785 | k = p->i + n; | ||
| 209786 | z = (const char*)&p->sParse.aBlob[k]; | ||
| 209787 | if( sz==0 || !sqlite3Isalpha(z[0]) ){ | ||
| 209788 | needQuote = 1; | ||
| 209789 | }else{ | ||
| 209790 | for(i=0; i<sz; i++){ | ||
| 209791 | if( !sqlite3Isalnum(z[i]) ){ | ||
| 209792 | needQuote = 1; | ||
| 209793 | break; | ||
| 205957 | } | 209794 | } |
| 205958 | } | 209795 | } |
| 205959 | } | 209796 | } |
| 205960 | }else{ | 209797 | if( needQuote ){ |
| 205961 | switch( p->eType ){ | 209798 | jsonPrintf(sz+4,&p->path,".\"%.*s\"", sz, z); |
| 205962 | case JSON_ARRAY: { | 209799 | }else{ |
| 205963 | p->i += jsonNodeSize(&p->sParse.aNode[p->i]); | 209800 | jsonPrintf(sz+2,&p->path,".%.*s", sz, z); |
| 205964 | p->iRowid++; | ||
| 205965 | break; | ||
| 205966 | } | ||
| 205967 | case JSON_OBJECT: { | ||
| 205968 | p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); | ||
| 205969 | p->iRowid++; | ||
| 205970 | break; | ||
| 205971 | } | ||
| 205972 | default: { | ||
| 205973 | p->i = p->iEnd; | ||
| 205974 | break; | ||
| 205975 | } | ||
| 205976 | } | 209801 | } |
| 205977 | } | 209802 | } |
| 205978 | return SQLITE_OK; | ||
| 205979 | } | 209803 | } |
| 205980 | 209804 | ||
| 205981 | /* Append an object label to the JSON Path being constructed | 209805 | /* Advance the cursor to the next element for json_tree() */ |
| 205982 | ** in pStr. | 209806 | static int jsonEachNext(sqlite3_vtab_cursor *cur){ |
| 205983 | */ | 209807 | JsonEachCursor *p = (JsonEachCursor*)cur; |
| 205984 | static void jsonAppendObjectPathElement( | 209808 | int rc = SQLITE_OK; |
| 205985 | JsonString *pStr, | 209809 | if( p->bRecursive ){ |
| 205986 | JsonNode *pNode | 209810 | u8 x; |
| 205987 | ){ | 209811 | u8 levelChange = 0; |
| 205988 | int jj, nn; | 209812 | u32 n, sz = 0; |
| 205989 | const char *z; | 209813 | u32 i = jsonSkipLabel(p); |
| 205990 | assert( pNode->eType==JSON_STRING ); | 209814 | x = p->sParse.aBlob[i] & 0x0f; |
| 205991 | assert( pNode->jnFlags & JNODE_LABEL ); | 209815 | n = jsonbPayloadSize(&p->sParse, i, &sz); |
| 205992 | assert( pNode->eU==1 ); | 209816 | if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ |
| 205993 | z = pNode->u.zJContent; | 209817 | JsonParent *pParent; |
| 205994 | nn = pNode->n; | 209818 | if( p->nParent>=p->nParentAlloc ){ |
| 205995 | if( (pNode->jnFlags & JNODE_RAW)==0 ){ | 209819 | JsonParent *pNew; |
| 205996 | assert( nn>=2 ); | 209820 | u64 nNew; |
| 205997 | assert( z[0]=='"' || z[0]=='\'' ); | 209821 | nNew = p->nParentAlloc*2 + 3; |
| 205998 | assert( z[nn-1]=='"' || z[0]=='\'' ); | 209822 | pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); |
| 205999 | if( nn>2 && sqlite3Isalpha(z[1]) ){ | 209823 | if( pNew==0 ) return SQLITE_NOMEM; |
| 206000 | for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){} | 209824 | p->nParentAlloc = (u32)nNew; |
| 206001 | if( jj==nn-1 ){ | 209825 | p->aParent = pNew; |
| 206002 | z++; | 209826 | } |
| 206003 | nn -= 2; | 209827 | levelChange = 1; |
| 209828 | pParent = &p->aParent[p->nParent]; | ||
| 209829 | pParent->iHead = p->i; | ||
| 209830 | pParent->iValue = i; | ||
| 209831 | pParent->iEnd = i + n + sz; | ||
| 209832 | pParent->iKey = -1; | ||
| 209833 | pParent->nPath = (u32)p->path.nUsed; | ||
| 209834 | if( p->eType && p->nParent ){ | ||
| 209835 | jsonAppendPathName(p); | ||
| 209836 | if( p->path.eErr ) rc = SQLITE_NOMEM; | ||
| 209837 | } | ||
| 209838 | p->nParent++; | ||
| 209839 | p->i = i + n; | ||
| 209840 | }else{ | ||
| 209841 | p->i = i + n + sz; | ||
| 209842 | } | ||
| 209843 | while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ | ||
| 209844 | p->nParent--; | ||
| 209845 | p->path.nUsed = p->aParent[p->nParent].nPath; | ||
| 209846 | levelChange = 1; | ||
| 209847 | } | ||
| 209848 | if( levelChange ){ | ||
| 209849 | if( p->nParent>0 ){ | ||
| 209850 | JsonParent *pParent = &p->aParent[p->nParent-1]; | ||
| 209851 | u32 iVal = pParent->iValue; | ||
| 209852 | p->eType = p->sParse.aBlob[iVal] & 0x0f; | ||
| 209853 | }else{ | ||
| 209854 | p->eType = 0; | ||
| 206004 | } | 209855 | } |
| 206005 | } | 209856 | } |
| 209857 | }else{ | ||
| 209858 | u32 n, sz = 0; | ||
| 209859 | u32 i = jsonSkipLabel(p); | ||
| 209860 | n = jsonbPayloadSize(&p->sParse, i, &sz); | ||
| 209861 | p->i = i + n + sz; | ||
| 209862 | } | ||
| 209863 | if( p->eType==JSONB_ARRAY && p->nParent ){ | ||
| 209864 | p->aParent[p->nParent-1].iKey++; | ||
| 206006 | } | 209865 | } |
| 206007 | jsonPrintf(nn+2, pStr, ".%.*s", nn, z); | 209866 | p->iRowid++; |
| 209867 | return rc; | ||
| 206008 | } | 209868 | } |
| 206009 | 209869 | ||
| 206010 | /* Append the name of the path for element i to pStr | 209870 | /* Length of the path for rowid==0 in bRecursive mode. |
| 206011 | */ | 209871 | */ |
| 206012 | static void jsonEachComputePath( | 209872 | static int jsonEachPathLength(JsonEachCursor *p){ |
| 206013 | JsonEachCursor *p, /* The cursor */ | 209873 | u32 n = p->path.nUsed; |
| 206014 | JsonString *pStr, /* Write the path here */ | 209874 | char *z = p->path.zBuf; |
| 206015 | u32 i /* Path to this element */ | 209875 | if( p->iRowid==0 && p->bRecursive && n>=2 ){ |
| 206016 | ){ | 209876 | while( n>1 ){ |
| 206017 | JsonNode *pNode, *pUp; | 209877 | n--; |
| 206018 | u32 iUp; | 209878 | if( z[n]=='[' || z[n]=='.' ){ |
| 206019 | if( i==0 ){ | 209879 | u32 x, sz = 0; |
| 206020 | jsonAppendChar(pStr, '$'); | 209880 | char cSaved = z[n]; |
| 206021 | return; | 209881 | z[n] = 0; |
| 206022 | } | 209882 | assert( p->sParse.eEdit==0 ); |
| 206023 | iUp = p->sParse.aUp[i]; | 209883 | x = jsonLookupStep(&p->sParse, 0, z+1, 0); |
| 206024 | jsonEachComputePath(p, pStr, iUp); | 209884 | z[n] = cSaved; |
| 206025 | pNode = &p->sParse.aNode[i]; | 209885 | if( JSON_LOOKUP_ISERROR(x) ) continue; |
| 206026 | pUp = &p->sParse.aNode[iUp]; | 209886 | if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; |
| 206027 | if( pUp->eType==JSON_ARRAY ){ | 209887 | } |
| 206028 | assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) ); | 209888 | } |
| 206029 | testcase( pUp->eU==0 ); | ||
| 206030 | jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); | ||
| 206031 | }else{ | ||
| 206032 | assert( pUp->eType==JSON_OBJECT ); | ||
| 206033 | if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; | ||
| 206034 | jsonAppendObjectPathElement(pStr, pNode); | ||
| 206035 | } | 209889 | } |
| 209890 | return n; | ||
| 206036 | } | 209891 | } |
| 206037 | 209892 | ||
| 206038 | /* Return the value of a column */ | 209893 | /* Return the value of a column */ |
| 206039 | static int jsonEachColumn( | 209894 | static int jsonEachColumn( |
| 206040 | sqlite3_vtab_cursor *cur, /* The cursor */ | 209895 | sqlite3_vtab_cursor *cur, /* The cursor */ |
| 206041 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | 209896 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
| 206042 | int i /* Which column to return */ | 209897 | int iColumn /* Which column to return */ |
| 206043 | ){ | 209898 | ){ |
| 206044 | JsonEachCursor *p = (JsonEachCursor*)cur; | 209899 | JsonEachCursor *p = (JsonEachCursor*)cur; |
| 206045 | JsonNode *pThis = &p->sParse.aNode[p->i]; | 209900 | switch( iColumn ){ |
| 206046 | switch( i ){ | ||
| 206047 | case JEACH_KEY: { | 209901 | case JEACH_KEY: { |
| 206048 | if( p->i==0 ) break; | 209902 | if( p->nParent==0 ){ |
| 206049 | if( p->eType==JSON_OBJECT ){ | 209903 | u32 n, j; |
| 206050 | jsonReturn(&p->sParse, pThis, ctx); | 209904 | if( p->nRoot==1 ) break; |
| 206051 | }else if( p->eType==JSON_ARRAY ){ | 209905 | j = jsonEachPathLength(p); |
| 206052 | u32 iKey; | 209906 | n = p->nRoot - j; |
| 206053 | if( p->bRecursive ){ | 209907 | if( n==0 ){ |
| 206054 | if( p->iRowid==0 ) break; | 209908 | break; |
| 206055 | assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 ); | 209909 | }else if( p->path.zBuf[j]=='[' ){ |
| 206056 | iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; | 209910 | i64 x; |
| 209911 | sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); | ||
| 209912 | sqlite3_result_int64(ctx, x); | ||
| 209913 | }else if( p->path.zBuf[j+1]=='"' ){ | ||
| 209914 | sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); | ||
| 206057 | }else{ | 209915 | }else{ |
| 206058 | iKey = p->iRowid; | 209916 | sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); |
| 206059 | } | 209917 | } |
| 206060 | sqlite3_result_int64(ctx, (sqlite3_int64)iKey); | 209918 | break; |
| 209919 | } | ||
| 209920 | if( p->eType==JSONB_OBJECT ){ | ||
| 209921 | jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); | ||
| 209922 | }else{ | ||
| 209923 | assert( p->eType==JSONB_ARRAY ); | ||
| 209924 | sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); | ||
| 206061 | } | 209925 | } |
| 206062 | break; | 209926 | break; |
| 206063 | } | 209927 | } |
| 206064 | case JEACH_VALUE: { | 209928 | case JEACH_VALUE: { |
| 206065 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; | 209929 | u32 i = jsonSkipLabel(p); |
| 206066 | jsonReturn(&p->sParse, pThis, ctx); | 209930 | jsonReturnFromBlob(&p->sParse, i, ctx, 1); |
| 209931 | if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){ | ||
| 209932 | sqlite3_result_subtype(ctx, JSON_SUBTYPE); | ||
| 209933 | } | ||
| 206067 | break; | 209934 | break; |
| 206068 | } | 209935 | } |
| 206069 | case JEACH_TYPE: { | 209936 | case JEACH_TYPE: { |
| 206070 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; | 209937 | u32 i = jsonSkipLabel(p); |
| 206071 | sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); | 209938 | u8 eType = p->sParse.aBlob[i] & 0x0f; |
| 209939 | sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); | ||
| 206072 | break; | 209940 | break; |
| 206073 | } | 209941 | } |
| 206074 | case JEACH_ATOM: { | 209942 | case JEACH_ATOM: { |
| 206075 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; | 209943 | u32 i = jsonSkipLabel(p); |
| 206076 | if( pThis->eType>=JSON_ARRAY ) break; | 209944 | if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){ |
| 206077 | jsonReturn(&p->sParse, pThis, ctx); | 209945 | jsonReturnFromBlob(&p->sParse, i, ctx, 1); |
| 209946 | } | ||
| 206078 | break; | 209947 | break; |
| 206079 | } | 209948 | } |
| 206080 | case JEACH_ID: { | 209949 | case JEACH_ID: { |
| 206081 | sqlite3_result_int64(ctx, | 209950 | sqlite3_result_int64(ctx, (sqlite3_int64)p->i); |
| 206082 | (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); | ||
| 206083 | break; | 209951 | break; |
| 206084 | } | 209952 | } |
| 206085 | case JEACH_PARENT: { | 209953 | case JEACH_PARENT: { |
| 206086 | if( p->i>p->iBegin && p->bRecursive ){ | 209954 | if( p->nParent>0 && p->bRecursive ){ |
| 206087 | sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); | 209955 | sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); |
| 206088 | } | 209956 | } |
| 206089 | break; | 209957 | break; |
| 206090 | } | 209958 | } |
| 206091 | case JEACH_FULLKEY: { | 209959 | case JEACH_FULLKEY: { |
| 206092 | JsonString x; | 209960 | u64 nBase = p->path.nUsed; |
| 206093 | jsonInit(&x, ctx); | 209961 | if( p->nParent ) jsonAppendPathName(p); |
| 206094 | if( p->bRecursive ){ | 209962 | sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, |
| 206095 | jsonEachComputePath(p, &x, p->i); | 209963 | SQLITE_TRANSIENT, SQLITE_UTF8); |
| 206096 | }else{ | 209964 | p->path.nUsed = nBase; |
| 206097 | if( p->zRoot ){ | ||
| 206098 | jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); | ||
| 206099 | }else{ | ||
| 206100 | jsonAppendChar(&x, '$'); | ||
| 206101 | } | ||
| 206102 | if( p->eType==JSON_ARRAY ){ | ||
| 206103 | jsonPrintf(30, &x, "[%d]", p->iRowid); | ||
| 206104 | }else if( p->eType==JSON_OBJECT ){ | ||
| 206105 | jsonAppendObjectPathElement(&x, pThis); | ||
| 206106 | } | ||
| 206107 | } | ||
| 206108 | jsonResult(&x); | ||
| 206109 | break; | 209965 | break; |
| 206110 | } | 209966 | } |
| 206111 | case JEACH_PATH: { | 209967 | case JEACH_PATH: { |
| 206112 | if( p->bRecursive ){ | 209968 | u32 n = jsonEachPathLength(p); |
| 206113 | JsonString x; | 209969 | sqlite3_result_text64(ctx, p->path.zBuf, n, |
| 206114 | jsonInit(&x, ctx); | 209970 | SQLITE_TRANSIENT, SQLITE_UTF8); |
| 206115 | jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); | 209971 | break; |
| 206116 | jsonResult(&x); | ||
| 206117 | break; | ||
| 206118 | } | ||
| 206119 | /* For json_each() path and root are the same so fall through | ||
| 206120 | ** into the root case */ | ||
| 206121 | /* no break */ deliberate_fall_through | ||
| 206122 | } | 209972 | } |
| 206123 | default: { | 209973 | default: { |
| 206124 | const char *zRoot = p->zRoot; | 209974 | sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); |
| 206125 | if( zRoot==0 ) zRoot = "$"; | ||
| 206126 | sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); | ||
| 206127 | break; | 209975 | break; |
| 206128 | } | 209976 | } |
| 206129 | case JEACH_JSON: { | 209977 | case JEACH_JSON: { |
| 206130 | assert( i==JEACH_JSON ); | 209978 | if( p->sParse.zJson==0 ){ |
| 206131 | sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); | 209979 | sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, |
| 209980 | SQLITE_TRANSIENT); | ||
| 209981 | }else{ | ||
| 209982 | sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT); | ||
| 209983 | } | ||
| 206132 | break; | 209984 | break; |
| 206133 | } | 209985 | } |
| 206134 | } | 209986 | } |
| @@ -206219,86 +210071,97 @@ static int jsonEachFilter( | |||
| 206219 | int argc, sqlite3_value **argv | 210071 | int argc, sqlite3_value **argv |
| 206220 | ){ | 210072 | ){ |
| 206221 | JsonEachCursor *p = (JsonEachCursor*)cur; | 210073 | JsonEachCursor *p = (JsonEachCursor*)cur; |
| 206222 | const char *z; | ||
| 206223 | const char *zRoot = 0; | 210074 | const char *zRoot = 0; |
| 206224 | sqlite3_int64 n; | 210075 | u32 i, n, sz; |
| 206225 | 210076 | ||
| 206226 | UNUSED_PARAMETER(idxStr); | 210077 | UNUSED_PARAMETER(idxStr); |
| 206227 | UNUSED_PARAMETER(argc); | 210078 | UNUSED_PARAMETER(argc); |
| 206228 | jsonEachCursorReset(p); | 210079 | jsonEachCursorReset(p); |
| 206229 | if( idxNum==0 ) return SQLITE_OK; | 210080 | if( idxNum==0 ) return SQLITE_OK; |
| 206230 | z = (const char*)sqlite3_value_text(argv[0]); | ||
| 206231 | if( z==0 ) return SQLITE_OK; | ||
| 206232 | memset(&p->sParse, 0, sizeof(p->sParse)); | 210081 | memset(&p->sParse, 0, sizeof(p->sParse)); |
| 206233 | p->sParse.nJPRef = 1; | 210082 | p->sParse.nJPRef = 1; |
| 206234 | if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ | 210083 | p->sParse.db = p->db; |
| 206235 | p->sParse.zJson = sqlite3RCStrRef((char*)z); | 210084 | if( jsonFuncArgMightBeBinary(argv[0]) ){ |
| 206236 | }else{ | 210085 | p->sParse.nBlob = sqlite3_value_bytes(argv[0]); |
| 206237 | n = sqlite3_value_bytes(argv[0]); | 210086 | p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); |
| 206238 | p->sParse.zJson = sqlite3RCStrNew( n+1 ); | 210087 | }else{ |
| 206239 | if( p->sParse.zJson==0 ) return SQLITE_NOMEM; | 210088 | p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); |
| 206240 | memcpy(p->sParse.zJson, z, (size_t)n+1); | 210089 | p->sParse.nJson = sqlite3_value_bytes(argv[0]); |
| 206241 | } | 210090 | if( p->sParse.zJson==0 ){ |
| 206242 | p->sParse.bJsonIsRCStr = 1; | 210091 | p->i = p->iEnd = 0; |
| 206243 | p->zJson = p->sParse.zJson; | 210092 | return SQLITE_OK; |
| 206244 | if( jsonParse(&p->sParse, 0) ){ | ||
| 206245 | int rc = SQLITE_NOMEM; | ||
| 206246 | if( p->sParse.oom==0 ){ | ||
| 206247 | sqlite3_free(cur->pVtab->zErrMsg); | ||
| 206248 | cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); | ||
| 206249 | if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; | ||
| 206250 | } | 210093 | } |
| 206251 | jsonEachCursorReset(p); | 210094 | if( jsonConvertTextToBlob(&p->sParse, 0) ){ |
| 206252 | return rc; | 210095 | if( p->sParse.oom ){ |
| 206253 | }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ | 210096 | return SQLITE_NOMEM; |
| 206254 | jsonEachCursorReset(p); | ||
| 206255 | return SQLITE_NOMEM; | ||
| 206256 | }else{ | ||
| 206257 | JsonNode *pNode = 0; | ||
| 206258 | if( idxNum==3 ){ | ||
| 206259 | const char *zErr = 0; | ||
| 206260 | zRoot = (const char*)sqlite3_value_text(argv[1]); | ||
| 206261 | if( zRoot==0 ) return SQLITE_OK; | ||
| 206262 | n = sqlite3_value_bytes(argv[1]); | ||
| 206263 | p->zRoot = sqlite3_malloc64( n+1 ); | ||
| 206264 | if( p->zRoot==0 ) return SQLITE_NOMEM; | ||
| 206265 | memcpy(p->zRoot, zRoot, (size_t)n+1); | ||
| 206266 | if( zRoot[0]!='$' ){ | ||
| 206267 | zErr = zRoot; | ||
| 206268 | }else{ | ||
| 206269 | pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); | ||
| 206270 | } | 210097 | } |
| 206271 | if( zErr ){ | 210098 | goto json_each_malformed_input; |
| 210099 | } | ||
| 210100 | } | ||
| 210101 | if( idxNum==3 ){ | ||
| 210102 | zRoot = (const char*)sqlite3_value_text(argv[1]); | ||
| 210103 | if( zRoot==0 ) return SQLITE_OK; | ||
| 210104 | if( zRoot[0]!='$' ){ | ||
| 210105 | sqlite3_free(cur->pVtab->zErrMsg); | ||
| 210106 | cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); | ||
| 210107 | jsonEachCursorReset(p); | ||
| 210108 | return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; | ||
| 210109 | } | ||
| 210110 | p->nRoot = sqlite3Strlen30(zRoot); | ||
| 210111 | if( zRoot[1]==0 ){ | ||
| 210112 | i = p->i = 0; | ||
| 210113 | p->eType = 0; | ||
| 210114 | }else{ | ||
| 210115 | i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); | ||
| 210116 | if( JSON_LOOKUP_ISERROR(i) ){ | ||
| 210117 | if( i==JSON_LOOKUP_NOTFOUND ){ | ||
| 210118 | p->i = 0; | ||
| 210119 | p->eType = 0; | ||
| 210120 | p->iEnd = 0; | ||
| 210121 | return SQLITE_OK; | ||
| 210122 | } | ||
| 206272 | sqlite3_free(cur->pVtab->zErrMsg); | 210123 | sqlite3_free(cur->pVtab->zErrMsg); |
| 206273 | cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); | 210124 | cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); |
| 206274 | jsonEachCursorReset(p); | 210125 | jsonEachCursorReset(p); |
| 206275 | return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; | 210126 | return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; |
| 206276 | }else if( pNode==0 ){ | ||
| 206277 | return SQLITE_OK; | ||
| 206278 | } | 210127 | } |
| 206279 | }else{ | 210128 | if( p->sParse.iLabel ){ |
| 206280 | pNode = p->sParse.aNode; | 210129 | p->i = p->sParse.iLabel; |
| 206281 | } | 210130 | p->eType = JSONB_OBJECT; |
| 206282 | p->iBegin = p->i = (int)(pNode - p->sParse.aNode); | ||
| 206283 | p->eType = pNode->eType; | ||
| 206284 | if( p->eType>=JSON_ARRAY ){ | ||
| 206285 | assert( pNode->eU==0 ); | ||
| 206286 | VVA( pNode->eU = 3 ); | ||
| 206287 | pNode->u.iKey = 0; | ||
| 206288 | p->iEnd = p->i + pNode->n + 1; | ||
| 206289 | if( p->bRecursive ){ | ||
| 206290 | p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; | ||
| 206291 | if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ | ||
| 206292 | p->i--; | ||
| 206293 | } | ||
| 206294 | }else{ | 210131 | }else{ |
| 206295 | p->i++; | 210132 | p->i = i; |
| 206296 | } | 210133 | p->eType = JSONB_ARRAY; |
| 206297 | }else{ | 210134 | } |
| 206298 | p->iEnd = p->i+1; | 210135 | } |
| 206299 | } | 210136 | jsonAppendRaw(&p->path, zRoot, p->nRoot); |
| 210137 | }else{ | ||
| 210138 | i = p->i = 0; | ||
| 210139 | p->eType = 0; | ||
| 210140 | p->nRoot = 1; | ||
| 210141 | jsonAppendRaw(&p->path, "$", 1); | ||
| 210142 | } | ||
| 210143 | p->nParent = 0; | ||
| 210144 | n = jsonbPayloadSize(&p->sParse, i, &sz); | ||
| 210145 | p->iEnd = i+n+sz; | ||
| 210146 | if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ | ||
| 210147 | p->i = i + n; | ||
| 210148 | p->eType = p->sParse.aBlob[i] & 0x0f; | ||
| 210149 | p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); | ||
| 210150 | if( p->aParent==0 ) return SQLITE_NOMEM; | ||
| 210151 | p->nParent = 1; | ||
| 210152 | p->nParentAlloc = 1; | ||
| 210153 | p->aParent[0].iKey = 0; | ||
| 210154 | p->aParent[0].iEnd = p->iEnd; | ||
| 210155 | p->aParent[0].iHead = p->i; | ||
| 210156 | p->aParent[0].iValue = i; | ||
| 206300 | } | 210157 | } |
| 206301 | return SQLITE_OK; | 210158 | return SQLITE_OK; |
| 210159 | |||
| 210160 | json_each_malformed_input: | ||
| 210161 | sqlite3_free(cur->pVtab->zErrMsg); | ||
| 210162 | cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); | ||
| 210163 | jsonEachCursorReset(p); | ||
| 210164 | return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; | ||
| 206302 | } | 210165 | } |
| 206303 | 210166 | ||
| 206304 | /* The methods of the json_each virtual table */ | 210167 | /* The methods of the json_each virtual table */ |
| @@ -206367,34 +210230,59 @@ static sqlite3_module jsonTreeModule = { | |||
| 206367 | SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ | 210230 | SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ |
| 206368 | #ifndef SQLITE_OMIT_JSON | 210231 | #ifndef SQLITE_OMIT_JSON |
| 206369 | static FuncDef aJsonFunc[] = { | 210232 | static FuncDef aJsonFunc[] = { |
| 206370 | JFUNCTION(json, 1, 0, jsonRemoveFunc), | 210233 | /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ |
| 206371 | JFUNCTION(json_array, -1, 0, jsonArrayFunc), | 210234 | /* | | */ |
| 206372 | JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), | 210235 | /* Uses cache ------, | | ,---- Returns JSONB */ |
| 206373 | JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), | 210236 | /* | | | | */ |
| 206374 | JFUNCTION(json_error_position,1, 0, jsonErrorFunc), | 210237 | /* Number of arguments ---, | | | | ,--- Flags */ |
| 206375 | JFUNCTION(json_extract, -1, 0, jsonExtractFunc), | 210238 | /* | | | | | | */ |
| 206376 | JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), | 210239 | JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), |
| 206377 | JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), | 210240 | JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), |
| 206378 | JFUNCTION(json_insert, -1, 0, jsonSetFunc), | 210241 | JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), |
| 206379 | JFUNCTION(json_object, -1, 0, jsonObjectFunc), | 210242 | JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), |
| 206380 | JFUNCTION(json_patch, 2, 0, jsonPatchFunc), | 210243 | JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), |
| 206381 | JFUNCTION(json_quote, 1, 0, jsonQuoteFunc), | 210244 | JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), |
| 206382 | JFUNCTION(json_remove, -1, 0, jsonRemoveFunc), | 210245 | JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), |
| 206383 | JFUNCTION(json_replace, -1, 0, jsonReplaceFunc), | 210246 | JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), |
| 206384 | JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc), | 210247 | JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), |
| 206385 | JFUNCTION(json_type, 1, 0, jsonTypeFunc), | 210248 | JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), |
| 206386 | JFUNCTION(json_type, 2, 0, jsonTypeFunc), | 210249 | JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), |
| 206387 | JFUNCTION(json_valid, 1, 0, jsonValidFunc), | 210250 | JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), |
| 210251 | JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), | ||
| 210252 | JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), | ||
| 210253 | JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), | ||
| 210254 | JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), | ||
| 210255 | JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), | ||
| 210256 | JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc), | ||
| 210257 | JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc), | ||
| 210258 | JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), | ||
| 210259 | JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), | ||
| 210260 | JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), | ||
| 210261 | JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), | ||
| 210262 | JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), | ||
| 210263 | JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), | ||
| 210264 | JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), | ||
| 210265 | JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), | ||
| 210266 | JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), | ||
| 210267 | JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), | ||
| 210268 | JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), | ||
| 206388 | #if SQLITE_DEBUG | 210269 | #if SQLITE_DEBUG |
| 206389 | JFUNCTION(json_parse, 1, 0, jsonParseFunc), | 210270 | JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), |
| 206390 | JFUNCTION(json_test1, 1, 0, jsonTest1Func), | ||
| 206391 | #endif | 210271 | #endif |
| 206392 | WAGGREGATE(json_group_array, 1, 0, 0, | 210272 | WAGGREGATE(json_group_array, 1, 0, 0, |
| 206393 | jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, | 210273 | jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, |
| 206394 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), | 210274 | SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| |
| 210275 | SQLITE_DETERMINISTIC), | ||
| 210276 | WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, | ||
| 210277 | jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, | ||
| 210278 | SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), | ||
| 206395 | WAGGREGATE(json_group_object, 2, 0, 0, | 210279 | WAGGREGATE(json_group_object, 2, 0, 0, |
| 206396 | jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, | 210280 | jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, |
| 206397 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) | 210281 | SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), |
| 210282 | WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, | ||
| 210283 | jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, | ||
| 210284 | SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| | ||
| 210285 | SQLITE_DETERMINISTIC) | ||
| 206398 | }; | 210286 | }; |
| 206399 | sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); | 210287 | sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); |
| 206400 | #endif | 210288 | #endif |
| @@ -207119,11 +211007,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ | |||
| 207119 | ** Clear the Rtree.pNodeBlob object | 211007 | ** Clear the Rtree.pNodeBlob object |
| 207120 | */ | 211008 | */ |
| 207121 | static void nodeBlobReset(Rtree *pRtree){ | 211009 | static void nodeBlobReset(Rtree *pRtree){ |
| 207122 | if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ | 211010 | sqlite3_blob *pBlob = pRtree->pNodeBlob; |
| 207123 | sqlite3_blob *pBlob = pRtree->pNodeBlob; | 211011 | pRtree->pNodeBlob = 0; |
| 207124 | pRtree->pNodeBlob = 0; | 211012 | sqlite3_blob_close(pBlob); |
| 207125 | sqlite3_blob_close(pBlob); | ||
| 207126 | } | ||
| 207127 | } | 211013 | } |
| 207128 | 211014 | ||
| 207129 | /* | 211015 | /* |
| @@ -207142,7 +211028,7 @@ static int nodeAcquire( | |||
| 207142 | ** increase its reference count and return it. | 211028 | ** increase its reference count and return it. |
| 207143 | */ | 211029 | */ |
| 207144 | if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ | 211030 | if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ |
| 207145 | if( pParent && pParent!=pNode->pParent ){ | 211031 | if( pParent && ALWAYS(pParent!=pNode->pParent) ){ |
| 207146 | RTREE_IS_CORRUPT(pRtree); | 211032 | RTREE_IS_CORRUPT(pRtree); |
| 207147 | return SQLITE_CORRUPT_VTAB; | 211033 | return SQLITE_CORRUPT_VTAB; |
| 207148 | } | 211034 | } |
| @@ -207167,7 +211053,6 @@ static int nodeAcquire( | |||
| 207167 | &pRtree->pNodeBlob); | 211053 | &pRtree->pNodeBlob); |
| 207168 | } | 211054 | } |
| 207169 | if( rc ){ | 211055 | if( rc ){ |
| 207170 | nodeBlobReset(pRtree); | ||
| 207171 | *ppNode = 0; | 211056 | *ppNode = 0; |
| 207172 | /* If unable to open an sqlite3_blob on the desired row, that can only | 211057 | /* If unable to open an sqlite3_blob on the desired row, that can only |
| 207173 | ** be because the shadow tables hold erroneous data. */ | 211058 | ** be because the shadow tables hold erroneous data. */ |
| @@ -207227,6 +211112,7 @@ static int nodeAcquire( | |||
| 207227 | } | 211112 | } |
| 207228 | *ppNode = pNode; | 211113 | *ppNode = pNode; |
| 207229 | }else{ | 211114 | }else{ |
| 211115 | nodeBlobReset(pRtree); | ||
| 207230 | if( pNode ){ | 211116 | if( pNode ){ |
| 207231 | pRtree->nNodeRef--; | 211117 | pRtree->nNodeRef--; |
| 207232 | sqlite3_free(pNode); | 211118 | sqlite3_free(pNode); |
| @@ -207371,6 +211257,7 @@ static void nodeGetCoord( | |||
| 207371 | int iCoord, /* Which coordinate to extract */ | 211257 | int iCoord, /* Which coordinate to extract */ |
| 207372 | RtreeCoord *pCoord /* OUT: Space to write result to */ | 211258 | RtreeCoord *pCoord /* OUT: Space to write result to */ |
| 207373 | ){ | 211259 | ){ |
| 211260 | assert( iCell<NCELL(pNode) ); | ||
| 207374 | readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); | 211261 | readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); |
| 207375 | } | 211262 | } |
| 207376 | 211263 | ||
| @@ -207560,7 +211447,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ | |||
| 207560 | sqlite3_finalize(pCsr->pReadAux); | 211447 | sqlite3_finalize(pCsr->pReadAux); |
| 207561 | sqlite3_free(pCsr); | 211448 | sqlite3_free(pCsr); |
| 207562 | pRtree->nCursor--; | 211449 | pRtree->nCursor--; |
| 207563 | nodeBlobReset(pRtree); | 211450 | if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){ |
| 211451 | nodeBlobReset(pRtree); | ||
| 211452 | } | ||
| 207564 | return SQLITE_OK; | 211453 | return SQLITE_OK; |
| 207565 | } | 211454 | } |
| 207566 | 211455 | ||
| @@ -208145,7 +212034,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ | |||
| 208145 | int rc = SQLITE_OK; | 212034 | int rc = SQLITE_OK; |
| 208146 | RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); | 212035 | RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); |
| 208147 | if( rc==SQLITE_OK && ALWAYS(p) ){ | 212036 | if( rc==SQLITE_OK && ALWAYS(p) ){ |
| 208148 | *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); | 212037 | if( p->iCell>=NCELL(pNode) ){ |
| 212038 | rc = SQLITE_ABORT; | ||
| 212039 | }else{ | ||
| 212040 | *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); | ||
| 212041 | } | ||
| 208149 | } | 212042 | } |
| 208150 | return rc; | 212043 | return rc; |
| 208151 | } | 212044 | } |
| @@ -208163,6 +212056,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ | |||
| 208163 | 212056 | ||
| 208164 | if( rc ) return rc; | 212057 | if( rc ) return rc; |
| 208165 | if( NEVER(p==0) ) return SQLITE_OK; | 212058 | if( NEVER(p==0) ) return SQLITE_OK; |
| 212059 | if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT; | ||
| 208166 | if( i==0 ){ | 212060 | if( i==0 ){ |
| 208167 | sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); | 212061 | sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); |
| 208168 | }else if( i<=pRtree->nDim2 ){ | 212062 | }else if( i<=pRtree->nDim2 ){ |
| @@ -208260,6 +212154,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ | |||
| 208260 | return SQLITE_OK; | 212154 | return SQLITE_OK; |
| 208261 | } | 212155 | } |
| 208262 | 212156 | ||
| 212157 | SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); | ||
| 212158 | |||
| 208263 | /* | 212159 | /* |
| 208264 | ** Rtree virtual table module xFilter method. | 212160 | ** Rtree virtual table module xFilter method. |
| 208265 | */ | 212161 | */ |
| @@ -208289,7 +212185,8 @@ static int rtreeFilter( | |||
| 208289 | i64 iNode = 0; | 212185 | i64 iNode = 0; |
| 208290 | int eType = sqlite3_value_numeric_type(argv[0]); | 212186 | int eType = sqlite3_value_numeric_type(argv[0]); |
| 208291 | if( eType==SQLITE_INTEGER | 212187 | if( eType==SQLITE_INTEGER |
| 208292 | || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) | 212188 | || (eType==SQLITE_FLOAT |
| 212189 | && 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0]))) | ||
| 208293 | ){ | 212190 | ){ |
| 208294 | rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); | 212191 | rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); |
| 208295 | }else{ | 212192 | }else{ |
| @@ -209645,7 +213542,7 @@ constraint: | |||
| 209645 | static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ | 213542 | static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ |
| 209646 | Rtree *pRtree = (Rtree *)pVtab; | 213543 | Rtree *pRtree = (Rtree *)pVtab; |
| 209647 | assert( pRtree->inWrTrans==0 ); | 213544 | assert( pRtree->inWrTrans==0 ); |
| 209648 | pRtree->inWrTrans++; | 213545 | pRtree->inWrTrans = 1; |
| 209649 | return SQLITE_OK; | 213546 | return SQLITE_OK; |
| 209650 | } | 213547 | } |
| 209651 | 213548 | ||
| @@ -209659,6 +213556,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){ | |||
| 209659 | nodeBlobReset(pRtree); | 213556 | nodeBlobReset(pRtree); |
| 209660 | return SQLITE_OK; | 213557 | return SQLITE_OK; |
| 209661 | } | 213558 | } |
| 213559 | static int rtreeRollback(sqlite3_vtab *pVtab){ | ||
| 213560 | return rtreeEndTransaction(pVtab); | ||
| 213561 | } | ||
| 209662 | 213562 | ||
| 209663 | /* | 213563 | /* |
| 209664 | ** The xRename method for rtree module virtual tables. | 213564 | ** The xRename method for rtree module virtual tables. |
| @@ -209777,7 +213677,7 @@ static sqlite3_module rtreeModule = { | |||
| 209777 | rtreeBeginTransaction, /* xBegin - begin transaction */ | 213677 | rtreeBeginTransaction, /* xBegin - begin transaction */ |
| 209778 | rtreeEndTransaction, /* xSync - sync transaction */ | 213678 | rtreeEndTransaction, /* xSync - sync transaction */ |
| 209779 | rtreeEndTransaction, /* xCommit - commit transaction */ | 213679 | rtreeEndTransaction, /* xCommit - commit transaction */ |
| 209780 | rtreeEndTransaction, /* xRollback - rollback transaction */ | 213680 | rtreeRollback, /* xRollback - rollback transaction */ |
| 209781 | 0, /* xFindFunction - function overloading */ | 213681 | 0, /* xFindFunction - function overloading */ |
| 209782 | rtreeRename, /* xRename - rename the table */ | 213682 | rtreeRename, /* xRename - rename the table */ |
| 209783 | rtreeSavepoint, /* xSavepoint */ | 213683 | rtreeSavepoint, /* xSavepoint */ |
| @@ -209877,7 +213777,7 @@ static int rtreeSqlInit( | |||
| 209877 | } | 213777 | } |
| 209878 | sqlite3_free(zSql); | 213778 | sqlite3_free(zSql); |
| 209879 | } | 213779 | } |
| 209880 | if( pRtree->nAux ){ | 213780 | if( pRtree->nAux && rc!=SQLITE_NOMEM ){ |
| 209881 | pRtree->zReadAuxSql = sqlite3_mprintf( | 213781 | pRtree->zReadAuxSql = sqlite3_mprintf( |
| 209882 | "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", | 213782 | "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", |
| 209883 | zDb, zPrefix); | 213783 | zDb, zPrefix); |
| @@ -210566,15 +214466,13 @@ static int rtreeCheckTable( | |||
| 210566 | check.zTab = zTab; | 214466 | check.zTab = zTab; |
| 210567 | 214467 | ||
| 210568 | /* Find the number of auxiliary columns */ | 214468 | /* Find the number of auxiliary columns */ |
| 210569 | if( check.rc==SQLITE_OK ){ | 214469 | pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); |
| 210570 | pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); | 214470 | if( pStmt ){ |
| 210571 | if( pStmt ){ | 214471 | nAux = sqlite3_column_count(pStmt) - 2; |
| 210572 | nAux = sqlite3_column_count(pStmt) - 2; | 214472 | sqlite3_finalize(pStmt); |
| 210573 | sqlite3_finalize(pStmt); | 214473 | }else |
| 210574 | }else | 214474 | if( check.rc!=SQLITE_NOMEM ){ |
| 210575 | if( check.rc!=SQLITE_NOMEM ){ | 214475 | check.rc = SQLITE_OK; |
| 210576 | check.rc = SQLITE_OK; | ||
| 210577 | } | ||
| 210578 | } | 214476 | } |
| 210579 | 214477 | ||
| 210580 | /* Find number of dimensions in the rtree table. */ | 214478 | /* Find number of dimensions in the rtree table. */ |
| @@ -210629,6 +214527,7 @@ static int rtreeIntegrity( | |||
| 210629 | if( rc==SQLITE_OK && *pzErr ){ | 214527 | if( rc==SQLITE_OK && *pzErr ){ |
| 210630 | *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", | 214528 | *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", |
| 210631 | pRtree->zDb, pRtree->zName, *pzErr); | 214529 | pRtree->zDb, pRtree->zName, *pzErr); |
| 214530 | if( (*pzErr)==0 ) rc = SQLITE_NOMEM; | ||
| 210632 | } | 214531 | } |
| 210633 | return rc; | 214532 | return rc; |
| 210634 | } | 214533 | } |
| @@ -213197,7 +217096,7 @@ static void icuLoadCollation( | |||
| 213197 | UCollator *pUCollator; /* ICU library collation object */ | 217096 | UCollator *pUCollator; /* ICU library collation object */ |
| 213198 | int rc; /* Return code from sqlite3_create_collation_x() */ | 217097 | int rc; /* Return code from sqlite3_create_collation_x() */ |
| 213199 | 217098 | ||
| 213200 | assert(nArg==2); | 217099 | assert(nArg==2 || nArg==3); |
| 213201 | (void)nArg; /* Unused parameter */ | 217100 | (void)nArg; /* Unused parameter */ |
| 213202 | zLocale = (const char *)sqlite3_value_text(apArg[0]); | 217101 | zLocale = (const char *)sqlite3_value_text(apArg[0]); |
| 213203 | zName = (const char *)sqlite3_value_text(apArg[1]); | 217102 | zName = (const char *)sqlite3_value_text(apArg[1]); |
| @@ -213212,7 +217111,39 @@ static void icuLoadCollation( | |||
| 213212 | return; | 217111 | return; |
| 213213 | } | 217112 | } |
| 213214 | assert(p); | 217113 | assert(p); |
| 213215 | 217114 | if(nArg==3){ | |
| 217115 | const char *zOption = (const char*)sqlite3_value_text(apArg[2]); | ||
| 217116 | static const struct { | ||
| 217117 | const char *zName; | ||
| 217118 | UColAttributeValue val; | ||
| 217119 | } aStrength[] = { | ||
| 217120 | { "PRIMARY", UCOL_PRIMARY }, | ||
| 217121 | { "SECONDARY", UCOL_SECONDARY }, | ||
| 217122 | { "TERTIARY", UCOL_TERTIARY }, | ||
| 217123 | { "DEFAULT", UCOL_DEFAULT_STRENGTH }, | ||
| 217124 | { "QUARTERNARY", UCOL_QUATERNARY }, | ||
| 217125 | { "IDENTICAL", UCOL_IDENTICAL }, | ||
| 217126 | }; | ||
| 217127 | unsigned int i; | ||
| 217128 | for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ | ||
| 217129 | if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){ | ||
| 217130 | ucol_setStrength(pUCollator, aStrength[i].val); | ||
| 217131 | break; | ||
| 217132 | } | ||
| 217133 | } | ||
| 217134 | if( i>=sizeof(aStrength)/sizeof(aStrength[0]) ){ | ||
| 217135 | sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p)); | ||
| 217136 | sqlite3_str_appendf(pStr, | ||
| 217137 | "unknown collation strength \"%s\" - should be one of:", | ||
| 217138 | zOption); | ||
| 217139 | for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){ | ||
| 217140 | sqlite3_str_appendf(pStr, " %s", aStrength[i].zName); | ||
| 217141 | } | ||
| 217142 | sqlite3_result_error(p, sqlite3_str_value(pStr), -1); | ||
| 217143 | sqlite3_free(sqlite3_str_finish(pStr)); | ||
| 217144 | return; | ||
| 217145 | } | ||
| 217146 | } | ||
| 213216 | rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, | 217147 | rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, |
| 213217 | icuCollationColl, icuCollationDel | 217148 | icuCollationColl, icuCollationDel |
| 213218 | ); | 217149 | ); |
| @@ -213235,6 +217166,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ | |||
| 213235 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); | 217166 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
| 213236 | } scalars[] = { | 217167 | } scalars[] = { |
| 213237 | {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, | 217168 | {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, |
| 217169 | {"icu_load_collation",3,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, | ||
| 213238 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) | 217170 | #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) |
| 213239 | {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, | 217171 | {"regexp", 2, SQLITE_ANY|SQLITEICU_EXTRAFLAGS, 0, icuRegexpFunc}, |
| 213240 | {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, | 217172 | {"lower", 1, SQLITE_UTF16|SQLITEICU_EXTRAFLAGS, 0, icuCaseFunc16}, |
| @@ -214385,6 +218317,7 @@ typedef unsigned int u32; | |||
| 214385 | typedef unsigned short u16; | 218317 | typedef unsigned short u16; |
| 214386 | typedef unsigned char u8; | 218318 | typedef unsigned char u8; |
| 214387 | typedef sqlite3_int64 i64; | 218319 | typedef sqlite3_int64 i64; |
| 218320 | typedef sqlite3_uint64 u64; | ||
| 214388 | #endif | 218321 | #endif |
| 214389 | 218322 | ||
| 214390 | /* | 218323 | /* |
| @@ -215071,6 +219004,7 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ | |||
| 215071 | if( rc!=SQLITE_ROW ){ | 219004 | if( rc!=SQLITE_ROW ){ |
| 215072 | rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); | 219005 | rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); |
| 215073 | pIter->zTbl = 0; | 219006 | pIter->zTbl = 0; |
| 219007 | pIter->zDataTbl = 0; | ||
| 215074 | }else{ | 219008 | }else{ |
| 215075 | pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); | 219009 | pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); |
| 215076 | pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); | 219010 | pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); |
| @@ -217165,7 +221099,7 @@ static i64 rbuShmChecksum(sqlite3rbu *p){ | |||
| 217165 | u32 volatile *ptr; | 221099 | u32 volatile *ptr; |
| 217166 | p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); | 221100 | p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); |
| 217167 | if( p->rc==SQLITE_OK ){ | 221101 | if( p->rc==SQLITE_OK ){ |
| 217168 | iRet = ((i64)ptr[10] << 32) + ptr[11]; | 221102 | iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]); |
| 217169 | } | 221103 | } |
| 217170 | } | 221104 | } |
| 217171 | return iRet; | 221105 | return iRet; |
| @@ -223299,9 +227233,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ | |||
| 223299 | ** associated hash-tables. */ | 227233 | ** associated hash-tables. */ |
| 223300 | sessionDeleteTable(pSession, pSession->pTable); | 227234 | sessionDeleteTable(pSession, pSession->pTable); |
| 223301 | 227235 | ||
| 223302 | /* Assert that all allocations have been freed and then free the | 227236 | /* Free the session object. */ |
| 223303 | ** session object itself. */ | ||
| 223304 | // assert( pSession->nMalloc==0 ); | ||
| 223305 | sqlite3_free(pSession); | 227237 | sqlite3_free(pSession); |
| 223306 | } | 227238 | } |
| 223307 | 227239 | ||
| @@ -224638,14 +228570,14 @@ static int sessionChangesetNextOne( | |||
| 224638 | p->rc = sessionInputBuffer(&p->in, 2); | 228570 | p->rc = sessionInputBuffer(&p->in, 2); |
| 224639 | if( p->rc!=SQLITE_OK ) return p->rc; | 228571 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 224640 | 228572 | ||
| 228573 | sessionDiscardData(&p->in); | ||
| 228574 | p->in.iCurrent = p->in.iNext; | ||
| 228575 | |||
| 224641 | /* If the iterator is already at the end of the changeset, return DONE. */ | 228576 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 224642 | if( p->in.iNext>=p->in.nData ){ | 228577 | if( p->in.iNext>=p->in.nData ){ |
| 224643 | return SQLITE_DONE; | 228578 | return SQLITE_DONE; |
| 224644 | } | 228579 | } |
| 224645 | 228580 | ||
| 224646 | sessionDiscardData(&p->in); | ||
| 224647 | p->in.iCurrent = p->in.iNext; | ||
| 224648 | |||
| 224649 | op = p->in.aData[p->in.iNext++]; | 228581 | op = p->in.aData[p->in.iNext++]; |
| 224650 | while( op=='T' || op=='P' ){ | 228582 | while( op=='T' || op=='P' ){ |
| 224651 | if( pbNew ) *pbNew = 1; | 228583 | if( pbNew ) *pbNew = 1; |
| @@ -226380,6 +230312,7 @@ struct sqlite3_changegroup { | |||
| 226380 | int rc; /* Error code */ | 230312 | int rc; /* Error code */ |
| 226381 | int bPatch; /* True to accumulate patchsets */ | 230313 | int bPatch; /* True to accumulate patchsets */ |
| 226382 | SessionTable *pList; /* List of tables in current patch */ | 230314 | SessionTable *pList; /* List of tables in current patch */ |
| 230315 | SessionBuffer rec; | ||
| 226383 | 230316 | ||
| 226384 | sqlite3 *db; /* Configured by changegroup_schema() */ | 230317 | sqlite3 *db; /* Configured by changegroup_schema() */ |
| 226385 | char *zDb; /* Configured by changegroup_schema() */ | 230318 | char *zDb; /* Configured by changegroup_schema() */ |
| @@ -226678,108 +230611,128 @@ static int sessionChangesetExtendRecord( | |||
| 226678 | } | 230611 | } |
| 226679 | 230612 | ||
| 226680 | /* | 230613 | /* |
| 226681 | ** Add all changes in the changeset traversed by the iterator passed as | 230614 | ** Locate or create a SessionTable object that may be used to add the |
| 226682 | ** the first argument to the changegroup hash tables. | 230615 | ** change currently pointed to by iterator pIter to changegroup pGrp. |
| 230616 | ** If successful, set output variable (*ppTab) to point to the table | ||
| 230617 | ** object and return SQLITE_OK. Otherwise, if some error occurs, return | ||
| 230618 | ** an SQLite error code and leave (*ppTab) set to NULL. | ||
| 226683 | */ | 230619 | */ |
| 226684 | static int sessionChangesetToHash( | 230620 | static int sessionChangesetFindTable( |
| 226685 | sqlite3_changeset_iter *pIter, /* Iterator to read from */ | 230621 | sqlite3_changegroup *pGrp, |
| 226686 | sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ | 230622 | const char *zTab, |
| 226687 | int bRebase /* True if hash table is for rebasing */ | 230623 | sqlite3_changeset_iter *pIter, |
| 230624 | SessionTable **ppTab | ||
| 226688 | ){ | 230625 | ){ |
| 226689 | u8 *aRec; | ||
| 226690 | int nRec; | ||
| 226691 | int rc = SQLITE_OK; | 230626 | int rc = SQLITE_OK; |
| 226692 | SessionTable *pTab = 0; | 230627 | SessionTable *pTab = 0; |
| 226693 | SessionBuffer rec = {0, 0, 0}; | 230628 | int nTab = (int)strlen(zTab); |
| 226694 | 230629 | u8 *abPK = 0; | |
| 226695 | while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ | 230630 | int nCol = 0; |
| 226696 | const char *zNew; | ||
| 226697 | int nCol; | ||
| 226698 | int op; | ||
| 226699 | int iHash; | ||
| 226700 | int bIndirect; | ||
| 226701 | SessionChange *pChange; | ||
| 226702 | SessionChange *pExist = 0; | ||
| 226703 | SessionChange **pp; | ||
| 226704 | |||
| 226705 | /* Ensure that only changesets, or only patchsets, but not a mixture | ||
| 226706 | ** of both, are being combined. It is an error to try to combine a | ||
| 226707 | ** changeset and a patchset. */ | ||
| 226708 | if( pGrp->pList==0 ){ | ||
| 226709 | pGrp->bPatch = pIter->bPatchset; | ||
| 226710 | }else if( pIter->bPatchset!=pGrp->bPatch ){ | ||
| 226711 | rc = SQLITE_ERROR; | ||
| 226712 | break; | ||
| 226713 | } | ||
| 226714 | 230631 | ||
| 226715 | sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); | 230632 | *ppTab = 0; |
| 226716 | if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ | 230633 | sqlite3changeset_pk(pIter, &abPK, &nCol); |
| 226717 | /* Search the list for a matching table */ | ||
| 226718 | int nNew = (int)strlen(zNew); | ||
| 226719 | u8 *abPK; | ||
| 226720 | 230634 | ||
| 226721 | sqlite3changeset_pk(pIter, &abPK, 0); | 230635 | /* Search the list for an existing table */ |
| 226722 | for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ | 230636 | for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ |
| 226723 | if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; | 230637 | if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break; |
| 226724 | } | 230638 | } |
| 226725 | if( !pTab ){ | ||
| 226726 | SessionTable **ppTab; | ||
| 226727 | 230639 | ||
| 226728 | pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); | 230640 | /* If one was not found above, create a new table now */ |
| 226729 | if( !pTab ){ | 230641 | if( !pTab ){ |
| 226730 | rc = SQLITE_NOMEM; | 230642 | SessionTable **ppNew; |
| 226731 | break; | ||
| 226732 | } | ||
| 226733 | memset(pTab, 0, sizeof(SessionTable)); | ||
| 226734 | pTab->nCol = nCol; | ||
| 226735 | pTab->abPK = (u8*)&pTab[1]; | ||
| 226736 | memcpy(pTab->abPK, abPK, nCol); | ||
| 226737 | pTab->zName = (char*)&pTab->abPK[nCol]; | ||
| 226738 | memcpy(pTab->zName, zNew, nNew+1); | ||
| 226739 | |||
| 226740 | if( pGrp->db ){ | ||
| 226741 | pTab->nCol = 0; | ||
| 226742 | rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); | ||
| 226743 | if( rc ){ | ||
| 226744 | assert( pTab->azCol==0 ); | ||
| 226745 | sqlite3_free(pTab); | ||
| 226746 | break; | ||
| 226747 | } | ||
| 226748 | } | ||
| 226749 | 230643 | ||
| 226750 | /* The new object must be linked on to the end of the list, not | 230644 | pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nTab+1); |
| 226751 | ** simply added to the start of it. This is to ensure that the | 230645 | if( !pTab ){ |
| 226752 | ** tables within the output of sqlite3changegroup_output() are in | 230646 | return SQLITE_NOMEM; |
| 226753 | ** the right order. */ | 230647 | } |
| 226754 | for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); | 230648 | memset(pTab, 0, sizeof(SessionTable)); |
| 226755 | *ppTab = pTab; | 230649 | pTab->nCol = nCol; |
| 226756 | } | 230650 | pTab->abPK = (u8*)&pTab[1]; |
| 230651 | memcpy(pTab->abPK, abPK, nCol); | ||
| 230652 | pTab->zName = (char*)&pTab->abPK[nCol]; | ||
| 230653 | memcpy(pTab->zName, zTab, nTab+1); | ||
| 226757 | 230654 | ||
| 226758 | if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ | 230655 | if( pGrp->db ){ |
| 226759 | rc = SQLITE_SCHEMA; | 230656 | pTab->nCol = 0; |
| 226760 | break; | 230657 | rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); |
| 230658 | if( rc ){ | ||
| 230659 | assert( pTab->azCol==0 ); | ||
| 230660 | sqlite3_free(pTab); | ||
| 230661 | return rc; | ||
| 226761 | } | 230662 | } |
| 226762 | } | 230663 | } |
| 226763 | 230664 | ||
| 226764 | if( nCol<pTab->nCol ){ | 230665 | /* The new object must be linked on to the end of the list, not |
| 226765 | assert( pGrp->db ); | 230666 | ** simply added to the start of it. This is to ensure that the |
| 226766 | rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); | 230667 | ** tables within the output of sqlite3changegroup_output() are in |
| 226767 | if( rc ) break; | 230668 | ** the right order. */ |
| 226768 | aRec = rec.aBuf; | 230669 | for(ppNew=&pGrp->pList; *ppNew; ppNew=&(*ppNew)->pNext); |
| 226769 | nRec = rec.nBuf; | 230670 | *ppNew = pTab; |
| 226770 | } | 230671 | } |
| 226771 | 230672 | ||
| 226772 | if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ | 230673 | /* Check that the table is compatible. */ |
| 226773 | rc = SQLITE_NOMEM; | 230674 | if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ |
| 226774 | break; | 230675 | rc = SQLITE_SCHEMA; |
| 226775 | } | 230676 | } |
| 230677 | |||
| 230678 | *ppTab = pTab; | ||
| 230679 | return rc; | ||
| 230680 | } | ||
| 230681 | |||
| 230682 | /* | ||
| 230683 | ** Add the change currently indicated by iterator pIter to the hash table | ||
| 230684 | ** belonging to changegroup pGrp. | ||
| 230685 | */ | ||
| 230686 | static int sessionOneChangeToHash( | ||
| 230687 | sqlite3_changegroup *pGrp, | ||
| 230688 | sqlite3_changeset_iter *pIter, | ||
| 230689 | int bRebase | ||
| 230690 | ){ | ||
| 230691 | int rc = SQLITE_OK; | ||
| 230692 | int nCol = 0; | ||
| 230693 | int op = 0; | ||
| 230694 | int iHash = 0; | ||
| 230695 | int bIndirect = 0; | ||
| 230696 | SessionChange *pChange = 0; | ||
| 230697 | SessionChange *pExist = 0; | ||
| 230698 | SessionChange **pp = 0; | ||
| 230699 | SessionTable *pTab = 0; | ||
| 230700 | u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; | ||
| 230701 | int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; | ||
| 230702 | |||
| 230703 | /* 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 | ||
| 230705 | ** changeset and a patchset. */ | ||
| 230706 | if( pGrp->pList==0 ){ | ||
| 230707 | pGrp->bPatch = pIter->bPatchset; | ||
| 230708 | }else if( pIter->bPatchset!=pGrp->bPatch ){ | ||
| 230709 | rc = SQLITE_ERROR; | ||
| 230710 | } | ||
| 230711 | |||
| 230712 | if( rc==SQLITE_OK ){ | ||
| 230713 | const char *zTab = 0; | ||
| 230714 | sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); | ||
| 230715 | rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); | ||
| 230716 | } | ||
| 230717 | |||
| 230718 | if( rc==SQLITE_OK && nCol<pTab->nCol ){ | ||
| 230719 | SessionBuffer *pBuf = &pGrp->rec; | ||
| 230720 | rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf); | ||
| 230721 | aRec = pBuf->aBuf; | ||
| 230722 | nRec = pBuf->nBuf; | ||
| 230723 | assert( pGrp->db ); | ||
| 230724 | } | ||
| 230725 | |||
| 230726 | if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){ | ||
| 230727 | rc = SQLITE_NOMEM; | ||
| 230728 | } | ||
| 230729 | |||
| 230730 | if( rc==SQLITE_OK ){ | ||
| 230731 | /* Search for existing entry. If found, remove it from the hash table. | ||
| 230732 | ** Code below may link it back in. */ | ||
| 226776 | iHash = sessionChangeHash( | 230733 | iHash = sessionChangeHash( |
| 226777 | pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange | 230734 | pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange |
| 226778 | ); | 230735 | ); |
| 226779 | |||
| 226780 | /* Search for existing entry. If found, remove it from the hash table. | ||
| 226781 | ** Code below may link it back in. | ||
| 226782 | */ | ||
| 226783 | for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ | 230736 | for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ |
| 226784 | int bPkOnly1 = 0; | 230737 | int bPkOnly1 = 0; |
| 226785 | int bPkOnly2 = 0; | 230738 | int bPkOnly2 = 0; |
| @@ -226794,19 +230747,41 @@ static int sessionChangesetToHash( | |||
| 226794 | break; | 230747 | break; |
| 226795 | } | 230748 | } |
| 226796 | } | 230749 | } |
| 230750 | } | ||
| 226797 | 230751 | ||
| 230752 | if( rc==SQLITE_OK ){ | ||
| 226798 | rc = sessionChangeMerge(pTab, bRebase, | 230753 | rc = sessionChangeMerge(pTab, bRebase, |
| 226799 | pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange | 230754 | pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange |
| 226800 | ); | 230755 | ); |
| 226801 | if( rc ) break; | 230756 | } |
| 226802 | if( pChange ){ | 230757 | if( rc==SQLITE_OK && pChange ){ |
| 226803 | pChange->pNext = pTab->apChange[iHash]; | 230758 | pChange->pNext = pTab->apChange[iHash]; |
| 226804 | pTab->apChange[iHash] = pChange; | 230759 | pTab->apChange[iHash] = pChange; |
| 226805 | pTab->nEntry++; | 230760 | pTab->nEntry++; |
| 226806 | } | 230761 | } |
| 230762 | |||
| 230763 | if( rc==SQLITE_OK ) rc = pIter->rc; | ||
| 230764 | return rc; | ||
| 230765 | } | ||
| 230766 | |||
| 230767 | /* | ||
| 230768 | ** Add all changes in the changeset traversed by the iterator passed as | ||
| 230769 | ** the first argument to the changegroup hash tables. | ||
| 230770 | */ | ||
| 230771 | static int sessionChangesetToHash( | ||
| 230772 | sqlite3_changeset_iter *pIter, /* Iterator to read from */ | ||
| 230773 | sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ | ||
| 230774 | int bRebase /* True if hash table is for rebasing */ | ||
| 230775 | ){ | ||
| 230776 | u8 *aRec; | ||
| 230777 | int nRec; | ||
| 230778 | int rc = SQLITE_OK; | ||
| 230779 | |||
| 230780 | while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ | ||
| 230781 | rc = sessionOneChangeToHash(pGrp, pIter, bRebase); | ||
| 230782 | if( rc!=SQLITE_OK ) break; | ||
| 226807 | } | 230783 | } |
| 226808 | 230784 | ||
| 226809 | sqlite3_free(rec.aBuf); | ||
| 226810 | if( rc==SQLITE_OK ) rc = pIter->rc; | 230785 | if( rc==SQLITE_OK ) rc = pIter->rc; |
| 226811 | return rc; | 230786 | return rc; |
| 226812 | } | 230787 | } |
| @@ -226935,6 +230910,23 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void | |||
| 226935 | } | 230910 | } |
| 226936 | 230911 | ||
| 226937 | /* | 230912 | /* |
| 230913 | ** Add a single change to a changeset-group. | ||
| 230914 | */ | ||
| 230915 | SQLITE_API int sqlite3changegroup_add_change( | ||
| 230916 | sqlite3_changegroup *pGrp, | ||
| 230917 | sqlite3_changeset_iter *pIter | ||
| 230918 | ){ | ||
| 230919 | if( pIter->in.iCurrent==pIter->in.iNext | ||
| 230920 | || pIter->rc!=SQLITE_OK | ||
| 230921 | || pIter->bInvert | ||
| 230922 | ){ | ||
| 230923 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ | ||
| 230924 | return SQLITE_ERROR; | ||
| 230925 | } | ||
| 230926 | return sessionOneChangeToHash(pGrp, pIter, 0); | ||
| 230927 | } | ||
| 230928 | |||
| 230929 | /* | ||
| 226938 | ** Obtain a buffer containing a changeset representing the concatenation | 230930 | ** Obtain a buffer containing a changeset representing the concatenation |
| 226939 | ** of all changesets added to the group so far. | 230931 | ** of all changesets added to the group so far. |
| 226940 | */ | 230932 | */ |
| @@ -226983,6 +230975,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ | |||
| 226983 | if( pGrp ){ | 230975 | if( pGrp ){ |
| 226984 | sqlite3_free(pGrp->zDb); | 230976 | sqlite3_free(pGrp->zDb); |
| 226985 | sessionDeleteTable(0, pGrp->pList); | 230977 | sessionDeleteTable(0, pGrp->pList); |
| 230978 | sqlite3_free(pGrp->rec.aBuf); | ||
| 226986 | sqlite3_free(pGrp); | 230979 | sqlite3_free(pGrp); |
| 226987 | } | 230980 | } |
| 226988 | } | 230981 | } |
| @@ -227384,6 +231377,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm( | |||
| 227384 | SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ | 231377 | SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ |
| 227385 | if( p ){ | 231378 | if( p ){ |
| 227386 | sessionDeleteTable(0, p->grp.pList); | 231379 | sessionDeleteTable(0, p->grp.pList); |
| 231380 | sqlite3_free(p->grp.rec.aBuf); | ||
| 227387 | sqlite3_free(p); | 231381 | sqlite3_free(p); |
| 227388 | } | 231382 | } |
| 227389 | } | 231383 | } |
| @@ -227481,8 +231475,8 @@ struct Fts5PhraseIter { | |||
| 227481 | ** EXTENSION API FUNCTIONS | 231475 | ** EXTENSION API FUNCTIONS |
| 227482 | ** | 231476 | ** |
| 227483 | ** xUserData(pFts): | 231477 | ** xUserData(pFts): |
| 227484 | ** Return a copy of the context pointer the extension function was | 231478 | ** Return a copy of the pUserData pointer passed to the xCreateFunction() |
| 227485 | ** registered with. | 231479 | ** API when the extension function was registered. |
| 227486 | ** | 231480 | ** |
| 227487 | ** xColumnTotalSize(pFts, iCol, pnToken): | 231481 | ** xColumnTotalSize(pFts, iCol, pnToken): |
| 227488 | ** If parameter iCol is less than zero, set output variable *pnToken | 231482 | ** If parameter iCol is less than zero, set output variable *pnToken |
| @@ -227514,8 +231508,11 @@ struct Fts5PhraseIter { | |||
| 227514 | ** created with the "columnsize=0" option. | 231508 | ** created with the "columnsize=0" option. |
| 227515 | ** | 231509 | ** |
| 227516 | ** xColumnText: | 231510 | ** xColumnText: |
| 227517 | ** This function attempts to retrieve the text of column iCol of the | 231511 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 227518 | ** current document. If successful, (*pz) is set to point to a buffer | 231512 | ** number of columns in the table, SQLITE_RANGE is returned. |
| 231513 | ** | ||
| 231514 | ** Otherwise, this function attempts to retrieve the text of column iCol of | ||
| 231515 | ** the current document. If successful, (*pz) is set to point to a buffer | ||
| 227519 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes | 231516 | ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes |
| 227520 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, | 231517 | ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, |
| 227521 | ** if an error occurs, an SQLite error code is returned and the final values | 231518 | ** if an error occurs, an SQLite error code is returned and the final values |
| @@ -227525,8 +231522,10 @@ struct Fts5PhraseIter { | |||
| 227525 | ** Returns the number of phrases in the current query expression. | 231522 | ** Returns the number of phrases in the current query expression. |
| 227526 | ** | 231523 | ** |
| 227527 | ** xPhraseSize: | 231524 | ** xPhraseSize: |
| 227528 | ** Returns the number of tokens in phrase iPhrase of the query. Phrases | 231525 | ** If parameter iCol is less than zero, or greater than or equal to the |
| 227529 | ** are numbered starting from zero. | 231526 | ** number of phrases in the current query, as returned by xPhraseCount, |
| 231527 | ** 0 is returned. Otherwise, this function returns the number of tokens in | ||
| 231528 | ** phrase iPhrase of the query. Phrases are numbered starting from zero. | ||
| 227530 | ** | 231529 | ** |
| 227531 | ** xInstCount: | 231530 | ** xInstCount: |
| 227532 | ** Set *pnInst to the total number of occurrences of all phrases within | 231531 | ** Set *pnInst to the total number of occurrences of all phrases within |
| @@ -227542,12 +231541,13 @@ struct Fts5PhraseIter { | |||
| 227542 | ** Query for the details of phrase match iIdx within the current row. | 231541 | ** Query for the details of phrase match iIdx within the current row. |
| 227543 | ** Phrase matches are numbered starting from zero, so the iIdx argument | 231542 | ** Phrase matches are numbered starting from zero, so the iIdx argument |
| 227544 | ** should be greater than or equal to zero and smaller than the value | 231543 | ** should be greater than or equal to zero and smaller than the value |
| 227545 | ** output by xInstCount(). | 231544 | ** output by xInstCount(). If iIdx is less than zero or greater than |
| 231545 | ** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. | ||
| 227546 | ** | 231546 | ** |
| 227547 | ** Usually, output parameter *piPhrase is set to the phrase number, *piCol | 231547 | ** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol |
| 227548 | ** to the column in which it occurs and *piOff the token offset of the | 231548 | ** to the column in which it occurs and *piOff the token offset of the |
| 227549 | ** first token of the phrase. Returns SQLITE_OK if successful, or an error | 231549 | ** first token of the phrase. SQLITE_OK is returned if successful, or an |
| 227550 | ** code (i.e. SQLITE_NOMEM) if an error occurs. | 231550 | ** error code (i.e. SQLITE_NOMEM) if an error occurs. |
| 227551 | ** | 231551 | ** |
| 227552 | ** This API can be quite slow if used with an FTS5 table created with the | 231552 | ** This API can be quite slow if used with an FTS5 table created with the |
| 227553 | ** "detail=none" or "detail=column" option. | 231553 | ** "detail=none" or "detail=column" option. |
| @@ -227573,6 +231573,10 @@ struct Fts5PhraseIter { | |||
| 227573 | ** Invoking Api.xUserData() returns a copy of the pointer passed as | 231573 | ** Invoking Api.xUserData() returns a copy of the pointer passed as |
| 227574 | ** the third argument to pUserData. | 231574 | ** the third argument to pUserData. |
| 227575 | ** | 231575 | ** |
| 231576 | ** If parameter iPhrase is less than zero, or greater than or equal to | ||
| 231577 | ** the number of phrases in the query, as returned by xPhraseCount(), | ||
| 231578 | ** this function returns SQLITE_RANGE. | ||
| 231579 | ** | ||
| 227576 | ** If the callback function returns any value other than SQLITE_OK, the | 231580 | ** If the callback function returns any value other than SQLITE_OK, the |
| 227577 | ** query is abandoned and the xQueryPhrase function returns immediately. | 231581 | ** query is abandoned and the xQueryPhrase function returns immediately. |
| 227578 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. | 231582 | ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. |
| @@ -227687,9 +231691,42 @@ struct Fts5PhraseIter { | |||
| 227687 | ** | 231691 | ** |
| 227688 | ** xPhraseNextColumn() | 231692 | ** xPhraseNextColumn() |
| 227689 | ** See xPhraseFirstColumn above. | 231693 | ** See xPhraseFirstColumn above. |
| 231694 | ** | ||
| 231695 | ** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) | ||
| 231696 | ** This is used to access token iToken of phrase iPhrase of the current | ||
| 231697 | ** query. Before returning, output parameter *ppToken is set to point | ||
| 231698 | ** to a buffer containing the requested token, and *pnToken to the | ||
| 231699 | ** size of this buffer in bytes. | ||
| 231700 | ** | ||
| 231701 | ** If iPhrase or iToken are less than zero, or if iPhrase is greater than | ||
| 231702 | ** or equal to the number of phrases in the query as reported by | ||
| 231703 | ** xPhraseCount(), or if iToken is equal to or greater than the number of | ||
| 231704 | ** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken | ||
| 231705 | are both zeroed. | ||
| 231706 | ** | ||
| 231707 | ** The output text is not a copy of the query text that specified the | ||
| 231708 | ** token. It is the output of the tokenizer module. For tokendata=1 | ||
| 231709 | ** tables, this includes any embedded 0x00 and trailing data. | ||
| 231710 | ** | ||
| 231711 | ** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) | ||
| 231712 | ** This is used to access token iToken of phrase hit iIdx within the | ||
| 231713 | ** current row. If iIdx is less than zero or greater than or equal to the | ||
| 231714 | ** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, | ||
| 231715 | ** output variable (*ppToken) is set to point to a buffer containing the | ||
| 231716 | ** matching document token, and (*pnToken) to the size of that buffer in | ||
| 231717 | ** bytes. This API is not available if the specified token matches a | ||
| 231718 | ** prefix query term. In that case both output variables are always set | ||
| 231719 | ** to 0. | ||
| 231720 | ** | ||
| 231721 | ** The output text is not a copy of the document text that was tokenized. | ||
| 231722 | ** It is the output of the tokenizer module. For tokendata=1 tables, this | ||
| 231723 | ** includes any embedded 0x00 and trailing data. | ||
| 231724 | ** | ||
| 231725 | ** This API can be quite slow if used with an FTS5 table created with the | ||
| 231726 | ** "detail=none" or "detail=column" option. | ||
| 227690 | */ | 231727 | */ |
| 227691 | struct Fts5ExtensionApi { | 231728 | struct Fts5ExtensionApi { |
| 227692 | int iVersion; /* Currently always set to 2 */ | 231729 | int iVersion; /* Currently always set to 3 */ |
| 227693 | 231730 | ||
| 227694 | void *(*xUserData)(Fts5Context*); | 231731 | void *(*xUserData)(Fts5Context*); |
| 227695 | 231732 | ||
| @@ -227724,6 +231761,13 @@ struct Fts5ExtensionApi { | |||
| 227724 | 231761 | ||
| 227725 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); | 231762 | int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); |
| 227726 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); | 231763 | void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); |
| 231764 | |||
| 231765 | /* Below this point are iVersion>=3 only */ | ||
| 231766 | int (*xQueryToken)(Fts5Context*, | ||
| 231767 | int iPhrase, int iToken, | ||
| 231768 | const char **ppToken, int *pnToken | ||
| 231769 | ); | ||
| 231770 | int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); | ||
| 227727 | }; | 231771 | }; |
| 227728 | 231772 | ||
| 227729 | /* | 231773 | /* |
| @@ -228198,6 +232242,7 @@ struct Fts5Config { | |||
| 228198 | char *zContent; /* content table */ | 232242 | char *zContent; /* content table */ |
| 228199 | char *zContentRowid; /* "content_rowid=" option value */ | 232243 | char *zContentRowid; /* "content_rowid=" option value */ |
| 228200 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ | 232244 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ |
| 232245 | int bTokendata; /* "tokendata=" option value (dflt==0) */ | ||
| 228201 | int eDetail; /* FTS5_DETAIL_XXX value */ | 232246 | int eDetail; /* FTS5_DETAIL_XXX value */ |
| 228202 | char *zContentExprlist; | 232247 | char *zContentExprlist; |
| 228203 | Fts5Tokenizer *pTok; | 232248 | Fts5Tokenizer *pTok; |
| @@ -228386,17 +232431,19 @@ struct Fts5IndexIter { | |||
| 228386 | /* | 232431 | /* |
| 228387 | ** Values used as part of the flags argument passed to IndexQuery(). | 232432 | ** Values used as part of the flags argument passed to IndexQuery(). |
| 228388 | */ | 232433 | */ |
| 228389 | #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ | 232434 | #define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ |
| 228390 | #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ | 232435 | #define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ |
| 228391 | #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ | 232436 | #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ |
| 228392 | #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ | 232437 | #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ |
| 228393 | 232438 | ||
| 228394 | /* The following are used internally by the fts5_index.c module. They are | 232439 | /* The following are used internally by the fts5_index.c module. They are |
| 228395 | ** defined here only to make it easier to avoid clashes with the flags | 232440 | ** defined here only to make it easier to avoid clashes with the flags |
| 228396 | ** above. */ | 232441 | ** above. */ |
| 228397 | #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 | 232442 | #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 |
| 228398 | #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 | 232443 | #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 |
| 228399 | #define FTS5INDEX_QUERY_SKIPHASH 0x0040 | 232444 | #define FTS5INDEX_QUERY_SKIPHASH 0x0040 |
| 232445 | #define FTS5INDEX_QUERY_NOTOKENDATA 0x0080 | ||
| 232446 | #define FTS5INDEX_QUERY_SCANONETERM 0x0100 | ||
| 228400 | 232447 | ||
| 228401 | /* | 232448 | /* |
| 228402 | ** Create/destroy an Fts5Index object. | 232449 | ** Create/destroy an Fts5Index object. |
| @@ -228465,6 +232512,10 @@ static void *sqlite3Fts5StructureRef(Fts5Index*); | |||
| 228465 | static void sqlite3Fts5StructureRelease(void*); | 232512 | static void sqlite3Fts5StructureRelease(void*); |
| 228466 | static int sqlite3Fts5StructureTest(Fts5Index*, void*); | 232513 | static int sqlite3Fts5StructureTest(Fts5Index*, void*); |
| 228467 | 232514 | ||
| 232515 | /* | ||
| 232516 | ** Used by xInstToken(): | ||
| 232517 | */ | ||
| 232518 | static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); | ||
| 228468 | 232519 | ||
| 228469 | /* | 232520 | /* |
| 228470 | ** Insert or remove data to or from the index. Each time a document is | 232521 | ** Insert or remove data to or from the index. Each time a document is |
| @@ -228542,6 +232593,13 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); | |||
| 228542 | static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); | 232593 | static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); |
| 228543 | static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); | 232594 | static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); |
| 228544 | 232595 | ||
| 232596 | static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*); | ||
| 232597 | |||
| 232598 | /* Used to populate hash tables for xInstToken in detail=none/column mode. */ | ||
| 232599 | static int sqlite3Fts5IndexIterWriteTokendata( | ||
| 232600 | Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff | ||
| 232601 | ); | ||
| 232602 | |||
| 228545 | /* | 232603 | /* |
| 228546 | ** End of interface to code in fts5_index.c. | 232604 | ** End of interface to code in fts5_index.c. |
| 228547 | **************************************************************************/ | 232605 | **************************************************************************/ |
| @@ -228647,6 +232705,7 @@ static void sqlite3Fts5HashScanNext(Fts5Hash*); | |||
| 228647 | static int sqlite3Fts5HashScanEof(Fts5Hash*); | 232705 | static int sqlite3Fts5HashScanEof(Fts5Hash*); |
| 228648 | static void sqlite3Fts5HashScanEntry(Fts5Hash *, | 232706 | static void sqlite3Fts5HashScanEntry(Fts5Hash *, |
| 228649 | const char **pzTerm, /* OUT: term (nul-terminated) */ | 232707 | const char **pzTerm, /* OUT: term (nul-terminated) */ |
| 232708 | int *pnTerm, /* OUT: Size of term in bytes */ | ||
| 228650 | const u8 **ppDoclist, /* OUT: pointer to doclist */ | 232709 | const u8 **ppDoclist, /* OUT: pointer to doclist */ |
| 228651 | int *pnDoclist /* OUT: size of doclist in bytes */ | 232710 | int *pnDoclist /* OUT: size of doclist in bytes */ |
| 228652 | ); | 232711 | ); |
| @@ -228773,6 +232832,10 @@ static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); | |||
| 228773 | 232832 | ||
| 228774 | static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); | 232833 | static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); |
| 228775 | 232834 | ||
| 232835 | static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*); | ||
| 232836 | static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*); | ||
| 232837 | static void sqlite3Fts5ExprClearTokens(Fts5Expr*); | ||
| 232838 | |||
| 228776 | /******************************************* | 232839 | /******************************************* |
| 228777 | ** The fts5_expr.c API above this point is used by the other hand-written | 232840 | ** The fts5_expr.c API above this point is used by the other hand-written |
| 228778 | ** C code in this module. The interfaces below this point are called by | 232841 | ** C code in this module. The interfaces below this point are called by |
| @@ -229009,6 +233072,9 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); | |||
| 229009 | ** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser | 233072 | ** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser |
| 229010 | ** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser | 233073 | ** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser |
| 229011 | ** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context | 233074 | ** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context |
| 233075 | ** fts5YYREALLOC Name of the realloc() function to use | ||
| 233076 | ** fts5YYFREE Name of the free() function to use | ||
| 233077 | ** fts5YYDYNSTACK True if stack space should be extended on heap | ||
| 229012 | ** fts5YYERRORSYMBOL is the code number of the error symbol. If not | 233078 | ** fts5YYERRORSYMBOL is the code number of the error symbol. If not |
| 229013 | ** defined, then do no error processing. | 233079 | ** defined, then do no error processing. |
| 229014 | ** fts5YYNSTATE the combined number of states. | 233080 | ** fts5YYNSTATE the combined number of states. |
| @@ -229022,6 +233088,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); | |||
| 229022 | ** fts5YY_NO_ACTION The fts5yy_action[] code for no-op | 233088 | ** fts5YY_NO_ACTION The fts5yy_action[] code for no-op |
| 229023 | ** fts5YY_MIN_REDUCE Minimum value for reduce actions | 233089 | ** fts5YY_MIN_REDUCE Minimum value for reduce actions |
| 229024 | ** fts5YY_MAX_REDUCE Maximum value for reduce actions | 233090 | ** fts5YY_MAX_REDUCE Maximum value for reduce actions |
| 233091 | ** fts5YY_MIN_DSTRCTR Minimum symbol value that has a destructor | ||
| 233092 | ** fts5YY_MAX_DSTRCTR Maximum symbol value that has a destructor | ||
| 229025 | */ | 233093 | */ |
| 229026 | #ifndef INTERFACE | 233094 | #ifndef INTERFACE |
| 229027 | # define INTERFACE 1 | 233095 | # define INTERFACE 1 |
| @@ -229048,6 +233116,9 @@ typedef union { | |||
| 229048 | #define sqlite3Fts5ParserARG_PARAM ,pParse | 233116 | #define sqlite3Fts5ParserARG_PARAM ,pParse |
| 229049 | #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; | 233117 | #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; |
| 229050 | #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; | 233118 | #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; |
| 233119 | #define fts5YYREALLOC realloc | ||
| 233120 | #define fts5YYFREE free | ||
| 233121 | #define fts5YYDYNSTACK 0 | ||
| 229051 | #define sqlite3Fts5ParserCTX_SDECL | 233122 | #define sqlite3Fts5ParserCTX_SDECL |
| 229052 | #define sqlite3Fts5ParserCTX_PDECL | 233123 | #define sqlite3Fts5ParserCTX_PDECL |
| 229053 | #define sqlite3Fts5ParserCTX_PARAM | 233124 | #define sqlite3Fts5ParserCTX_PARAM |
| @@ -229065,6 +233136,8 @@ typedef union { | |||
| 229065 | #define fts5YY_NO_ACTION 82 | 233136 | #define fts5YY_NO_ACTION 82 |
| 229066 | #define fts5YY_MIN_REDUCE 83 | 233137 | #define fts5YY_MIN_REDUCE 83 |
| 229067 | #define fts5YY_MAX_REDUCE 110 | 233138 | #define fts5YY_MAX_REDUCE 110 |
| 233139 | #define fts5YY_MIN_DSTRCTR 16 | ||
| 233140 | #define fts5YY_MAX_DSTRCTR 24 | ||
| 229068 | /************* End control #defines *******************************************/ | 233141 | /************* End control #defines *******************************************/ |
| 229069 | #define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]))) | 233142 | #define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]))) |
| 229070 | 233143 | ||
| @@ -229080,6 +233153,22 @@ typedef union { | |||
| 229080 | # define fts5yytestcase(X) | 233153 | # define fts5yytestcase(X) |
| 229081 | #endif | 233154 | #endif |
| 229082 | 233155 | ||
| 233156 | /* Macro to determine if stack space has the ability to grow using | ||
| 233157 | ** heap memory. | ||
| 233158 | */ | ||
| 233159 | #if fts5YYSTACKDEPTH<=0 || fts5YYDYNSTACK | ||
| 233160 | # define fts5YYGROWABLESTACK 1 | ||
| 233161 | #else | ||
| 233162 | # define fts5YYGROWABLESTACK 0 | ||
| 233163 | #endif | ||
| 233164 | |||
| 233165 | /* Guarantee a minimum number of initial stack slots. | ||
| 233166 | */ | ||
| 233167 | #if fts5YYSTACKDEPTH<=0 | ||
| 233168 | # undef fts5YYSTACKDEPTH | ||
| 233169 | # define fts5YYSTACKDEPTH 2 /* Need a minimum stack size */ | ||
| 233170 | #endif | ||
| 233171 | |||
| 229083 | 233172 | ||
| 229084 | /* Next are the tables used to determine what action to take based on the | 233173 | /* Next are the tables used to determine what action to take based on the |
| 229085 | ** current state and lookahead token. These tables are used to implement | 233174 | ** current state and lookahead token. These tables are used to implement |
| @@ -229240,14 +233329,9 @@ struct fts5yyParser { | |||
| 229240 | #endif | 233329 | #endif |
| 229241 | sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ | 233330 | sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ |
| 229242 | sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ | 233331 | sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ |
| 229243 | #if fts5YYSTACKDEPTH<=0 | 233332 | fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */ |
| 229244 | int fts5yystksz; /* Current side of the stack */ | 233333 | fts5yyStackEntry *fts5yystack; /* The parser stack */ |
| 229245 | fts5yyStackEntry *fts5yystack; /* The parser's stack */ | 233334 | fts5yyStackEntry fts5yystk0[fts5YYSTACKDEPTH]; /* Initial stack space */ |
| 229246 | fts5yyStackEntry fts5yystk0; /* First stack entry */ | ||
| 229247 | #else | ||
| 229248 | fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */ | ||
| 229249 | fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */ | ||
| 229250 | #endif | ||
| 229251 | }; | 233335 | }; |
| 229252 | typedef struct fts5yyParser fts5yyParser; | 233336 | typedef struct fts5yyParser fts5yyParser; |
| 229253 | 233337 | ||
| @@ -229354,37 +233438,45 @@ static const char *const fts5yyRuleName[] = { | |||
| 229354 | #endif /* NDEBUG */ | 233438 | #endif /* NDEBUG */ |
| 229355 | 233439 | ||
| 229356 | 233440 | ||
| 229357 | #if fts5YYSTACKDEPTH<=0 | 233441 | #if fts5YYGROWABLESTACK |
| 229358 | /* | 233442 | /* |
| 229359 | ** Try to increase the size of the parser stack. Return the number | 233443 | ** Try to increase the size of the parser stack. Return the number |
| 229360 | ** of errors. Return 0 on success. | 233444 | ** of errors. Return 0 on success. |
| 229361 | */ | 233445 | */ |
| 229362 | static int fts5yyGrowStack(fts5yyParser *p){ | 233446 | static int fts5yyGrowStack(fts5yyParser *p){ |
| 233447 | int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack); | ||
| 229363 | int newSize; | 233448 | int newSize; |
| 229364 | int idx; | 233449 | int idx; |
| 229365 | fts5yyStackEntry *pNew; | 233450 | fts5yyStackEntry *pNew; |
| 229366 | 233451 | ||
| 229367 | newSize = p->fts5yystksz*2 + 100; | 233452 | newSize = oldSize*2 + 100; |
| 229368 | idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0; | 233453 | idx = (int)(p->fts5yytos - p->fts5yystack); |
| 229369 | if( p->fts5yystack==&p->fts5yystk0 ){ | 233454 | if( p->fts5yystack==p->fts5yystk0 ){ |
| 229370 | pNew = malloc(newSize*sizeof(pNew[0])); | 233455 | pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0])); |
| 229371 | if( pNew ) pNew[0] = p->fts5yystk0; | 233456 | if( pNew==0 ) return 1; |
| 233457 | memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0])); | ||
| 229372 | }else{ | 233458 | }else{ |
| 229373 | pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0])); | 233459 | pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0])); |
| 233460 | if( pNew==0 ) return 1; | ||
| 229374 | } | 233461 | } |
| 229375 | if( pNew ){ | 233462 | p->fts5yystack = pNew; |
| 229376 | p->fts5yystack = pNew; | 233463 | p->fts5yytos = &p->fts5yystack[idx]; |
| 229377 | p->fts5yytos = &p->fts5yystack[idx]; | ||
| 229378 | #ifndef NDEBUG | 233464 | #ifndef NDEBUG |
| 229379 | if( fts5yyTraceFILE ){ | 233465 | if( fts5yyTraceFILE ){ |
| 229380 | fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n", | 233466 | fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n", |
| 229381 | fts5yyTracePrompt, p->fts5yystksz, newSize); | 233467 | fts5yyTracePrompt, oldSize, newSize); |
| 229382 | } | ||
| 229383 | #endif | ||
| 229384 | p->fts5yystksz = newSize; | ||
| 229385 | } | 233468 | } |
| 229386 | return pNew==0; | 233469 | #endif |
| 233470 | p->fts5yystackEnd = &p->fts5yystack[newSize-1]; | ||
| 233471 | return 0; | ||
| 229387 | } | 233472 | } |
| 233473 | #endif /* fts5YYGROWABLESTACK */ | ||
| 233474 | |||
| 233475 | #if !fts5YYGROWABLESTACK | ||
| 233476 | /* For builds that do no have a growable stack, fts5yyGrowStack always | ||
| 233477 | ** returns an error. | ||
| 233478 | */ | ||
| 233479 | # define fts5yyGrowStack(X) 1 | ||
| 229388 | #endif | 233480 | #endif |
| 229389 | 233481 | ||
| 229390 | /* Datatype of the argument to the memory allocated passed as the | 233482 | /* Datatype of the argument to the memory allocated passed as the |
| @@ -229404,24 +233496,14 @@ static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PD | |||
| 229404 | #ifdef fts5YYTRACKMAXSTACKDEPTH | 233496 | #ifdef fts5YYTRACKMAXSTACKDEPTH |
| 229405 | fts5yypParser->fts5yyhwm = 0; | 233497 | fts5yypParser->fts5yyhwm = 0; |
| 229406 | #endif | 233498 | #endif |
| 229407 | #if fts5YYSTACKDEPTH<=0 | 233499 | fts5yypParser->fts5yystack = fts5yypParser->fts5yystk0; |
| 229408 | fts5yypParser->fts5yytos = NULL; | 233500 | fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1]; |
| 229409 | fts5yypParser->fts5yystack = NULL; | ||
| 229410 | fts5yypParser->fts5yystksz = 0; | ||
| 229411 | if( fts5yyGrowStack(fts5yypParser) ){ | ||
| 229412 | fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0; | ||
| 229413 | fts5yypParser->fts5yystksz = 1; | ||
| 229414 | } | ||
| 229415 | #endif | ||
| 229416 | #ifndef fts5YYNOERRORRECOVERY | 233501 | #ifndef fts5YYNOERRORRECOVERY |
| 229417 | fts5yypParser->fts5yyerrcnt = -1; | 233502 | fts5yypParser->fts5yyerrcnt = -1; |
| 229418 | #endif | 233503 | #endif |
| 229419 | fts5yypParser->fts5yytos = fts5yypParser->fts5yystack; | 233504 | fts5yypParser->fts5yytos = fts5yypParser->fts5yystack; |
| 229420 | fts5yypParser->fts5yystack[0].stateno = 0; | 233505 | fts5yypParser->fts5yystack[0].stateno = 0; |
| 229421 | fts5yypParser->fts5yystack[0].major = 0; | 233506 | fts5yypParser->fts5yystack[0].major = 0; |
| 229422 | #if fts5YYSTACKDEPTH>0 | ||
| 229423 | fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1]; | ||
| 229424 | #endif | ||
| 229425 | } | 233507 | } |
| 229426 | 233508 | ||
| 229427 | #ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK | 233509 | #ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK |
| @@ -229535,9 +233617,26 @@ static void fts5yy_pop_parser_stack(fts5yyParser *pParser){ | |||
| 229535 | */ | 233617 | */ |
| 229536 | static void sqlite3Fts5ParserFinalize(void *p){ | 233618 | static void sqlite3Fts5ParserFinalize(void *p){ |
| 229537 | fts5yyParser *pParser = (fts5yyParser*)p; | 233619 | fts5yyParser *pParser = (fts5yyParser*)p; |
| 229538 | while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser); | 233620 | |
| 229539 | #if fts5YYSTACKDEPTH<=0 | 233621 | /* In-lined version of calling fts5yy_pop_parser_stack() for each |
| 229540 | if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack); | 233622 | ** element left in the stack */ |
| 233623 | fts5yyStackEntry *fts5yytos = pParser->fts5yytos; | ||
| 233624 | while( fts5yytos>pParser->fts5yystack ){ | ||
| 233625 | #ifndef NDEBUG | ||
| 233626 | if( fts5yyTraceFILE ){ | ||
| 233627 | fprintf(fts5yyTraceFILE,"%sPopping %s\n", | ||
| 233628 | fts5yyTracePrompt, | ||
| 233629 | fts5yyTokenName[fts5yytos->major]); | ||
| 233630 | } | ||
| 233631 | #endif | ||
| 233632 | if( fts5yytos->major>=fts5YY_MIN_DSTRCTR ){ | ||
| 233633 | fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor); | ||
| 233634 | } | ||
| 233635 | fts5yytos--; | ||
| 233636 | } | ||
| 233637 | |||
| 233638 | #if fts5YYGROWABLESTACK | ||
| 233639 | if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack); | ||
| 229541 | #endif | 233640 | #endif |
| 229542 | } | 233641 | } |
| 229543 | 233642 | ||
| @@ -229764,25 +233863,19 @@ static void fts5yy_shift( | |||
| 229764 | assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) ); | 233863 | assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) ); |
| 229765 | } | 233864 | } |
| 229766 | #endif | 233865 | #endif |
| 229767 | #if fts5YYSTACKDEPTH>0 | 233866 | fts5yytos = fts5yypParser->fts5yytos; |
| 229768 | if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){ | 233867 | if( fts5yytos>fts5yypParser->fts5yystackEnd ){ |
| 229769 | fts5yypParser->fts5yytos--; | ||
| 229770 | fts5yyStackOverflow(fts5yypParser); | ||
| 229771 | return; | ||
| 229772 | } | ||
| 229773 | #else | ||
| 229774 | if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){ | ||
| 229775 | if( fts5yyGrowStack(fts5yypParser) ){ | 233868 | if( fts5yyGrowStack(fts5yypParser) ){ |
| 229776 | fts5yypParser->fts5yytos--; | 233869 | fts5yypParser->fts5yytos--; |
| 229777 | fts5yyStackOverflow(fts5yypParser); | 233870 | fts5yyStackOverflow(fts5yypParser); |
| 229778 | return; | 233871 | return; |
| 229779 | } | 233872 | } |
| 233873 | fts5yytos = fts5yypParser->fts5yytos; | ||
| 233874 | assert( fts5yytos <= fts5yypParser->fts5yystackEnd ); | ||
| 229780 | } | 233875 | } |
| 229781 | #endif | ||
| 229782 | if( fts5yyNewState > fts5YY_MAX_SHIFT ){ | 233876 | if( fts5yyNewState > fts5YY_MAX_SHIFT ){ |
| 229783 | fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE; | 233877 | fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE; |
| 229784 | } | 233878 | } |
| 229785 | fts5yytos = fts5yypParser->fts5yytos; | ||
| 229786 | fts5yytos->stateno = fts5yyNewState; | 233879 | fts5yytos->stateno = fts5yyNewState; |
| 229787 | fts5yytos->major = fts5yyMajor; | 233880 | fts5yytos->major = fts5yyMajor; |
| 229788 | fts5yytos->minor.fts5yy0 = fts5yyMinor; | 233881 | fts5yytos->minor.fts5yy0 = fts5yyMinor; |
| @@ -230219,19 +234312,12 @@ static void sqlite3Fts5Parser( | |||
| 230219 | (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); | 234312 | (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); |
| 230220 | } | 234313 | } |
| 230221 | #endif | 234314 | #endif |
| 230222 | #if fts5YYSTACKDEPTH>0 | ||
| 230223 | if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ | 234315 | if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ |
| 230224 | fts5yyStackOverflow(fts5yypParser); | ||
| 230225 | break; | ||
| 230226 | } | ||
| 230227 | #else | ||
| 230228 | if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ | ||
| 230229 | if( fts5yyGrowStack(fts5yypParser) ){ | 234316 | if( fts5yyGrowStack(fts5yypParser) ){ |
| 230230 | fts5yyStackOverflow(fts5yypParser); | 234317 | fts5yyStackOverflow(fts5yypParser); |
| 230231 | break; | 234318 | break; |
| 230232 | } | 234319 | } |
| 230233 | } | 234320 | } |
| 230234 | #endif | ||
| 230235 | } | 234321 | } |
| 230236 | fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM); | 234322 | fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM); |
| 230237 | }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ | 234323 | }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ |
| @@ -230588,6 +234674,14 @@ static int fts5HighlightCb( | |||
| 230588 | } | 234674 | } |
| 230589 | 234675 | ||
| 230590 | if( iPos==p->iRangeEnd ){ | 234676 | if( iPos==p->iRangeEnd ){ |
| 234677 | if( p->bOpen ){ | ||
| 234678 | if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){ | ||
| 234679 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); | ||
| 234680 | p->iOff = iEndOff; | ||
| 234681 | } | ||
| 234682 | fts5HighlightAppend(&rc, p, p->zClose, -1); | ||
| 234683 | p->bOpen = 0; | ||
| 234684 | } | ||
| 230591 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); | 234685 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); |
| 230592 | p->iOff = iEndOff; | 234686 | p->iOff = iEndOff; |
| 230593 | } | 234687 | } |
| @@ -230621,8 +234715,10 @@ static void fts5HighlightFunction( | |||
| 230621 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); | 234715 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); |
| 230622 | ctx.iRangeEnd = -1; | 234716 | ctx.iRangeEnd = -1; |
| 230623 | rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); | 234717 | rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); |
| 230624 | 234718 | if( rc==SQLITE_RANGE ){ | |
| 230625 | if( ctx.zIn ){ | 234719 | sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); |
| 234720 | rc = SQLITE_OK; | ||
| 234721 | }else if( ctx.zIn ){ | ||
| 230626 | if( rc==SQLITE_OK ){ | 234722 | if( rc==SQLITE_OK ){ |
| 230627 | rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); | 234723 | rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); |
| 230628 | } | 234724 | } |
| @@ -231189,6 +235285,7 @@ static void sqlite3Fts5BufferAppendBlob( | |||
| 231189 | ){ | 235285 | ){ |
| 231190 | if( nData ){ | 235286 | if( nData ){ |
| 231191 | if( fts5BufferGrow(pRc, pBuf, nData) ) return; | 235287 | if( fts5BufferGrow(pRc, pBuf, nData) ) return; |
| 235288 | assert( pBuf->p!=0 ); | ||
| 231192 | memcpy(&pBuf->p[pBuf->n], pData, nData); | 235289 | memcpy(&pBuf->p[pBuf->n], pData, nData); |
| 231193 | pBuf->n += nData; | 235290 | pBuf->n += nData; |
| 231194 | } | 235291 | } |
| @@ -231290,6 +235387,7 @@ static int sqlite3Fts5PoslistNext64( | |||
| 231290 | i64 *piOff /* IN/OUT: Current offset */ | 235387 | i64 *piOff /* IN/OUT: Current offset */ |
| 231291 | ){ | 235388 | ){ |
| 231292 | int i = *pi; | 235389 | int i = *pi; |
| 235390 | assert( a!=0 || i==0 ); | ||
| 231293 | if( i>=n ){ | 235391 | if( i>=n ){ |
| 231294 | /* EOF */ | 235392 | /* EOF */ |
| 231295 | *piOff = -1; | 235393 | *piOff = -1; |
| @@ -231297,6 +235395,7 @@ static int sqlite3Fts5PoslistNext64( | |||
| 231297 | }else{ | 235395 | }else{ |
| 231298 | i64 iOff = *piOff; | 235396 | i64 iOff = *piOff; |
| 231299 | u32 iVal; | 235397 | u32 iVal; |
| 235398 | assert( a!=0 ); | ||
| 231300 | fts5FastGetVarint32(a, i, iVal); | 235399 | fts5FastGetVarint32(a, i, iVal); |
| 231301 | if( iVal<=1 ){ | 235400 | if( iVal<=1 ){ |
| 231302 | if( iVal==0 ){ | 235401 | if( iVal==0 ){ |
| @@ -231928,6 +236027,16 @@ static int fts5ConfigParseSpecial( | |||
| 231928 | return rc; | 236027 | return rc; |
| 231929 | } | 236028 | } |
| 231930 | 236029 | ||
| 236030 | if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){ | ||
| 236031 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ | ||
| 236032 | *pzErr = sqlite3_mprintf("malformed tokendata=... directive"); | ||
| 236033 | rc = SQLITE_ERROR; | ||
| 236034 | }else{ | ||
| 236035 | pConfig->bTokendata = (zArg[0]=='1'); | ||
| 236036 | } | ||
| 236037 | return rc; | ||
| 236038 | } | ||
| 236039 | |||
| 231931 | *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); | 236040 | *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); |
| 231932 | return SQLITE_ERROR; | 236041 | return SQLITE_ERROR; |
| 231933 | } | 236042 | } |
| @@ -232661,7 +236770,9 @@ struct Fts5ExprNode { | |||
| 232661 | struct Fts5ExprTerm { | 236770 | struct Fts5ExprTerm { |
| 232662 | u8 bPrefix; /* True for a prefix term */ | 236771 | u8 bPrefix; /* True for a prefix term */ |
| 232663 | u8 bFirst; /* True if token must be first in column */ | 236772 | u8 bFirst; /* True if token must be first in column */ |
| 232664 | char *zTerm; /* nul-terminated term */ | 236773 | char *pTerm; /* Term data */ |
| 236774 | int nQueryTerm; /* Effective size of term in bytes */ | ||
| 236775 | int nFullTerm; /* Size of term in bytes incl. tokendata */ | ||
| 232665 | Fts5IndexIter *pIter; /* Iterator for this term */ | 236776 | Fts5IndexIter *pIter; /* Iterator for this term */ |
| 232666 | Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ | 236777 | Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ |
| 232667 | }; | 236778 | }; |
| @@ -232883,7 +236994,11 @@ static int sqlite3Fts5ExprNew( | |||
| 232883 | } | 236994 | } |
| 232884 | 236995 | ||
| 232885 | sqlite3_free(sParse.apPhrase); | 236996 | sqlite3_free(sParse.apPhrase); |
| 232886 | *pzErr = sParse.zErr; | 236997 | if( 0==*pzErr ){ |
| 236998 | *pzErr = sParse.zErr; | ||
| 236999 | }else{ | ||
| 237000 | sqlite3_free(sParse.zErr); | ||
| 237001 | } | ||
| 232887 | return sParse.rc; | 237002 | return sParse.rc; |
| 232888 | } | 237003 | } |
| 232889 | 237004 | ||
| @@ -233528,7 +237643,7 @@ static int fts5ExprNearInitAll( | |||
| 233528 | p->pIter = 0; | 237643 | p->pIter = 0; |
| 233529 | } | 237644 | } |
| 233530 | rc = sqlite3Fts5IndexQuery( | 237645 | rc = sqlite3Fts5IndexQuery( |
| 233531 | pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), | 237646 | pExpr->pIndex, p->pTerm, p->nQueryTerm, |
| 233532 | (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | | 237647 | (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | |
| 233533 | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), | 237648 | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), |
| 233534 | pNear->pColset, | 237649 | pNear->pColset, |
| @@ -234165,7 +238280,7 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ | |||
| 234165 | Fts5ExprTerm *pSyn; | 238280 | Fts5ExprTerm *pSyn; |
| 234166 | Fts5ExprTerm *pNext; | 238281 | Fts5ExprTerm *pNext; |
| 234167 | Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; | 238282 | Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; |
| 234168 | sqlite3_free(pTerm->zTerm); | 238283 | sqlite3_free(pTerm->pTerm); |
| 234169 | sqlite3Fts5IterClose(pTerm->pIter); | 238284 | sqlite3Fts5IterClose(pTerm->pIter); |
| 234170 | for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ | 238285 | for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ |
| 234171 | pNext = pSyn->pSynonym; | 238286 | pNext = pSyn->pSynonym; |
| @@ -234263,6 +238378,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( | |||
| 234263 | typedef struct TokenCtx TokenCtx; | 238378 | typedef struct TokenCtx TokenCtx; |
| 234264 | struct TokenCtx { | 238379 | struct TokenCtx { |
| 234265 | Fts5ExprPhrase *pPhrase; | 238380 | Fts5ExprPhrase *pPhrase; |
| 238381 | Fts5Config *pConfig; | ||
| 234266 | int rc; | 238382 | int rc; |
| 234267 | }; | 238383 | }; |
| 234268 | 238384 | ||
| @@ -234296,8 +238412,12 @@ static int fts5ParseTokenize( | |||
| 234296 | rc = SQLITE_NOMEM; | 238412 | rc = SQLITE_NOMEM; |
| 234297 | }else{ | 238413 | }else{ |
| 234298 | memset(pSyn, 0, (size_t)nByte); | 238414 | memset(pSyn, 0, (size_t)nByte); |
| 234299 | pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); | 238415 | pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); |
| 234300 | memcpy(pSyn->zTerm, pToken, nToken); | 238416 | pSyn->nFullTerm = pSyn->nQueryTerm = nToken; |
| 238417 | if( pCtx->pConfig->bTokendata ){ | ||
| 238418 | pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); | ||
| 238419 | } | ||
| 238420 | memcpy(pSyn->pTerm, pToken, nToken); | ||
| 234301 | pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; | 238421 | pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; |
| 234302 | pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; | 238422 | pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; |
| 234303 | } | 238423 | } |
| @@ -234322,7 +238442,11 @@ static int fts5ParseTokenize( | |||
| 234322 | if( rc==SQLITE_OK ){ | 238442 | if( rc==SQLITE_OK ){ |
| 234323 | pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; | 238443 | pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; |
| 234324 | memset(pTerm, 0, sizeof(Fts5ExprTerm)); | 238444 | memset(pTerm, 0, sizeof(Fts5ExprTerm)); |
| 234325 | pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); | 238445 | pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); |
| 238446 | pTerm->nFullTerm = pTerm->nQueryTerm = nToken; | ||
| 238447 | if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){ | ||
| 238448 | pTerm->nQueryTerm = (int)strlen(pTerm->pTerm); | ||
| 238449 | } | ||
| 234326 | } | 238450 | } |
| 234327 | } | 238451 | } |
| 234328 | 238452 | ||
| @@ -234389,6 +238513,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( | |||
| 234389 | 238513 | ||
| 234390 | memset(&sCtx, 0, sizeof(TokenCtx)); | 238514 | memset(&sCtx, 0, sizeof(TokenCtx)); |
| 234391 | sCtx.pPhrase = pAppend; | 238515 | sCtx.pPhrase = pAppend; |
| 238516 | sCtx.pConfig = pConfig; | ||
| 234392 | 238517 | ||
| 234393 | rc = fts5ParseStringFromToken(pToken, &z); | 238518 | rc = fts5ParseStringFromToken(pToken, &z); |
| 234394 | if( rc==SQLITE_OK ){ | 238519 | if( rc==SQLITE_OK ){ |
| @@ -234436,12 +238561,15 @@ static int sqlite3Fts5ExprClonePhrase( | |||
| 234436 | Fts5Expr **ppNew | 238561 | Fts5Expr **ppNew |
| 234437 | ){ | 238562 | ){ |
| 234438 | int rc = SQLITE_OK; /* Return code */ | 238563 | int rc = SQLITE_OK; /* Return code */ |
| 234439 | Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */ | 238564 | Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ |
| 234440 | Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ | 238565 | Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ |
| 234441 | TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ | 238566 | TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ |
| 234442 | 238567 | if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ | |
| 234443 | pOrig = pExpr->apExprPhrase[iPhrase]; | 238568 | rc = SQLITE_RANGE; |
| 234444 | pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); | 238569 | }else{ |
| 238570 | pOrig = pExpr->apExprPhrase[iPhrase]; | ||
| 238571 | pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); | ||
| 238572 | } | ||
| 234445 | if( rc==SQLITE_OK ){ | 238573 | if( rc==SQLITE_OK ){ |
| 234446 | pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, | 238574 | pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, |
| 234447 | sizeof(Fts5ExprPhrase*)); | 238575 | sizeof(Fts5ExprPhrase*)); |
| @@ -234454,7 +238582,7 @@ static int sqlite3Fts5ExprClonePhrase( | |||
| 234454 | pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, | 238582 | pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, |
| 234455 | sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); | 238583 | sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); |
| 234456 | } | 238584 | } |
| 234457 | if( rc==SQLITE_OK ){ | 238585 | if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ |
| 234458 | Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; | 238586 | Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; |
| 234459 | if( pColsetOrig ){ | 238587 | if( pColsetOrig ){ |
| 234460 | sqlite3_int64 nByte; | 238588 | sqlite3_int64 nByte; |
| @@ -234468,26 +238596,27 @@ static int sqlite3Fts5ExprClonePhrase( | |||
| 234468 | } | 238596 | } |
| 234469 | } | 238597 | } |
| 234470 | 238598 | ||
| 234471 | if( pOrig->nTerm ){ | 238599 | if( rc==SQLITE_OK ){ |
| 234472 | int i; /* Used to iterate through phrase terms */ | 238600 | if( pOrig->nTerm ){ |
| 234473 | for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ | 238601 | int i; /* Used to iterate through phrase terms */ |
| 234474 | int tflags = 0; | 238602 | sCtx.pConfig = pExpr->pConfig; |
| 234475 | Fts5ExprTerm *p; | 238603 | for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){ |
| 234476 | for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ | 238604 | int tflags = 0; |
| 234477 | const char *zTerm = p->zTerm; | 238605 | Fts5ExprTerm *p; |
| 234478 | rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), | 238606 | for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ |
| 234479 | 0, 0); | 238607 | rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0); |
| 234480 | tflags = FTS5_TOKEN_COLOCATED; | 238608 | tflags = FTS5_TOKEN_COLOCATED; |
| 234481 | } | 238609 | } |
| 234482 | if( rc==SQLITE_OK ){ | 238610 | if( rc==SQLITE_OK ){ |
| 234483 | sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; | 238611 | sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; |
| 234484 | sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; | 238612 | sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; |
| 238613 | } | ||
| 234485 | } | 238614 | } |
| 238615 | }else{ | ||
| 238616 | /* This happens when parsing a token or quoted phrase that contains | ||
| 238617 | ** no token characters at all. (e.g ... MATCH '""'). */ | ||
| 238618 | sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); | ||
| 234486 | } | 238619 | } |
| 234487 | }else{ | ||
| 234488 | /* This happens when parsing a token or quoted phrase that contains | ||
| 234489 | ** no token characters at all. (e.g ... MATCH '""'). */ | ||
| 234490 | sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); | ||
| 234491 | } | 238620 | } |
| 234492 | 238621 | ||
| 234493 | if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ | 238622 | if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ |
| @@ -234857,11 +238986,13 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( | |||
| 234857 | if( parseGrowPhraseArray(pParse) ){ | 238986 | if( parseGrowPhraseArray(pParse) ){ |
| 234858 | fts5ExprPhraseFree(pPhrase); | 238987 | fts5ExprPhraseFree(pPhrase); |
| 234859 | }else{ | 238988 | }else{ |
| 238989 | Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii]; | ||
| 238990 | Fts5ExprTerm *pTo = &pPhrase->aTerm[0]; | ||
| 234860 | pParse->apPhrase[pParse->nPhrase++] = pPhrase; | 238991 | pParse->apPhrase[pParse->nPhrase++] = pPhrase; |
| 234861 | pPhrase->nTerm = 1; | 238992 | pPhrase->nTerm = 1; |
| 234862 | pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( | 238993 | pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm); |
| 234863 | &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 | 238994 | pTo->nQueryTerm = p->nQueryTerm; |
| 234864 | ); | 238995 | pTo->nFullTerm = p->nFullTerm; |
| 234865 | pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, | 238996 | pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, |
| 234866 | 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) | 238997 | 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) |
| 234867 | ); | 238998 | ); |
| @@ -234995,6 +239126,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( | |||
| 234995 | assert( pRight->eType==FTS5_STRING | 239126 | assert( pRight->eType==FTS5_STRING |
| 234996 | || pRight->eType==FTS5_TERM | 239127 | || pRight->eType==FTS5_TERM |
| 234997 | || pRight->eType==FTS5_EOF | 239128 | || pRight->eType==FTS5_EOF |
| 239129 | || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) | ||
| 234998 | ); | 239130 | ); |
| 234999 | 239131 | ||
| 235000 | if( pLeft->eType==FTS5_AND ){ | 239132 | if( pLeft->eType==FTS5_AND ){ |
| @@ -235046,16 +239178,17 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ | |||
| 235046 | 239178 | ||
| 235047 | /* Determine the maximum amount of space required. */ | 239179 | /* Determine the maximum amount of space required. */ |
| 235048 | for(p=pTerm; p; p=p->pSynonym){ | 239180 | for(p=pTerm; p; p=p->pSynonym){ |
| 235049 | nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; | 239181 | nByte += pTerm->nQueryTerm * 2 + 3 + 2; |
| 235050 | } | 239182 | } |
| 235051 | zQuoted = sqlite3_malloc64(nByte); | 239183 | zQuoted = sqlite3_malloc64(nByte); |
| 235052 | 239184 | ||
| 235053 | if( zQuoted ){ | 239185 | if( zQuoted ){ |
| 235054 | int i = 0; | 239186 | int i = 0; |
| 235055 | for(p=pTerm; p; p=p->pSynonym){ | 239187 | for(p=pTerm; p; p=p->pSynonym){ |
| 235056 | char *zIn = p->zTerm; | 239188 | char *zIn = p->pTerm; |
| 239189 | char *zEnd = &zIn[p->nQueryTerm]; | ||
| 235057 | zQuoted[i++] = '"'; | 239190 | zQuoted[i++] = '"'; |
| 235058 | while( *zIn ){ | 239191 | while( zIn<zEnd ){ |
| 235059 | if( *zIn=='"' ) zQuoted[i++] = '"'; | 239192 | if( *zIn=='"' ) zQuoted[i++] = '"'; |
| 235060 | zQuoted[i++] = *zIn++; | 239193 | zQuoted[i++] = *zIn++; |
| 235061 | } | 239194 | } |
| @@ -235133,8 +239266,10 @@ static char *fts5ExprPrintTcl( | |||
| 235133 | 239266 | ||
| 235134 | zRet = fts5PrintfAppend(zRet, " {"); | 239267 | zRet = fts5PrintfAppend(zRet, " {"); |
| 235135 | for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){ | 239268 | for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){ |
| 235136 | char *zTerm = pPhrase->aTerm[iTerm].zTerm; | 239269 | Fts5ExprTerm *p = &pPhrase->aTerm[iTerm]; |
| 235137 | zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm); | 239270 | zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ", |
| 239271 | p->nQueryTerm, p->pTerm | ||
| 239272 | ); | ||
| 235138 | if( pPhrase->aTerm[iTerm].bPrefix ){ | 239273 | if( pPhrase->aTerm[iTerm].bPrefix ){ |
| 235139 | zRet = fts5PrintfAppend(zRet, "*"); | 239274 | zRet = fts5PrintfAppend(zRet, "*"); |
| 235140 | } | 239275 | } |
| @@ -235535,6 +239670,17 @@ static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){ | |||
| 235535 | return 0; | 239670 | return 0; |
| 235536 | } | 239671 | } |
| 235537 | 239672 | ||
| 239673 | /* | ||
| 239674 | ** pToken is a buffer nToken bytes in size that may or may not contain | ||
| 239675 | ** an embedded 0x00 byte. If it does, return the number of bytes in | ||
| 239676 | ** the buffer before the 0x00. If it does not, return nToken. | ||
| 239677 | */ | ||
| 239678 | static int fts5QueryTerm(const char *pToken, int nToken){ | ||
| 239679 | int ii; | ||
| 239680 | for(ii=0; ii<nToken && pToken[ii]; ii++){} | ||
| 239681 | return ii; | ||
| 239682 | } | ||
| 239683 | |||
| 235538 | static int fts5ExprPopulatePoslistsCb( | 239684 | static int fts5ExprPopulatePoslistsCb( |
| 235539 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ | 239685 | void *pCtx, /* Copy of 2nd argument to xTokenize() */ |
| 235540 | int tflags, /* Mask of FTS5_TOKEN_* flags */ | 239686 | int tflags, /* Mask of FTS5_TOKEN_* flags */ |
| @@ -235546,22 +239692,33 @@ static int fts5ExprPopulatePoslistsCb( | |||
| 235546 | Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx; | 239692 | Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx; |
| 235547 | Fts5Expr *pExpr = p->pExpr; | 239693 | Fts5Expr *pExpr = p->pExpr; |
| 235548 | int i; | 239694 | int i; |
| 239695 | int nQuery = nToken; | ||
| 239696 | i64 iRowid = pExpr->pRoot->iRowid; | ||
| 235549 | 239697 | ||
| 235550 | UNUSED_PARAM2(iUnused1, iUnused2); | 239698 | UNUSED_PARAM2(iUnused1, iUnused2); |
| 235551 | 239699 | ||
| 235552 | if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; | 239700 | if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE; |
| 239701 | if( pExpr->pConfig->bTokendata ){ | ||
| 239702 | nQuery = fts5QueryTerm(pToken, nQuery); | ||
| 239703 | } | ||
| 235553 | if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; | 239704 | if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; |
| 235554 | for(i=0; i<pExpr->nPhrase; i++){ | 239705 | for(i=0; i<pExpr->nPhrase; i++){ |
| 235555 | Fts5ExprTerm *pTerm; | 239706 | Fts5ExprTerm *pT; |
| 235556 | if( p->aPopulator[i].bOk==0 ) continue; | 239707 | if( p->aPopulator[i].bOk==0 ) continue; |
| 235557 | for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ | 239708 | for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){ |
| 235558 | int nTerm = (int)strlen(pTerm->zTerm); | 239709 | if( (pT->nQueryTerm==nQuery || (pT->nQueryTerm<nQuery && pT->bPrefix)) |
| 235559 | if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix)) | 239710 | && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0 |
| 235560 | && memcmp(pTerm->zTerm, pToken, nTerm)==0 | ||
| 235561 | ){ | 239711 | ){ |
| 235562 | int rc = sqlite3Fts5PoslistWriterAppend( | 239712 | int rc = sqlite3Fts5PoslistWriterAppend( |
| 235563 | &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff | 239713 | &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff |
| 235564 | ); | 239714 | ); |
| 239715 | if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ | ||
| 239716 | int iCol = p->iOff>>32; | ||
| 239717 | int iTokOff = p->iOff & 0x7FFFFFFF; | ||
| 239718 | rc = sqlite3Fts5IndexIterWriteTokendata( | ||
| 239719 | pT->pIter, pToken, nToken, iRowid, iCol, iTokOff | ||
| 239720 | ); | ||
| 239721 | } | ||
| 235565 | if( rc ) return rc; | 239722 | if( rc ) return rc; |
| 235566 | break; | 239723 | break; |
| 235567 | } | 239724 | } |
| @@ -235698,6 +239855,83 @@ static int sqlite3Fts5ExprPhraseCollist( | |||
| 235698 | } | 239855 | } |
| 235699 | 239856 | ||
| 235700 | /* | 239857 | /* |
| 239858 | ** Does the work of the fts5_api.xQueryToken() API method. | ||
| 239859 | */ | ||
| 239860 | static int sqlite3Fts5ExprQueryToken( | ||
| 239861 | Fts5Expr *pExpr, | ||
| 239862 | int iPhrase, | ||
| 239863 | int iToken, | ||
| 239864 | const char **ppOut, | ||
| 239865 | int *pnOut | ||
| 239866 | ){ | ||
| 239867 | Fts5ExprPhrase *pPhrase = 0; | ||
| 239868 | |||
| 239869 | if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ | ||
| 239870 | return SQLITE_RANGE; | ||
| 239871 | } | ||
| 239872 | pPhrase = pExpr->apExprPhrase[iPhrase]; | ||
| 239873 | if( iToken<0 || iToken>=pPhrase->nTerm ){ | ||
| 239874 | return SQLITE_RANGE; | ||
| 239875 | } | ||
| 239876 | |||
| 239877 | *ppOut = pPhrase->aTerm[iToken].pTerm; | ||
| 239878 | *pnOut = pPhrase->aTerm[iToken].nFullTerm; | ||
| 239879 | return SQLITE_OK; | ||
| 239880 | } | ||
| 239881 | |||
| 239882 | /* | ||
| 239883 | ** Does the work of the fts5_api.xInstToken() API method. | ||
| 239884 | */ | ||
| 239885 | static int sqlite3Fts5ExprInstToken( | ||
| 239886 | Fts5Expr *pExpr, | ||
| 239887 | i64 iRowid, | ||
| 239888 | int iPhrase, | ||
| 239889 | int iCol, | ||
| 239890 | int iOff, | ||
| 239891 | int iToken, | ||
| 239892 | const char **ppOut, | ||
| 239893 | int *pnOut | ||
| 239894 | ){ | ||
| 239895 | Fts5ExprPhrase *pPhrase = 0; | ||
| 239896 | Fts5ExprTerm *pTerm = 0; | ||
| 239897 | int rc = SQLITE_OK; | ||
| 239898 | |||
| 239899 | if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ | ||
| 239900 | return SQLITE_RANGE; | ||
| 239901 | } | ||
| 239902 | pPhrase = pExpr->apExprPhrase[iPhrase]; | ||
| 239903 | if( iToken<0 || iToken>=pPhrase->nTerm ){ | ||
| 239904 | return SQLITE_RANGE; | ||
| 239905 | } | ||
| 239906 | pTerm = &pPhrase->aTerm[iToken]; | ||
| 239907 | if( pTerm->bPrefix==0 ){ | ||
| 239908 | if( pExpr->pConfig->bTokendata ){ | ||
| 239909 | rc = sqlite3Fts5IterToken( | ||
| 239910 | pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut | ||
| 239911 | ); | ||
| 239912 | }else{ | ||
| 239913 | *ppOut = pTerm->pTerm; | ||
| 239914 | *pnOut = pTerm->nFullTerm; | ||
| 239915 | } | ||
| 239916 | } | ||
| 239917 | return rc; | ||
| 239918 | } | ||
| 239919 | |||
| 239920 | /* | ||
| 239921 | ** Clear the token mappings for all Fts5IndexIter objects mannaged by | ||
| 239922 | ** the expression passed as the only argument. | ||
| 239923 | */ | ||
| 239924 | static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ | ||
| 239925 | int ii; | ||
| 239926 | for(ii=0; ii<pExpr->nPhrase; ii++){ | ||
| 239927 | Fts5ExprTerm *pT; | ||
| 239928 | for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){ | ||
| 239929 | sqlite3Fts5IndexIterClearTokendata(pT->pIter); | ||
| 239930 | } | ||
| 239931 | } | ||
| 239932 | } | ||
| 239933 | |||
| 239934 | /* | ||
| 235701 | ** 2014 August 11 | 239935 | ** 2014 August 11 |
| 235702 | ** | 239936 | ** |
| 235703 | ** The author disclaims copyright to this source code. In place of | 239937 | ** The author disclaims copyright to this source code. In place of |
| @@ -235735,10 +239969,15 @@ struct Fts5Hash { | |||
| 235735 | 239969 | ||
| 235736 | /* | 239970 | /* |
| 235737 | ** Each entry in the hash table is represented by an object of the | 239971 | ** Each entry in the hash table is represented by an object of the |
| 235738 | ** following type. Each object, its key (a nul-terminated string) and | 239972 | ** following type. Each object, its key, and its current data are stored |
| 235739 | ** its current data are stored in a single memory allocation. The | 239973 | ** in a single memory allocation. The key immediately follows the object |
| 235740 | ** key immediately follows the object in memory. The position list | 239974 | ** in memory. The position list data immediately follows the key data |
| 235741 | ** data immediately follows the key data in memory. | 239975 | ** in memory. |
| 239976 | ** | ||
| 239977 | ** The key is Fts5HashEntry.nKey bytes in size. It consists of a single | ||
| 239978 | ** byte identifying the index (either the main term index or a prefix-index), | ||
| 239979 | ** followed by the term data. For example: "0token". There is no | ||
| 239980 | ** nul-terminator - in this case nKey=6. | ||
| 235742 | ** | 239981 | ** |
| 235743 | ** The data that follows the key is in a similar, but not identical format | 239982 | ** The data that follows the key is in a similar, but not identical format |
| 235744 | ** to the doclist data stored in the database. It is: | 239983 | ** to the doclist data stored in the database. It is: |
| @@ -235873,8 +240112,7 @@ static int fts5HashResize(Fts5Hash *pHash){ | |||
| 235873 | unsigned int iHash; | 240112 | unsigned int iHash; |
| 235874 | Fts5HashEntry *p = apOld[i]; | 240113 | Fts5HashEntry *p = apOld[i]; |
| 235875 | apOld[i] = p->pHashNext; | 240114 | apOld[i] = p->pHashNext; |
| 235876 | iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), | 240115 | iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey); |
| 235877 | (int)strlen(fts5EntryKey(p))); | ||
| 235878 | p->pHashNext = apNew[iHash]; | 240116 | p->pHashNext = apNew[iHash]; |
| 235879 | apNew[iHash] = p; | 240117 | apNew[iHash] = p; |
| 235880 | } | 240118 | } |
| @@ -235958,7 +240196,7 @@ static int sqlite3Fts5HashWrite( | |||
| 235958 | for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ | 240196 | for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ |
| 235959 | char *zKey = fts5EntryKey(p); | 240197 | char *zKey = fts5EntryKey(p); |
| 235960 | if( zKey[0]==bByte | 240198 | if( zKey[0]==bByte |
| 235961 | && p->nKey==nToken | 240199 | && p->nKey==nToken+1 |
| 235962 | && memcmp(&zKey[1], pToken, nToken)==0 | 240200 | && memcmp(&zKey[1], pToken, nToken)==0 |
| 235963 | ){ | 240201 | ){ |
| 235964 | break; | 240202 | break; |
| @@ -235988,9 +240226,9 @@ static int sqlite3Fts5HashWrite( | |||
| 235988 | zKey[0] = bByte; | 240226 | zKey[0] = bByte; |
| 235989 | memcpy(&zKey[1], pToken, nToken); | 240227 | memcpy(&zKey[1], pToken, nToken); |
| 235990 | assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); | 240228 | assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); |
| 235991 | p->nKey = nToken; | 240229 | p->nKey = nToken+1; |
| 235992 | zKey[nToken+1] = '\0'; | 240230 | zKey[nToken+1] = '\0'; |
| 235993 | p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); | 240231 | p->nData = nToken+1 + sizeof(Fts5HashEntry); |
| 235994 | p->pHashNext = pHash->aSlot[iHash]; | 240232 | p->pHashNext = pHash->aSlot[iHash]; |
| 235995 | pHash->aSlot[iHash] = p; | 240233 | pHash->aSlot[iHash] = p; |
| 235996 | pHash->nEntry++; | 240234 | pHash->nEntry++; |
| @@ -236107,12 +240345,17 @@ static Fts5HashEntry *fts5HashEntryMerge( | |||
| 236107 | *ppOut = p1; | 240345 | *ppOut = p1; |
| 236108 | p1 = 0; | 240346 | p1 = 0; |
| 236109 | }else{ | 240347 | }else{ |
| 236110 | int i = 0; | ||
| 236111 | char *zKey1 = fts5EntryKey(p1); | 240348 | char *zKey1 = fts5EntryKey(p1); |
| 236112 | char *zKey2 = fts5EntryKey(p2); | 240349 | char *zKey2 = fts5EntryKey(p2); |
| 236113 | while( zKey1[i]==zKey2[i] ) i++; | 240350 | int nMin = MIN(p1->nKey, p2->nKey); |
| 236114 | 240351 | ||
| 236115 | if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ | 240352 | int cmp = memcmp(zKey1, zKey2, nMin); |
| 240353 | if( cmp==0 ){ | ||
| 240354 | cmp = p1->nKey - p2->nKey; | ||
| 240355 | } | ||
| 240356 | assert( cmp!=0 ); | ||
| 240357 | |||
| 240358 | if( cmp>0 ){ | ||
| 236116 | /* p2 is smaller */ | 240359 | /* p2 is smaller */ |
| 236117 | *ppOut = p2; | 240360 | *ppOut = p2; |
| 236118 | ppOut = &p2->pScanNext; | 240361 | ppOut = &p2->pScanNext; |
| @@ -236131,10 +240374,8 @@ static Fts5HashEntry *fts5HashEntryMerge( | |||
| 236131 | } | 240374 | } |
| 236132 | 240375 | ||
| 236133 | /* | 240376 | /* |
| 236134 | ** Extract all tokens from hash table iHash and link them into a list | 240377 | ** Link all tokens from hash table iHash into a list in sorted order. The |
| 236135 | ** in sorted order. The hash table is cleared before returning. It is | 240378 | ** tokens are not removed from the hash table. |
| 236136 | ** the responsibility of the caller to free the elements of the returned | ||
| 236137 | ** list. | ||
| 236138 | */ | 240379 | */ |
| 236139 | static int fts5HashEntrySort( | 240380 | static int fts5HashEntrySort( |
| 236140 | Fts5Hash *pHash, | 240381 | Fts5Hash *pHash, |
| @@ -236156,7 +240397,7 @@ static int fts5HashEntrySort( | |||
| 236156 | Fts5HashEntry *pIter; | 240397 | Fts5HashEntry *pIter; |
| 236157 | for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ | 240398 | for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ |
| 236158 | if( pTerm==0 | 240399 | if( pTerm==0 |
| 236159 | || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) | 240400 | || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) |
| 236160 | ){ | 240401 | ){ |
| 236161 | Fts5HashEntry *pEntry = pIter; | 240402 | Fts5HashEntry *pEntry = pIter; |
| 236162 | pEntry->pScanNext = 0; | 240403 | pEntry->pScanNext = 0; |
| @@ -236195,12 +240436,11 @@ static int sqlite3Fts5HashQuery( | |||
| 236195 | 240436 | ||
| 236196 | for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ | 240437 | for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ |
| 236197 | zKey = fts5EntryKey(p); | 240438 | zKey = fts5EntryKey(p); |
| 236198 | assert( p->nKey+1==(int)strlen(zKey) ); | 240439 | if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break; |
| 236199 | if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break; | ||
| 236200 | } | 240440 | } |
| 236201 | 240441 | ||
| 236202 | if( p ){ | 240442 | if( p ){ |
| 236203 | int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1; | 240443 | int nHashPre = sizeof(Fts5HashEntry) + nTerm; |
| 236204 | int nList = p->nData - nHashPre; | 240444 | int nList = p->nData - nHashPre; |
| 236205 | u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); | 240445 | u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); |
| 236206 | if( pRet ){ | 240446 | if( pRet ){ |
| @@ -236261,19 +240501,22 @@ static int sqlite3Fts5HashScanEof(Fts5Hash *p){ | |||
| 236261 | static void sqlite3Fts5HashScanEntry( | 240501 | static void sqlite3Fts5HashScanEntry( |
| 236262 | Fts5Hash *pHash, | 240502 | Fts5Hash *pHash, |
| 236263 | const char **pzTerm, /* OUT: term (nul-terminated) */ | 240503 | const char **pzTerm, /* OUT: term (nul-terminated) */ |
| 240504 | int *pnTerm, /* OUT: Size of term in bytes */ | ||
| 236264 | const u8 **ppDoclist, /* OUT: pointer to doclist */ | 240505 | const u8 **ppDoclist, /* OUT: pointer to doclist */ |
| 236265 | int *pnDoclist /* OUT: size of doclist in bytes */ | 240506 | int *pnDoclist /* OUT: size of doclist in bytes */ |
| 236266 | ){ | 240507 | ){ |
| 236267 | Fts5HashEntry *p; | 240508 | Fts5HashEntry *p; |
| 236268 | if( (p = pHash->pScan) ){ | 240509 | if( (p = pHash->pScan) ){ |
| 236269 | char *zKey = fts5EntryKey(p); | 240510 | char *zKey = fts5EntryKey(p); |
| 236270 | int nTerm = (int)strlen(zKey); | 240511 | int nTerm = p->nKey; |
| 236271 | fts5HashAddPoslistSize(pHash, p, 0); | 240512 | fts5HashAddPoslistSize(pHash, p, 0); |
| 236272 | *pzTerm = zKey; | 240513 | *pzTerm = zKey; |
| 236273 | *ppDoclist = (const u8*)&zKey[nTerm+1]; | 240514 | *pnTerm = nTerm; |
| 236274 | *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); | 240515 | *ppDoclist = (const u8*)&zKey[nTerm]; |
| 240516 | *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm); | ||
| 236275 | }else{ | 240517 | }else{ |
| 236276 | *pzTerm = 0; | 240518 | *pzTerm = 0; |
| 240519 | *pnTerm = 0; | ||
| 236277 | *ppDoclist = 0; | 240520 | *ppDoclist = 0; |
| 236278 | *pnDoclist = 0; | 240521 | *pnDoclist = 0; |
| 236279 | } | 240522 | } |
| @@ -236604,6 +240847,9 @@ typedef struct Fts5SegWriter Fts5SegWriter; | |||
| 236604 | typedef struct Fts5Structure Fts5Structure; | 240847 | typedef struct Fts5Structure Fts5Structure; |
| 236605 | typedef struct Fts5StructureLevel Fts5StructureLevel; | 240848 | typedef struct Fts5StructureLevel Fts5StructureLevel; |
| 236606 | typedef struct Fts5StructureSegment Fts5StructureSegment; | 240849 | typedef struct Fts5StructureSegment Fts5StructureSegment; |
| 240850 | typedef struct Fts5TokenDataIter Fts5TokenDataIter; | ||
| 240851 | typedef struct Fts5TokenDataMap Fts5TokenDataMap; | ||
| 240852 | typedef struct Fts5TombstoneArray Fts5TombstoneArray; | ||
| 236607 | 240853 | ||
| 236608 | struct Fts5Data { | 240854 | struct Fts5Data { |
| 236609 | u8 *p; /* Pointer to buffer containing record */ | 240855 | u8 *p; /* Pointer to buffer containing record */ |
| @@ -236638,6 +240884,7 @@ struct Fts5Index { | |||
| 236638 | 240884 | ||
| 236639 | /* Error state. */ | 240885 | /* Error state. */ |
| 236640 | int rc; /* Current error code */ | 240886 | int rc; /* Current error code */ |
| 240887 | int flushRc; | ||
| 236641 | 240888 | ||
| 236642 | /* State used by the fts5DataXXX() functions. */ | 240889 | /* State used by the fts5DataXXX() functions. */ |
| 236643 | sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ | 240890 | sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ |
| @@ -236646,6 +240893,7 @@ struct Fts5Index { | |||
| 236646 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ | 240893 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 236647 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ | 240894 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ |
| 236648 | sqlite3_stmt *pIdxSelect; | 240895 | sqlite3_stmt *pIdxSelect; |
| 240896 | sqlite3_stmt *pIdxNextSelect; | ||
| 236649 | int nRead; /* Total number of blocks read */ | 240897 | int nRead; /* Total number of blocks read */ |
| 236650 | 240898 | ||
| 236651 | sqlite3_stmt *pDeleteFromIdx; | 240899 | sqlite3_stmt *pDeleteFromIdx; |
| @@ -236799,8 +241047,7 @@ struct Fts5SegIter { | |||
| 236799 | Fts5Data *pLeaf; /* Current leaf data */ | 241047 | Fts5Data *pLeaf; /* Current leaf data */ |
| 236800 | Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ | 241048 | Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ |
| 236801 | i64 iLeafOffset; /* Byte offset within current leaf */ | 241049 | i64 iLeafOffset; /* Byte offset within current leaf */ |
| 236802 | Fts5Data **apTombstone; /* Array of tombstone pages */ | 241050 | Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */ |
| 236803 | int nTombstone; | ||
| 236804 | 241051 | ||
| 236805 | /* Next method */ | 241052 | /* Next method */ |
| 236806 | void (*xNext)(Fts5Index*, Fts5SegIter*, int*); | 241053 | void (*xNext)(Fts5Index*, Fts5SegIter*, int*); |
| @@ -236828,6 +241075,15 @@ struct Fts5SegIter { | |||
| 236828 | }; | 241075 | }; |
| 236829 | 241076 | ||
| 236830 | /* | 241077 | /* |
| 241078 | ** Array of tombstone pages. Reference counted. | ||
| 241079 | */ | ||
| 241080 | struct Fts5TombstoneArray { | ||
| 241081 | int nRef; /* Number of pointers to this object */ | ||
| 241082 | int nTombstone; | ||
| 241083 | Fts5Data *apTombstone[1]; /* Array of tombstone pages */ | ||
| 241084 | }; | ||
| 241085 | |||
| 241086 | /* | ||
| 236831 | ** Argument is a pointer to an Fts5Data structure that contains a | 241087 | ** Argument is a pointer to an Fts5Data structure that contains a |
| 236832 | ** leaf page. | 241088 | ** leaf page. |
| 236833 | */ | 241089 | */ |
| @@ -236871,9 +241127,16 @@ struct Fts5SegIter { | |||
| 236871 | ** poslist: | 241127 | ** poslist: |
| 236872 | ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. | 241128 | ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. |
| 236873 | ** There is no way to tell if this is populated or not. | 241129 | ** There is no way to tell if this is populated or not. |
| 241130 | ** | ||
| 241131 | ** pColset: | ||
| 241132 | ** If not NULL, points to an object containing a set of column indices. | ||
| 241133 | ** Only matches that occur in one of these columns will be returned. | ||
| 241134 | ** The Fts5Iter does not own the Fts5Colset object, and so it is not | ||
| 241135 | ** freed when the iterator is closed - it is owned by the upper layer. | ||
| 236874 | */ | 241136 | */ |
| 236875 | struct Fts5Iter { | 241137 | struct Fts5Iter { |
| 236876 | Fts5IndexIter base; /* Base class containing output vars */ | 241138 | Fts5IndexIter base; /* Base class containing output vars */ |
| 241139 | Fts5TokenDataIter *pTokenDataIter; | ||
| 236877 | 241140 | ||
| 236878 | Fts5Index *pIndex; /* Index that owns this iterator */ | 241141 | Fts5Index *pIndex; /* Index that owns this iterator */ |
| 236879 | Fts5Buffer poslist; /* Buffer containing current poslist */ | 241142 | Fts5Buffer poslist; /* Buffer containing current poslist */ |
| @@ -236891,7 +241154,6 @@ struct Fts5Iter { | |||
| 236891 | Fts5SegIter aSeg[1]; /* Array of segment iterators */ | 241154 | Fts5SegIter aSeg[1]; /* Array of segment iterators */ |
| 236892 | }; | 241155 | }; |
| 236893 | 241156 | ||
| 236894 | |||
| 236895 | /* | 241157 | /* |
| 236896 | ** An instance of the following type is used to iterate through the contents | 241158 | ** An instance of the following type is used to iterate through the contents |
| 236897 | ** of a doclist-index record. | 241159 | ** of a doclist-index record. |
| @@ -237809,9 +242071,9 @@ static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){ | |||
| 237809 | } | 242071 | } |
| 237810 | 242072 | ||
| 237811 | if( iOff<pData->nn ){ | 242073 | if( iOff<pData->nn ){ |
| 237812 | i64 iVal; | 242074 | u64 iVal; |
| 237813 | pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1; | 242075 | pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1; |
| 237814 | iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal); | 242076 | iOff += fts5GetVarint(&pData->p[iOff], &iVal); |
| 237815 | pLvl->iRowid += iVal; | 242077 | pLvl->iRowid += iVal; |
| 237816 | pLvl->iOff = iOff; | 242078 | pLvl->iOff = iOff; |
| 237817 | }else{ | 242079 | }else{ |
| @@ -238190,18 +242452,20 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ | |||
| 238190 | } | 242452 | } |
| 238191 | 242453 | ||
| 238192 | /* | 242454 | /* |
| 238193 | ** Allocate a tombstone hash page array (pIter->apTombstone) for the | 242455 | ** Allocate a tombstone hash page array object (pIter->pTombArray) for |
| 238194 | ** iterator passed as the second argument. If an OOM error occurs, leave | 242456 | ** the iterator passed as the second argument. If an OOM error occurs, |
| 238195 | ** an error in the Fts5Index object. | 242457 | ** leave an error in the Fts5Index object. |
| 238196 | */ | 242458 | */ |
| 238197 | static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ | 242459 | static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ |
| 238198 | const int nTomb = pIter->pSeg->nPgTombstone; | 242460 | const int nTomb = pIter->pSeg->nPgTombstone; |
| 238199 | if( nTomb>0 ){ | 242461 | if( nTomb>0 ){ |
| 238200 | Fts5Data **apTomb = 0; | 242462 | int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); |
| 238201 | apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); | 242463 | Fts5TombstoneArray *pNew; |
| 238202 | if( apTomb ){ | 242464 | pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); |
| 238203 | pIter->apTombstone = apTomb; | 242465 | if( pNew ){ |
| 238204 | pIter->nTombstone = nTomb; | 242466 | pNew->nTombstone = nTomb; |
| 242467 | pNew->nRef = 1; | ||
| 242468 | pIter->pTombArray = pNew; | ||
| 238205 | } | 242469 | } |
| 238206 | } | 242470 | } |
| 238207 | } | 242471 | } |
| @@ -238458,15 +242722,16 @@ static void fts5SegIterNext_None( | |||
| 238458 | }else{ | 242722 | }else{ |
| 238459 | const u8 *pList = 0; | 242723 | const u8 *pList = 0; |
| 238460 | const char *zTerm = 0; | 242724 | const char *zTerm = 0; |
| 242725 | int nTerm = 0; | ||
| 238461 | int nList; | 242726 | int nList; |
| 238462 | sqlite3Fts5HashScanNext(p->pHash); | 242727 | sqlite3Fts5HashScanNext(p->pHash); |
| 238463 | sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); | 242728 | sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); |
| 238464 | if( pList==0 ) goto next_none_eof; | 242729 | if( pList==0 ) goto next_none_eof; |
| 238465 | pIter->pLeaf->p = (u8*)pList; | 242730 | pIter->pLeaf->p = (u8*)pList; |
| 238466 | pIter->pLeaf->nn = nList; | 242731 | pIter->pLeaf->nn = nList; |
| 238467 | pIter->pLeaf->szLeaf = nList; | 242732 | pIter->pLeaf->szLeaf = nList; |
| 238468 | pIter->iEndofDoclist = nList; | 242733 | pIter->iEndofDoclist = nList; |
| 238469 | sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); | 242734 | sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm); |
| 238470 | pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); | 242735 | pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); |
| 238471 | } | 242736 | } |
| 238472 | 242737 | ||
| @@ -238532,11 +242797,12 @@ static void fts5SegIterNext( | |||
| 238532 | }else if( pIter->pSeg==0 ){ | 242797 | }else if( pIter->pSeg==0 ){ |
| 238533 | const u8 *pList = 0; | 242798 | const u8 *pList = 0; |
| 238534 | const char *zTerm = 0; | 242799 | const char *zTerm = 0; |
| 242800 | int nTerm = 0; | ||
| 238535 | int nList = 0; | 242801 | int nList = 0; |
| 238536 | assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); | 242802 | assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); |
| 238537 | if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ | 242803 | if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ |
| 238538 | sqlite3Fts5HashScanNext(p->pHash); | 242804 | sqlite3Fts5HashScanNext(p->pHash); |
| 238539 | sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); | 242805 | sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); |
| 238540 | } | 242806 | } |
| 238541 | if( pList==0 ){ | 242807 | if( pList==0 ){ |
| 238542 | fts5DataRelease(pIter->pLeaf); | 242808 | fts5DataRelease(pIter->pLeaf); |
| @@ -238546,8 +242812,7 @@ static void fts5SegIterNext( | |||
| 238546 | pIter->pLeaf->nn = nList; | 242812 | pIter->pLeaf->nn = nList; |
| 238547 | pIter->pLeaf->szLeaf = nList; | 242813 | pIter->pLeaf->szLeaf = nList; |
| 238548 | pIter->iEndofDoclist = nList+1; | 242814 | pIter->iEndofDoclist = nList+1; |
| 238549 | sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), | 242815 | sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm); |
| 238550 | (u8*)zTerm); | ||
| 238551 | pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); | 242816 | pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); |
| 238552 | *pbNewTerm = 1; | 242817 | *pbNewTerm = 1; |
| 238553 | } | 242818 | } |
| @@ -238933,7 +243198,7 @@ static void fts5SegIterSeekInit( | |||
| 238933 | fts5LeafSeek(p, bGe, pIter, pTerm, nTerm); | 243198 | fts5LeafSeek(p, bGe, pIter, pTerm, nTerm); |
| 238934 | } | 243199 | } |
| 238935 | 243200 | ||
| 238936 | if( p->rc==SQLITE_OK && bGe==0 ){ | 243201 | if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){ |
| 238937 | pIter->flags |= FTS5_SEGITER_ONETERM; | 243202 | pIter->flags |= FTS5_SEGITER_ONETERM; |
| 238938 | if( pIter->pLeaf ){ | 243203 | if( pIter->pLeaf ){ |
| 238939 | if( flags & FTS5INDEX_QUERY_DESC ){ | 243204 | if( flags & FTS5INDEX_QUERY_DESC ){ |
| @@ -238949,7 +243214,9 @@ static void fts5SegIterSeekInit( | |||
| 238949 | } | 243214 | } |
| 238950 | 243215 | ||
| 238951 | fts5SegIterSetNext(p, pIter); | 243216 | fts5SegIterSetNext(p, pIter); |
| 238952 | fts5SegIterAllocTombstone(p, pIter); | 243217 | if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){ |
| 243218 | fts5SegIterAllocTombstone(p, pIter); | ||
| 243219 | } | ||
| 238953 | 243220 | ||
| 238954 | /* Either: | 243221 | /* Either: |
| 238955 | ** | 243222 | ** |
| @@ -238966,6 +243233,79 @@ static void fts5SegIterSeekInit( | |||
| 238966 | ); | 243233 | ); |
| 238967 | } | 243234 | } |
| 238968 | 243235 | ||
| 243236 | |||
| 243237 | /* | ||
| 243238 | ** SQL used by fts5SegIterNextInit() to find the page to open. | ||
| 243239 | */ | ||
| 243240 | static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){ | ||
| 243241 | if( p->pIdxNextSelect==0 ){ | ||
| 243242 | Fts5Config *pConfig = p->pConfig; | ||
| 243243 | fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf( | ||
| 243244 | "SELECT pgno FROM '%q'.'%q_idx' WHERE " | ||
| 243245 | "segid=? AND term>? ORDER BY term ASC LIMIT 1", | ||
| 243246 | pConfig->zDb, pConfig->zName | ||
| 243247 | )); | ||
| 243248 | |||
| 243249 | } | ||
| 243250 | return p->pIdxNextSelect; | ||
| 243251 | } | ||
| 243252 | |||
| 243253 | /* | ||
| 243254 | ** This is similar to fts5SegIterSeekInit(), except that it initializes | ||
| 243255 | ** the segment iterator to point to the first term following the page | ||
| 243256 | ** with pToken/nToken on it. | ||
| 243257 | */ | ||
| 243258 | static void fts5SegIterNextInit( | ||
| 243259 | Fts5Index *p, | ||
| 243260 | const char *pTerm, int nTerm, | ||
| 243261 | Fts5StructureSegment *pSeg, /* Description of segment */ | ||
| 243262 | Fts5SegIter *pIter /* Object to populate */ | ||
| 243263 | ){ | ||
| 243264 | int iPg = -1; /* Page of segment to open */ | ||
| 243265 | int bDlidx = 0; | ||
| 243266 | sqlite3_stmt *pSel = 0; /* SELECT to find iPg */ | ||
| 243267 | |||
| 243268 | pSel = fts5IdxNextStmt(p); | ||
| 243269 | if( pSel ){ | ||
| 243270 | assert( p->rc==SQLITE_OK ); | ||
| 243271 | sqlite3_bind_int(pSel, 1, pSeg->iSegid); | ||
| 243272 | sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC); | ||
| 243273 | |||
| 243274 | if( sqlite3_step(pSel)==SQLITE_ROW ){ | ||
| 243275 | i64 val = sqlite3_column_int64(pSel, 0); | ||
| 243276 | iPg = (int)(val>>1); | ||
| 243277 | bDlidx = (val & 0x0001); | ||
| 243278 | } | ||
| 243279 | p->rc = sqlite3_reset(pSel); | ||
| 243280 | sqlite3_bind_null(pSel, 2); | ||
| 243281 | if( p->rc ) return; | ||
| 243282 | } | ||
| 243283 | |||
| 243284 | memset(pIter, 0, sizeof(*pIter)); | ||
| 243285 | pIter->pSeg = pSeg; | ||
| 243286 | pIter->flags |= FTS5_SEGITER_ONETERM; | ||
| 243287 | if( iPg>=0 ){ | ||
| 243288 | pIter->iLeafPgno = iPg - 1; | ||
| 243289 | fts5SegIterNextPage(p, pIter); | ||
| 243290 | fts5SegIterSetNext(p, pIter); | ||
| 243291 | } | ||
| 243292 | if( pIter->pLeaf ){ | ||
| 243293 | const u8 *a = pIter->pLeaf->p; | ||
| 243294 | int iTermOff = 0; | ||
| 243295 | |||
| 243296 | pIter->iPgidxOff = pIter->pLeaf->szLeaf; | ||
| 243297 | pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); | ||
| 243298 | pIter->iLeafOffset = iTermOff; | ||
| 243299 | fts5SegIterLoadTerm(p, pIter, 0); | ||
| 243300 | fts5SegIterLoadNPos(p, pIter); | ||
| 243301 | if( bDlidx ) fts5SegIterLoadDlidx(p, pIter); | ||
| 243302 | |||
| 243303 | assert( p->rc!=SQLITE_OK || | ||
| 243304 | fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0 | ||
| 243305 | ); | ||
| 243306 | } | ||
| 243307 | } | ||
| 243308 | |||
| 238969 | /* | 243309 | /* |
| 238970 | ** Initialize the object pIter to point to term pTerm/nTerm within the | 243310 | ** Initialize the object pIter to point to term pTerm/nTerm within the |
| 238971 | ** in-memory hash table. If there is no such term in the hash-table, the | 243311 | ** in-memory hash table. If there is no such term in the hash-table, the |
| @@ -238992,14 +243332,21 @@ static void fts5SegIterHashInit( | |||
| 238992 | const u8 *pList = 0; | 243332 | const u8 *pList = 0; |
| 238993 | 243333 | ||
| 238994 | p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); | 243334 | p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); |
| 238995 | sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); | 243335 | sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList); |
| 238996 | n = (z ? (int)strlen((const char*)z) : 0); | ||
| 238997 | if( pList ){ | 243336 | if( pList ){ |
| 238998 | pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); | 243337 | pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); |
| 238999 | if( pLeaf ){ | 243338 | if( pLeaf ){ |
| 239000 | pLeaf->p = (u8*)pList; | 243339 | pLeaf->p = (u8*)pList; |
| 239001 | } | 243340 | } |
| 239002 | } | 243341 | } |
| 243342 | |||
| 243343 | /* The call to sqlite3Fts5HashScanInit() causes the hash table to | ||
| 243344 | ** fill the size field of all existing position lists. This means they | ||
| 243345 | ** can no longer be appended to. Since the only scenario in which they | ||
| 243346 | ** can be appended to is if the previous operation on this table was | ||
| 243347 | ** a DELETE, by clearing the Fts5Index.bDelete flag we can avoid this | ||
| 243348 | ** possibility altogether. */ | ||
| 243349 | p->bDelete = 0; | ||
| 239003 | }else{ | 243350 | }else{ |
| 239004 | p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), | 243351 | p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), |
| 239005 | (const char*)pTerm, nTerm, (void**)&pLeaf, &nList | 243352 | (const char*)pTerm, nTerm, (void**)&pLeaf, &nList |
| @@ -239045,13 +243392,30 @@ static void fts5IndexFreeArray(Fts5Data **ap, int n){ | |||
| 239045 | } | 243392 | } |
| 239046 | 243393 | ||
| 239047 | /* | 243394 | /* |
| 243395 | ** Decrement the ref-count of the object passed as the only argument. If it | ||
| 243396 | ** reaches 0, free it and its contents. | ||
| 243397 | */ | ||
| 243398 | static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){ | ||
| 243399 | if( p ){ | ||
| 243400 | p->nRef--; | ||
| 243401 | if( p->nRef<=0 ){ | ||
| 243402 | int ii; | ||
| 243403 | for(ii=0; ii<p->nTombstone; ii++){ | ||
| 243404 | fts5DataRelease(p->apTombstone[ii]); | ||
| 243405 | } | ||
| 243406 | sqlite3_free(p); | ||
| 243407 | } | ||
| 243408 | } | ||
| 243409 | } | ||
| 243410 | |||
| 243411 | /* | ||
| 239048 | ** Zero the iterator passed as the only argument. | 243412 | ** Zero the iterator passed as the only argument. |
| 239049 | */ | 243413 | */ |
| 239050 | static void fts5SegIterClear(Fts5SegIter *pIter){ | 243414 | static void fts5SegIterClear(Fts5SegIter *pIter){ |
| 239051 | fts5BufferFree(&pIter->term); | 243415 | fts5BufferFree(&pIter->term); |
| 239052 | fts5DataRelease(pIter->pLeaf); | 243416 | fts5DataRelease(pIter->pLeaf); |
| 239053 | fts5DataRelease(pIter->pNextLeaf); | 243417 | fts5DataRelease(pIter->pNextLeaf); |
| 239054 | fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); | 243418 | fts5TombstoneArrayDelete(pIter->pTombArray); |
| 239055 | fts5DlidxIterFree(pIter->pDlidx); | 243419 | fts5DlidxIterFree(pIter->pDlidx); |
| 239056 | sqlite3_free(pIter->aRowidOffset); | 243420 | sqlite3_free(pIter->aRowidOffset); |
| 239057 | memset(pIter, 0, sizeof(Fts5SegIter)); | 243421 | memset(pIter, 0, sizeof(Fts5SegIter)); |
| @@ -239296,7 +243660,6 @@ static void fts5SegIterNextFrom( | |||
| 239296 | }while( p->rc==SQLITE_OK ); | 243660 | }while( p->rc==SQLITE_OK ); |
| 239297 | } | 243661 | } |
| 239298 | 243662 | ||
| 239299 | |||
| 239300 | /* | 243663 | /* |
| 239301 | ** Free the iterator object passed as the second argument. | 243664 | ** Free the iterator object passed as the second argument. |
| 239302 | */ | 243665 | */ |
| @@ -239441,24 +243804,25 @@ static int fts5IndexTombstoneQuery( | |||
| 239441 | static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ | 243804 | static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ |
| 239442 | int iFirst = pIter->aFirst[1].iFirst; | 243805 | int iFirst = pIter->aFirst[1].iFirst; |
| 239443 | Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; | 243806 | Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; |
| 243807 | Fts5TombstoneArray *pArray = pSeg->pTombArray; | ||
| 239444 | 243808 | ||
| 239445 | if( pSeg->pLeaf && pSeg->nTombstone ){ | 243809 | if( pSeg->pLeaf && pArray ){ |
| 239446 | /* Figure out which page the rowid might be present on. */ | 243810 | /* Figure out which page the rowid might be present on. */ |
| 239447 | int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; | 243811 | int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone; |
| 239448 | assert( iPg>=0 ); | 243812 | assert( iPg>=0 ); |
| 239449 | 243813 | ||
| 239450 | /* If tombstone hash page iPg has not yet been loaded from the | 243814 | /* If tombstone hash page iPg has not yet been loaded from the |
| 239451 | ** database, load it now. */ | 243815 | ** database, load it now. */ |
| 239452 | if( pSeg->apTombstone[iPg]==0 ){ | 243816 | if( pArray->apTombstone[iPg]==0 ){ |
| 239453 | pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, | 243817 | pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex, |
| 239454 | FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) | 243818 | FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) |
| 239455 | ); | 243819 | ); |
| 239456 | if( pSeg->apTombstone[iPg]==0 ) return 0; | 243820 | if( pArray->apTombstone[iPg]==0 ) return 0; |
| 239457 | } | 243821 | } |
| 239458 | 243822 | ||
| 239459 | return fts5IndexTombstoneQuery( | 243823 | return fts5IndexTombstoneQuery( |
| 239460 | pSeg->apTombstone[iPg], | 243824 | pArray->apTombstone[iPg], |
| 239461 | pSeg->nTombstone, | 243825 | pArray->nTombstone, |
| 239462 | pSeg->iRowid | 243826 | pSeg->iRowid |
| 239463 | ); | 243827 | ); |
| 239464 | } | 243828 | } |
| @@ -239997,6 +244361,32 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ | |||
| 239997 | } | 244361 | } |
| 239998 | } | 244362 | } |
| 239999 | 244363 | ||
| 244364 | /* | ||
| 244365 | ** All the component segment-iterators of pIter have been set up. This | ||
| 244366 | ** functions finishes setup for iterator pIter itself. | ||
| 244367 | */ | ||
| 244368 | static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){ | ||
| 244369 | int iIter; | ||
| 244370 | for(iIter=pIter->nSeg-1; iIter>0; iIter--){ | ||
| 244371 | int iEq; | ||
| 244372 | if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){ | ||
| 244373 | Fts5SegIter *pSeg = &pIter->aSeg[iEq]; | ||
| 244374 | if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); | ||
| 244375 | fts5MultiIterAdvanced(p, pIter, iEq, iIter); | ||
| 244376 | } | ||
| 244377 | } | ||
| 244378 | fts5MultiIterSetEof(pIter); | ||
| 244379 | fts5AssertMultiIterSetup(p, pIter); | ||
| 244380 | |||
| 244381 | if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter)) | ||
| 244382 | || fts5MultiIterIsDeleted(pIter) | ||
| 244383 | ){ | ||
| 244384 | fts5MultiIterNext(p, pIter, 0, 0); | ||
| 244385 | }else if( pIter->base.bEof==0 ){ | ||
| 244386 | Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; | ||
| 244387 | pIter->xSetOutputs(pIter, pSeg); | ||
| 244388 | } | ||
| 244389 | } | ||
| 240000 | 244390 | ||
| 240001 | /* | 244391 | /* |
| 240002 | ** Allocate a new Fts5Iter object. | 244392 | ** Allocate a new Fts5Iter object. |
| @@ -240078,31 +244468,12 @@ static void fts5MultiIterNew( | |||
| 240078 | assert( iIter==nSeg ); | 244468 | assert( iIter==nSeg ); |
| 240079 | } | 244469 | } |
| 240080 | 244470 | ||
| 240081 | /* If the above was successful, each component iterators now points | 244471 | /* If the above was successful, each component iterator now points |
| 240082 | ** to the first entry in its segment. In this case initialize the | 244472 | ** to the first entry in its segment. In this case initialize the |
| 240083 | ** aFirst[] array. Or, if an error has occurred, free the iterator | 244473 | ** aFirst[] array. Or, if an error has occurred, free the iterator |
| 240084 | ** object and set the output variable to NULL. */ | 244474 | ** object and set the output variable to NULL. */ |
| 240085 | if( p->rc==SQLITE_OK ){ | 244475 | if( p->rc==SQLITE_OK ){ |
| 240086 | for(iIter=pNew->nSeg-1; iIter>0; iIter--){ | 244476 | fts5MultiIterFinishSetup(p, pNew); |
| 240087 | int iEq; | ||
| 240088 | if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){ | ||
| 240089 | Fts5SegIter *pSeg = &pNew->aSeg[iEq]; | ||
| 240090 | if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); | ||
| 240091 | fts5MultiIterAdvanced(p, pNew, iEq, iIter); | ||
| 240092 | } | ||
| 240093 | } | ||
| 240094 | fts5MultiIterSetEof(pNew); | ||
| 240095 | fts5AssertMultiIterSetup(p, pNew); | ||
| 240096 | |||
| 240097 | if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) | ||
| 240098 | || fts5MultiIterIsDeleted(pNew) | ||
| 240099 | ){ | ||
| 240100 | fts5MultiIterNext(p, pNew, 0, 0); | ||
| 240101 | }else if( pNew->base.bEof==0 ){ | ||
| 240102 | Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; | ||
| 240103 | pNew->xSetOutputs(pNew, pSeg); | ||
| 240104 | } | ||
| 240105 | |||
| 240106 | }else{ | 244477 | }else{ |
| 240107 | fts5MultiIterFree(pNew); | 244478 | fts5MultiIterFree(pNew); |
| 240108 | *ppOut = 0; | 244479 | *ppOut = 0; |
| @@ -240127,7 +244498,6 @@ static void fts5MultiIterNew2( | |||
| 240127 | pNew = fts5MultiIterAlloc(p, 2); | 244498 | pNew = fts5MultiIterAlloc(p, 2); |
| 240128 | if( pNew ){ | 244499 | if( pNew ){ |
| 240129 | Fts5SegIter *pIter = &pNew->aSeg[1]; | 244500 | Fts5SegIter *pIter = &pNew->aSeg[1]; |
| 240130 | |||
| 240131 | pIter->flags = FTS5_SEGITER_ONETERM; | 244501 | pIter->flags = FTS5_SEGITER_ONETERM; |
| 240132 | if( pData->szLeaf>0 ){ | 244502 | if( pData->szLeaf>0 ){ |
| 240133 | pIter->pLeaf = pData; | 244503 | pIter->pLeaf = pData; |
| @@ -240275,6 +244645,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ | |||
| 240275 | sqlite3Fts5HashClear(p->pHash); | 244645 | sqlite3Fts5HashClear(p->pHash); |
| 240276 | p->nPendingData = 0; | 244646 | p->nPendingData = 0; |
| 240277 | p->nPendingRow = 0; | 244647 | p->nPendingRow = 0; |
| 244648 | p->flushRc = SQLITE_OK; | ||
| 240278 | } | 244649 | } |
| 240279 | p->nContentlessDelete = 0; | 244650 | p->nContentlessDelete = 0; |
| 240280 | } | 244651 | } |
| @@ -240490,7 +244861,7 @@ static void fts5WriteDlidxAppend( | |||
| 240490 | } | 244861 | } |
| 240491 | 244862 | ||
| 240492 | if( pDlidx->bPrevValid ){ | 244863 | if( pDlidx->bPrevValid ){ |
| 240493 | iVal = iRowid - pDlidx->iPrev; | 244864 | iVal = (u64)iRowid - (u64)pDlidx->iPrev; |
| 240494 | }else{ | 244865 | }else{ |
| 240495 | i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); | 244866 | i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); |
| 240496 | assert( pDlidx->buf.n==0 ); | 244867 | assert( pDlidx->buf.n==0 ); |
| @@ -240677,7 +245048,7 @@ static void fts5WriteAppendPoslistData( | |||
| 240677 | const u8 *a = aData; | 245048 | const u8 *a = aData; |
| 240678 | int n = nData; | 245049 | int n = nData; |
| 240679 | 245050 | ||
| 240680 | assert( p->pConfig->pgsz>0 ); | 245051 | assert( p->pConfig->pgsz>0 || p->rc!=SQLITE_OK ); |
| 240681 | while( p->rc==SQLITE_OK | 245052 | while( p->rc==SQLITE_OK |
| 240682 | && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz | 245053 | && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz |
| 240683 | ){ | 245054 | ){ |
| @@ -241410,18 +245781,24 @@ static void fts5DoSecureDelete( | |||
| 241410 | 245781 | ||
| 241411 | iOff = iStart; | 245782 | iOff = iStart; |
| 241412 | 245783 | ||
| 241413 | /* Set variable bLastInDoclist to true if this entry happens to be | 245784 | /* If the position-list for the entry being removed flows over past |
| 241414 | ** the last rowid in the doclist for its term. */ | 245785 | ** the end of this page, delete the portion of the position-list on the |
| 245786 | ** next page and beyond. | ||
| 245787 | ** | ||
| 245788 | ** Set variable bLastInDoclist to true if this entry happens | ||
| 245789 | ** to be the last rowid in the doclist for its term. */ | ||
| 245790 | if( iNextOff>=iPgIdx ){ | ||
| 245791 | int pgno = pSeg->iLeafPgno+1; | ||
| 245792 | fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); | ||
| 245793 | iNextOff = iPgIdx; | ||
| 245794 | } | ||
| 245795 | |||
| 241415 | if( pSeg->bDel==0 ){ | 245796 | if( pSeg->bDel==0 ){ |
| 241416 | if( iNextOff>=iPgIdx ){ | 245797 | if( iNextOff!=iPgIdx ){ |
| 241417 | int pgno = pSeg->iLeafPgno+1; | ||
| 241418 | fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); | ||
| 241419 | iNextOff = iPgIdx; | ||
| 241420 | }else{ | ||
| 241421 | /* Loop through the page-footer. If iNextOff (offset of the | 245798 | /* Loop through the page-footer. If iNextOff (offset of the |
| 241422 | ** entry following the one we are removing) is equal to the | 245799 | ** entry following the one we are removing) is equal to the |
| 241423 | ** offset of a key on this page, then the entry is the last | 245800 | ** offset of a key on this page, then the entry is the last |
| 241424 | ** in its doclist. */ | 245801 | ** in its doclist. */ |
| 241425 | int iKeyOff = 0; | 245802 | int iKeyOff = 0; |
| 241426 | for(iIdx=0; iIdx<nIdx; /* no-op */){ | 245803 | for(iIdx=0; iIdx<nIdx; /* no-op */){ |
| 241427 | u32 iVal = 0; | 245804 | u32 iVal = 0; |
| @@ -241607,10 +245984,10 @@ static void fts5FlushSecureDelete( | |||
| 241607 | Fts5Index *p, | 245984 | Fts5Index *p, |
| 241608 | Fts5Structure *pStruct, | 245985 | Fts5Structure *pStruct, |
| 241609 | const char *zTerm, | 245986 | const char *zTerm, |
| 245987 | int nTerm, | ||
| 241610 | i64 iRowid | 245988 | i64 iRowid |
| 241611 | ){ | 245989 | ){ |
| 241612 | const int f = FTS5INDEX_QUERY_SKIPHASH; | 245990 | const int f = FTS5INDEX_QUERY_SKIPHASH; |
| 241613 | int nTerm = (int)strlen(zTerm); | ||
| 241614 | Fts5Iter *pIter = 0; /* Used to find term instance */ | 245991 | Fts5Iter *pIter = 0; /* Used to find term instance */ |
| 241615 | 245992 | ||
| 241616 | fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); | 245993 | fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); |
| @@ -241684,8 +246061,7 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 241684 | int nDoclist; /* Size of doclist in bytes */ | 246061 | int nDoclist; /* Size of doclist in bytes */ |
| 241685 | 246062 | ||
| 241686 | /* Get the term and doclist for this entry. */ | 246063 | /* Get the term and doclist for this entry. */ |
| 241687 | sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); | 246064 | sqlite3Fts5HashScanEntry(pHash, &zTerm, &nTerm, &pDoclist, &nDoclist); |
| 241688 | nTerm = (int)strlen(zTerm); | ||
| 241689 | if( bSecureDelete==0 ){ | 246065 | if( bSecureDelete==0 ){ |
| 241690 | fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); | 246066 | fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); |
| 241691 | if( p->rc!=SQLITE_OK ) break; | 246067 | if( p->rc!=SQLITE_OK ) break; |
| @@ -241715,7 +246091,7 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 241715 | if( bSecureDelete ){ | 246091 | if( bSecureDelete ){ |
| 241716 | if( eDetail==FTS5_DETAIL_NONE ){ | 246092 | if( eDetail==FTS5_DETAIL_NONE ){ |
| 241717 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ | 246093 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ |
| 241718 | fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); | 246094 | fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid); |
| 241719 | iOff++; | 246095 | iOff++; |
| 241720 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ | 246096 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ |
| 241721 | iOff++; | 246097 | iOff++; |
| @@ -241725,7 +246101,7 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 241725 | } | 246101 | } |
| 241726 | } | 246102 | } |
| 241727 | }else if( (pDoclist[iOff] & 0x01) ){ | 246103 | }else if( (pDoclist[iOff] & 0x01) ){ |
| 241728 | fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); | 246104 | fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid); |
| 241729 | if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ | 246105 | if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ |
| 241730 | iOff++; | 246106 | iOff++; |
| 241731 | continue; | 246107 | continue; |
| @@ -241851,6 +246227,10 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 241851 | */ | 246227 | */ |
| 241852 | static void fts5IndexFlush(Fts5Index *p){ | 246228 | static void fts5IndexFlush(Fts5Index *p){ |
| 241853 | /* Unless it is empty, flush the hash table to disk */ | 246229 | /* Unless it is empty, flush the hash table to disk */ |
| 246230 | if( p->flushRc ){ | ||
| 246231 | p->rc = p->flushRc; | ||
| 246232 | return; | ||
| 246233 | } | ||
| 241854 | if( p->nPendingData || p->nContentlessDelete ){ | 246234 | if( p->nPendingData || p->nContentlessDelete ){ |
| 241855 | assert( p->pHash ); | 246235 | assert( p->pHash ); |
| 241856 | fts5FlushOneHash(p); | 246236 | fts5FlushOneHash(p); |
| @@ -241859,6 +246239,8 @@ static void fts5IndexFlush(Fts5Index *p){ | |||
| 241859 | p->nPendingData = 0; | 246239 | p->nPendingData = 0; |
| 241860 | p->nPendingRow = 0; | 246240 | p->nPendingRow = 0; |
| 241861 | p->nContentlessDelete = 0; | 246241 | p->nContentlessDelete = 0; |
| 246242 | }else if( p->nPendingData || p->nContentlessDelete ){ | ||
| 246243 | p->flushRc = p->rc; | ||
| 241862 | } | 246244 | } |
| 241863 | } | 246245 | } |
| 241864 | } | 246246 | } |
| @@ -241937,8 +246319,9 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ | |||
| 241937 | 246319 | ||
| 241938 | assert( p->rc==SQLITE_OK ); | 246320 | assert( p->rc==SQLITE_OK ); |
| 241939 | fts5IndexFlush(p); | 246321 | fts5IndexFlush(p); |
| 241940 | assert( p->nContentlessDelete==0 ); | 246322 | assert( p->rc!=SQLITE_OK || p->nContentlessDelete==0 ); |
| 241941 | pStruct = fts5StructureRead(p); | 246323 | pStruct = fts5StructureRead(p); |
| 246324 | assert( p->rc!=SQLITE_OK || pStruct!=0 ); | ||
| 241942 | fts5StructureInvalidate(p); | 246325 | fts5StructureInvalidate(p); |
| 241943 | 246326 | ||
| 241944 | if( pStruct ){ | 246327 | if( pStruct ){ |
| @@ -242344,7 +246727,7 @@ static void fts5SetupPrefixIter( | |||
| 242344 | u8 *pToken, /* Buffer containing prefix to match */ | 246727 | u8 *pToken, /* Buffer containing prefix to match */ |
| 242345 | int nToken, /* Size of buffer pToken in bytes */ | 246728 | int nToken, /* Size of buffer pToken in bytes */ |
| 242346 | Fts5Colset *pColset, /* Restrict matches to these columns */ | 246729 | Fts5Colset *pColset, /* Restrict matches to these columns */ |
| 242347 | Fts5Iter **ppIter /* OUT: New iterator */ | 246730 | Fts5Iter **ppIter /* OUT: New iterator */ |
| 242348 | ){ | 246731 | ){ |
| 242349 | Fts5Structure *pStruct; | 246732 | Fts5Structure *pStruct; |
| 242350 | Fts5Buffer *aBuf; | 246733 | Fts5Buffer *aBuf; |
| @@ -242365,8 +246748,9 @@ static void fts5SetupPrefixIter( | |||
| 242365 | 246748 | ||
| 242366 | aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); | 246749 | aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); |
| 242367 | pStruct = fts5StructureRead(p); | 246750 | pStruct = fts5StructureRead(p); |
| 246751 | assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); | ||
| 242368 | 246752 | ||
| 242369 | if( aBuf && pStruct ){ | 246753 | if( p->rc==SQLITE_OK ){ |
| 242370 | const int flags = FTS5INDEX_QUERY_SCAN | 246754 | const int flags = FTS5INDEX_QUERY_SCAN |
| 242371 | | FTS5INDEX_QUERY_SKIPEMPTY | 246755 | | FTS5INDEX_QUERY_SKIPEMPTY |
| 242372 | | FTS5INDEX_QUERY_NOOUTPUT; | 246756 | | FTS5INDEX_QUERY_NOOUTPUT; |
| @@ -242378,6 +246762,12 @@ static void fts5SetupPrefixIter( | |||
| 242378 | int bNewTerm = 1; | 246762 | int bNewTerm = 1; |
| 242379 | 246763 | ||
| 242380 | memset(&doclist, 0, sizeof(doclist)); | 246764 | memset(&doclist, 0, sizeof(doclist)); |
| 246765 | |||
| 246766 | /* If iIdx is non-zero, then it is the number of a prefix-index for | ||
| 246767 | ** prefixes 1 character longer than the prefix being queried for. That | ||
| 246768 | ** index contains all the doclists required, except for the one | ||
| 246769 | ** corresponding to the prefix itself. That one is extracted from the | ||
| 246770 | ** main term index here. */ | ||
| 242381 | if( iIdx!=0 ){ | 246771 | if( iIdx!=0 ){ |
| 242382 | int dummy = 0; | 246772 | int dummy = 0; |
| 242383 | const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; | 246773 | const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; |
| @@ -242401,6 +246791,7 @@ static void fts5SetupPrefixIter( | |||
| 242401 | pToken[0] = FTS5_MAIN_PREFIX + iIdx; | 246791 | pToken[0] = FTS5_MAIN_PREFIX + iIdx; |
| 242402 | fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); | 246792 | fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); |
| 242403 | fts5IterSetOutputCb(&p->rc, p1); | 246793 | fts5IterSetOutputCb(&p->rc, p1); |
| 246794 | |||
| 242404 | for( /* no-op */ ; | 246795 | for( /* no-op */ ; |
| 242405 | fts5MultiIterEof(p, p1)==0; | 246796 | fts5MultiIterEof(p, p1)==0; |
| 242406 | fts5MultiIterNext2(p, p1, &bNewTerm) | 246797 | fts5MultiIterNext2(p, p1, &bNewTerm) |
| @@ -242416,7 +246807,6 @@ static void fts5SetupPrefixIter( | |||
| 242416 | } | 246807 | } |
| 242417 | 246808 | ||
| 242418 | if( p1->base.nData==0 ) continue; | 246809 | if( p1->base.nData==0 ) continue; |
| 242419 | |||
| 242420 | if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ | 246810 | if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ |
| 242421 | for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ | 246811 | for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ |
| 242422 | int i1 = i*nMerge; | 246812 | int i1 = i*nMerge; |
| @@ -242455,7 +246845,7 @@ static void fts5SetupPrefixIter( | |||
| 242455 | } | 246845 | } |
| 242456 | fts5MultiIterFree(p1); | 246846 | fts5MultiIterFree(p1); |
| 242457 | 246847 | ||
| 242458 | pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING); | 246848 | pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING); |
| 242459 | if( pData ){ | 246849 | if( pData ){ |
| 242460 | pData->p = (u8*)&pData[1]; | 246850 | pData->p = (u8*)&pData[1]; |
| 242461 | pData->nn = pData->szLeaf = doclist.n; | 246851 | pData->nn = pData->szLeaf = doclist.n; |
| @@ -242598,6 +246988,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ | |||
| 242598 | sqlite3_finalize(p->pIdxWriter); | 246988 | sqlite3_finalize(p->pIdxWriter); |
| 242599 | sqlite3_finalize(p->pIdxDeleter); | 246989 | sqlite3_finalize(p->pIdxDeleter); |
| 242600 | sqlite3_finalize(p->pIdxSelect); | 246990 | sqlite3_finalize(p->pIdxSelect); |
| 246991 | sqlite3_finalize(p->pIdxNextSelect); | ||
| 242601 | sqlite3_finalize(p->pDataVersion); | 246992 | sqlite3_finalize(p->pDataVersion); |
| 242602 | sqlite3_finalize(p->pDeleteFromIdx); | 246993 | sqlite3_finalize(p->pDeleteFromIdx); |
| 242603 | sqlite3Fts5HashFree(p->pHash); | 246994 | sqlite3Fts5HashFree(p->pHash); |
| @@ -242694,6 +247085,457 @@ static int sqlite3Fts5IndexWrite( | |||
| 242694 | } | 247085 | } |
| 242695 | 247086 | ||
| 242696 | /* | 247087 | /* |
| 247088 | ** pToken points to a buffer of size nToken bytes containing a search | ||
| 247089 | ** term, including the index number at the start, used on a tokendata=1 | ||
| 247090 | ** table. This function returns true if the term in buffer pBuf matches | ||
| 247091 | ** token pToken/nToken. | ||
| 247092 | */ | ||
| 247093 | static int fts5IsTokendataPrefix( | ||
| 247094 | Fts5Buffer *pBuf, | ||
| 247095 | const u8 *pToken, | ||
| 247096 | int nToken | ||
| 247097 | ){ | ||
| 247098 | return ( | ||
| 247099 | pBuf->n>=nToken | ||
| 247100 | && 0==memcmp(pBuf->p, pToken, nToken) | ||
| 247101 | && (pBuf->n==nToken || pBuf->p[nToken]==0x00) | ||
| 247102 | ); | ||
| 247103 | } | ||
| 247104 | |||
| 247105 | /* | ||
| 247106 | ** Ensure the segment-iterator passed as the only argument points to EOF. | ||
| 247107 | */ | ||
| 247108 | static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ | ||
| 247109 | fts5DataRelease(pSeg->pLeaf); | ||
| 247110 | pSeg->pLeaf = 0; | ||
| 247111 | } | ||
| 247112 | |||
| 247113 | /* | ||
| 247114 | ** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an | ||
| 247115 | ** array of these for each row it visits. Or, for an iterator used by an | ||
| 247116 | ** "ORDER BY rank" query, it accumulates an array of these for the entire | ||
| 247117 | ** query. | ||
| 247118 | ** | ||
| 247119 | ** Each instance in the array indicates the iterator (and therefore term) | ||
| 247120 | ** associated with position iPos of rowid iRowid. This is used by the | ||
| 247121 | ** xInstToken() API. | ||
| 247122 | */ | ||
| 247123 | struct Fts5TokenDataMap { | ||
| 247124 | i64 iRowid; /* Row this token is located in */ | ||
| 247125 | i64 iPos; /* Position of token */ | ||
| 247126 | int iIter; /* Iterator token was read from */ | ||
| 247127 | }; | ||
| 247128 | |||
| 247129 | /* | ||
| 247130 | ** An object used to supplement Fts5Iter for tokendata=1 iterators. | ||
| 247131 | */ | ||
| 247132 | struct Fts5TokenDataIter { | ||
| 247133 | int nIter; | ||
| 247134 | int nIterAlloc; | ||
| 247135 | |||
| 247136 | int nMap; | ||
| 247137 | int nMapAlloc; | ||
| 247138 | Fts5TokenDataMap *aMap; | ||
| 247139 | |||
| 247140 | Fts5PoslistReader *aPoslistReader; | ||
| 247141 | int *aPoslistToIter; | ||
| 247142 | Fts5Iter *apIter[1]; | ||
| 247143 | }; | ||
| 247144 | |||
| 247145 | /* | ||
| 247146 | ** This function appends iterator pAppend to Fts5TokenDataIter pIn and | ||
| 247147 | ** returns the result. | ||
| 247148 | */ | ||
| 247149 | static Fts5TokenDataIter *fts5AppendTokendataIter( | ||
| 247150 | Fts5Index *p, /* Index object (for error code) */ | ||
| 247151 | Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */ | ||
| 247152 | Fts5Iter *pAppend /* Append this iterator */ | ||
| 247153 | ){ | ||
| 247154 | Fts5TokenDataIter *pRet = pIn; | ||
| 247155 | |||
| 247156 | if( p->rc==SQLITE_OK ){ | ||
| 247157 | if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ | ||
| 247158 | int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; | ||
| 247159 | int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); | ||
| 247160 | Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); | ||
| 247161 | |||
| 247162 | if( pNew==0 ){ | ||
| 247163 | p->rc = SQLITE_NOMEM; | ||
| 247164 | }else{ | ||
| 247165 | if( pIn==0 ) memset(pNew, 0, nByte); | ||
| 247166 | pRet = pNew; | ||
| 247167 | pNew->nIterAlloc = nAlloc; | ||
| 247168 | } | ||
| 247169 | } | ||
| 247170 | } | ||
| 247171 | if( p->rc ){ | ||
| 247172 | sqlite3Fts5IterClose((Fts5IndexIter*)pAppend); | ||
| 247173 | }else{ | ||
| 247174 | pRet->apIter[pRet->nIter++] = pAppend; | ||
| 247175 | } | ||
| 247176 | assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc ); | ||
| 247177 | |||
| 247178 | return pRet; | ||
| 247179 | } | ||
| 247180 | |||
| 247181 | /* | ||
| 247182 | ** Delete an Fts5TokenDataIter structure and its contents. | ||
| 247183 | */ | ||
| 247184 | static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ | ||
| 247185 | if( pSet ){ | ||
| 247186 | int ii; | ||
| 247187 | for(ii=0; ii<pSet->nIter; ii++){ | ||
| 247188 | fts5MultiIterFree(pSet->apIter[ii]); | ||
| 247189 | } | ||
| 247190 | sqlite3_free(pSet->aPoslistReader); | ||
| 247191 | sqlite3_free(pSet->aMap); | ||
| 247192 | sqlite3_free(pSet); | ||
| 247193 | } | ||
| 247194 | } | ||
| 247195 | |||
| 247196 | /* | ||
| 247197 | ** Append a mapping to the token-map belonging to object pT. | ||
| 247198 | */ | ||
| 247199 | static void fts5TokendataIterAppendMap( | ||
| 247200 | Fts5Index *p, | ||
| 247201 | Fts5TokenDataIter *pT, | ||
| 247202 | int iIter, | ||
| 247203 | i64 iRowid, | ||
| 247204 | i64 iPos | ||
| 247205 | ){ | ||
| 247206 | if( p->rc==SQLITE_OK ){ | ||
| 247207 | if( pT->nMap==pT->nMapAlloc ){ | ||
| 247208 | int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; | ||
| 247209 | int nByte = nNew * sizeof(Fts5TokenDataMap); | ||
| 247210 | Fts5TokenDataMap *aNew; | ||
| 247211 | |||
| 247212 | aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); | ||
| 247213 | if( aNew==0 ){ | ||
| 247214 | p->rc = SQLITE_NOMEM; | ||
| 247215 | return; | ||
| 247216 | } | ||
| 247217 | |||
| 247218 | pT->aMap = aNew; | ||
| 247219 | pT->nMapAlloc = nNew; | ||
| 247220 | } | ||
| 247221 | |||
| 247222 | pT->aMap[pT->nMap].iRowid = iRowid; | ||
| 247223 | pT->aMap[pT->nMap].iPos = iPos; | ||
| 247224 | pT->aMap[pT->nMap].iIter = iIter; | ||
| 247225 | pT->nMap++; | ||
| 247226 | } | ||
| 247227 | } | ||
| 247228 | |||
| 247229 | /* | ||
| 247230 | ** The iterator passed as the only argument must be a tokendata=1 iterator | ||
| 247231 | ** (pIter->pTokenDataIter!=0). This function sets the iterator output | ||
| 247232 | ** variables (pIter->base.*) according to the contents of the current | ||
| 247233 | ** row. | ||
| 247234 | */ | ||
| 247235 | static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ | ||
| 247236 | int ii; | ||
| 247237 | int nHit = 0; | ||
| 247238 | i64 iRowid = SMALLEST_INT64; | ||
| 247239 | int iMin = 0; | ||
| 247240 | |||
| 247241 | Fts5TokenDataIter *pT = pIter->pTokenDataIter; | ||
| 247242 | |||
| 247243 | pIter->base.nData = 0; | ||
| 247244 | pIter->base.pData = 0; | ||
| 247245 | |||
| 247246 | for(ii=0; ii<pT->nIter; ii++){ | ||
| 247247 | Fts5Iter *p = pT->apIter[ii]; | ||
| 247248 | if( p->base.bEof==0 ){ | ||
| 247249 | if( nHit==0 || p->base.iRowid<iRowid ){ | ||
| 247250 | iRowid = p->base.iRowid; | ||
| 247251 | nHit = 1; | ||
| 247252 | pIter->base.pData = p->base.pData; | ||
| 247253 | pIter->base.nData = p->base.nData; | ||
| 247254 | iMin = ii; | ||
| 247255 | }else if( p->base.iRowid==iRowid ){ | ||
| 247256 | nHit++; | ||
| 247257 | } | ||
| 247258 | } | ||
| 247259 | } | ||
| 247260 | |||
| 247261 | if( nHit==0 ){ | ||
| 247262 | pIter->base.bEof = 1; | ||
| 247263 | }else{ | ||
| 247264 | int eDetail = pIter->pIndex->pConfig->eDetail; | ||
| 247265 | pIter->base.bEof = 0; | ||
| 247266 | pIter->base.iRowid = iRowid; | ||
| 247267 | |||
| 247268 | if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ | ||
| 247269 | fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); | ||
| 247270 | }else | ||
| 247271 | if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ | ||
| 247272 | int nReader = 0; | ||
| 247273 | int nByte = 0; | ||
| 247274 | i64 iPrev = 0; | ||
| 247275 | |||
| 247276 | /* Allocate array of iterators if they are not already allocated. */ | ||
| 247277 | if( pT->aPoslistReader==0 ){ | ||
| 247278 | pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero( | ||
| 247279 | &pIter->pIndex->rc, | ||
| 247280 | pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int)) | ||
| 247281 | ); | ||
| 247282 | if( pT->aPoslistReader==0 ) return; | ||
| 247283 | pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter]; | ||
| 247284 | } | ||
| 247285 | |||
| 247286 | /* Populate an iterator for each poslist that will be merged */ | ||
| 247287 | for(ii=0; ii<pT->nIter; ii++){ | ||
| 247288 | Fts5Iter *p = pT->apIter[ii]; | ||
| 247289 | if( iRowid==p->base.iRowid ){ | ||
| 247290 | pT->aPoslistToIter[nReader] = ii; | ||
| 247291 | sqlite3Fts5PoslistReaderInit( | ||
| 247292 | p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++] | ||
| 247293 | ); | ||
| 247294 | nByte += p->base.nData; | ||
| 247295 | } | ||
| 247296 | } | ||
| 247297 | |||
| 247298 | /* Ensure the output buffer is large enough */ | ||
| 247299 | if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){ | ||
| 247300 | return; | ||
| 247301 | } | ||
| 247302 | |||
| 247303 | /* Ensure the token-mapping is large enough */ | ||
| 247304 | if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ | ||
| 247305 | int nNew = (pT->nMapAlloc + nByte) * 2; | ||
| 247306 | Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( | ||
| 247307 | pT->aMap, nNew*sizeof(Fts5TokenDataMap) | ||
| 247308 | ); | ||
| 247309 | if( aNew==0 ){ | ||
| 247310 | pIter->pIndex->rc = SQLITE_NOMEM; | ||
| 247311 | return; | ||
| 247312 | } | ||
| 247313 | pT->aMap = aNew; | ||
| 247314 | pT->nMapAlloc = nNew; | ||
| 247315 | } | ||
| 247316 | |||
| 247317 | pIter->poslist.n = 0; | ||
| 247318 | |||
| 247319 | while( 1 ){ | ||
| 247320 | i64 iMinPos = LARGEST_INT64; | ||
| 247321 | |||
| 247322 | /* Find smallest position */ | ||
| 247323 | iMin = 0; | ||
| 247324 | for(ii=0; ii<nReader; ii++){ | ||
| 247325 | Fts5PoslistReader *pReader = &pT->aPoslistReader[ii]; | ||
| 247326 | if( pReader->bEof==0 ){ | ||
| 247327 | if( pReader->iPos<iMinPos ){ | ||
| 247328 | iMinPos = pReader->iPos; | ||
| 247329 | iMin = ii; | ||
| 247330 | } | ||
| 247331 | } | ||
| 247332 | } | ||
| 247333 | |||
| 247334 | /* If all readers were at EOF, break out of the loop. */ | ||
| 247335 | if( iMinPos==LARGEST_INT64 ) break; | ||
| 247336 | |||
| 247337 | sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos); | ||
| 247338 | sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]); | ||
| 247339 | |||
| 247340 | if( eDetail==FTS5_DETAIL_FULL ){ | ||
| 247341 | pT->aMap[pT->nMap].iPos = iMinPos; | ||
| 247342 | pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin]; | ||
| 247343 | pT->aMap[pT->nMap].iRowid = iRowid; | ||
| 247344 | pT->nMap++; | ||
| 247345 | } | ||
| 247346 | } | ||
| 247347 | |||
| 247348 | pIter->base.pData = pIter->poslist.p; | ||
| 247349 | pIter->base.nData = pIter->poslist.n; | ||
| 247350 | } | ||
| 247351 | } | ||
| 247352 | } | ||
| 247353 | |||
| 247354 | /* | ||
| 247355 | ** The iterator passed as the only argument must be a tokendata=1 iterator | ||
| 247356 | ** (pIter->pTokenDataIter!=0). This function advances the iterator. If | ||
| 247357 | ** argument bFrom is false, then the iterator is advanced to the next | ||
| 247358 | ** entry. Or, if bFrom is true, it is advanced to the first entry with | ||
| 247359 | ** a rowid of iFrom or greater. | ||
| 247360 | */ | ||
| 247361 | static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){ | ||
| 247362 | int ii; | ||
| 247363 | Fts5TokenDataIter *pT = pIter->pTokenDataIter; | ||
| 247364 | Fts5Index *pIndex = pIter->pIndex; | ||
| 247365 | |||
| 247366 | for(ii=0; ii<pT->nIter; ii++){ | ||
| 247367 | Fts5Iter *p = pT->apIter[ii]; | ||
| 247368 | if( p->base.bEof==0 | ||
| 247369 | && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowid<iFrom)) | ||
| 247370 | ){ | ||
| 247371 | fts5MultiIterNext(pIndex, p, bFrom, iFrom); | ||
| 247372 | while( bFrom && p->base.bEof==0 | ||
| 247373 | && p->base.iRowid<iFrom | ||
| 247374 | && pIndex->rc==SQLITE_OK | ||
| 247375 | ){ | ||
| 247376 | fts5MultiIterNext(pIndex, p, 0, 0); | ||
| 247377 | } | ||
| 247378 | } | ||
| 247379 | } | ||
| 247380 | |||
| 247381 | if( pIndex->rc==SQLITE_OK ){ | ||
| 247382 | fts5IterSetOutputsTokendata(pIter); | ||
| 247383 | } | ||
| 247384 | } | ||
| 247385 | |||
| 247386 | /* | ||
| 247387 | ** If the segment-iterator passed as the first argument is at EOF, then | ||
| 247388 | ** set pIter->term to a copy of buffer pTerm. | ||
| 247389 | */ | ||
| 247390 | static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){ | ||
| 247391 | if( pIter && pIter->aSeg[0].pLeaf==0 ){ | ||
| 247392 | fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p); | ||
| 247393 | } | ||
| 247394 | } | ||
| 247395 | |||
| 247396 | /* | ||
| 247397 | ** This function sets up an iterator to use for a non-prefix query on a | ||
| 247398 | ** tokendata=1 table. | ||
| 247399 | */ | ||
| 247400 | static Fts5Iter *fts5SetupTokendataIter( | ||
| 247401 | Fts5Index *p, /* FTS index to query */ | ||
| 247402 | const u8 *pToken, /* Buffer containing query term */ | ||
| 247403 | int nToken, /* Size of buffer pToken in bytes */ | ||
| 247404 | Fts5Colset *pColset /* Colset to filter on */ | ||
| 247405 | ){ | ||
| 247406 | Fts5Iter *pRet = 0; | ||
| 247407 | Fts5TokenDataIter *pSet = 0; | ||
| 247408 | Fts5Structure *pStruct = 0; | ||
| 247409 | const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN; | ||
| 247410 | |||
| 247411 | Fts5Buffer bSeek = {0, 0, 0}; | ||
| 247412 | Fts5Buffer *pSmall = 0; | ||
| 247413 | |||
| 247414 | fts5IndexFlush(p); | ||
| 247415 | pStruct = fts5StructureRead(p); | ||
| 247416 | |||
| 247417 | while( p->rc==SQLITE_OK ){ | ||
| 247418 | Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0; | ||
| 247419 | Fts5Iter *pNew = 0; | ||
| 247420 | Fts5SegIter *pNewIter = 0; | ||
| 247421 | Fts5SegIter *pPrevIter = 0; | ||
| 247422 | |||
| 247423 | int iLvl, iSeg, ii; | ||
| 247424 | |||
| 247425 | pNew = fts5MultiIterAlloc(p, pStruct->nSegment); | ||
| 247426 | if( pSmall ){ | ||
| 247427 | fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); | ||
| 247428 | fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); | ||
| 247429 | }else{ | ||
| 247430 | fts5BufferSet(&p->rc, &bSeek, nToken, pToken); | ||
| 247431 | } | ||
| 247432 | if( p->rc ){ | ||
| 247433 | sqlite3Fts5IterClose((Fts5IndexIter*)pNew); | ||
| 247434 | break; | ||
| 247435 | } | ||
| 247436 | |||
| 247437 | pNewIter = &pNew->aSeg[0]; | ||
| 247438 | pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0); | ||
| 247439 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ | ||
| 247440 | for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ | ||
| 247441 | Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; | ||
| 247442 | int bDone = 0; | ||
| 247443 | |||
| 247444 | if( pPrevIter ){ | ||
| 247445 | if( fts5BufferCompare(pSmall, &pPrevIter->term) ){ | ||
| 247446 | memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter)); | ||
| 247447 | memset(pPrevIter, 0, sizeof(Fts5SegIter)); | ||
| 247448 | bDone = 1; | ||
| 247449 | }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){ | ||
| 247450 | fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter); | ||
| 247451 | bDone = 1; | ||
| 247452 | } | ||
| 247453 | } | ||
| 247454 | |||
| 247455 | if( bDone==0 ){ | ||
| 247456 | fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter); | ||
| 247457 | } | ||
| 247458 | |||
| 247459 | if( pPrevIter ){ | ||
| 247460 | if( pPrevIter->pTombArray ){ | ||
| 247461 | pNewIter->pTombArray = pPrevIter->pTombArray; | ||
| 247462 | pNewIter->pTombArray->nRef++; | ||
| 247463 | } | ||
| 247464 | }else{ | ||
| 247465 | fts5SegIterAllocTombstone(p, pNewIter); | ||
| 247466 | } | ||
| 247467 | |||
| 247468 | pNewIter++; | ||
| 247469 | if( pPrevIter ) pPrevIter++; | ||
| 247470 | if( p->rc ) break; | ||
| 247471 | } | ||
| 247472 | } | ||
| 247473 | fts5TokendataSetTermIfEof(pPrev, pSmall); | ||
| 247474 | |||
| 247475 | pNew->bSkipEmpty = 1; | ||
| 247476 | pNew->pColset = pColset; | ||
| 247477 | fts5IterSetOutputCb(&p->rc, pNew); | ||
| 247478 | |||
| 247479 | /* Loop through all segments in the new iterator. Find the smallest | ||
| 247480 | ** term that any segment-iterator points to. Iterator pNew will be | ||
| 247481 | ** used for this term. Also, set any iterator that points to a term that | ||
| 247482 | ** does not match pToken/nToken to point to EOF */ | ||
| 247483 | pSmall = 0; | ||
| 247484 | for(ii=0; ii<pNew->nSeg; ii++){ | ||
| 247485 | Fts5SegIter *pII = &pNew->aSeg[ii]; | ||
| 247486 | if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ | ||
| 247487 | fts5SegIterSetEOF(pII); | ||
| 247488 | } | ||
| 247489 | if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ | ||
| 247490 | pSmall = &pII->term; | ||
| 247491 | } | ||
| 247492 | } | ||
| 247493 | |||
| 247494 | /* If pSmall is still NULL at this point, then the new iterator does | ||
| 247495 | ** not point to any terms that match the query. So delete it and break | ||
| 247496 | ** out of the loop - all required iterators have been collected. */ | ||
| 247497 | if( pSmall==0 ){ | ||
| 247498 | sqlite3Fts5IterClose((Fts5IndexIter*)pNew); | ||
| 247499 | break; | ||
| 247500 | } | ||
| 247501 | |||
| 247502 | /* Append this iterator to the set and continue. */ | ||
| 247503 | pSet = fts5AppendTokendataIter(p, pSet, pNew); | ||
| 247504 | } | ||
| 247505 | |||
| 247506 | if( p->rc==SQLITE_OK && pSet ){ | ||
| 247507 | int ii; | ||
| 247508 | for(ii=0; ii<pSet->nIter; ii++){ | ||
| 247509 | Fts5Iter *pIter = pSet->apIter[ii]; | ||
| 247510 | int iSeg; | ||
| 247511 | for(iSeg=0; iSeg<pIter->nSeg; iSeg++){ | ||
| 247512 | pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM; | ||
| 247513 | } | ||
| 247514 | fts5MultiIterFinishSetup(p, pIter); | ||
| 247515 | } | ||
| 247516 | } | ||
| 247517 | |||
| 247518 | if( p->rc==SQLITE_OK ){ | ||
| 247519 | pRet = fts5MultiIterAlloc(p, 0); | ||
| 247520 | } | ||
| 247521 | if( pRet ){ | ||
| 247522 | pRet->pTokenDataIter = pSet; | ||
| 247523 | if( pSet ){ | ||
| 247524 | fts5IterSetOutputsTokendata(pRet); | ||
| 247525 | }else{ | ||
| 247526 | pRet->base.bEof = 1; | ||
| 247527 | } | ||
| 247528 | }else{ | ||
| 247529 | fts5TokendataIterDelete(pSet); | ||
| 247530 | } | ||
| 247531 | |||
| 247532 | fts5StructureRelease(pStruct); | ||
| 247533 | fts5BufferFree(&bSeek); | ||
| 247534 | return pRet; | ||
| 247535 | } | ||
| 247536 | |||
| 247537 | |||
| 247538 | /* | ||
| 242697 | ** Open a new iterator to iterate though all rowid that match the | 247539 | ** Open a new iterator to iterate though all rowid that match the |
| 242698 | ** specified token or token prefix. | 247540 | ** specified token or token prefix. |
| 242699 | */ | 247541 | */ |
| @@ -242714,8 +247556,13 @@ static int sqlite3Fts5IndexQuery( | |||
| 242714 | if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ | 247556 | if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ |
| 242715 | int iIdx = 0; /* Index to search */ | 247557 | int iIdx = 0; /* Index to search */ |
| 242716 | int iPrefixIdx = 0; /* +1 prefix index */ | 247558 | int iPrefixIdx = 0; /* +1 prefix index */ |
| 247559 | int bTokendata = pConfig->bTokendata; | ||
| 242717 | if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); | 247560 | if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); |
| 242718 | 247561 | ||
| 247562 | if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ | ||
| 247563 | bTokendata = 0; | ||
| 247564 | } | ||
| 247565 | |||
| 242719 | /* Figure out which index to search and set iIdx accordingly. If this | 247566 | /* Figure out which index to search and set iIdx accordingly. If this |
| 242720 | ** is a prefix query for which there is no prefix index, set iIdx to | 247567 | ** is a prefix query for which there is no prefix index, set iIdx to |
| 242721 | ** greater than pConfig->nPrefix to indicate that the query will be | 247568 | ** greater than pConfig->nPrefix to indicate that the query will be |
| @@ -242741,7 +247588,10 @@ static int sqlite3Fts5IndexQuery( | |||
| 242741 | } | 247588 | } |
| 242742 | } | 247589 | } |
| 242743 | 247590 | ||
| 242744 | if( iIdx<=pConfig->nPrefix ){ | 247591 | if( bTokendata && iIdx==0 ){ |
| 247592 | buf.p[0] = '0'; | ||
| 247593 | pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); | ||
| 247594 | }else if( iIdx<=pConfig->nPrefix ){ | ||
| 242745 | /* Straight index lookup */ | 247595 | /* Straight index lookup */ |
| 242746 | Fts5Structure *pStruct = fts5StructureRead(p); | 247596 | Fts5Structure *pStruct = fts5StructureRead(p); |
| 242747 | buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); | 247597 | buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); |
| @@ -242788,7 +247638,11 @@ static int sqlite3Fts5IndexQuery( | |||
| 242788 | static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ | 247638 | static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ |
| 242789 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | 247639 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; |
| 242790 | assert( pIter->pIndex->rc==SQLITE_OK ); | 247640 | assert( pIter->pIndex->rc==SQLITE_OK ); |
| 242791 | fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); | 247641 | if( pIter->pTokenDataIter ){ |
| 247642 | fts5TokendataIterNext(pIter, 0, 0); | ||
| 247643 | }else{ | ||
| 247644 | fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); | ||
| 247645 | } | ||
| 242792 | return fts5IndexReturn(pIter->pIndex); | 247646 | return fts5IndexReturn(pIter->pIndex); |
| 242793 | } | 247647 | } |
| 242794 | 247648 | ||
| @@ -242821,7 +247675,11 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ | |||
| 242821 | */ | 247675 | */ |
| 242822 | static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ | 247676 | static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ |
| 242823 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | 247677 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; |
| 242824 | fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); | 247678 | if( pIter->pTokenDataIter ){ |
| 247679 | fts5TokendataIterNext(pIter, 1, iMatch); | ||
| 247680 | }else{ | ||
| 247681 | fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); | ||
| 247682 | } | ||
| 242825 | return fts5IndexReturn(pIter->pIndex); | 247683 | return fts5IndexReturn(pIter->pIndex); |
| 242826 | } | 247684 | } |
| 242827 | 247685 | ||
| @@ -242837,12 +247695,106 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ | |||
| 242837 | } | 247695 | } |
| 242838 | 247696 | ||
| 242839 | /* | 247697 | /* |
| 247698 | ** This is used by xInstToken() to access the token at offset iOff, column | ||
| 247699 | ** iCol of row iRowid. The token is returned via output variables *ppOut | ||
| 247700 | ** and *pnOut. The iterator passed as the first argument must be a tokendata=1 | ||
| 247701 | ** iterator (pIter->pTokenDataIter!=0). | ||
| 247702 | */ | ||
| 247703 | static int sqlite3Fts5IterToken( | ||
| 247704 | Fts5IndexIter *pIndexIter, | ||
| 247705 | i64 iRowid, | ||
| 247706 | int iCol, | ||
| 247707 | int iOff, | ||
| 247708 | const char **ppOut, int *pnOut | ||
| 247709 | ){ | ||
| 247710 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | ||
| 247711 | Fts5TokenDataIter *pT = pIter->pTokenDataIter; | ||
| 247712 | Fts5TokenDataMap *aMap = pT->aMap; | ||
| 247713 | i64 iPos = (((i64)iCol)<<32) + iOff; | ||
| 247714 | |||
| 247715 | int i1 = 0; | ||
| 247716 | int i2 = pT->nMap; | ||
| 247717 | int iTest = 0; | ||
| 247718 | |||
| 247719 | while( i2>i1 ){ | ||
| 247720 | iTest = (i1 + i2) / 2; | ||
| 247721 | |||
| 247722 | if( aMap[iTest].iRowid<iRowid ){ | ||
| 247723 | i1 = iTest+1; | ||
| 247724 | }else if( aMap[iTest].iRowid>iRowid ){ | ||
| 247725 | i2 = iTest; | ||
| 247726 | }else{ | ||
| 247727 | if( aMap[iTest].iPos<iPos ){ | ||
| 247728 | if( aMap[iTest].iPos<0 ){ | ||
| 247729 | break; | ||
| 247730 | } | ||
| 247731 | i1 = iTest+1; | ||
| 247732 | }else if( aMap[iTest].iPos>iPos ){ | ||
| 247733 | i2 = iTest; | ||
| 247734 | }else{ | ||
| 247735 | break; | ||
| 247736 | } | ||
| 247737 | } | ||
| 247738 | } | ||
| 247739 | |||
| 247740 | if( i2>i1 ){ | ||
| 247741 | Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; | ||
| 247742 | *ppOut = (const char*)pMap->aSeg[0].term.p+1; | ||
| 247743 | *pnOut = pMap->aSeg[0].term.n-1; | ||
| 247744 | } | ||
| 247745 | |||
| 247746 | return SQLITE_OK; | ||
| 247747 | } | ||
| 247748 | |||
| 247749 | /* | ||
| 247750 | ** Clear any existing entries from the token-map associated with the | ||
| 247751 | ** iterator passed as the only argument. | ||
| 247752 | */ | ||
| 247753 | static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ | ||
| 247754 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | ||
| 247755 | if( pIter && pIter->pTokenDataIter ){ | ||
| 247756 | pIter->pTokenDataIter->nMap = 0; | ||
| 247757 | } | ||
| 247758 | } | ||
| 247759 | |||
| 247760 | /* | ||
| 247761 | ** Set a token-mapping for the iterator passed as the first argument. This | ||
| 247762 | ** is used in detail=column or detail=none mode when a token is requested | ||
| 247763 | ** using the xInstToken() API. In this case the caller tokenizers the | ||
| 247764 | ** current row and configures the token-mapping via multiple calls to this | ||
| 247765 | ** function. | ||
| 247766 | */ | ||
| 247767 | static int sqlite3Fts5IndexIterWriteTokendata( | ||
| 247768 | Fts5IndexIter *pIndexIter, | ||
| 247769 | const char *pToken, int nToken, | ||
| 247770 | i64 iRowid, int iCol, int iOff | ||
| 247771 | ){ | ||
| 247772 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | ||
| 247773 | Fts5TokenDataIter *pT = pIter->pTokenDataIter; | ||
| 247774 | Fts5Index *p = pIter->pIndex; | ||
| 247775 | int ii; | ||
| 247776 | |||
| 247777 | assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); | ||
| 247778 | assert( pIter->pTokenDataIter ); | ||
| 247779 | |||
| 247780 | for(ii=0; ii<pT->nIter; ii++){ | ||
| 247781 | Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; | ||
| 247782 | if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; | ||
| 247783 | } | ||
| 247784 | if( ii<pT->nIter ){ | ||
| 247785 | fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); | ||
| 247786 | } | ||
| 247787 | return fts5IndexReturn(p); | ||
| 247788 | } | ||
| 247789 | |||
| 247790 | /* | ||
| 242840 | ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). | 247791 | ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). |
| 242841 | */ | 247792 | */ |
| 242842 | static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ | 247793 | static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ |
| 242843 | if( pIndexIter ){ | 247794 | if( pIndexIter ){ |
| 242844 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; | 247795 | Fts5Iter *pIter = (Fts5Iter*)pIndexIter; |
| 242845 | Fts5Index *pIndex = pIter->pIndex; | 247796 | Fts5Index *pIndex = pIter->pIndex; |
| 247797 | fts5TokendataIterDelete(pIter->pTokenDataIter); | ||
| 242846 | fts5MultiIterFree(pIter); | 247798 | fts5MultiIterFree(pIter); |
| 242847 | sqlite3Fts5IndexCloseReader(pIndex); | 247799 | sqlite3Fts5IndexCloseReader(pIndex); |
| 242848 | } | 247800 | } |
| @@ -243350,7 +248302,9 @@ static int fts5QueryCksum( | |||
| 243350 | int eDetail = p->pConfig->eDetail; | 248302 | int eDetail = p->pConfig->eDetail; |
| 243351 | u64 cksum = *pCksum; | 248303 | u64 cksum = *pCksum; |
| 243352 | Fts5IndexIter *pIter = 0; | 248304 | Fts5IndexIter *pIter = 0; |
| 243353 | int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); | 248305 | int rc = sqlite3Fts5IndexQuery( |
| 248306 | p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter | ||
| 248307 | ); | ||
| 243354 | 248308 | ||
| 243355 | while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ | 248309 | while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ |
| 243356 | i64 rowid = pIter->iRowid; | 248310 | i64 rowid = pIter->iRowid; |
| @@ -243517,7 +248471,7 @@ static void fts5IndexIntegrityCheckEmpty( | |||
| 243517 | } | 248471 | } |
| 243518 | 248472 | ||
| 243519 | static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ | 248473 | static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ |
| 243520 | int iTermOff = 0; | 248474 | i64 iTermOff = 0; |
| 243521 | int ii; | 248475 | int ii; |
| 243522 | 248476 | ||
| 243523 | Fts5Buffer buf1 = {0,0,0}; | 248477 | Fts5Buffer buf1 = {0,0,0}; |
| @@ -243526,7 +248480,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ | |||
| 243526 | ii = pLeaf->szLeaf; | 248480 | ii = pLeaf->szLeaf; |
| 243527 | while( ii<pLeaf->nn && p->rc==SQLITE_OK ){ | 248481 | while( ii<pLeaf->nn && p->rc==SQLITE_OK ){ |
| 243528 | int res; | 248482 | int res; |
| 243529 | int iOff; | 248483 | i64 iOff; |
| 243530 | int nIncr; | 248484 | int nIncr; |
| 243531 | 248485 | ||
| 243532 | ii += fts5GetVarint32(&pLeaf->p[ii], nIncr); | 248486 | ii += fts5GetVarint32(&pLeaf->p[ii], nIncr); |
| @@ -244049,6 +249003,24 @@ static void fts5DecodeRowidList( | |||
| 244049 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ | 249003 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 244050 | 249004 | ||
| 244051 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) | 249005 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 249006 | static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){ | ||
| 249007 | int ii; | ||
| 249008 | fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1); | ||
| 249009 | if( *pRc==SQLITE_OK ){ | ||
| 249010 | for(ii=0; ii<pTerm->n; ii++){ | ||
| 249011 | if( pTerm->p[ii]==0x00 ){ | ||
| 249012 | pBuf->p[pBuf->n++] = '\\'; | ||
| 249013 | pBuf->p[pBuf->n++] = '0'; | ||
| 249014 | }else{ | ||
| 249015 | pBuf->p[pBuf->n++] = pTerm->p[ii]; | ||
| 249016 | } | ||
| 249017 | } | ||
| 249018 | pBuf->p[pBuf->n] = 0x00; | ||
| 249019 | } | ||
| 249020 | } | ||
| 249021 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ | ||
| 249022 | |||
| 249023 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) | ||
| 244052 | /* | 249024 | /* |
| 244053 | ** The implementation of user-defined scalar function fts5_decode(). | 249025 | ** The implementation of user-defined scalar function fts5_decode(). |
| 244054 | */ | 249026 | */ |
| @@ -244155,9 +249127,8 @@ static void fts5DecodeFunction( | |||
| 244155 | iOff += fts5GetVarint32(&a[iOff], nAppend); | 249127 | iOff += fts5GetVarint32(&a[iOff], nAppend); |
| 244156 | term.n = nKeep; | 249128 | term.n = nKeep; |
| 244157 | fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); | 249129 | fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); |
| 244158 | sqlite3Fts5BufferAppendPrintf( | 249130 | sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); |
| 244159 | &rc, &s, " term=%.*s", term.n, (const char*)term.p | 249131 | fts5BufferAppendTerm(&rc, &s, &term); |
| 244160 | ); | ||
| 244161 | iOff += nAppend; | 249132 | iOff += nAppend; |
| 244162 | 249133 | ||
| 244163 | /* Figure out where the doclist for this term ends */ | 249134 | /* Figure out where the doclist for this term ends */ |
| @@ -244265,9 +249236,8 @@ static void fts5DecodeFunction( | |||
| 244265 | fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); | 249236 | fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); |
| 244266 | iOff += nByte; | 249237 | iOff += nByte; |
| 244267 | 249238 | ||
| 244268 | sqlite3Fts5BufferAppendPrintf( | 249239 | sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); |
| 244269 | &rc, &s, " term=%.*s", term.n, (const char*)term.p | 249240 | fts5BufferAppendTerm(&rc, &s, &term); |
| 244270 | ); | ||
| 244271 | iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); | 249241 | iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); |
| 244272 | } | 249242 | } |
| 244273 | 249243 | ||
| @@ -244742,7 +249712,7 @@ struct Fts5FullTable { | |||
| 244742 | Fts5Global *pGlobal; /* Global (connection wide) data */ | 249712 | Fts5Global *pGlobal; /* Global (connection wide) data */ |
| 244743 | Fts5Cursor *pSortCsr; /* Sort data from this cursor */ | 249713 | Fts5Cursor *pSortCsr; /* Sort data from this cursor */ |
| 244744 | int iSavepoint; /* Successful xSavepoint()+1 */ | 249714 | int iSavepoint; /* Successful xSavepoint()+1 */ |
| 244745 | int bInSavepoint; | 249715 | |
| 244746 | #ifdef SQLITE_DEBUG | 249716 | #ifdef SQLITE_DEBUG |
| 244747 | struct Fts5TransactionState ts; | 249717 | struct Fts5TransactionState ts; |
| 244748 | #endif | 249718 | #endif |
| @@ -245280,12 +250250,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ | |||
| 245280 | } | 250250 | } |
| 245281 | idxStr[iIdxStr] = '\0'; | 250251 | idxStr[iIdxStr] = '\0'; |
| 245282 | 250252 | ||
| 245283 | /* Set idxFlags flags for the ORDER BY clause */ | 250253 | /* Set idxFlags flags for the ORDER BY clause |
| 250254 | ** | ||
| 250255 | ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". | ||
| 250256 | */ | ||
| 245284 | if( pInfo->nOrderBy==1 ){ | 250257 | if( pInfo->nOrderBy==1 ){ |
| 245285 | int iSort = pInfo->aOrderBy[0].iColumn; | 250258 | int iSort = pInfo->aOrderBy[0].iColumn; |
| 245286 | if( iSort==(pConfig->nCol+1) && bSeenMatch ){ | 250259 | if( iSort==(pConfig->nCol+1) && bSeenMatch ){ |
| 245287 | idxFlags |= FTS5_BI_ORDER_RANK; | 250260 | idxFlags |= FTS5_BI_ORDER_RANK; |
| 245288 | }else if( iSort==-1 ){ | 250261 | }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ |
| 245289 | idxFlags |= FTS5_BI_ORDER_ROWID; | 250262 | idxFlags |= FTS5_BI_ORDER_ROWID; |
| 245290 | } | 250263 | } |
| 245291 | if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ | 250264 | if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ |
| @@ -245537,6 +250510,16 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ | |||
| 245537 | ); | 250510 | ); |
| 245538 | assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); | 250511 | assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); |
| 245539 | 250512 | ||
| 250513 | /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table, | ||
| 250514 | ** clear any token mappings accumulated at the fts5_index.c level. In | ||
| 250515 | ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH, | ||
| 250516 | ** we need to retain the mappings for the entire query. */ | ||
| 250517 | if( pCsr->ePlan==FTS5_PLAN_MATCH | ||
| 250518 | && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata | ||
| 250519 | ){ | ||
| 250520 | sqlite3Fts5ExprClearTokens(pCsr->pExpr); | ||
| 250521 | } | ||
| 250522 | |||
| 245540 | if( pCsr->ePlan<3 ){ | 250523 | if( pCsr->ePlan<3 ){ |
| 245541 | int bSkip = 0; | 250524 | int bSkip = 0; |
| 245542 | if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; | 250525 | if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; |
| @@ -246197,7 +251180,10 @@ static int fts5SpecialInsert( | |||
| 246197 | }else if( 0==sqlite3_stricmp("flush", zCmd) ){ | 251180 | }else if( 0==sqlite3_stricmp("flush", zCmd) ){ |
| 246198 | rc = sqlite3Fts5FlushToDisk(&pTab->p); | 251181 | rc = sqlite3Fts5FlushToDisk(&pTab->p); |
| 246199 | }else{ | 251182 | }else{ |
| 246200 | rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); | 251183 | rc = sqlite3Fts5FlushToDisk(&pTab->p); |
| 251184 | if( rc==SQLITE_OK ){ | ||
| 251185 | rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); | ||
| 251186 | } | ||
| 246201 | if( rc==SQLITE_OK ){ | 251187 | if( rc==SQLITE_OK ){ |
| 246202 | rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); | 251188 | rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); |
| 246203 | } | 251189 | } |
| @@ -246308,6 +251294,7 @@ static int fts5UpdateMethod( | |||
| 246308 | rc = SQLITE_ERROR; | 251294 | rc = SQLITE_ERROR; |
| 246309 | }else{ | 251295 | }else{ |
| 246310 | rc = fts5SpecialDelete(pTab, apVal); | 251296 | rc = fts5SpecialDelete(pTab, apVal); |
| 251297 | bUpdateOrDelete = 1; | ||
| 246311 | } | 251298 | } |
| 246312 | }else{ | 251299 | }else{ |
| 246313 | rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); | 251300 | rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); |
| @@ -246522,7 +251509,10 @@ static int fts5ApiColumnText( | |||
| 246522 | ){ | 251509 | ){ |
| 246523 | int rc = SQLITE_OK; | 251510 | int rc = SQLITE_OK; |
| 246524 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | 251511 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; |
| 246525 | if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) | 251512 | Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); |
| 251513 | if( iCol<0 || iCol>=pTab->pConfig->nCol ){ | ||
| 251514 | rc = SQLITE_RANGE; | ||
| 251515 | }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) | ||
| 246526 | || pCsr->ePlan==FTS5_PLAN_SPECIAL | 251516 | || pCsr->ePlan==FTS5_PLAN_SPECIAL |
| 246527 | ){ | 251517 | ){ |
| 246528 | *pz = 0; | 251518 | *pz = 0; |
| @@ -246547,8 +251537,9 @@ static int fts5CsrPoslist( | |||
| 246547 | int rc = SQLITE_OK; | 251537 | int rc = SQLITE_OK; |
| 246548 | int bLive = (pCsr->pSorter==0); | 251538 | int bLive = (pCsr->pSorter==0); |
| 246549 | 251539 | ||
| 246550 | if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ | 251540 | if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ |
| 246551 | 251541 | rc = SQLITE_RANGE; | |
| 251542 | }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ | ||
| 246552 | if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ | 251543 | if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ |
| 246553 | Fts5PoslistPopulator *aPopulator; | 251544 | Fts5PoslistPopulator *aPopulator; |
| 246554 | int i; | 251545 | int i; |
| @@ -246572,15 +251563,21 @@ static int fts5CsrPoslist( | |||
| 246572 | CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); | 251563 | CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); |
| 246573 | } | 251564 | } |
| 246574 | 251565 | ||
| 246575 | if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ | 251566 | if( rc==SQLITE_OK ){ |
| 246576 | Fts5Sorter *pSorter = pCsr->pSorter; | 251567 | if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ |
| 246577 | int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); | 251568 | Fts5Sorter *pSorter = pCsr->pSorter; |
| 246578 | *pn = pSorter->aIdx[iPhrase] - i1; | 251569 | int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); |
| 246579 | *pa = &pSorter->aPoslist[i1]; | 251570 | *pn = pSorter->aIdx[iPhrase] - i1; |
| 251571 | *pa = &pSorter->aPoslist[i1]; | ||
| 251572 | }else{ | ||
| 251573 | *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); | ||
| 251574 | } | ||
| 246580 | }else{ | 251575 | }else{ |
| 246581 | *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); | 251576 | *pa = 0; |
| 251577 | *pn = 0; | ||
| 246582 | } | 251578 | } |
| 246583 | 251579 | ||
| 251580 | |||
| 246584 | return rc; | 251581 | return rc; |
| 246585 | } | 251582 | } |
| 246586 | 251583 | ||
| @@ -246687,12 +251684,6 @@ static int fts5ApiInst( | |||
| 246687 | ){ | 251684 | ){ |
| 246688 | if( iIdx<0 || iIdx>=pCsr->nInstCount ){ | 251685 | if( iIdx<0 || iIdx>=pCsr->nInstCount ){ |
| 246689 | rc = SQLITE_RANGE; | 251686 | rc = SQLITE_RANGE; |
| 246690 | #if 0 | ||
| 246691 | }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){ | ||
| 246692 | *piPhrase = pCsr->aInst[iIdx*3]; | ||
| 246693 | *piCol = pCsr->aInst[iIdx*3 + 2]; | ||
| 246694 | *piOff = -1; | ||
| 246695 | #endif | ||
| 246696 | }else{ | 251687 | }else{ |
| 246697 | *piPhrase = pCsr->aInst[iIdx*3]; | 251688 | *piPhrase = pCsr->aInst[iIdx*3]; |
| 246698 | *piCol = pCsr->aInst[iIdx*3 + 1]; | 251689 | *piCol = pCsr->aInst[iIdx*3 + 1]; |
| @@ -246947,13 +251938,56 @@ static int fts5ApiPhraseFirstColumn( | |||
| 246947 | return rc; | 251938 | return rc; |
| 246948 | } | 251939 | } |
| 246949 | 251940 | ||
| 251941 | /* | ||
| 251942 | ** xQueryToken() API implemenetation. | ||
| 251943 | */ | ||
| 251944 | static int fts5ApiQueryToken( | ||
| 251945 | Fts5Context* pCtx, | ||
| 251946 | int iPhrase, | ||
| 251947 | int iToken, | ||
| 251948 | const char **ppOut, | ||
| 251949 | int *pnOut | ||
| 251950 | ){ | ||
| 251951 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | ||
| 251952 | return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut); | ||
| 251953 | } | ||
| 251954 | |||
| 251955 | /* | ||
| 251956 | ** xInstToken() API implemenetation. | ||
| 251957 | */ | ||
| 251958 | static int fts5ApiInstToken( | ||
| 251959 | Fts5Context *pCtx, | ||
| 251960 | int iIdx, | ||
| 251961 | int iToken, | ||
| 251962 | const char **ppOut, int *pnOut | ||
| 251963 | ){ | ||
| 251964 | Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; | ||
| 251965 | int rc = SQLITE_OK; | ||
| 251966 | if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 | ||
| 251967 | || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) | ||
| 251968 | ){ | ||
| 251969 | if( iIdx<0 || iIdx>=pCsr->nInstCount ){ | ||
| 251970 | rc = SQLITE_RANGE; | ||
| 251971 | }else{ | ||
| 251972 | int iPhrase = pCsr->aInst[iIdx*3]; | ||
| 251973 | int iCol = pCsr->aInst[iIdx*3 + 1]; | ||
| 251974 | int iOff = pCsr->aInst[iIdx*3 + 2]; | ||
| 251975 | i64 iRowid = fts5CursorRowid(pCsr); | ||
| 251976 | rc = sqlite3Fts5ExprInstToken( | ||
| 251977 | pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut | ||
| 251978 | ); | ||
| 251979 | } | ||
| 251980 | } | ||
| 251981 | return rc; | ||
| 251982 | } | ||
| 251983 | |||
| 246950 | 251984 | ||
| 246951 | static int fts5ApiQueryPhrase(Fts5Context*, int, void*, | 251985 | static int fts5ApiQueryPhrase(Fts5Context*, int, void*, |
| 246952 | int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) | 251986 | int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) |
| 246953 | ); | 251987 | ); |
| 246954 | 251988 | ||
| 246955 | static const Fts5ExtensionApi sFts5Api = { | 251989 | static const Fts5ExtensionApi sFts5Api = { |
| 246956 | 2, /* iVersion */ | 251990 | 3, /* iVersion */ |
| 246957 | fts5ApiUserData, | 251991 | fts5ApiUserData, |
| 246958 | fts5ApiColumnCount, | 251992 | fts5ApiColumnCount, |
| 246959 | fts5ApiRowCount, | 251993 | fts5ApiRowCount, |
| @@ -246973,6 +252007,8 @@ static const Fts5ExtensionApi sFts5Api = { | |||
| 246973 | fts5ApiPhraseNext, | 252007 | fts5ApiPhraseNext, |
| 246974 | fts5ApiPhraseFirstColumn, | 252008 | fts5ApiPhraseFirstColumn, |
| 246975 | fts5ApiPhraseNextColumn, | 252009 | fts5ApiPhraseNextColumn, |
| 252010 | fts5ApiQueryToken, | ||
| 252011 | fts5ApiInstToken | ||
| 246976 | }; | 252012 | }; |
| 246977 | 252013 | ||
| 246978 | /* | 252014 | /* |
| @@ -247239,9 +252275,7 @@ static int fts5RenameMethod( | |||
| 247239 | ){ | 252275 | ){ |
| 247240 | int rc; | 252276 | int rc; |
| 247241 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; | 252277 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; |
| 247242 | pTab->bInSavepoint = 1; | ||
| 247243 | rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); | 252278 | rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); |
| 247244 | pTab->bInSavepoint = 0; | ||
| 247245 | return rc; | 252279 | return rc; |
| 247246 | } | 252280 | } |
| 247247 | 252281 | ||
| @@ -247258,26 +252292,12 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ | |||
| 247258 | static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ | 252292 | static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 247259 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; | 252293 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; |
| 247260 | int rc = SQLITE_OK; | 252294 | int rc = SQLITE_OK; |
| 247261 | char *zSql = 0; | ||
| 247262 | fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); | ||
| 247263 | 252295 | ||
| 247264 | if( pTab->bInSavepoint==0 ){ | 252296 | fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); |
| 247265 | zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", | 252297 | rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); |
| 247266 | pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName | 252298 | if( rc==SQLITE_OK ){ |
| 247267 | ); | 252299 | pTab->iSavepoint = iSavepoint+1; |
| 247268 | if( zSql ){ | ||
| 247269 | pTab->bInSavepoint = 1; | ||
| 247270 | rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); | ||
| 247271 | pTab->bInSavepoint = 0; | ||
| 247272 | sqlite3_free(zSql); | ||
| 247273 | }else{ | ||
| 247274 | rc = SQLITE_NOMEM; | ||
| 247275 | } | ||
| 247276 | if( rc==SQLITE_OK ){ | ||
| 247277 | pTab->iSavepoint = iSavepoint+1; | ||
| 247278 | } | ||
| 247279 | } | 252300 | } |
| 247280 | |||
| 247281 | return rc; | 252301 | return rc; |
| 247282 | } | 252302 | } |
| 247283 | 252303 | ||
| @@ -247309,8 +252329,8 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ | |||
| 247309 | int rc = SQLITE_OK; | 252329 | int rc = SQLITE_OK; |
| 247310 | fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); | 252330 | fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); |
| 247311 | fts5TripCursors(pTab); | 252331 | fts5TripCursors(pTab); |
| 247312 | pTab->p.pConfig->pgsz = 0; | ||
| 247313 | if( (iSavepoint+1)<=pTab->iSavepoint ){ | 252332 | if( (iSavepoint+1)<=pTab->iSavepoint ){ |
| 252333 | pTab->p.pConfig->pgsz = 0; | ||
| 247314 | rc = sqlite3Fts5StorageRollback(pTab->pStorage); | 252334 | rc = sqlite3Fts5StorageRollback(pTab->pStorage); |
| 247315 | } | 252335 | } |
| 247316 | return rc; | 252336 | return rc; |
| @@ -247449,14 +252469,16 @@ static int sqlite3Fts5GetTokenizer( | |||
| 247449 | if( pMod==0 ){ | 252469 | if( pMod==0 ){ |
| 247450 | assert( nArg>0 ); | 252470 | assert( nArg>0 ); |
| 247451 | rc = SQLITE_ERROR; | 252471 | rc = SQLITE_ERROR; |
| 247452 | *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); | 252472 | if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); |
| 247453 | }else{ | 252473 | }else{ |
| 247454 | rc = pMod->x.xCreate( | 252474 | rc = pMod->x.xCreate( |
| 247455 | pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok | 252475 | pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok |
| 247456 | ); | 252476 | ); |
| 247457 | pConfig->pTokApi = &pMod->x; | 252477 | pConfig->pTokApi = &pMod->x; |
| 247458 | if( rc!=SQLITE_OK ){ | 252478 | if( rc!=SQLITE_OK ){ |
| 247459 | if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); | 252479 | if( pzErr && rc!=SQLITE_NOMEM ){ |
| 252480 | *pzErr = sqlite3_mprintf("error in tokenizer constructor"); | ||
| 252481 | } | ||
| 247460 | }else{ | 252482 | }else{ |
| 247461 | pConfig->ePattern = sqlite3Fts5TokenizerPattern( | 252483 | pConfig->ePattern = sqlite3Fts5TokenizerPattern( |
| 247462 | pMod->x.xCreate, pConfig->pTok | 252484 | pMod->x.xCreate, pConfig->pTok |
| @@ -247515,7 +252537,7 @@ static void fts5SourceIdFunc( | |||
| 247515 | ){ | 252537 | ){ |
| 247516 | assert( nArg==0 ); | 252538 | assert( nArg==0 ); |
| 247517 | UNUSED_PARAM2(nArg, apUnused); | 252539 | UNUSED_PARAM2(nArg, apUnused); |
| 247518 | sqlite3_result_text(pCtx, "fts5: 2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301", -1, SQLITE_TRANSIENT); | 252540 | sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT); |
| 247519 | } | 252541 | } |
| 247520 | 252542 | ||
| 247521 | /* | 252543 | /* |
| @@ -247538,7 +252560,7 @@ static int fts5ShadowName(const char *zName){ | |||
| 247538 | ** if anything is found amiss. Return a NULL pointer if everything is | 252560 | ** if anything is found amiss. Return a NULL pointer if everything is |
| 247539 | ** OK. | 252561 | ** OK. |
| 247540 | */ | 252562 | */ |
| 247541 | static int fts5Integrity( | 252563 | static int fts5IntegrityMethod( |
| 247542 | sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ | 252564 | sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ |
| 247543 | const char *zSchema, /* Name of schema in which this table lives */ | 252565 | const char *zSchema, /* Name of schema in which this table lives */ |
| 247544 | const char *zTabname, /* Name of the table itself */ | 252566 | const char *zTabname, /* Name of the table itself */ |
| @@ -247546,28 +252568,29 @@ static int fts5Integrity( | |||
| 247546 | char **pzErr /* Write error message here */ | 252568 | char **pzErr /* Write error message here */ |
| 247547 | ){ | 252569 | ){ |
| 247548 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; | 252570 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; |
| 247549 | Fts5Config *pConfig = pTab->p.pConfig; | ||
| 247550 | char *zSql; | ||
| 247551 | char *zErr = 0; | ||
| 247552 | int rc; | 252571 | int rc; |
| 252572 | |||
| 247553 | assert( pzErr!=0 && *pzErr==0 ); | 252573 | assert( pzErr!=0 && *pzErr==0 ); |
| 247554 | UNUSED_PARAM(isQuick); | 252574 | UNUSED_PARAM(isQuick); |
| 247555 | zSql = sqlite3_mprintf( | 252575 | assert( pTab->p.pConfig->pzErrmsg==0 ); |
| 247556 | "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", | 252576 | pTab->p.pConfig->pzErrmsg = pzErr; |
| 247557 | zSchema, zTabname, pConfig->zName); | 252577 | rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); |
| 247558 | if( zSql==0 ) return SQLITE_NOMEM; | 252578 | if( *pzErr==0 && rc!=SQLITE_OK ){ |
| 247559 | rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); | 252579 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 247560 | sqlite3_free(zSql); | 252580 | *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", |
| 247561 | if( (rc&0xff)==SQLITE_CORRUPT ){ | 252581 | zSchema, zTabname); |
| 247562 | *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", | 252582 | rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; |
| 247563 | zSchema, zTabname); | 252583 | }else{ |
| 247564 | }else if( rc!=SQLITE_OK ){ | 252584 | *pzErr = sqlite3_mprintf("unable to validate the inverted index for" |
| 247565 | *pzErr = sqlite3_mprintf("unable to validate the inverted index for" | 252585 | " FTS5 table %s.%s: %s", |
| 247566 | " FTS5 table %s.%s: %s", | 252586 | zSchema, zTabname, sqlite3_errstr(rc)); |
| 247567 | zSchema, zTabname, zErr); | 252587 | } |
| 247568 | } | 252588 | } |
| 247569 | sqlite3_free(zErr); | 252589 | |
| 247570 | return SQLITE_OK; | 252590 | sqlite3Fts5IndexCloseReader(pTab->p.pIndex); |
| 252591 | pTab->p.pConfig->pzErrmsg = 0; | ||
| 252592 | |||
| 252593 | return rc; | ||
| 247571 | } | 252594 | } |
| 247572 | 252595 | ||
| 247573 | static int fts5Init(sqlite3 *db){ | 252596 | static int fts5Init(sqlite3 *db){ |
| @@ -247596,7 +252619,7 @@ static int fts5Init(sqlite3 *db){ | |||
| 247596 | /* xRelease */ fts5ReleaseMethod, | 252619 | /* xRelease */ fts5ReleaseMethod, |
| 247597 | /* xRollbackTo */ fts5RollbackToMethod, | 252620 | /* xRollbackTo */ fts5RollbackToMethod, |
| 247598 | /* xShadowName */ fts5ShadowName, | 252621 | /* xShadowName */ fts5ShadowName, |
| 247599 | /* xIntegrity */ fts5Integrity | 252622 | /* xIntegrity */ fts5IntegrityMethod |
| 247600 | }; | 252623 | }; |
| 247601 | 252624 | ||
| 247602 | int rc; | 252625 | int rc; |
| @@ -248362,7 +253385,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ | |||
| 248362 | } | 253385 | } |
| 248363 | 253386 | ||
| 248364 | if( rc==SQLITE_OK ){ | 253387 | if( rc==SQLITE_OK ){ |
| 248365 | rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); | 253388 | rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg); |
| 248366 | } | 253389 | } |
| 248367 | 253390 | ||
| 248368 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ | 253391 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ |
| @@ -248999,7 +254022,7 @@ static int fts5AsciiCreate( | |||
| 248999 | int i; | 254022 | int i; |
| 249000 | memset(p, 0, sizeof(AsciiTokenizer)); | 254023 | memset(p, 0, sizeof(AsciiTokenizer)); |
| 249001 | memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); | 254024 | memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); |
| 249002 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ | 254025 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ |
| 249003 | const char *zArg = azArg[i+1]; | 254026 | const char *zArg = azArg[i+1]; |
| 249004 | if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ | 254027 | if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ |
| 249005 | fts5AsciiAddExceptions(p, zArg, 1); | 254028 | fts5AsciiAddExceptions(p, zArg, 1); |
| @@ -249010,6 +254033,7 @@ static int fts5AsciiCreate( | |||
| 249010 | rc = SQLITE_ERROR; | 254033 | rc = SQLITE_ERROR; |
| 249011 | } | 254034 | } |
| 249012 | } | 254035 | } |
| 254036 | if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR; | ||
| 249013 | if( rc!=SQLITE_OK ){ | 254037 | if( rc!=SQLITE_OK ){ |
| 249014 | fts5AsciiDelete((Fts5Tokenizer*)p); | 254038 | fts5AsciiDelete((Fts5Tokenizer*)p); |
| 249015 | p = 0; | 254039 | p = 0; |
| @@ -249149,6 +254173,12 @@ static const unsigned char sqlite3Utf8Trans1[] = { | |||
| 249149 | 254173 | ||
| 249150 | #endif /* ifndef SQLITE_AMALGAMATION */ | 254174 | #endif /* ifndef SQLITE_AMALGAMATION */ |
| 249151 | 254175 | ||
| 254176 | #define FTS5_SKIP_UTF8(zIn) { \ | ||
| 254177 | if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ | ||
| 254178 | while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \ | ||
| 254179 | } \ | ||
| 254180 | } | ||
| 254181 | |||
| 249152 | typedef struct Unicode61Tokenizer Unicode61Tokenizer; | 254182 | typedef struct Unicode61Tokenizer Unicode61Tokenizer; |
| 249153 | struct Unicode61Tokenizer { | 254183 | struct Unicode61Tokenizer { |
| 249154 | unsigned char aTokenChar[128]; /* ASCII range token characters */ | 254184 | unsigned char aTokenChar[128]; /* ASCII range token characters */ |
| @@ -249295,17 +254325,16 @@ static int fts5UnicodeCreate( | |||
| 249295 | } | 254325 | } |
| 249296 | 254326 | ||
| 249297 | /* Search for a "categories" argument */ | 254327 | /* Search for a "categories" argument */ |
| 249298 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ | 254328 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ |
| 249299 | if( 0==sqlite3_stricmp(azArg[i], "categories") ){ | 254329 | if( 0==sqlite3_stricmp(azArg[i], "categories") ){ |
| 249300 | zCat = azArg[i+1]; | 254330 | zCat = azArg[i+1]; |
| 249301 | } | 254331 | } |
| 249302 | } | 254332 | } |
| 249303 | |||
| 249304 | if( rc==SQLITE_OK ){ | 254333 | if( rc==SQLITE_OK ){ |
| 249305 | rc = unicodeSetCategories(p, zCat); | 254334 | rc = unicodeSetCategories(p, zCat); |
| 249306 | } | 254335 | } |
| 249307 | 254336 | ||
| 249308 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ | 254337 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ |
| 249309 | const char *zArg = azArg[i+1]; | 254338 | const char *zArg = azArg[i+1]; |
| 249310 | if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ | 254339 | if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ |
| 249311 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ | 254340 | if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ |
| @@ -249330,6 +254359,7 @@ static int fts5UnicodeCreate( | |||
| 249330 | rc = SQLITE_ERROR; | 254359 | rc = SQLITE_ERROR; |
| 249331 | } | 254360 | } |
| 249332 | } | 254361 | } |
| 254362 | if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; | ||
| 249333 | 254363 | ||
| 249334 | }else{ | 254364 | }else{ |
| 249335 | rc = SQLITE_NOMEM; | 254365 | rc = SQLITE_NOMEM; |
| @@ -250184,6 +255214,7 @@ static int fts5PorterTokenize( | |||
| 250184 | typedef struct TrigramTokenizer TrigramTokenizer; | 255214 | typedef struct TrigramTokenizer TrigramTokenizer; |
| 250185 | struct TrigramTokenizer { | 255215 | struct TrigramTokenizer { |
| 250186 | int bFold; /* True to fold to lower-case */ | 255216 | int bFold; /* True to fold to lower-case */ |
| 255217 | int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */ | ||
| 250187 | }; | 255218 | }; |
| 250188 | 255219 | ||
| 250189 | /* | 255220 | /* |
| @@ -250210,7 +255241,8 @@ static int fts5TriCreate( | |||
| 250210 | }else{ | 255241 | }else{ |
| 250211 | int i; | 255242 | int i; |
| 250212 | pNew->bFold = 1; | 255243 | pNew->bFold = 1; |
| 250213 | for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ | 255244 | pNew->iFoldParam = 0; |
| 255245 | for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){ | ||
| 250214 | const char *zArg = azArg[i+1]; | 255246 | const char *zArg = azArg[i+1]; |
| 250215 | if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ | 255247 | if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){ |
| 250216 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ | 255248 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ |
| @@ -250218,10 +255250,22 @@ static int fts5TriCreate( | |||
| 250218 | }else{ | 255250 | }else{ |
| 250219 | pNew->bFold = (zArg[0]=='0'); | 255251 | pNew->bFold = (zArg[0]=='0'); |
| 250220 | } | 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; | ||
| 255256 | }else{ | ||
| 255257 | pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; | ||
| 255258 | } | ||
| 250221 | }else{ | 255259 | }else{ |
| 250222 | rc = SQLITE_ERROR; | 255260 | rc = SQLITE_ERROR; |
| 250223 | } | 255261 | } |
| 250224 | } | 255262 | } |
| 255263 | if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR; | ||
| 255264 | |||
| 255265 | if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ | ||
| 255266 | rc = SQLITE_ERROR; | ||
| 255267 | } | ||
| 255268 | |||
| 250225 | if( rc!=SQLITE_OK ){ | 255269 | if( rc!=SQLITE_OK ){ |
| 250226 | fts5TriDelete((Fts5Tokenizer*)pNew); | 255270 | fts5TriDelete((Fts5Tokenizer*)pNew); |
| 250227 | pNew = 0; | 255271 | pNew = 0; |
| @@ -250244,40 +255288,62 @@ static int fts5TriTokenize( | |||
| 250244 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; | 255288 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; |
| 250245 | int rc = SQLITE_OK; | 255289 | int rc = SQLITE_OK; |
| 250246 | char aBuf[32]; | 255290 | char aBuf[32]; |
| 255291 | char *zOut = aBuf; | ||
| 255292 | int ii; | ||
| 250247 | const unsigned char *zIn = (const unsigned char*)pText; | 255293 | const unsigned char *zIn = (const unsigned char*)pText; |
| 250248 | const unsigned char *zEof = &zIn[nText]; | 255294 | const unsigned char *zEof = &zIn[nText]; |
| 250249 | u32 iCode; | 255295 | u32 iCode; |
| 255296 | int aStart[3]; /* Input offset of each character in aBuf[] */ | ||
| 250250 | 255297 | ||
| 250251 | UNUSED_PARAM(unusedFlags); | 255298 | UNUSED_PARAM(unusedFlags); |
| 250252 | while( 1 ){ | 255299 | |
| 250253 | char *zOut = aBuf; | 255300 | /* Populate aBuf[] with the characters for the first trigram. */ |
| 250254 | int iStart = zIn - (const unsigned char*)pText; | 255301 | for(ii=0; ii<3; ii++){ |
| 250255 | const unsigned char *zNext; | 255302 | do { |
| 250256 | 255303 | aStart[ii] = zIn - (const unsigned char*)pText; | |
| 250257 | READ_UTF8(zIn, zEof, iCode); | ||
| 250258 | if( iCode==0 ) break; | ||
| 250259 | zNext = zIn; | ||
| 250260 | if( zIn<zEof ){ | ||
| 250261 | if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); | ||
| 250262 | WRITE_UTF8(zOut, iCode); | ||
| 250263 | READ_UTF8(zIn, zEof, iCode); | 255304 | READ_UTF8(zIn, zEof, iCode); |
| 250264 | if( iCode==0 ) break; | 255305 | if( iCode==0 ) return SQLITE_OK; |
| 250265 | }else{ | 255306 | if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); |
| 250266 | break; | 255307 | }while( iCode==0 ); |
| 250267 | } | 255308 | WRITE_UTF8(zOut, iCode); |
| 250268 | if( zIn<zEof ){ | 255309 | } |
| 250269 | if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); | 255310 | |
| 250270 | WRITE_UTF8(zOut, iCode); | 255311 | /* At the start of each iteration of this loop: |
| 255312 | ** | ||
| 255313 | ** aBuf: Contains 3 characters. The 3 characters of the next trigram. | ||
| 255314 | ** zOut: Points to the byte following the last character in aBuf. | ||
| 255315 | ** aStart[3]: Contains the byte offset in the input text corresponding | ||
| 255316 | ** to the start of each of the three characters in the buffer. | ||
| 255317 | */ | ||
| 255318 | assert( zIn<=zEof ); | ||
| 255319 | while( 1 ){ | ||
| 255320 | int iNext; /* Start of character following current tri */ | ||
| 255321 | const char *z1; | ||
| 255322 | |||
| 255323 | /* Read characters from the input up until the first non-diacritic */ | ||
| 255324 | do { | ||
| 255325 | iNext = zIn - (const unsigned char*)pText; | ||
| 250271 | READ_UTF8(zIn, zEof, iCode); | 255326 | READ_UTF8(zIn, zEof, iCode); |
| 250272 | if( iCode==0 ) break; | 255327 | if( iCode==0 ) break; |
| 250273 | if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); | 255328 | if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); |
| 250274 | WRITE_UTF8(zOut, iCode); | 255329 | }while( iCode==0 ); |
| 250275 | }else{ | 255330 | |
| 250276 | break; | 255331 | /* Pass the current trigram back to fts5 */ |
| 250277 | } | 255332 | rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext); |
| 250278 | rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); | 255333 | if( iCode==0 || rc!=SQLITE_OK ) break; |
| 250279 | if( rc!=SQLITE_OK ) break; | 255334 | |
| 250280 | zIn = zNext; | 255335 | /* Remove the first character from buffer aBuf[]. Append the character |
| 255336 | ** with codepoint iCode. */ | ||
| 255337 | z1 = aBuf; | ||
| 255338 | FTS5_SKIP_UTF8(z1); | ||
| 255339 | memmove(aBuf, z1, zOut - z1); | ||
| 255340 | zOut -= (z1 - aBuf); | ||
| 255341 | WRITE_UTF8(zOut, iCode); | ||
| 255342 | |||
| 255343 | /* Update the aStart[] array */ | ||
| 255344 | aStart[0] = aStart[1]; | ||
| 255345 | aStart[1] = aStart[2]; | ||
| 255346 | aStart[2] = iNext; | ||
| 250281 | } | 255347 | } |
| 250282 | 255348 | ||
| 250283 | return rc; | 255349 | return rc; |
| @@ -250300,7 +255366,9 @@ static int sqlite3Fts5TokenizerPattern( | |||
| 250300 | ){ | 255366 | ){ |
| 250301 | if( xCreate==fts5TriCreate ){ | 255367 | if( xCreate==fts5TriCreate ){ |
| 250302 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; | 255368 | TrigramTokenizer *p = (TrigramTokenizer*)pTok; |
| 250303 | return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; | 255369 | if( p->iFoldParam==0 ){ |
| 255370 | return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; | ||
| 255371 | } | ||
| 250304 | } | 255372 | } |
| 250305 | return FTS5_PATTERN_NONE; | 255373 | return FTS5_PATTERN_NONE; |
| 250306 | } | 255374 | } |
| @@ -252089,7 +257157,7 @@ static int fts5VocabFilterMethod( | |||
| 252089 | if( pEq ){ | 257157 | if( pEq ){ |
| 252090 | zTerm = (const char *)sqlite3_value_text(pEq); | 257158 | zTerm = (const char *)sqlite3_value_text(pEq); |
| 252091 | nTerm = sqlite3_value_bytes(pEq); | 257159 | nTerm = sqlite3_value_bytes(pEq); |
| 252092 | f = 0; | 257160 | f = FTS5INDEX_QUERY_NOTOKENDATA; |
| 252093 | }else{ | 257161 | }else{ |
| 252094 | if( pGe ){ | 257162 | if( pGe ){ |
| 252095 | zTerm = (const char *)sqlite3_value_text(pGe); | 257163 | zTerm = (const char *)sqlite3_value_text(pGe); |