| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.7.16.1. By combining all the individual C code files into this |
| 3 | +** version 3.7.17. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -360,15 +360,15 @@ |
| 360 | 360 | ** |
| 361 | 361 | ** Older versions of SQLite used an optional THREADSAFE macro. |
| 362 | 362 | ** We support that for legacy. |
| 363 | 363 | */ |
| 364 | 364 | #if !defined(SQLITE_THREADSAFE) |
| 365 | | -#if defined(THREADSAFE) |
| 366 | | -# define SQLITE_THREADSAFE THREADSAFE |
| 367 | | -#else |
| 368 | | -# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ |
| 369 | | -#endif |
| 365 | +# if defined(THREADSAFE) |
| 366 | +# define SQLITE_THREADSAFE THREADSAFE |
| 367 | +# else |
| 368 | +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ |
| 369 | +# endif |
| 370 | 370 | #endif |
| 371 | 371 | |
| 372 | 372 | /* |
| 373 | 373 | ** Powersafe overwrite is on by default. But can be turned off using |
| 374 | 374 | ** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. |
| | @@ -676,13 +676,13 @@ |
| 676 | 676 | ** |
| 677 | 677 | ** See also: [sqlite3_libversion()], |
| 678 | 678 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 679 | 679 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 680 | 680 | */ |
| 681 | | -#define SQLITE_VERSION "3.7.16.1" |
| 682 | | -#define SQLITE_VERSION_NUMBER 3007016 |
| 683 | | -#define SQLITE_SOURCE_ID "2013-03-27 20:41:15 274d2a22660c7b34b8bbd85f3c29cbafbcb1b4e7" |
| 681 | +#define SQLITE_VERSION "3.7.17" |
| 682 | +#define SQLITE_VERSION_NUMBER 3007017 |
| 683 | +#define SQLITE_SOURCE_ID "2013-04-25 17:27:08 aabeea98f53edde68f484f1794ae70789dac3889" |
| 684 | 684 | |
| 685 | 685 | /* |
| 686 | 686 | ** CAPI3REF: Run-Time Library Version Numbers |
| 687 | 687 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 688 | 688 | ** |
| | @@ -994,10 +994,12 @@ |
| 994 | 994 | #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ |
| 995 | 995 | #define SQLITE_AUTH 23 /* Authorization denied */ |
| 996 | 996 | #define SQLITE_FORMAT 24 /* Auxiliary database format error */ |
| 997 | 997 | #define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ |
| 998 | 998 | #define SQLITE_NOTADB 26 /* File opened that is not a database file */ |
| 999 | +#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ |
| 1000 | +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ |
| 999 | 1001 | #define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ |
| 1000 | 1002 | #define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ |
| 1001 | 1003 | /* end-of-error-codes */ |
| 1002 | 1004 | |
| 1003 | 1005 | /* |
| | @@ -1044,10 +1046,11 @@ |
| 1044 | 1046 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) |
| 1045 | 1047 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) |
| 1046 | 1048 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1047 | 1049 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1048 | 1050 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1051 | +#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1049 | 1052 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1050 | 1053 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1051 | 1054 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1052 | 1055 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1053 | 1056 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| | @@ -1063,10 +1066,12 @@ |
| 1063 | 1066 | #define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) |
| 1064 | 1067 | #define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) |
| 1065 | 1068 | #define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) |
| 1066 | 1069 | #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) |
| 1067 | 1070 | #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) |
| 1071 | +#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) |
| 1072 | +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) |
| 1068 | 1073 | |
| 1069 | 1074 | /* |
| 1070 | 1075 | ** CAPI3REF: Flags For File Open Operations |
| 1071 | 1076 | ** |
| 1072 | 1077 | ** These bit values are intended for use in the |
| | @@ -1302,10 +1307,13 @@ |
| 1302 | 1307 | int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); |
| 1303 | 1308 | int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); |
| 1304 | 1309 | void (*xShmBarrier)(sqlite3_file*); |
| 1305 | 1310 | int (*xShmUnmap)(sqlite3_file*, int deleteFlag); |
| 1306 | 1311 | /* Methods above are valid for version 2 */ |
| 1312 | + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); |
| 1313 | + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); |
| 1314 | + /* Methods above are valid for version 3 */ |
| 1307 | 1315 | /* Additional methods may be added in future releases */ |
| 1308 | 1316 | }; |
| 1309 | 1317 | |
| 1310 | 1318 | /* |
| 1311 | 1319 | ** CAPI3REF: Standard File Control Opcodes |
| | @@ -1438,11 +1446,12 @@ |
| 1438 | 1446 | ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] |
| 1439 | 1447 | ** file control occurs at the beginning of pragma statement analysis and so |
| 1440 | 1448 | ** it is able to override built-in [PRAGMA] statements. |
| 1441 | 1449 | ** |
| 1442 | 1450 | ** <li>[[SQLITE_FCNTL_BUSYHANDLER]] |
| 1443 | | -** ^This file-control may be invoked by SQLite on the database file handle |
| 1451 | +** ^The [SQLITE_FCNTL_BUSYHANDLER] |
| 1452 | +** file-control may be invoked by SQLite on the database file handle |
| 1444 | 1453 | ** shortly after it is opened in order to provide a custom VFS with access |
| 1445 | 1454 | ** to the connections busy-handler callback. The argument is of type (void **) |
| 1446 | 1455 | ** - an array of two (void *) values. The first (void *) actually points |
| 1447 | 1456 | ** to a function of type (int (*)(void *)). In order to invoke the connections |
| 1448 | 1457 | ** busy-handler, this function should be invoked with the second (void *) in |
| | @@ -1449,17 +1458,28 @@ |
| 1449 | 1458 | ** the array as the only argument. If it returns non-zero, then the operation |
| 1450 | 1459 | ** should be retried. If it returns zero, the custom VFS should abandon the |
| 1451 | 1460 | ** current operation. |
| 1452 | 1461 | ** |
| 1453 | 1462 | ** <li>[[SQLITE_FCNTL_TEMPFILENAME]] |
| 1454 | | -** ^Application can invoke this file-control to have SQLite generate a |
| 1463 | +** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control |
| 1464 | +** to have SQLite generate a |
| 1455 | 1465 | ** temporary filename using the same algorithm that is followed to generate |
| 1456 | 1466 | ** temporary filenames for TEMP tables and other internal uses. The |
| 1457 | 1467 | ** argument should be a char** which will be filled with the filename |
| 1458 | 1468 | ** written into memory obtained from [sqlite3_malloc()]. The caller should |
| 1459 | 1469 | ** invoke [sqlite3_free()] on the result to avoid a memory leak. |
| 1460 | 1470 | ** |
| 1471 | +** <li>[[SQLITE_FCNTL_MMAP_SIZE]] |
| 1472 | +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the |
| 1473 | +** maximum number of bytes that will be used for memory-mapped I/O. |
| 1474 | +** The argument is a pointer to a value of type sqlite3_int64 that |
| 1475 | +** is an advisory maximum number of bytes in the file to memory map. The |
| 1476 | +** pointer is overwritten with the old value. The limit is not changed if |
| 1477 | +** the value originally pointed to is negative, and so the current limit |
| 1478 | +** can be queried by passing in a pointer to a negative number. This |
| 1479 | +** file-control is used internally to implement [PRAGMA mmap_size]. |
| 1480 | +** |
| 1461 | 1481 | ** </ul> |
| 1462 | 1482 | */ |
| 1463 | 1483 | #define SQLITE_FCNTL_LOCKSTATE 1 |
| 1464 | 1484 | #define SQLITE_GET_LOCKPROXYFILE 2 |
| 1465 | 1485 | #define SQLITE_SET_LOCKPROXYFILE 3 |
| | @@ -1474,10 +1494,11 @@ |
| 1474 | 1494 | #define SQLITE_FCNTL_VFSNAME 12 |
| 1475 | 1495 | #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 |
| 1476 | 1496 | #define SQLITE_FCNTL_PRAGMA 14 |
| 1477 | 1497 | #define SQLITE_FCNTL_BUSYHANDLER 15 |
| 1478 | 1498 | #define SQLITE_FCNTL_TEMPFILENAME 16 |
| 1499 | +#define SQLITE_FCNTL_MMAP_SIZE 18 |
| 1479 | 1500 | |
| 1480 | 1501 | /* |
| 1481 | 1502 | ** CAPI3REF: Mutex Handle |
| 1482 | 1503 | ** |
| 1483 | 1504 | ** The mutex module within SQLite defines [sqlite3_mutex] to be an |
| | @@ -2186,26 +2207,42 @@ |
| 2186 | 2207 | ** |
| 2187 | 2208 | ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] |
| 2188 | 2209 | ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE |
| 2189 | 2210 | ** <dd> These options are obsolete and should not be used by new code. |
| 2190 | 2211 | ** They are retained for backwards compatibility but are now no-ops. |
| 2191 | | -** </dl> |
| 2212 | +** </dd> |
| 2192 | 2213 | ** |
| 2193 | 2214 | ** [[SQLITE_CONFIG_SQLLOG]] |
| 2194 | 2215 | ** <dt>SQLITE_CONFIG_SQLLOG |
| 2195 | 2216 | ** <dd>This option is only available if sqlite is compiled with the |
| 2196 | | -** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should |
| 2217 | +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should |
| 2197 | 2218 | ** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). |
| 2198 | 2219 | ** The second should be of type (void*). The callback is invoked by the library |
| 2199 | 2220 | ** in three separate circumstances, identified by the value passed as the |
| 2200 | 2221 | ** fourth parameter. If the fourth parameter is 0, then the database connection |
| 2201 | 2222 | ** passed as the second argument has just been opened. The third argument |
| 2202 | 2223 | ** points to a buffer containing the name of the main database file. If the |
| 2203 | 2224 | ** fourth parameter is 1, then the SQL statement that the third parameter |
| 2204 | 2225 | ** points to has just been executed. Or, if the fourth parameter is 2, then |
| 2205 | 2226 | ** the connection being passed as the second parameter is being closed. The |
| 2206 | | -** third parameter is passed NULL In this case. |
| 2227 | +** third parameter is passed NULL In this case. An example of using this |
| 2228 | +** configuration option can be seen in the "test_sqllog.c" source file in |
| 2229 | +** the canonical SQLite source tree.</dd> |
| 2230 | +** |
| 2231 | +** [[SQLITE_CONFIG_MMAP_SIZE]] |
| 2232 | +** <dt>SQLITE_CONFIG_MMAP_SIZE |
| 2233 | +** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values |
| 2234 | +** that are the default mmap size limit (the default setting for |
| 2235 | +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. |
| 2236 | +** The default setting can be overridden by each database connection using |
| 2237 | +** either the [PRAGMA mmap_size] command, or by using the |
| 2238 | +** [SQLITE_FCNTL_MMAP_SIZE] file control. The maximum allowed mmap size |
| 2239 | +** cannot be changed at run-time. Nor may the maximum allowed mmap size |
| 2240 | +** exceed the compile-time maximum mmap size set by the |
| 2241 | +** [SQLITE_MAX_MMAP_SIZE] compile-time option. |
| 2242 | +** If either argument to this option is negative, then that argument is |
| 2243 | +** changed to its compile-time default. |
| 2207 | 2244 | ** </dl> |
| 2208 | 2245 | */ |
| 2209 | 2246 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 2210 | 2247 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| 2211 | 2248 | #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| | @@ -2225,10 +2262,11 @@ |
| 2225 | 2262 | #define SQLITE_CONFIG_URI 17 /* int */ |
| 2226 | 2263 | #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ |
| 2227 | 2264 | #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ |
| 2228 | 2265 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ |
| 2229 | 2266 | #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ |
| 2267 | +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ |
| 2230 | 2268 | |
| 2231 | 2269 | /* |
| 2232 | 2270 | ** CAPI3REF: Database Connection Configuration Options |
| 2233 | 2271 | ** |
| 2234 | 2272 | ** These constants are the available integer configuration options that |
| | @@ -4756,11 +4794,11 @@ |
| 4756 | 4794 | ** SQLITE_TRANSIENT value means that the content will likely change in |
| 4757 | 4795 | ** the near future and that SQLite should make its own private copy of |
| 4758 | 4796 | ** the content before returning. |
| 4759 | 4797 | ** |
| 4760 | 4798 | ** The typedef is necessary to work around problems in certain |
| 4761 | | -** C++ compilers. See ticket #2191. |
| 4799 | +** C++ compilers. |
| 4762 | 4800 | */ |
| 4763 | 4801 | typedef void (*sqlite3_destructor_type)(void*); |
| 4764 | 4802 | #define SQLITE_STATIC ((sqlite3_destructor_type)0) |
| 4765 | 4803 | #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) |
| 4766 | 4804 | |
| | @@ -5555,15 +5593,24 @@ |
| 5555 | 5593 | ** CAPI3REF: Load An Extension |
| 5556 | 5594 | ** |
| 5557 | 5595 | ** ^This interface loads an SQLite extension library from the named file. |
| 5558 | 5596 | ** |
| 5559 | 5597 | ** ^The sqlite3_load_extension() interface attempts to load an |
| 5560 | | -** SQLite extension library contained in the file zFile. |
| 5598 | +** [SQLite extension] library contained in the file zFile. If |
| 5599 | +** the file cannot be loaded directly, attempts are made to load |
| 5600 | +** with various operating-system specific extensions added. |
| 5601 | +** So for example, if "samplelib" cannot be loaded, then names like |
| 5602 | +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might |
| 5603 | +** be tried also. |
| 5561 | 5604 | ** |
| 5562 | 5605 | ** ^The entry point is zProc. |
| 5563 | | -** ^zProc may be 0, in which case the name of the entry point |
| 5564 | | -** defaults to "sqlite3_extension_init". |
| 5606 | +** ^(zProc may be 0, in which case SQLite will try to come up with an |
| 5607 | +** entry point name on its own. It first tries "sqlite3_extension_init". |
| 5608 | +** If that does not work, it constructs a name "sqlite3_X_init" where the |
| 5609 | +** X is consists of the lower-case equivalent of all ASCII alphabetic |
| 5610 | +** characters in the filename from the last "/" to the first following |
| 5611 | +** "." and omitting any initial "lib".)^ |
| 5565 | 5612 | ** ^The sqlite3_load_extension() interface returns |
| 5566 | 5613 | ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. |
| 5567 | 5614 | ** ^If an error occurs and pzErrMsg is not 0, then the |
| 5568 | 5615 | ** [sqlite3_load_extension()] interface shall attempt to |
| 5569 | 5616 | ** fill *pzErrMsg with error message text stored in memory |
| | @@ -5585,15 +5632,15 @@ |
| 5585 | 5632 | |
| 5586 | 5633 | /* |
| 5587 | 5634 | ** CAPI3REF: Enable Or Disable Extension Loading |
| 5588 | 5635 | ** |
| 5589 | 5636 | ** ^So as not to open security holes in older applications that are |
| 5590 | | -** unprepared to deal with extension loading, and as a means of disabling |
| 5591 | | -** extension loading while evaluating user-entered SQL, the following API |
| 5637 | +** unprepared to deal with [extension loading], and as a means of disabling |
| 5638 | +** [extension loading] while evaluating user-entered SQL, the following API |
| 5592 | 5639 | ** is provided to turn the [sqlite3_load_extension()] mechanism on and off. |
| 5593 | 5640 | ** |
| 5594 | | -** ^Extension loading is off by default. See ticket #1863. |
| 5641 | +** ^Extension loading is off by default. |
| 5595 | 5642 | ** ^Call the sqlite3_enable_load_extension() routine with onoff==1 |
| 5596 | 5643 | ** to turn extension loading on and call it with onoff==0 to turn |
| 5597 | 5644 | ** it back off again. |
| 5598 | 5645 | */ |
| 5599 | 5646 | SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); |
| | @@ -5601,11 +5648,11 @@ |
| 5601 | 5648 | /* |
| 5602 | 5649 | ** CAPI3REF: Automatically Load Statically Linked Extensions |
| 5603 | 5650 | ** |
| 5604 | 5651 | ** ^This interface causes the xEntryPoint() function to be invoked for |
| 5605 | 5652 | ** each new [database connection] that is created. The idea here is that |
| 5606 | | -** xEntryPoint() is the entry point for a statically linked SQLite extension |
| 5653 | +** xEntryPoint() is the entry point for a statically linked [SQLite extension] |
| 5607 | 5654 | ** that is to be automatically loaded into all new database connections. |
| 5608 | 5655 | ** |
| 5609 | 5656 | ** ^(Even though the function prototype shows that xEntryPoint() takes |
| 5610 | 5657 | ** no arguments and returns void, SQLite invokes xEntryPoint() with three |
| 5611 | 5658 | ** arguments and expects and integer result as if the signature of the |
| | @@ -7381,10 +7428,25 @@ |
| 7381 | 7428 | ** independence" that SQLite uses internally when comparing identifiers. |
| 7382 | 7429 | */ |
| 7383 | 7430 | SQLITE_API int sqlite3_stricmp(const char *, const char *); |
| 7384 | 7431 | SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); |
| 7385 | 7432 | |
| 7433 | +/* |
| 7434 | +** CAPI3REF: String Globbing |
| 7435 | +* |
| 7436 | +** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches |
| 7437 | +** the glob pattern P, and it returns non-zero if string X does not match |
| 7438 | +** the glob pattern P. ^The definition of glob pattern matching used in |
| 7439 | +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the |
| 7440 | +** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case |
| 7441 | +** sensitive. |
| 7442 | +** |
| 7443 | +** Note that this routine returns zero on a match and non-zero if the strings |
| 7444 | +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. |
| 7445 | +*/ |
| 7446 | +SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); |
| 7447 | + |
| 7386 | 7448 | /* |
| 7387 | 7449 | ** CAPI3REF: Error Logging Interface |
| 7388 | 7450 | ** |
| 7389 | 7451 | ** ^The [sqlite3_log()] interface writes a message into the error log |
| 7390 | 7452 | ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. |
| | @@ -8069,10 +8131,11 @@ |
| 8069 | 8131 | ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified |
| 8070 | 8132 | ** on the command-line |
| 8071 | 8133 | */ |
| 8072 | 8134 | #ifndef SQLITE_TEMP_STORE |
| 8073 | 8135 | # define SQLITE_TEMP_STORE 1 |
| 8136 | +# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ |
| 8074 | 8137 | #endif |
| 8075 | 8138 | |
| 8076 | 8139 | /* |
| 8077 | 8140 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 8078 | 8141 | ** ourselves. |
| | @@ -8216,10 +8279,53 @@ |
| 8216 | 8279 | # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) |
| 8217 | 8280 | #else |
| 8218 | 8281 | # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) |
| 8219 | 8282 | #endif |
| 8220 | 8283 | |
| 8284 | +/* |
| 8285 | +** Disable MMAP on platforms where it is known to not work |
| 8286 | +*/ |
| 8287 | +#if defined(__OpenBSD__) || defined(__QNXNTO__) |
| 8288 | +# undef SQLITE_MAX_MMAP_SIZE |
| 8289 | +# define SQLITE_MAX_MMAP_SIZE 0 |
| 8290 | +#endif |
| 8291 | + |
| 8292 | +/* |
| 8293 | +** Default maximum size of memory used by memory-mapped I/O in the VFS |
| 8294 | +*/ |
| 8295 | +#ifdef __APPLE__ |
| 8296 | +# include <TargetConditionals.h> |
| 8297 | +# if TARGET_OS_IPHONE |
| 8298 | +# undef SQLITE_MAX_MMAP_SIZE |
| 8299 | +# define SQLITE_MAX_MMAP_SIZE 0 |
| 8300 | +# endif |
| 8301 | +#endif |
| 8302 | +#ifndef SQLITE_MAX_MMAP_SIZE |
| 8303 | +# if defined(__linux__) \ |
| 8304 | + || defined(_WIN32) \ |
| 8305 | + || (defined(__APPLE__) && defined(__MACH__)) \ |
| 8306 | + || defined(__sun) |
| 8307 | +# define SQLITE_MAX_MMAP_SIZE 2147483648 |
| 8308 | +# else |
| 8309 | +# define SQLITE_MAX_MMAP_SIZE 0 |
| 8310 | +# endif |
| 8311 | +# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */ |
| 8312 | +#endif |
| 8313 | + |
| 8314 | +/* |
| 8315 | +** The default MMAP_SIZE is zero on all platforms. Or, even if a larger |
| 8316 | +** default MMAP_SIZE is specified at compile-time, make sure that it does |
| 8317 | +** not exceed the maximum mmap size. |
| 8318 | +*/ |
| 8319 | +#ifndef SQLITE_DEFAULT_MMAP_SIZE |
| 8320 | +# define SQLITE_DEFAULT_MMAP_SIZE 0 |
| 8321 | +# define SQLITE_DEFAULT_MMAP_SIZE_xc 1 /* Exclude from ctime.c */ |
| 8322 | +#endif |
| 8323 | +#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8324 | +# undef SQLITE_DEFAULT_MMAP_SIZE |
| 8325 | +# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8326 | +#endif |
| 8221 | 8327 | |
| 8222 | 8328 | /* |
| 8223 | 8329 | ** An instance of the following structure is used to store the busy-handler |
| 8224 | 8330 | ** callback for a given sqlite handle. |
| 8225 | 8331 | ** |
| | @@ -8437,10 +8543,11 @@ |
| 8437 | 8543 | #define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ |
| 8438 | 8544 | #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ |
| 8439 | 8545 | |
| 8440 | 8546 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 8441 | 8547 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 8548 | +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); |
| 8442 | 8549 | SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); |
| 8443 | 8550 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| 8444 | 8551 | SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); |
| 8445 | 8552 | SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); |
| 8446 | 8553 | SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); |
| | @@ -9137,10 +9244,16 @@ |
| 9137 | 9244 | #define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ |
| 9138 | 9245 | #define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ |
| 9139 | 9246 | #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ |
| 9140 | 9247 | #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ |
| 9141 | 9248 | |
| 9249 | +/* |
| 9250 | +** Flags that make up the mask passed to sqlite3PagerAcquire(). |
| 9251 | +*/ |
| 9252 | +#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */ |
| 9253 | +#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */ |
| 9254 | + |
| 9142 | 9255 | /* |
| 9143 | 9256 | ** The remainder of this file contains the declarations of the functions |
| 9144 | 9257 | ** that make up the Pager sub-system API. See source code comments for |
| 9145 | 9258 | ** a detailed description of each routine. |
| 9146 | 9259 | */ |
| | @@ -9161,10 +9274,11 @@ |
| 9161 | 9274 | /* Functions used to configure a Pager object. */ |
| 9162 | 9275 | SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); |
| 9163 | 9276 | SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); |
| 9164 | 9277 | SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); |
| 9165 | 9278 | SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); |
| 9279 | +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); |
| 9166 | 9280 | SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); |
| 9167 | 9281 | SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); |
| 9168 | 9282 | SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); |
| 9169 | 9283 | SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); |
| 9170 | 9284 | SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); |
| | @@ -9306,10 +9420,12 @@ |
| 9306 | 9420 | #define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before |
| 9307 | 9421 | ** writing this page to the database */ |
| 9308 | 9422 | #define PGHDR_NEED_READ 0x008 /* Content is unread */ |
| 9309 | 9423 | #define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */ |
| 9310 | 9424 | #define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ |
| 9425 | + |
| 9426 | +#define PGHDR_MMAP 0x040 /* This is an mmap page object */ |
| 9311 | 9427 | |
| 9312 | 9428 | /* Initialize and shutdown the page cache subsystem */ |
| 9313 | 9429 | SQLITE_PRIVATE int sqlite3PcacheInitialize(void); |
| 9314 | 9430 | SQLITE_PRIVATE void sqlite3PcacheShutdown(void); |
| 9315 | 9431 | |
| | @@ -9518,18 +9634,10 @@ |
| 9518 | 9634 | */ |
| 9519 | 9635 | #if !defined(SQLITE_OS_WINRT) |
| 9520 | 9636 | # define SQLITE_OS_WINRT 0 |
| 9521 | 9637 | #endif |
| 9522 | 9638 | |
| 9523 | | -/* |
| 9524 | | -** When compiled for WinCE or WinRT, there is no concept of the current |
| 9525 | | -** directory. |
| 9526 | | - */ |
| 9527 | | -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 9528 | | -# define SQLITE_CURDIR 1 |
| 9529 | | -#endif |
| 9530 | | - |
| 9531 | 9639 | /* If the SET_FULLSYNC macro is not defined above, then make it |
| 9532 | 9640 | ** a no-op |
| 9533 | 9641 | */ |
| 9534 | 9642 | #ifndef SET_FULLSYNC |
| 9535 | 9643 | # define SET_FULLSYNC(x,y) |
| | @@ -9678,10 +9786,12 @@ |
| 9678 | 9786 | SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); |
| 9679 | 9787 | SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); |
| 9680 | 9788 | SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); |
| 9681 | 9789 | SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); |
| 9682 | 9790 | SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); |
| 9791 | +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); |
| 9792 | +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); |
| 9683 | 9793 | |
| 9684 | 9794 | |
| 9685 | 9795 | /* |
| 9686 | 9796 | ** Functions for accessing sqlite3_vfs methods |
| 9687 | 9797 | */ |
| | @@ -9917,10 +10027,11 @@ |
| 9917 | 10027 | sqlite3_mutex *mutex; /* Connection mutex */ |
| 9918 | 10028 | Db *aDb; /* All backends */ |
| 9919 | 10029 | int nDb; /* Number of backends currently in use */ |
| 9920 | 10030 | int flags; /* Miscellaneous flags. See below */ |
| 9921 | 10031 | i64 lastRowid; /* ROWID of most recent insert (see above) */ |
| 10032 | + i64 szMmap; /* Default mmap_size setting */ |
| 9922 | 10033 | unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ |
| 9923 | 10034 | int errCode; /* Most recent error code (SQLITE_*) */ |
| 9924 | 10035 | int errMask; /* & result codes with this before returning */ |
| 9925 | 10036 | u16 dbOptFlags; /* Flags to enable/disable optimizations */ |
| 9926 | 10037 | u8 autoCommit; /* The auto-commit flag. */ |
| | @@ -11153,10 +11264,12 @@ |
| 11153 | 11264 | */ |
| 11154 | 11265 | #define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */ |
| 11155 | 11266 | #define NC_HasAgg 0x02 /* One or more aggregate functions seen */ |
| 11156 | 11267 | #define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */ |
| 11157 | 11268 | #define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */ |
| 11269 | +#define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only |
| 11270 | + ** if no other resolution is available */ |
| 11158 | 11271 | |
| 11159 | 11272 | /* |
| 11160 | 11273 | ** An instance of the following structure contains all information |
| 11161 | 11274 | ** needed to generate code for a single SELECT statement. |
| 11162 | 11275 | ** |
| | @@ -11588,10 +11701,12 @@ |
| 11588 | 11701 | sqlite3_mutex_methods mutex; /* Low-level mutex interface */ |
| 11589 | 11702 | sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ |
| 11590 | 11703 | void *pHeap; /* Heap storage space */ |
| 11591 | 11704 | int nHeap; /* Size of pHeap[] */ |
| 11592 | 11705 | int mnReq, mxReq; /* Min and max heap requests sizes */ |
| 11706 | + sqlite3_int64 szMmap; /* mmap() space per open file */ |
| 11707 | + sqlite3_int64 mxMmap; /* Maximum value for szMmap */ |
| 11593 | 11708 | void *pScratch; /* Scratch memory */ |
| 11594 | 11709 | int szScratch; /* Size of each scratch buffer */ |
| 11595 | 11710 | int nScratch; /* Number of scratch buffers */ |
| 11596 | 11711 | void *pPage; /* Page cache memory */ |
| 11597 | 11712 | int szPage; /* Size of each page in pPage[] */ |
| | @@ -11622,10 +11737,11 @@ |
| 11622 | 11737 | struct Walker { |
| 11623 | 11738 | int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ |
| 11624 | 11739 | int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ |
| 11625 | 11740 | Parse *pParse; /* Parser context. */ |
| 11626 | 11741 | int walkerDepth; /* Number of subqueries */ |
| 11742 | + u8 bSelectDepthFirst; /* Do subqueries first */ |
| 11627 | 11743 | union { /* Extra data for callback */ |
| 11628 | 11744 | NameContext *pNC; /* Naming context */ |
| 11629 | 11745 | int i; /* Integer value */ |
| 11630 | 11746 | SrcList *pSrcList; /* FROM clause */ |
| 11631 | 11747 | struct SrcCount *pSrcCount; /* Counting column references */ |
| | @@ -12609,10 +12725,12 @@ |
| 12609 | 12725 | {0,0,0,0,0,0,0,0,0}, /* mutex */ |
| 12610 | 12726 | {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ |
| 12611 | 12727 | (void*)0, /* pHeap */ |
| 12612 | 12728 | 0, /* nHeap */ |
| 12613 | 12729 | 0, 0, /* mnHeap, mxHeap */ |
| 12730 | + SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ |
| 12731 | + SQLITE_MAX_MMAP_SIZE, /* mxMmap */ |
| 12614 | 12732 | (void*)0, /* pScratch */ |
| 12615 | 12733 | 0, /* szScratch */ |
| 12616 | 12734 | 0, /* nScratch */ |
| 12617 | 12735 | (void*)0, /* pPage */ |
| 12618 | 12736 | 0, /* szPage */ |
| | @@ -12732,18 +12850,18 @@ |
| 12732 | 12850 | "CHECK_PAGES", |
| 12733 | 12851 | #endif |
| 12734 | 12852 | #ifdef SQLITE_COVERAGE_TEST |
| 12735 | 12853 | "COVERAGE_TEST", |
| 12736 | 12854 | #endif |
| 12737 | | -#ifdef SQLITE_CURDIR |
| 12738 | | - "CURDIR", |
| 12739 | | -#endif |
| 12740 | 12855 | #ifdef SQLITE_DEBUG |
| 12741 | 12856 | "DEBUG", |
| 12742 | 12857 | #endif |
| 12743 | 12858 | #ifdef SQLITE_DEFAULT_LOCKING_MODE |
| 12744 | 12859 | "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), |
| 12860 | +#endif |
| 12861 | +#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) |
| 12862 | + "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), |
| 12745 | 12863 | #endif |
| 12746 | 12864 | #ifdef SQLITE_DISABLE_DIRSYNC |
| 12747 | 12865 | "DISABLE_DIRSYNC", |
| 12748 | 12866 | #endif |
| 12749 | 12867 | #ifdef SQLITE_DISABLE_LFS |
| | @@ -12831,10 +12949,13 @@ |
| 12831 | 12949 | "INT64_TYPE", |
| 12832 | 12950 | #endif |
| 12833 | 12951 | #ifdef SQLITE_LOCK_TRACE |
| 12834 | 12952 | "LOCK_TRACE", |
| 12835 | 12953 | #endif |
| 12954 | +#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) |
| 12955 | + "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), |
| 12956 | +#endif |
| 12836 | 12957 | #ifdef SQLITE_MAX_SCHEMA_RETRY |
| 12837 | 12958 | "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 12838 | 12959 | #endif |
| 12839 | 12960 | #ifdef SQLITE_MEMDEBUG |
| 12840 | 12961 | "MEMDEBUG", |
| | @@ -12888,15 +13009,10 @@ |
| 12888 | 13009 | "OMIT_CAST", |
| 12889 | 13010 | #endif |
| 12890 | 13011 | #ifdef SQLITE_OMIT_CHECK |
| 12891 | 13012 | "OMIT_CHECK", |
| 12892 | 13013 | #endif |
| 12893 | | -/* // redundant |
| 12894 | | -** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS |
| 12895 | | -** "OMIT_COMPILEOPTION_DIAGS", |
| 12896 | | -** #endif |
| 12897 | | -*/ |
| 12898 | 13014 | #ifdef SQLITE_OMIT_COMPLETE |
| 12899 | 13015 | "OMIT_COMPLETE", |
| 12900 | 13016 | #endif |
| 12901 | 13017 | #ifdef SQLITE_OMIT_COMPOUND_SELECT |
| 12902 | 13018 | "OMIT_COMPOUND_SELECT", |
| | @@ -13034,17 +13150,17 @@ |
| 13034 | 13150 | "SOUNDEX", |
| 13035 | 13151 | #endif |
| 13036 | 13152 | #ifdef SQLITE_TCL |
| 13037 | 13153 | "TCL", |
| 13038 | 13154 | #endif |
| 13039 | | -#ifdef SQLITE_TEMP_STORE |
| 13155 | +#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) |
| 13040 | 13156 | "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), |
| 13041 | 13157 | #endif |
| 13042 | 13158 | #ifdef SQLITE_TEST |
| 13043 | 13159 | "TEST", |
| 13044 | 13160 | #endif |
| 13045 | | -#ifdef SQLITE_THREADSAFE |
| 13161 | +#if defined(SQLITE_THREADSAFE) |
| 13046 | 13162 | "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), |
| 13047 | 13163 | #endif |
| 13048 | 13164 | #ifdef SQLITE_USE_ALLOCA |
| 13049 | 13165 | "USE_ALLOCA", |
| 13050 | 13166 | #endif |
| | @@ -13066,12 +13182,15 @@ |
| 13066 | 13182 | n = sqlite3Strlen30(zOptName); |
| 13067 | 13183 | |
| 13068 | 13184 | /* Since ArraySize(azCompileOpt) is normally in single digits, a |
| 13069 | 13185 | ** linear search is adequate. No need for a binary search. */ |
| 13070 | 13186 | for(i=0; i<ArraySize(azCompileOpt); i++){ |
| 13071 | | - if( (sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0) |
| 13072 | | - && ( (azCompileOpt[i][n]==0) || (azCompileOpt[i][n]=='=') ) ) return 1; |
| 13187 | + if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0 |
| 13188 | + && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0 |
| 13189 | + ){ |
| 13190 | + return 1; |
| 13191 | + } |
| 13073 | 13192 | } |
| 13074 | 13193 | return 0; |
| 13075 | 13194 | } |
| 13076 | 13195 | |
| 13077 | 13196 | /* |
| | @@ -13124,10 +13243,18 @@ |
| 13124 | 13243 | ** this header information was factored out. |
| 13125 | 13244 | */ |
| 13126 | 13245 | #ifndef _VDBEINT_H_ |
| 13127 | 13246 | #define _VDBEINT_H_ |
| 13128 | 13247 | |
| 13248 | +/* |
| 13249 | +** The maximum number of times that a statement will try to reparse |
| 13250 | +** itself before giving up and returning SQLITE_SCHEMA. |
| 13251 | +*/ |
| 13252 | +#ifndef SQLITE_MAX_SCHEMA_RETRY |
| 13253 | +# define SQLITE_MAX_SCHEMA_RETRY 50 |
| 13254 | +#endif |
| 13255 | + |
| 13129 | 13256 | /* |
| 13130 | 13257 | ** SQL is translated into a sequence of instructions to be |
| 13131 | 13258 | ** executed by a virtual machine. Each instruction is an instance |
| 13132 | 13259 | ** of the following structure. |
| 13133 | 13260 | */ |
| | @@ -15089,10 +15216,30 @@ |
| 15089 | 15216 | void volatile **pp /* OUT: Pointer to mapping */ |
| 15090 | 15217 | ){ |
| 15091 | 15218 | DO_OS_MALLOC_TEST(id); |
| 15092 | 15219 | return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); |
| 15093 | 15220 | } |
| 15221 | + |
| 15222 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 15223 | +/* The real implementation of xFetch and xUnfetch */ |
| 15224 | +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ |
| 15225 | + DO_OS_MALLOC_TEST(id); |
| 15226 | + return id->pMethods->xFetch(id, iOff, iAmt, pp); |
| 15227 | +} |
| 15228 | +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ |
| 15229 | + return id->pMethods->xUnfetch(id, iOff, p); |
| 15230 | +} |
| 15231 | +#else |
| 15232 | +/* No-op stubs to use when memory-mapped I/O is disabled */ |
| 15233 | +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ |
| 15234 | + *pp = 0; |
| 15235 | + return SQLITE_OK; |
| 15236 | +} |
| 15237 | +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ |
| 15238 | + return SQLITE_OK; |
| 15239 | +} |
| 15240 | +#endif |
| 15094 | 15241 | |
| 15095 | 15242 | /* |
| 15096 | 15243 | ** The next group of routines are convenience wrappers around the |
| 15097 | 15244 | ** VFS methods. |
| 15098 | 15245 | */ |
| | @@ -21584,11 +21731,11 @@ |
| 21584 | 21731 | *pNum = (i64)u; |
| 21585 | 21732 | } |
| 21586 | 21733 | testcase( i==18 ); |
| 21587 | 21734 | testcase( i==19 ); |
| 21588 | 21735 | testcase( i==20 ); |
| 21589 | | - if( (c+nonNum!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){ |
| 21736 | + if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){ |
| 21590 | 21737 | /* zNum is empty or contains non-numeric text or is longer |
| 21591 | 21738 | ** than 19 digits (thus guaranteeing that it is too large) */ |
| 21592 | 21739 | return 1; |
| 21593 | 21740 | }else if( i<19*incr ){ |
| 21594 | 21741 | /* Less than 19 digits, so we know that it fits in 64 bits */ |
| | @@ -22945,10 +23092,15 @@ |
| 22945 | 23092 | void *lockingContext; /* Locking style specific state */ |
| 22946 | 23093 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 22947 | 23094 | const char *zPath; /* Name of the file */ |
| 22948 | 23095 | unixShm *pShm; /* Shared memory segment information */ |
| 22949 | 23096 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23097 | + int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23098 | + sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23099 | + sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23100 | + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23101 | + void *pMapRegion; /* Memory mapped region */ |
| 22950 | 23102 | #ifdef __QNXNTO__ |
| 22951 | 23103 | int sectorSize; /* Device sector size */ |
| 22952 | 23104 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 22953 | 23105 | #endif |
| 22954 | 23106 | #if SQLITE_ENABLE_LOCKING_STYLE |
| | @@ -22969,11 +23121,13 @@ |
| 22969 | 23121 | ** one described by ticket #3584. |
| 22970 | 23122 | */ |
| 22971 | 23123 | unsigned char transCntrChng; /* True if the transaction counter changed */ |
| 22972 | 23124 | unsigned char dbUpdate; /* True if any part of database file changed */ |
| 22973 | 23125 | unsigned char inNormalWrite; /* True if in a normal write operation */ |
| 23126 | + |
| 22974 | 23127 | #endif |
| 23128 | + |
| 22975 | 23129 | #ifdef SQLITE_TEST |
| 22976 | 23130 | /* In test mode, increase the size of this structure a bit so that |
| 22977 | 23131 | ** it is larger than the struct CrashFile defined in test6.c. |
| 22978 | 23132 | */ |
| 22979 | 23133 | char aPadding[32]; |
| | @@ -22993,10 +23147,11 @@ |
| 22993 | 23147 | #endif |
| 22994 | 23148 | #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ |
| 22995 | 23149 | #define UNIXFILE_DELETE 0x20 /* Delete on close */ |
| 22996 | 23150 | #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ |
| 22997 | 23151 | #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ |
| 23152 | +#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */ |
| 22998 | 23153 | |
| 22999 | 23154 | /* |
| 23000 | 23155 | ** Include code that is common to all os_*.c files |
| 23001 | 23156 | */ |
| 23002 | 23157 | /************** Include os_common.h in the middle of os_unix.c ***************/ |
| | @@ -23234,10 +23389,21 @@ |
| 23234 | 23389 | #define threadid pthread_self() |
| 23235 | 23390 | #else |
| 23236 | 23391 | #define threadid 0 |
| 23237 | 23392 | #endif |
| 23238 | 23393 | |
| 23394 | +/* |
| 23395 | +** HAVE_MREMAP defaults to true on Linux and false everywhere else. |
| 23396 | +*/ |
| 23397 | +#if !defined(HAVE_MREMAP) |
| 23398 | +# if defined(__linux__) && defined(_GNU_SOURCE) |
| 23399 | +# define HAVE_MREMAP 1 |
| 23400 | +# else |
| 23401 | +# define HAVE_MREMAP 0 |
| 23402 | +# endif |
| 23403 | +#endif |
| 23404 | + |
| 23239 | 23405 | /* |
| 23240 | 23406 | ** Different Unix systems declare open() in different ways. Same use |
| 23241 | 23407 | ** open(const char*,int,mode_t). Others use open(const char*,int,...). |
| 23242 | 23408 | ** The difference is important when using a pointer to the function. |
| 23243 | 23409 | ** |
| | @@ -23365,10 +23531,23 @@ |
| 23365 | 23531 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23366 | 23532 | |
| 23367 | 23533 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23368 | 23534 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23369 | 23535 | |
| 23536 | + { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23537 | +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23538 | + |
| 23539 | + { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23540 | +#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| 23541 | + |
| 23542 | +#if HAVE_MREMAP |
| 23543 | + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23544 | +#else |
| 23545 | + { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23546 | +#endif |
| 23547 | +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23548 | + |
| 23370 | 23549 | }; /* End of the overrideable system calls */ |
| 23371 | 23550 | |
| 23372 | 23551 | /* |
| 23373 | 23552 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| 23374 | 23553 | ** "unix" VFSes. Return SQLITE_OK opon successfully updating the |
| | @@ -23694,11 +23873,10 @@ |
| 23694 | 23873 | |
| 23695 | 23874 | default: |
| 23696 | 23875 | return sqliteIOErr; |
| 23697 | 23876 | } |
| 23698 | 23877 | } |
| 23699 | | - |
| 23700 | 23878 | |
| 23701 | 23879 | |
| 23702 | 23880 | /****************************************************************************** |
| 23703 | 23881 | ****************** Begin Unique File ID Utility Used By VxWorks *************** |
| 23704 | 23882 | ** |
| | @@ -24032,11 +24210,10 @@ |
| 24032 | 24210 | #else |
| 24033 | 24211 | /* Non-threadsafe build, use strerror(). */ |
| 24034 | 24212 | zErr = strerror(iErrno); |
| 24035 | 24213 | #endif |
| 24036 | 24214 | |
| 24037 | | - assert( errcode!=SQLITE_OK ); |
| 24038 | 24215 | if( zPath==0 ) zPath = ""; |
| 24039 | 24216 | sqlite3_log(errcode, |
| 24040 | 24217 | "os_unix.c:%d: (%d) %s(%s) - %s", |
| 24041 | 24218 | iLine, iErrno, zFunc, zPath, zErr |
| 24042 | 24219 | ); |
| | @@ -24197,10 +24374,54 @@ |
| 24197 | 24374 | } |
| 24198 | 24375 | *ppInode = pInode; |
| 24199 | 24376 | return SQLITE_OK; |
| 24200 | 24377 | } |
| 24201 | 24378 | |
| 24379 | + |
| 24380 | +/* |
| 24381 | +** Check a unixFile that is a database. Verify the following: |
| 24382 | +** |
| 24383 | +** (1) There is exactly one hard link on the file |
| 24384 | +** (2) The file is not a symbolic link |
| 24385 | +** (3) The file has not been renamed or unlinked |
| 24386 | +** |
| 24387 | +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. |
| 24388 | +*/ |
| 24389 | +static void verifyDbFile(unixFile *pFile){ |
| 24390 | + struct stat buf; |
| 24391 | + int rc; |
| 24392 | + if( pFile->ctrlFlags & UNIXFILE_WARNED ){ |
| 24393 | + /* One or more of the following warnings have already been issued. Do not |
| 24394 | + ** repeat them so as not to clutter the error log */ |
| 24395 | + return; |
| 24396 | + } |
| 24397 | + rc = osFstat(pFile->h, &buf); |
| 24398 | + if( rc!=0 ){ |
| 24399 | + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); |
| 24400 | + pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24401 | + return; |
| 24402 | + } |
| 24403 | + if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ |
| 24404 | + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); |
| 24405 | + pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24406 | + return; |
| 24407 | + } |
| 24408 | + if( buf.st_nlink>1 ){ |
| 24409 | + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
| 24410 | + pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24411 | + return; |
| 24412 | + } |
| 24413 | + if( pFile->pInode!=0 |
| 24414 | + && ((rc = osStat(pFile->zPath, &buf))!=0 |
| 24415 | + || buf.st_ino!=pFile->pInode->fileId.ino) |
| 24416 | + ){ |
| 24417 | + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); |
| 24418 | + pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24419 | + return; |
| 24420 | + } |
| 24421 | +} |
| 24422 | + |
| 24202 | 24423 | |
| 24203 | 24424 | /* |
| 24204 | 24425 | ** This routine checks if there is a RESERVED lock held on the specified |
| 24205 | 24426 | ** file by this or any other process. If such a lock is held, set *pResOut |
| 24206 | 24427 | ** to a non-zero value otherwise *pResOut is set to zero. The return value |
| | @@ -24728,12 +24949,16 @@ |
| 24728 | 24949 | ** |
| 24729 | 24950 | ** If the locking level of the file descriptor is already at or below |
| 24730 | 24951 | ** the requested locking level, this routine is a no-op. |
| 24731 | 24952 | */ |
| 24732 | 24953 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24954 | + assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24733 | 24955 | return posixUnlock(id, eFileLock, 0); |
| 24734 | 24956 | } |
| 24957 | + |
| 24958 | +static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24959 | +static void unixUnmapfile(unixFile *pFd); |
| 24735 | 24960 | |
| 24736 | 24961 | /* |
| 24737 | 24962 | ** This function performs the parts of the "close file" operation |
| 24738 | 24963 | ** common to all locking schemes. It closes the directory and file |
| 24739 | 24964 | ** handles, if they are valid, and sets all fields of the unixFile |
| | @@ -24743,10 +24968,11 @@ |
| 24743 | 24968 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24744 | 24969 | ** vxworksReleaseFileId() routine. |
| 24745 | 24970 | */ |
| 24746 | 24971 | static int closeUnixFile(sqlite3_file *id){ |
| 24747 | 24972 | unixFile *pFile = (unixFile*)id; |
| 24973 | + unixUnmapfile(pFile); |
| 24748 | 24974 | if( pFile->h>=0 ){ |
| 24749 | 24975 | robust_close(pFile, pFile->h, __LINE__); |
| 24750 | 24976 | pFile->h = -1; |
| 24751 | 24977 | } |
| 24752 | 24978 | #if OS_VXWORKS |
| | @@ -24769,10 +24995,11 @@ |
| 24769 | 24995 | ** Close a file. |
| 24770 | 24996 | */ |
| 24771 | 24997 | static int unixClose(sqlite3_file *id){ |
| 24772 | 24998 | int rc = SQLITE_OK; |
| 24773 | 24999 | unixFile *pFile = (unixFile *)id; |
| 25000 | + verifyDbFile(pFile); |
| 24774 | 25001 | unixUnlock(id, NO_LOCK); |
| 24775 | 25002 | unixEnterMutex(); |
| 24776 | 25003 | |
| 24777 | 25004 | /* unixFile.pInode is always valid here. Otherwise, a different close |
| 24778 | 25005 | ** routine (e.g. nolockClose()) would be called instead. |
| | @@ -26009,10 +26236,27 @@ |
| 26009 | 26236 | assert( pFile->pUnused==0 |
| 26010 | 26237 | || offset>=PENDING_BYTE+512 |
| 26011 | 26238 | || offset+amt<=PENDING_BYTE |
| 26012 | 26239 | ); |
| 26013 | 26240 | #endif |
| 26241 | + |
| 26242 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26243 | + /* Deal with as much of this read request as possible by transfering |
| 26244 | + ** data from the memory mapping using memcpy(). */ |
| 26245 | + if( offset<pFile->mmapSize ){ |
| 26246 | + if( offset+amt <= pFile->mmapSize ){ |
| 26247 | + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); |
| 26248 | + return SQLITE_OK; |
| 26249 | + }else{ |
| 26250 | + int nCopy = pFile->mmapSize - offset; |
| 26251 | + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); |
| 26252 | + pBuf = &((u8 *)pBuf)[nCopy]; |
| 26253 | + amt -= nCopy; |
| 26254 | + offset += nCopy; |
| 26255 | + } |
| 26256 | + } |
| 26257 | +#endif |
| 26014 | 26258 | |
| 26015 | 26259 | got = seekAndRead(pFile, offset, pBuf, amt); |
| 26016 | 26260 | if( got==amt ){ |
| 26017 | 26261 | return SQLITE_OK; |
| 26018 | 26262 | }else if( got<0 ){ |
| | @@ -26111,10 +26355,27 @@ |
| 26111 | 26355 | SimulateIOErrorBenign(0); |
| 26112 | 26356 | if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ |
| 26113 | 26357 | pFile->transCntrChng = 1; /* The transaction counter has changed */ |
| 26114 | 26358 | } |
| 26115 | 26359 | } |
| 26360 | + } |
| 26361 | +#endif |
| 26362 | + |
| 26363 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26364 | + /* Deal with as much of this write request as possible by transfering |
| 26365 | + ** data from the memory mapping using memcpy(). */ |
| 26366 | + if( offset<pFile->mmapSize ){ |
| 26367 | + if( offset+amt <= pFile->mmapSize ){ |
| 26368 | + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
| 26369 | + return SQLITE_OK; |
| 26370 | + }else{ |
| 26371 | + int nCopy = pFile->mmapSize - offset; |
| 26372 | + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
| 26373 | + pBuf = &((u8 *)pBuf)[nCopy]; |
| 26374 | + amt -= nCopy; |
| 26375 | + offset += nCopy; |
| 26376 | + } |
| 26116 | 26377 | } |
| 26117 | 26378 | #endif |
| 26118 | 26379 | |
| 26119 | 26380 | while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ |
| 26120 | 26381 | amt -= wrote; |
| | @@ -26395,10 +26656,18 @@ |
| 26395 | 26656 | */ |
| 26396 | 26657 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26397 | 26658 | pFile->transCntrChng = 1; |
| 26398 | 26659 | } |
| 26399 | 26660 | #endif |
| 26661 | + |
| 26662 | + /* If the file was just truncated to a size smaller than the currently |
| 26663 | + ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26664 | + ** use read() and write() to access data beyond this point from now on. |
| 26665 | + */ |
| 26666 | + if( nByte<pFile->mmapSize ){ |
| 26667 | + pFile->mmapSize = nByte; |
| 26668 | + } |
| 26400 | 26669 | |
| 26401 | 26670 | return SQLITE_OK; |
| 26402 | 26671 | } |
| 26403 | 26672 | } |
| 26404 | 26673 | |
| | @@ -26483,10 +26752,23 @@ |
| 26483 | 26752 | iWrite += nBlk; |
| 26484 | 26753 | } |
| 26485 | 26754 | #endif |
| 26486 | 26755 | } |
| 26487 | 26756 | } |
| 26757 | + |
| 26758 | + if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26759 | + int rc; |
| 26760 | + if( pFile->szChunk<=0 ){ |
| 26761 | + if( robust_ftruncate(pFile->h, nByte) ){ |
| 26762 | + pFile->lastErrno = errno; |
| 26763 | + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); |
| 26764 | + } |
| 26765 | + } |
| 26766 | + |
| 26767 | + rc = unixMapfile(pFile, nByte); |
| 26768 | + return rc; |
| 26769 | + } |
| 26488 | 26770 | |
| 26489 | 26771 | return SQLITE_OK; |
| 26490 | 26772 | } |
| 26491 | 26773 | |
| 26492 | 26774 | /* |
| | @@ -26550,10 +26832,22 @@ |
| 26550 | 26832 | if( zTFile ){ |
| 26551 | 26833 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26552 | 26834 | *(char**)pArg = zTFile; |
| 26553 | 26835 | } |
| 26554 | 26836 | return SQLITE_OK; |
| 26837 | + } |
| 26838 | + case SQLITE_FCNTL_MMAP_SIZE: { |
| 26839 | + i64 newLimit = *(i64*)pArg; |
| 26840 | + if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26841 | + newLimit = sqlite3GlobalConfig.mxMmap; |
| 26842 | + } |
| 26843 | + *(i64*)pArg = pFile->mmapSizeMax; |
| 26844 | + if( newLimit>=0 ){ |
| 26845 | + pFile->mmapSizeMax = newLimit; |
| 26846 | + if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit; |
| 26847 | + } |
| 26848 | + return SQLITE_OK; |
| 26555 | 26849 | } |
| 26556 | 26850 | #ifdef SQLITE_DEBUG |
| 26557 | 26851 | /* The pager calls this method to signal that it has done |
| 26558 | 26852 | ** a rollback and that the database is therefore unchanged and |
| 26559 | 26853 | ** it hence it is OK for the transaction change counter to be |
| | @@ -26863,11 +27157,11 @@ |
| 26863 | 27157 | int i; |
| 26864 | 27158 | assert( p->pInode==pFd->pInode ); |
| 26865 | 27159 | sqlite3_mutex_free(p->mutex); |
| 26866 | 27160 | for(i=0; i<p->nRegion; i++){ |
| 26867 | 27161 | if( p->h>=0 ){ |
| 26868 | | - munmap(p->apRegion[i], p->szRegion); |
| 27162 | + osMunmap(p->apRegion[i], p->szRegion); |
| 26869 | 27163 | }else{ |
| 26870 | 27164 | sqlite3_free(p->apRegion[i]); |
| 26871 | 27165 | } |
| 26872 | 27166 | } |
| 26873 | 27167 | sqlite3_free(p->apRegion); |
| | @@ -27136,11 +27430,11 @@ |
| 27136 | 27430 | } |
| 27137 | 27431 | pShmNode->apRegion = apNew; |
| 27138 | 27432 | while(pShmNode->nRegion<=iRegion){ |
| 27139 | 27433 | void *pMem; |
| 27140 | 27434 | if( pShmNode->h>=0 ){ |
| 27141 | | - pMem = mmap(0, szRegion, |
| 27435 | + pMem = osMmap(0, szRegion, |
| 27142 | 27436 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 27143 | 27437 | MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion |
| 27144 | 27438 | ); |
| 27145 | 27439 | if( pMem==MAP_FAILED ){ |
| 27146 | 27440 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| | @@ -27352,10 +27646,240 @@ |
| 27352 | 27646 | # define unixShmMap 0 |
| 27353 | 27647 | # define unixShmLock 0 |
| 27354 | 27648 | # define unixShmBarrier 0 |
| 27355 | 27649 | # define unixShmUnmap 0 |
| 27356 | 27650 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27651 | + |
| 27652 | +/* |
| 27653 | +** If it is currently memory mapped, unmap file pFd. |
| 27654 | +*/ |
| 27655 | +static void unixUnmapfile(unixFile *pFd){ |
| 27656 | + assert( pFd->nFetchOut==0 ); |
| 27657 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27658 | + if( pFd->pMapRegion ){ |
| 27659 | + osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27660 | + pFd->pMapRegion = 0; |
| 27661 | + pFd->mmapSize = 0; |
| 27662 | + pFd->mmapSizeActual = 0; |
| 27663 | + } |
| 27664 | +#endif |
| 27665 | +} |
| 27666 | + |
| 27667 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27668 | +/* |
| 27669 | +** Return the system page size. |
| 27670 | +*/ |
| 27671 | +static int unixGetPagesize(void){ |
| 27672 | +#if HAVE_MREMAP |
| 27673 | + return 512; |
| 27674 | +#elif defined(_BSD_SOURCE) |
| 27675 | + return getpagesize(); |
| 27676 | +#else |
| 27677 | + return (int)sysconf(_SC_PAGESIZE); |
| 27678 | +#endif |
| 27679 | +} |
| 27680 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27681 | + |
| 27682 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27683 | +/* |
| 27684 | +** Attempt to set the size of the memory mapping maintained by file |
| 27685 | +** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27686 | +** |
| 27687 | +** If successful, this function sets the following variables: |
| 27688 | +** |
| 27689 | +** unixFile.pMapRegion |
| 27690 | +** unixFile.mmapSize |
| 27691 | +** unixFile.mmapSizeActual |
| 27692 | +** |
| 27693 | +** If unsuccessful, an error message is logged via sqlite3_log() and |
| 27694 | +** the three variables above are zeroed. In this case SQLite should |
| 27695 | +** continue accessing the database using the xRead() and xWrite() |
| 27696 | +** methods. |
| 27697 | +*/ |
| 27698 | +static void unixRemapfile( |
| 27699 | + unixFile *pFd, /* File descriptor object */ |
| 27700 | + i64 nNew /* Required mapping size */ |
| 27701 | +){ |
| 27702 | + const char *zErr = "mmap"; |
| 27703 | + int h = pFd->h; /* File descriptor open on db file */ |
| 27704 | + u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ |
| 27705 | + i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ |
| 27706 | + u8 *pNew = 0; /* Location of new mapping */ |
| 27707 | + int flags = PROT_READ; /* Flags to pass to mmap() */ |
| 27708 | + |
| 27709 | + assert( pFd->nFetchOut==0 ); |
| 27710 | + assert( nNew>pFd->mmapSize ); |
| 27711 | + assert( nNew<=pFd->mmapSizeMax ); |
| 27712 | + assert( nNew>0 ); |
| 27713 | + assert( pFd->mmapSizeActual>=pFd->mmapSize ); |
| 27714 | + assert( MAP_FAILED!=0 ); |
| 27715 | + |
| 27716 | + if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; |
| 27717 | + |
| 27718 | + if( pOrig ){ |
| 27719 | + const int szSyspage = unixGetPagesize(); |
| 27720 | + i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); |
| 27721 | + u8 *pReq = &pOrig[nReuse]; |
| 27722 | + |
| 27723 | + /* Unmap any pages of the existing mapping that cannot be reused. */ |
| 27724 | + if( nReuse!=nOrig ){ |
| 27725 | + osMunmap(pReq, nOrig-nReuse); |
| 27726 | + } |
| 27727 | + |
| 27728 | +#if HAVE_MREMAP |
| 27729 | + pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); |
| 27730 | + zErr = "mremap"; |
| 27731 | +#else |
| 27732 | + pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); |
| 27733 | + if( pNew!=MAP_FAILED ){ |
| 27734 | + if( pNew!=pReq ){ |
| 27735 | + osMunmap(pNew, nNew - nReuse); |
| 27736 | + pNew = 0; |
| 27737 | + }else{ |
| 27738 | + pNew = pOrig; |
| 27739 | + } |
| 27740 | + } |
| 27741 | +#endif |
| 27742 | + |
| 27743 | + /* The attempt to extend the existing mapping failed. Free it. */ |
| 27744 | + if( pNew==MAP_FAILED || pNew==0 ){ |
| 27745 | + osMunmap(pOrig, nReuse); |
| 27746 | + } |
| 27747 | + } |
| 27748 | + |
| 27749 | + /* If pNew is still NULL, try to create an entirely new mapping. */ |
| 27750 | + if( pNew==0 ){ |
| 27751 | + pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0); |
| 27752 | + } |
| 27753 | + |
| 27754 | + if( pNew==MAP_FAILED ){ |
| 27755 | + pNew = 0; |
| 27756 | + nNew = 0; |
| 27757 | + unixLogError(SQLITE_OK, zErr, pFd->zPath); |
| 27758 | + |
| 27759 | + /* If the mmap() above failed, assume that all subsequent mmap() calls |
| 27760 | + ** will probably fail too. Fall back to using xRead/xWrite exclusively |
| 27761 | + ** in this case. */ |
| 27762 | + pFd->mmapSizeMax = 0; |
| 27763 | + } |
| 27764 | + pFd->pMapRegion = (void *)pNew; |
| 27765 | + pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27766 | +} |
| 27767 | +#endif |
| 27768 | + |
| 27769 | +/* |
| 27770 | +** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27771 | +** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27772 | +** there already exists a mapping for this file, and there are still |
| 27773 | +** outstanding xFetch() references to it, this function is a no-op. |
| 27774 | +** |
| 27775 | +** If parameter nByte is non-negative, then it is the requested size of |
| 27776 | +** the mapping to create. Otherwise, if nByte is less than zero, then the |
| 27777 | +** requested size is the size of the file on disk. The actual size of the |
| 27778 | +** created mapping is either the requested size or the value configured |
| 27779 | +** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. |
| 27780 | +** |
| 27781 | +** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27782 | +** recreated as a result of outstanding references) or an SQLite error |
| 27783 | +** code otherwise. |
| 27784 | +*/ |
| 27785 | +static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27786 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27787 | + i64 nMap = nByte; |
| 27788 | + int rc; |
| 27789 | + |
| 27790 | + assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27791 | + if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| 27792 | + |
| 27793 | + if( nMap<0 ){ |
| 27794 | + struct stat statbuf; /* Low-level file information */ |
| 27795 | + rc = osFstat(pFd->h, &statbuf); |
| 27796 | + if( rc!=SQLITE_OK ){ |
| 27797 | + return SQLITE_IOERR_FSTAT; |
| 27798 | + } |
| 27799 | + nMap = statbuf.st_size; |
| 27800 | + } |
| 27801 | + if( nMap>pFd->mmapSizeMax ){ |
| 27802 | + nMap = pFd->mmapSizeMax; |
| 27803 | + } |
| 27804 | + |
| 27805 | + if( nMap!=pFd->mmapSize ){ |
| 27806 | + if( nMap>0 ){ |
| 27807 | + unixRemapfile(pFd, nMap); |
| 27808 | + }else{ |
| 27809 | + unixUnmapfile(pFd); |
| 27810 | + } |
| 27811 | + } |
| 27812 | +#endif |
| 27813 | + |
| 27814 | + return SQLITE_OK; |
| 27815 | +} |
| 27816 | + |
| 27817 | +/* |
| 27818 | +** If possible, return a pointer to a mapping of file fd starting at offset |
| 27819 | +** iOff. The mapping must be valid for at least nAmt bytes. |
| 27820 | +** |
| 27821 | +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. |
| 27822 | +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. |
| 27823 | +** Finally, if an error does occur, return an SQLite error code. The final |
| 27824 | +** value of *pp is undefined in this case. |
| 27825 | +** |
| 27826 | +** If this function does return a pointer, the caller must eventually |
| 27827 | +** release the reference by calling unixUnfetch(). |
| 27828 | +*/ |
| 27829 | +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ |
| 27830 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27831 | + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27832 | +#endif |
| 27833 | + *pp = 0; |
| 27834 | + |
| 27835 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27836 | + if( pFd->mmapSizeMax>0 ){ |
| 27837 | + if( pFd->pMapRegion==0 ){ |
| 27838 | + int rc = unixMapfile(pFd, -1); |
| 27839 | + if( rc!=SQLITE_OK ) return rc; |
| 27840 | + } |
| 27841 | + if( pFd->mmapSize >= iOff+nAmt ){ |
| 27842 | + *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 27843 | + pFd->nFetchOut++; |
| 27844 | + } |
| 27845 | + } |
| 27846 | +#endif |
| 27847 | + return SQLITE_OK; |
| 27848 | +} |
| 27849 | + |
| 27850 | +/* |
| 27851 | +** If the third argument is non-NULL, then this function releases a |
| 27852 | +** reference obtained by an earlier call to unixFetch(). The second |
| 27853 | +** argument passed to this function must be the same as the corresponding |
| 27854 | +** argument that was passed to the unixFetch() invocation. |
| 27855 | +** |
| 27856 | +** Or, if the third argument is NULL, then this function is being called |
| 27857 | +** to inform the VFS layer that, according to POSIX, any existing mapping |
| 27858 | +** may now be invalid and should be unmapped. |
| 27859 | +*/ |
| 27860 | +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27861 | + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27862 | + UNUSED_PARAMETER(iOff); |
| 27863 | + |
| 27864 | + /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27865 | + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27866 | + ** then there must be at least one outstanding. */ |
| 27867 | + assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27868 | + |
| 27869 | + /* If p!=0, it must match the iOff value. */ |
| 27870 | + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); |
| 27871 | + |
| 27872 | + if( p ){ |
| 27873 | + pFd->nFetchOut--; |
| 27874 | + }else{ |
| 27875 | + unixUnmapfile(pFd); |
| 27876 | + } |
| 27877 | + |
| 27878 | + assert( pFd->nFetchOut>=0 ); |
| 27879 | + return SQLITE_OK; |
| 27880 | +} |
| 27357 | 27881 | |
| 27358 | 27882 | /* |
| 27359 | 27883 | ** Here ends the implementation of all sqlite3_file methods. |
| 27360 | 27884 | ** |
| 27361 | 27885 | ********************** End sqlite3_file Methods ******************************* |
| | @@ -27411,11 +27935,13 @@ |
| 27411 | 27935 | unixSectorSize, /* xSectorSize */ \ |
| 27412 | 27936 | unixDeviceCharacteristics, /* xDeviceCapabilities */ \ |
| 27413 | 27937 | unixShmMap, /* xShmMap */ \ |
| 27414 | 27938 | unixShmLock, /* xShmLock */ \ |
| 27415 | 27939 | unixShmBarrier, /* xShmBarrier */ \ |
| 27416 | | - unixShmUnmap /* xShmUnmap */ \ |
| 27940 | + unixShmUnmap, /* xShmUnmap */ \ |
| 27941 | + unixFetch, /* xFetch */ \ |
| 27942 | + unixUnfetch, /* xUnfetch */ \ |
| 27417 | 27943 | }; \ |
| 27418 | 27944 | static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ |
| 27419 | 27945 | UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ |
| 27420 | 27946 | return &METHOD; \ |
| 27421 | 27947 | } \ |
| | @@ -27428,11 +27954,11 @@ |
| 27428 | 27954 | ** are also created. |
| 27429 | 27955 | */ |
| 27430 | 27956 | IOMETHODS( |
| 27431 | 27957 | posixIoFinder, /* Finder function name */ |
| 27432 | 27958 | posixIoMethods, /* sqlite3_io_methods object name */ |
| 27433 | | - 2, /* shared memory is enabled */ |
| 27959 | + 3, /* shared memory and mmap are enabled */ |
| 27434 | 27960 | unixClose, /* xClose method */ |
| 27435 | 27961 | unixLock, /* xLock method */ |
| 27436 | 27962 | unixUnlock, /* xUnlock method */ |
| 27437 | 27963 | unixCheckReservedLock /* xCheckReservedLock method */ |
| 27438 | 27964 | ) |
| | @@ -27679,10 +28205,11 @@ |
| 27679 | 28205 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 27680 | 28206 | pNew->h = h; |
| 27681 | 28207 | pNew->pVfs = pVfs; |
| 27682 | 28208 | pNew->zPath = zFilename; |
| 27683 | 28209 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28210 | + pNew->mmapSizeMax = sqlite3GlobalConfig.mxMmap; |
| 27684 | 28211 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 27685 | 28212 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 27686 | 28213 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 27687 | 28214 | } |
| 27688 | 28215 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| | @@ -27823,10 +28350,11 @@ |
| 27823 | 28350 | if( rc!=SQLITE_OK ){ |
| 27824 | 28351 | if( h>=0 ) robust_close(pNew, h, __LINE__); |
| 27825 | 28352 | }else{ |
| 27826 | 28353 | pNew->pMethod = pLockingStyle; |
| 27827 | 28354 | OpenCounter(+1); |
| 28355 | + verifyDbFile(pNew); |
| 27828 | 28356 | } |
| 27829 | 28357 | return rc; |
| 27830 | 28358 | } |
| 27831 | 28359 | |
| 27832 | 28360 | /* |
| | @@ -29916,11 +30444,11 @@ |
| 29916 | 30444 | }; |
| 29917 | 30445 | unsigned int i; /* Loop counter */ |
| 29918 | 30446 | |
| 29919 | 30447 | /* Double-check that the aSyscall[] array has been constructed |
| 29920 | 30448 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 29921 | | - assert( ArraySize(aSyscall)==21 ); |
| 30449 | + assert( ArraySize(aSyscall)==24 ); |
| 29922 | 30450 | |
| 29923 | 30451 | /* Register all VFSes defined in the aVfs[] array */ |
| 29924 | 30452 | for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |
| 29925 | 30453 | sqlite3_vfs_register(&aVfs[i], i==0); |
| 29926 | 30454 | } |
| | @@ -30299,15 +30827,24 @@ |
| 30299 | 30827 | HANDLE hMutex; /* Mutex used to control access to shared lock */ |
| 30300 | 30828 | HANDLE hShared; /* Shared memory segment used for locking */ |
| 30301 | 30829 | winceLock local; /* Locks obtained by this instance of winFile */ |
| 30302 | 30830 | winceLock *shared; /* Global shared lock memory for the file */ |
| 30303 | 30831 | #endif |
| 30832 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 30833 | + int nFetchOut; /* Number of outstanding xFetch references */ |
| 30834 | + HANDLE hMap; /* Handle for accessing memory mapping */ |
| 30835 | + void *pMapRegion; /* Area memory mapped */ |
| 30836 | + sqlite3_int64 mmapSize; /* Usable size of mapped region */ |
| 30837 | + sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */ |
| 30838 | + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 30839 | +#endif |
| 30304 | 30840 | }; |
| 30305 | 30841 | |
| 30306 | 30842 | /* |
| 30307 | 30843 | ** Allowed values for winFile.ctrlFlags |
| 30308 | 30844 | */ |
| 30845 | +#define WINFILE_RDONLY 0x02 /* Connection is read only */ |
| 30309 | 30846 | #define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ |
| 30310 | 30847 | #define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ |
| 30311 | 30848 | |
| 30312 | 30849 | /* |
| 30313 | 30850 | * The size of the buffer used by sqlite3_win32_write_debug(). |
| | @@ -32210,10 +32747,15 @@ |
| 32210 | 32747 | |
| 32211 | 32748 | return 0; |
| 32212 | 32749 | #endif |
| 32213 | 32750 | } |
| 32214 | 32751 | |
| 32752 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 32753 | +/* Forward references to VFS methods */ |
| 32754 | +static int winUnmapfile(winFile*); |
| 32755 | +#endif |
| 32756 | + |
| 32215 | 32757 | /* |
| 32216 | 32758 | ** Close a file. |
| 32217 | 32759 | ** |
| 32218 | 32760 | ** It is reported that an attempt to close a handle might sometimes |
| 32219 | 32761 | ** fail. This is a very unreasonable result, but Windows is notorious |
| | @@ -32231,10 +32773,16 @@ |
| 32231 | 32773 | #ifndef SQLITE_OMIT_WAL |
| 32232 | 32774 | assert( pFile->pShm==0 ); |
| 32233 | 32775 | #endif |
| 32234 | 32776 | OSTRACE(("CLOSE %d\n", pFile->h)); |
| 32235 | 32777 | assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); |
| 32778 | + |
| 32779 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 32780 | + rc = winUnmapfile(pFile); |
| 32781 | + if( rc!=SQLITE_OK ) return rc; |
| 32782 | +#endif |
| 32783 | + |
| 32236 | 32784 | do{ |
| 32237 | 32785 | rc = osCloseHandle(pFile->h); |
| 32238 | 32786 | /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ |
| 32239 | 32787 | }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); |
| 32240 | 32788 | #if SQLITE_OS_WINCE |
| | @@ -32279,12 +32827,30 @@ |
| 32279 | 32827 | winFile *pFile = (winFile*)id; /* file handle */ |
| 32280 | 32828 | DWORD nRead; /* Number of bytes actually read from file */ |
| 32281 | 32829 | int nRetry = 0; /* Number of retrys */ |
| 32282 | 32830 | |
| 32283 | 32831 | assert( id!=0 ); |
| 32832 | + assert( amt>0 ); |
| 32284 | 32833 | SimulateIOError(return SQLITE_IOERR_READ); |
| 32285 | 32834 | OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); |
| 32835 | + |
| 32836 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 32837 | + /* Deal with as much of this read request as possible by transfering |
| 32838 | + ** data from the memory mapping using memcpy(). */ |
| 32839 | + if( offset<pFile->mmapSize ){ |
| 32840 | + if( offset+amt <= pFile->mmapSize ){ |
| 32841 | + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); |
| 32842 | + return SQLITE_OK; |
| 32843 | + }else{ |
| 32844 | + int nCopy = (int)(pFile->mmapSize - offset); |
| 32845 | + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); |
| 32846 | + pBuf = &((u8 *)pBuf)[nCopy]; |
| 32847 | + amt -= nCopy; |
| 32848 | + offset += nCopy; |
| 32849 | + } |
| 32850 | + } |
| 32851 | +#endif |
| 32286 | 32852 | |
| 32287 | 32853 | #if SQLITE_OS_WINCE |
| 32288 | 32854 | if( seekWinFile(pFile, offset) ){ |
| 32289 | 32855 | return SQLITE_FULL; |
| 32290 | 32856 | } |
| | @@ -32330,10 +32896,27 @@ |
| 32330 | 32896 | assert( pFile ); |
| 32331 | 32897 | SimulateIOError(return SQLITE_IOERR_WRITE); |
| 32332 | 32898 | SimulateDiskfullError(return SQLITE_FULL); |
| 32333 | 32899 | |
| 32334 | 32900 | OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); |
| 32901 | + |
| 32902 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 32903 | + /* Deal with as much of this write request as possible by transfering |
| 32904 | + ** data from the memory mapping using memcpy(). */ |
| 32905 | + if( offset<pFile->mmapSize ){ |
| 32906 | + if( offset+amt <= pFile->mmapSize ){ |
| 32907 | + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
| 32908 | + return SQLITE_OK; |
| 32909 | + }else{ |
| 32910 | + int nCopy = (int)(pFile->mmapSize - offset); |
| 32911 | + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
| 32912 | + pBuf = &((u8 *)pBuf)[nCopy]; |
| 32913 | + amt -= nCopy; |
| 32914 | + offset += nCopy; |
| 32915 | + } |
| 32916 | + } |
| 32917 | +#endif |
| 32335 | 32918 | |
| 32336 | 32919 | #if SQLITE_OS_WINCE |
| 32337 | 32920 | rc = seekWinFile(pFile, offset); |
| 32338 | 32921 | if( rc==0 ){ |
| 32339 | 32922 | #else |
| | @@ -32398,10 +32981,11 @@ |
| 32398 | 32981 | ** Truncate an open file to a specified size |
| 32399 | 32982 | */ |
| 32400 | 32983 | static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ |
| 32401 | 32984 | winFile *pFile = (winFile*)id; /* File handle object */ |
| 32402 | 32985 | int rc = SQLITE_OK; /* Return code for this function */ |
| 32986 | + DWORD lastErrno; |
| 32403 | 32987 | |
| 32404 | 32988 | assert( pFile ); |
| 32405 | 32989 | |
| 32406 | 32990 | OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); |
| 32407 | 32991 | SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
| | @@ -32416,16 +33000,27 @@ |
| 32416 | 33000 | } |
| 32417 | 33001 | |
| 32418 | 33002 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 32419 | 33003 | if( seekWinFile(pFile, nByte) ){ |
| 32420 | 33004 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 32421 | | - "winTruncate1", pFile->zPath); |
| 32422 | | - }else if( 0==osSetEndOfFile(pFile->h) ){ |
| 32423 | | - pFile->lastErrno = osGetLastError(); |
| 33005 | + "winTruncate1", pFile->zPath); |
| 33006 | + }else if( 0==osSetEndOfFile(pFile->h) && |
| 33007 | + ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33008 | + pFile->lastErrno = lastErrno; |
| 32424 | 33009 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 32425 | | - "winTruncate2", pFile->zPath); |
| 33010 | + "winTruncate2", pFile->zPath); |
| 32426 | 33011 | } |
| 33012 | + |
| 33013 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 33014 | + /* If the file was truncated to a size smaller than the currently |
| 33015 | + ** mapped region, reduce the effective mapping size as well. SQLite will |
| 33016 | + ** use read() and write() to access data beyond this point from now on. |
| 33017 | + */ |
| 33018 | + if( pFile->pMapRegion && nByte<pFile->mmapSize ){ |
| 33019 | + pFile->mmapSize = nByte; |
| 33020 | + } |
| 33021 | +#endif |
| 32427 | 33022 | |
| 32428 | 33023 | OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); |
| 32429 | 33024 | return rc; |
| 32430 | 33025 | } |
| 32431 | 33026 | |
| | @@ -32790,11 +33385,11 @@ |
| 32790 | 33385 | assert( id!=0 ); |
| 32791 | 33386 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 32792 | 33387 | rc = 1; |
| 32793 | 33388 | OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); |
| 32794 | 33389 | }else{ |
| 32795 | | - rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); |
| 33390 | + rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 32796 | 33391 | if( rc ){ |
| 32797 | 33392 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 32798 | 33393 | } |
| 32799 | 33394 | rc = !rc; |
| 32800 | 33395 | OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); |
| | @@ -32930,10 +33525,21 @@ |
| 32930 | 33525 | getTempname(pFile->pVfs->mxPathname, zTFile); |
| 32931 | 33526 | *(char**)pArg = zTFile; |
| 32932 | 33527 | } |
| 32933 | 33528 | return SQLITE_OK; |
| 32934 | 33529 | } |
| 33530 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 33531 | + case SQLITE_FCNTL_MMAP_SIZE: { |
| 33532 | + i64 newLimit = *(i64*)pArg; |
| 33533 | + if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 33534 | + newLimit = sqlite3GlobalConfig.mxMmap; |
| 33535 | + } |
| 33536 | + *(i64*)pArg = pFile->mmapSizeMax; |
| 33537 | + if( newLimit>=0 ) pFile->mmapSizeMax = newLimit; |
| 33538 | + return SQLITE_OK; |
| 33539 | + } |
| 33540 | +#endif |
| 32935 | 33541 | } |
| 32936 | 33542 | return SQLITE_NOTFOUND; |
| 32937 | 33543 | } |
| 32938 | 33544 | |
| 32939 | 33545 | /* |
| | @@ -33599,10 +34205,196 @@ |
| 33599 | 34205 | # define winShmMap 0 |
| 33600 | 34206 | # define winShmLock 0 |
| 33601 | 34207 | # define winShmBarrier 0 |
| 33602 | 34208 | # define winShmUnmap 0 |
| 33603 | 34209 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 34210 | + |
| 34211 | +/* |
| 34212 | +** Cleans up the mapped region of the specified file, if any. |
| 34213 | +*/ |
| 34214 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 34215 | +static int winUnmapfile(winFile *pFile){ |
| 34216 | + assert( pFile!=0 ); |
| 34217 | + if( pFile->pMapRegion ){ |
| 34218 | + if( !osUnmapViewOfFile(pFile->pMapRegion) ){ |
| 34219 | + pFile->lastErrno = osGetLastError(); |
| 34220 | + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34221 | + "winUnmap1", pFile->zPath); |
| 34222 | + } |
| 34223 | + pFile->pMapRegion = 0; |
| 34224 | + pFile->mmapSize = 0; |
| 34225 | + pFile->mmapSizeActual = 0; |
| 34226 | + } |
| 34227 | + if( pFile->hMap!=NULL ){ |
| 34228 | + if( !osCloseHandle(pFile->hMap) ){ |
| 34229 | + pFile->lastErrno = osGetLastError(); |
| 34230 | + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34231 | + "winUnmap2", pFile->zPath); |
| 34232 | + } |
| 34233 | + pFile->hMap = NULL; |
| 34234 | + } |
| 34235 | + return SQLITE_OK; |
| 34236 | +} |
| 34237 | + |
| 34238 | +/* |
| 34239 | +** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 34240 | +** is already mapped, the existing mapping is replaced by the new). Or, if |
| 34241 | +** there already exists a mapping for this file, and there are still |
| 34242 | +** outstanding xFetch() references to it, this function is a no-op. |
| 34243 | +** |
| 34244 | +** If parameter nByte is non-negative, then it is the requested size of |
| 34245 | +** the mapping to create. Otherwise, if nByte is less than zero, then the |
| 34246 | +** requested size is the size of the file on disk. The actual size of the |
| 34247 | +** created mapping is either the requested size or the value configured |
| 34248 | +** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. |
| 34249 | +** |
| 34250 | +** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 34251 | +** recreated as a result of outstanding references) or an SQLite error |
| 34252 | +** code otherwise. |
| 34253 | +*/ |
| 34254 | +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ |
| 34255 | + sqlite3_int64 nMap = nByte; |
| 34256 | + int rc; |
| 34257 | + |
| 34258 | + assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 34259 | + if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| 34260 | + |
| 34261 | + if( nMap<0 ){ |
| 34262 | + rc = winFileSize((sqlite3_file*)pFd, &nMap); |
| 34263 | + if( rc ){ |
| 34264 | + return SQLITE_IOERR_FSTAT; |
| 34265 | + } |
| 34266 | + } |
| 34267 | + if( nMap>pFd->mmapSizeMax ){ |
| 34268 | + nMap = pFd->mmapSizeMax; |
| 34269 | + } |
| 34270 | + nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); |
| 34271 | + |
| 34272 | + if( nMap==0 && pFd->mmapSize>0 ){ |
| 34273 | + winUnmapfile(pFd); |
| 34274 | + } |
| 34275 | + if( nMap!=pFd->mmapSize ){ |
| 34276 | + void *pNew = 0; |
| 34277 | + DWORD protect = PAGE_READONLY; |
| 34278 | + DWORD flags = FILE_MAP_READ; |
| 34279 | + |
| 34280 | + winUnmapfile(pFd); |
| 34281 | + if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ |
| 34282 | + protect = PAGE_READWRITE; |
| 34283 | + flags |= FILE_MAP_WRITE; |
| 34284 | + } |
| 34285 | +#if SQLITE_OS_WINRT |
| 34286 | + pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); |
| 34287 | +#elif defined(SQLITE_WIN32_HAS_WIDE) |
| 34288 | + pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, |
| 34289 | + (DWORD)((nMap>>32) & 0xffffffff), |
| 34290 | + (DWORD)(nMap & 0xffffffff), NULL); |
| 34291 | +#elif defined(SQLITE_WIN32_HAS_ANSI) |
| 34292 | + pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, |
| 34293 | + (DWORD)((nMap>>32) & 0xffffffff), |
| 34294 | + (DWORD)(nMap & 0xffffffff), NULL); |
| 34295 | +#endif |
| 34296 | + if( pFd->hMap==NULL ){ |
| 34297 | + pFd->lastErrno = osGetLastError(); |
| 34298 | + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34299 | + "winMapfile", pFd->zPath); |
| 34300 | + /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34301 | + return SQLITE_OK; |
| 34302 | + } |
| 34303 | + assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34304 | +#if SQLITE_OS_WINRT |
| 34305 | + pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap); |
| 34306 | +#else |
| 34307 | + assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 34308 | + pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); |
| 34309 | +#endif |
| 34310 | + if( pNew==NULL ){ |
| 34311 | + osCloseHandle(pFd->hMap); |
| 34312 | + pFd->hMap = NULL; |
| 34313 | + pFd->lastErrno = osGetLastError(); |
| 34314 | + winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34315 | + "winMapfile", pFd->zPath); |
| 34316 | + return SQLITE_OK; |
| 34317 | + } |
| 34318 | + pFd->pMapRegion = pNew; |
| 34319 | + pFd->mmapSize = nMap; |
| 34320 | + pFd->mmapSizeActual = nMap; |
| 34321 | + } |
| 34322 | + |
| 34323 | + return SQLITE_OK; |
| 34324 | +} |
| 34325 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 34326 | + |
| 34327 | +/* |
| 34328 | +** If possible, return a pointer to a mapping of file fd starting at offset |
| 34329 | +** iOff. The mapping must be valid for at least nAmt bytes. |
| 34330 | +** |
| 34331 | +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. |
| 34332 | +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. |
| 34333 | +** Finally, if an error does occur, return an SQLite error code. The final |
| 34334 | +** value of *pp is undefined in this case. |
| 34335 | +** |
| 34336 | +** If this function does return a pointer, the caller must eventually |
| 34337 | +** release the reference by calling unixUnfetch(). |
| 34338 | +*/ |
| 34339 | +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ |
| 34340 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 34341 | + winFile *pFd = (winFile*)fd; /* The underlying database file */ |
| 34342 | +#endif |
| 34343 | + *pp = 0; |
| 34344 | + |
| 34345 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 34346 | + if( pFd->mmapSizeMax>0 ){ |
| 34347 | + if( pFd->pMapRegion==0 ){ |
| 34348 | + int rc = winMapfile(pFd, -1); |
| 34349 | + if( rc!=SQLITE_OK ) return rc; |
| 34350 | + } |
| 34351 | + if( pFd->mmapSize >= iOff+nAmt ){ |
| 34352 | + *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 34353 | + pFd->nFetchOut++; |
| 34354 | + } |
| 34355 | + } |
| 34356 | +#endif |
| 34357 | + return SQLITE_OK; |
| 34358 | +} |
| 34359 | + |
| 34360 | +/* |
| 34361 | +** If the third argument is non-NULL, then this function releases a |
| 34362 | +** reference obtained by an earlier call to unixFetch(). The second |
| 34363 | +** argument passed to this function must be the same as the corresponding |
| 34364 | +** argument that was passed to the unixFetch() invocation. |
| 34365 | +** |
| 34366 | +** Or, if the third argument is NULL, then this function is being called |
| 34367 | +** to inform the VFS layer that, according to POSIX, any existing mapping |
| 34368 | +** may now be invalid and should be unmapped. |
| 34369 | +*/ |
| 34370 | +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 34371 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 34372 | + winFile *pFd = (winFile*)fd; /* The underlying database file */ |
| 34373 | + |
| 34374 | + /* If p==0 (unmap the entire file) then there must be no outstanding |
| 34375 | + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 34376 | + ** then there must be at least one outstanding. */ |
| 34377 | + assert( (p==0)==(pFd->nFetchOut==0) ); |
| 34378 | + |
| 34379 | + /* If p!=0, it must match the iOff value. */ |
| 34380 | + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); |
| 34381 | + |
| 34382 | + if( p ){ |
| 34383 | + pFd->nFetchOut--; |
| 34384 | + }else{ |
| 34385 | + /* FIXME: If Windows truly always prevents truncating or deleting a |
| 34386 | + ** file while a mapping is held, then the following winUnmapfile() call |
| 34387 | + ** is unnecessary can can be omitted - potentially improving |
| 34388 | + ** performance. */ |
| 34389 | + winUnmapfile(pFd); |
| 34390 | + } |
| 34391 | + |
| 34392 | + assert( pFd->nFetchOut>=0 ); |
| 34393 | +#endif |
| 34394 | + return SQLITE_OK; |
| 34395 | +} |
| 33604 | 34396 | |
| 33605 | 34397 | /* |
| 33606 | 34398 | ** Here ends the implementation of all sqlite3_file methods. |
| 33607 | 34399 | ** |
| 33608 | 34400 | ********************** End sqlite3_file Methods ******************************* |
| | @@ -33611,11 +34403,11 @@ |
| 33611 | 34403 | /* |
| 33612 | 34404 | ** This vector defines all the methods that can operate on an |
| 33613 | 34405 | ** sqlite3_file for win32. |
| 33614 | 34406 | */ |
| 33615 | 34407 | static const sqlite3_io_methods winIoMethod = { |
| 33616 | | - 2, /* iVersion */ |
| 34408 | + 3, /* iVersion */ |
| 33617 | 34409 | winClose, /* xClose */ |
| 33618 | 34410 | winRead, /* xRead */ |
| 33619 | 34411 | winWrite, /* xWrite */ |
| 33620 | 34412 | winTruncate, /* xTruncate */ |
| 33621 | 34413 | winSync, /* xSync */ |
| | @@ -33627,11 +34419,13 @@ |
| 33627 | 34419 | winSectorSize, /* xSectorSize */ |
| 33628 | 34420 | winDeviceCharacteristics, /* xDeviceCharacteristics */ |
| 33629 | 34421 | winShmMap, /* xShmMap */ |
| 33630 | 34422 | winShmLock, /* xShmLock */ |
| 33631 | 34423 | winShmBarrier, /* xShmBarrier */ |
| 33632 | | - winShmUnmap /* xShmUnmap */ |
| 34424 | + winShmUnmap, /* xShmUnmap */ |
| 34425 | + winFetch, /* xFetch */ |
| 34426 | + winUnfetch /* xUnfetch */ |
| 33633 | 34427 | }; |
| 33634 | 34428 | |
| 33635 | 34429 | /**************************************************************************** |
| 33636 | 34430 | **************************** sqlite3_vfs methods **************************** |
| 33637 | 34431 | ** |
| | @@ -33803,13 +34597,11 @@ |
| 33803 | 34597 | #endif |
| 33804 | 34598 | |
| 33805 | 34599 | int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); |
| 33806 | 34600 | int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); |
| 33807 | 34601 | int isCreate = (flags & SQLITE_OPEN_CREATE); |
| 33808 | | -#ifndef NDEBUG |
| 33809 | 34602 | int isReadonly = (flags & SQLITE_OPEN_READONLY); |
| 33810 | | -#endif |
| 33811 | 34603 | int isReadWrite = (flags & SQLITE_OPEN_READWRITE); |
| 33812 | 34604 | |
| 33813 | 34605 | #ifndef NDEBUG |
| 33814 | 34606 | int isOpenJournal = (isCreate && ( |
| 33815 | 34607 | eType==SQLITE_OPEN_MASTER_JOURNAL |
| | @@ -34016,15 +34808,25 @@ |
| 34016 | 34808 | } |
| 34017 | 34809 | |
| 34018 | 34810 | pFile->pMethod = &winIoMethod; |
| 34019 | 34811 | pFile->pVfs = pVfs; |
| 34020 | 34812 | pFile->h = h; |
| 34813 | + if( isReadonly ){ |
| 34814 | + pFile->ctrlFlags |= WINFILE_RDONLY; |
| 34815 | + } |
| 34021 | 34816 | if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 34022 | 34817 | pFile->ctrlFlags |= WINFILE_PSOW; |
| 34023 | 34818 | } |
| 34024 | 34819 | pFile->lastErrno = NO_ERROR; |
| 34025 | 34820 | pFile->zPath = zName; |
| 34821 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 34822 | + pFile->hMap = NULL; |
| 34823 | + pFile->pMapRegion = 0; |
| 34824 | + pFile->mmapSize = 0; |
| 34825 | + pFile->mmapSizeActual = 0; |
| 34826 | + pFile->mmapSizeMax = sqlite3GlobalConfig.mxMmap; |
| 34827 | +#endif |
| 34026 | 34828 | |
| 34027 | 34829 | OpenCounter(+1); |
| 34028 | 34830 | return rc; |
| 34029 | 34831 | } |
| 34030 | 34832 | |
| | @@ -34649,20 +35451,19 @@ |
| 34649 | 35451 | |
| 34650 | 35452 | /* Double-check that the aSyscall[] array has been constructed |
| 34651 | 35453 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 34652 | 35454 | assert( ArraySize(aSyscall)==74 ); |
| 34653 | 35455 | |
| 34654 | | -#ifndef SQLITE_OMIT_WAL |
| 34655 | 35456 | /* get memory map allocation granularity */ |
| 34656 | 35457 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 34657 | 35458 | #if SQLITE_OS_WINRT |
| 34658 | 35459 | osGetNativeSystemInfo(&winSysInfo); |
| 34659 | 35460 | #else |
| 34660 | 35461 | osGetSystemInfo(&winSysInfo); |
| 34661 | 35462 | #endif |
| 34662 | | - assert(winSysInfo.dwAllocationGranularity > 0); |
| 34663 | | -#endif |
| 35463 | + assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35464 | + assert( winSysInfo.dwPageSize>0 ); |
| 34664 | 35465 | |
| 34665 | 35466 | sqlite3_vfs_register(&winVfs, 1); |
| 34666 | 35467 | return SQLITE_OK; |
| 34667 | 35468 | } |
| 34668 | 35469 | |
| | @@ -37295,11 +38096,10 @@ |
| 37295 | 38096 | # define sqlite3WalOpen(x,y,z) 0 |
| 37296 | 38097 | # define sqlite3WalLimit(x,y) |
| 37297 | 38098 | # define sqlite3WalClose(w,x,y,z) 0 |
| 37298 | 38099 | # define sqlite3WalBeginReadTransaction(y,z) 0 |
| 37299 | 38100 | # define sqlite3WalEndReadTransaction(z) |
| 37300 | | -# define sqlite3WalRead(v,w,x,y,z) 0 |
| 37301 | 38101 | # define sqlite3WalDbsize(y) 0 |
| 37302 | 38102 | # define sqlite3WalBeginWriteTransaction(y) 0 |
| 37303 | 38103 | # define sqlite3WalEndWriteTransaction(x) 0 |
| 37304 | 38104 | # define sqlite3WalUndo(x,y,z) 0 |
| 37305 | 38105 | # define sqlite3WalSavepoint(y,z) |
| | @@ -37335,11 +38135,12 @@ |
| 37335 | 38135 | */ |
| 37336 | 38136 | SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); |
| 37337 | 38137 | SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); |
| 37338 | 38138 | |
| 37339 | 38139 | /* Read a page from the write-ahead log, if it is present. */ |
| 37340 | | -SQLITE_PRIVATE int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut); |
| 38140 | +SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); |
| 38141 | +SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); |
| 37341 | 38142 | |
| 37342 | 38143 | /* If the WAL is not empty, return the size of the database. */ |
| 37343 | 38144 | SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); |
| 37344 | 38145 | |
| 37345 | 38146 | /* Obtain or release the WRITER lock. */ |
| | @@ -38035,10 +38836,15 @@ |
| 38035 | 38836 | i64 journalHdr; /* Byte offset to previous journal header */ |
| 38036 | 38837 | sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ |
| 38037 | 38838 | PagerSavepoint *aSavepoint; /* Array of active savepoints */ |
| 38038 | 38839 | int nSavepoint; /* Number of elements in aSavepoint[] */ |
| 38039 | 38840 | char dbFileVers[16]; /* Changes whenever database file changes */ |
| 38841 | + |
| 38842 | + u8 bUseFetch; /* True to use xFetch() */ |
| 38843 | + int nMmapOut; /* Number of mmap pages currently outstanding */ |
| 38844 | + sqlite3_int64 szMmap; /* Desired maximum mmap size */ |
| 38845 | + PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ |
| 38040 | 38846 | /* |
| 38041 | 38847 | ** End of the routinely-changing class members |
| 38042 | 38848 | ***************************************************************************/ |
| 38043 | 38849 | |
| 38044 | 38850 | u16 nExtra; /* Add this many bytes to each in-memory page */ |
| | @@ -38145,10 +38951,20 @@ |
| 38145 | 38951 | # define MEMDB 0 |
| 38146 | 38952 | #else |
| 38147 | 38953 | # define MEMDB pPager->memDb |
| 38148 | 38954 | #endif |
| 38149 | 38955 | |
| 38956 | +/* |
| 38957 | +** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch |
| 38958 | +** interfaces to access the database using memory-mapped I/O. |
| 38959 | +*/ |
| 38960 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 38961 | +# define USEFETCH(x) ((x)->bUseFetch) |
| 38962 | +#else |
| 38963 | +# define USEFETCH(x) 0 |
| 38964 | +#endif |
| 38965 | + |
| 38150 | 38966 | /* |
| 38151 | 38967 | ** The maximum legal page number is (2^31 - 1). |
| 38152 | 38968 | */ |
| 38153 | 38969 | #define PAGER_MAX_PGNO 2147483647 |
| 38154 | 38970 | |
| | @@ -39632,11 +40448,11 @@ |
| 39632 | 40448 | && isSynced |
| 39633 | 40449 | ){ |
| 39634 | 40450 | i64 ofst = (pgno-1)*(i64)pPager->pageSize; |
| 39635 | 40451 | testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); |
| 39636 | 40452 | assert( !pagerUseWal(pPager) ); |
| 39637 | | - rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst); |
| 40453 | + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); |
| 39638 | 40454 | if( pgno>pPager->dbFileSize ){ |
| 39639 | 40455 | pPager->dbFileSize = pgno; |
| 39640 | 40456 | } |
| 39641 | 40457 | if( pPager->pBackup ){ |
| 39642 | 40458 | CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM); |
| | @@ -40023,10 +40839,11 @@ |
| 40023 | 40839 | Pgno mxPg = 0; /* Size of the original file in pages */ |
| 40024 | 40840 | int rc; /* Result code of a subroutine */ |
| 40025 | 40841 | int res = 1; /* Value returned by sqlite3OsAccess() */ |
| 40026 | 40842 | char *zMaster = 0; /* Name of master journal file if any */ |
| 40027 | 40843 | int needPagerReset; /* True to reset page prior to first page rollback */ |
| 40844 | + int nPlayback = 0; /* Total number of pages restored from journal */ |
| 40028 | 40845 | |
| 40029 | 40846 | /* Figure out how many records are in the journal. Abort early if |
| 40030 | 40847 | ** the journal is empty. |
| 40031 | 40848 | */ |
| 40032 | 40849 | assert( isOpen(pPager->jfd) ); |
| | @@ -40123,11 +40940,13 @@ |
| 40123 | 40940 | if( needPagerReset ){ |
| 40124 | 40941 | pager_reset(pPager); |
| 40125 | 40942 | needPagerReset = 0; |
| 40126 | 40943 | } |
| 40127 | 40944 | rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0); |
| 40128 | | - if( rc!=SQLITE_OK ){ |
| 40945 | + if( rc==SQLITE_OK ){ |
| 40946 | + nPlayback++; |
| 40947 | + }else{ |
| 40129 | 40948 | if( rc==SQLITE_DONE ){ |
| 40130 | 40949 | pPager->journalOff = szJ; |
| 40131 | 40950 | break; |
| 40132 | 40951 | }else if( rc==SQLITE_IOERR_SHORT_READ ){ |
| 40133 | 40952 | /* If the journal has been truncated, simply stop reading and |
| | @@ -40193,10 +41012,14 @@ |
| 40193 | 41012 | ** see if it is possible to delete the master journal. |
| 40194 | 41013 | */ |
| 40195 | 41014 | rc = pager_delmaster(pPager, zMaster); |
| 40196 | 41015 | testcase( rc!=SQLITE_OK ); |
| 40197 | 41016 | } |
| 41017 | + if( isHot && nPlayback ){ |
| 41018 | + sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", |
| 41019 | + nPlayback, pPager->zJournal); |
| 41020 | + } |
| 40198 | 41021 | |
| 40199 | 41022 | /* The Pager.sectorSize variable may have been updated while rolling |
| 40200 | 41023 | ** back a journal created by a process with a different sector size |
| 40201 | 41024 | ** value. Reset it to the correct value for this process. |
| 40202 | 41025 | */ |
| | @@ -40214,15 +41037,14 @@ |
| 40214 | 41037 | ** the value read from the database file. |
| 40215 | 41038 | ** |
| 40216 | 41039 | ** If an IO error occurs, then the IO error is returned to the caller. |
| 40217 | 41040 | ** Otherwise, SQLITE_OK is returned. |
| 40218 | 41041 | */ |
| 40219 | | -static int readDbPage(PgHdr *pPg){ |
| 41042 | +static int readDbPage(PgHdr *pPg, u32 iFrame){ |
| 40220 | 41043 | Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ |
| 40221 | 41044 | Pgno pgno = pPg->pgno; /* Page number to read */ |
| 40222 | 41045 | int rc = SQLITE_OK; /* Return code */ |
| 40223 | | - int isInWal = 0; /* True if page is in log file */ |
| 40224 | 41046 | int pgsz = pPager->pageSize; /* Number of bytes to read */ |
| 40225 | 41047 | |
| 40226 | 41048 | assert( pPager->eState>=PAGER_READER && !MEMDB ); |
| 40227 | 41049 | assert( isOpen(pPager->fd) ); |
| 40228 | 41050 | |
| | @@ -40230,15 +41052,14 @@ |
| 40230 | 41052 | assert( pPager->tempFile ); |
| 40231 | 41053 | memset(pPg->pData, 0, pPager->pageSize); |
| 40232 | 41054 | return SQLITE_OK; |
| 40233 | 41055 | } |
| 40234 | 41056 | |
| 40235 | | - if( pagerUseWal(pPager) ){ |
| 41057 | + if( iFrame ){ |
| 40236 | 41058 | /* Try to pull the page from the write-ahead log. */ |
| 40237 | | - rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData); |
| 40238 | | - } |
| 40239 | | - if( rc==SQLITE_OK && !isInWal ){ |
| 41059 | + rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); |
| 41060 | + }else{ |
| 40240 | 41061 | i64 iOffset = (pgno-1)*(i64)pPager->pageSize; |
| 40241 | 41062 | rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); |
| 40242 | 41063 | if( rc==SQLITE_IOERR_SHORT_READ ){ |
| 40243 | 41064 | rc = SQLITE_OK; |
| 40244 | 41065 | } |
| | @@ -40313,16 +41134,21 @@ |
| 40313 | 41134 | static int pagerUndoCallback(void *pCtx, Pgno iPg){ |
| 40314 | 41135 | int rc = SQLITE_OK; |
| 40315 | 41136 | Pager *pPager = (Pager *)pCtx; |
| 40316 | 41137 | PgHdr *pPg; |
| 40317 | 41138 | |
| 41139 | + assert( pagerUseWal(pPager) ); |
| 40318 | 41140 | pPg = sqlite3PagerLookup(pPager, iPg); |
| 40319 | 41141 | if( pPg ){ |
| 40320 | 41142 | if( sqlite3PcachePageRefcount(pPg)==1 ){ |
| 40321 | 41143 | sqlite3PcacheDrop(pPg); |
| 40322 | 41144 | }else{ |
| 40323 | | - rc = readDbPage(pPg); |
| 41145 | + u32 iFrame = 0; |
| 41146 | + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); |
| 41147 | + if( rc==SQLITE_OK ){ |
| 41148 | + rc = readDbPage(pPg, iFrame); |
| 41149 | + } |
| 40324 | 41150 | if( rc==SQLITE_OK ){ |
| 40325 | 41151 | pPager->xReiniter(pPg); |
| 40326 | 41152 | } |
| 40327 | 41153 | sqlite3PagerUnref(pPg); |
| 40328 | 41154 | } |
| | @@ -40462,10 +41288,11 @@ |
| 40462 | 41288 | sqlite3WalEndReadTransaction(pPager->pWal); |
| 40463 | 41289 | |
| 40464 | 41290 | rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); |
| 40465 | 41291 | if( rc!=SQLITE_OK || changed ){ |
| 40466 | 41292 | pager_reset(pPager); |
| 41293 | + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); |
| 40467 | 41294 | } |
| 40468 | 41295 | |
| 40469 | 41296 | return rc; |
| 40470 | 41297 | } |
| 40471 | 41298 | #endif |
| | @@ -40722,10 +41549,33 @@ |
| 40722 | 41549 | ** Change the maximum number of in-memory pages that are allowed. |
| 40723 | 41550 | */ |
| 40724 | 41551 | SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ |
| 40725 | 41552 | sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); |
| 40726 | 41553 | } |
| 41554 | + |
| 41555 | +/* |
| 41556 | +** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. |
| 41557 | +*/ |
| 41558 | +static void pagerFixMaplimit(Pager *pPager){ |
| 41559 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 41560 | + sqlite3_file *fd = pPager->fd; |
| 41561 | + if( isOpen(fd) ){ |
| 41562 | + sqlite3_int64 sz; |
| 41563 | + pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0; |
| 41564 | + sz = pPager->szMmap; |
| 41565 | + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 41566 | + } |
| 41567 | +#endif |
| 41568 | +} |
| 41569 | + |
| 41570 | +/* |
| 41571 | +** Change the maximum size of any memory mapping made of the database file. |
| 41572 | +*/ |
| 41573 | +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ |
| 41574 | + pPager->szMmap = szMmap; |
| 41575 | + pagerFixMaplimit(pPager); |
| 41576 | +} |
| 40727 | 41577 | |
| 40728 | 41578 | /* |
| 40729 | 41579 | ** Free as much memory as possible from the pager. |
| 40730 | 41580 | */ |
| 40731 | 41581 | SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ |
| | @@ -40958,10 +41808,11 @@ |
| 40958 | 41808 | if( rc==SQLITE_OK ){ |
| 40959 | 41809 | if( nReserve<0 ) nReserve = pPager->nReserve; |
| 40960 | 41810 | assert( nReserve>=0 && nReserve<1000 ); |
| 40961 | 41811 | pPager->nReserve = (i16)nReserve; |
| 40962 | 41812 | pagerReportSize(pPager); |
| 41813 | + pagerFixMaplimit(pPager); |
| 40963 | 41814 | } |
| 40964 | 41815 | return rc; |
| 40965 | 41816 | } |
| 40966 | 41817 | |
| 40967 | 41818 | /* |
| | @@ -41182,10 +42033,85 @@ |
| 41182 | 42033 | if( rc==SQLITE_OK ){ |
| 41183 | 42034 | rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); |
| 41184 | 42035 | } |
| 41185 | 42036 | return rc; |
| 41186 | 42037 | } |
| 42038 | + |
| 42039 | +/* |
| 42040 | +** Obtain a reference to a memory mapped page object for page number pgno. |
| 42041 | +** The new object will use the pointer pData, obtained from xFetch(). |
| 42042 | +** If successful, set *ppPage to point to the new page reference |
| 42043 | +** and return SQLITE_OK. Otherwise, return an SQLite error code and set |
| 42044 | +** *ppPage to zero. |
| 42045 | +** |
| 42046 | +** Page references obtained by calling this function should be released |
| 42047 | +** by calling pagerReleaseMapPage(). |
| 42048 | +*/ |
| 42049 | +static int pagerAcquireMapPage( |
| 42050 | + Pager *pPager, /* Pager object */ |
| 42051 | + Pgno pgno, /* Page number */ |
| 42052 | + void *pData, /* xFetch()'d data for this page */ |
| 42053 | + PgHdr **ppPage /* OUT: Acquired page object */ |
| 42054 | +){ |
| 42055 | + PgHdr *p; /* Memory mapped page to return */ |
| 42056 | + |
| 42057 | + if( pPager->pMmapFreelist ){ |
| 42058 | + *ppPage = p = pPager->pMmapFreelist; |
| 42059 | + pPager->pMmapFreelist = p->pDirty; |
| 42060 | + p->pDirty = 0; |
| 42061 | + memset(p->pExtra, 0, pPager->nExtra); |
| 42062 | + }else{ |
| 42063 | + *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); |
| 42064 | + if( p==0 ){ |
| 42065 | + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); |
| 42066 | + return SQLITE_NOMEM; |
| 42067 | + } |
| 42068 | + p->pExtra = (void *)&p[1]; |
| 42069 | + p->flags = PGHDR_MMAP; |
| 42070 | + p->nRef = 1; |
| 42071 | + p->pPager = pPager; |
| 42072 | + } |
| 42073 | + |
| 42074 | + assert( p->pExtra==(void *)&p[1] ); |
| 42075 | + assert( p->pPage==0 ); |
| 42076 | + assert( p->flags==PGHDR_MMAP ); |
| 42077 | + assert( p->pPager==pPager ); |
| 42078 | + assert( p->nRef==1 ); |
| 42079 | + |
| 42080 | + p->pgno = pgno; |
| 42081 | + p->pData = pData; |
| 42082 | + pPager->nMmapOut++; |
| 42083 | + |
| 42084 | + return SQLITE_OK; |
| 42085 | +} |
| 42086 | + |
| 42087 | +/* |
| 42088 | +** Release a reference to page pPg. pPg must have been returned by an |
| 42089 | +** earlier call to pagerAcquireMapPage(). |
| 42090 | +*/ |
| 42091 | +static void pagerReleaseMapPage(PgHdr *pPg){ |
| 42092 | + Pager *pPager = pPg->pPager; |
| 42093 | + pPager->nMmapOut--; |
| 42094 | + pPg->pDirty = pPager->pMmapFreelist; |
| 42095 | + pPager->pMmapFreelist = pPg; |
| 42096 | + |
| 42097 | + assert( pPager->fd->pMethods->iVersion>=3 ); |
| 42098 | + sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); |
| 42099 | +} |
| 42100 | + |
| 42101 | +/* |
| 42102 | +** Free all PgHdr objects stored in the Pager.pMmapFreelist list. |
| 42103 | +*/ |
| 42104 | +static void pagerFreeMapHdrs(Pager *pPager){ |
| 42105 | + PgHdr *p; |
| 42106 | + PgHdr *pNext; |
| 42107 | + for(p=pPager->pMmapFreelist; p; p=pNext){ |
| 42108 | + pNext = p->pDirty; |
| 42109 | + sqlite3_free(p); |
| 42110 | + } |
| 42111 | +} |
| 42112 | + |
| 41187 | 42113 | |
| 41188 | 42114 | /* |
| 41189 | 42115 | ** Shutdown the page cache. Free all memory and close all files. |
| 41190 | 42116 | ** |
| 41191 | 42117 | ** If a transaction was in progress when this routine is called, that |
| | @@ -41203,10 +42129,11 @@ |
| 41203 | 42129 | u8 *pTmp = (u8 *)pPager->pTmpSpace; |
| 41204 | 42130 | |
| 41205 | 42131 | assert( assert_pager_state(pPager) ); |
| 41206 | 42132 | disable_simulated_io_errors(); |
| 41207 | 42133 | sqlite3BeginBenignMalloc(); |
| 42134 | + pagerFreeMapHdrs(pPager); |
| 41208 | 42135 | /* pPager->errCode = 0; */ |
| 41209 | 42136 | pPager->exclusiveMode = 0; |
| 41210 | 42137 | #ifndef SQLITE_OMIT_WAL |
| 41211 | 42138 | sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); |
| 41212 | 42139 | pPager->pWal = 0; |
| | @@ -41464,11 +42391,13 @@ |
| 41464 | 42391 | |
| 41465 | 42392 | /* Before the first write, give the VFS a hint of what the final |
| 41466 | 42393 | ** file size will be. |
| 41467 | 42394 | */ |
| 41468 | 42395 | assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); |
| 41469 | | - if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){ |
| 42396 | + if( rc==SQLITE_OK |
| 42397 | + && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize |
| 42398 | + ){ |
| 41470 | 42399 | sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; |
| 41471 | 42400 | sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); |
| 41472 | 42401 | pPager->dbHintSize = pPager->dbSize; |
| 41473 | 42402 | } |
| 41474 | 42403 | |
| | @@ -42018,10 +42947,11 @@ |
| 42018 | 42947 | } |
| 42019 | 42948 | /* pPager->xBusyHandler = 0; */ |
| 42020 | 42949 | /* pPager->pBusyHandlerArg = 0; */ |
| 42021 | 42950 | pPager->xReiniter = xReinit; |
| 42022 | 42951 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ |
| 42952 | + /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ |
| 42023 | 42953 | |
| 42024 | 42954 | *ppPager = pPager; |
| 42025 | 42955 | return SQLITE_OK; |
| 42026 | 42956 | } |
| 42027 | 42957 | |
| | @@ -42309,13 +43239,15 @@ |
| 42309 | 43239 | assert( (pPager->eLock==SHARED_LOCK) |
| 42310 | 43240 | || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) |
| 42311 | 43241 | ); |
| 42312 | 43242 | } |
| 42313 | 43243 | |
| 42314 | | - if( !pPager->tempFile |
| 42315 | | - && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) |
| 42316 | | - ){ |
| 43244 | + if( !pPager->tempFile && ( |
| 43245 | + pPager->pBackup |
| 43246 | + || sqlite3PcachePagecount(pPager->pPCache)>0 |
| 43247 | + || USEFETCH(pPager) |
| 43248 | + )){ |
| 42317 | 43249 | /* The shared-lock has just been acquired on the database file |
| 42318 | 43250 | ** and there are already pages in the cache (from a previous |
| 42319 | 43251 | ** read or write transaction). Check to see if the database |
| 42320 | 43252 | ** has been modified. If the database has changed, flush the |
| 42321 | 43253 | ** cache. |
| | @@ -42337,19 +43269,29 @@ |
| 42337 | 43269 | if( rc ) goto failed; |
| 42338 | 43270 | |
| 42339 | 43271 | if( nPage>0 ){ |
| 42340 | 43272 | IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); |
| 42341 | 43273 | rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); |
| 42342 | | - if( rc!=SQLITE_OK ){ |
| 43274 | + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ |
| 42343 | 43275 | goto failed; |
| 42344 | 43276 | } |
| 42345 | 43277 | }else{ |
| 42346 | 43278 | memset(dbFileVers, 0, sizeof(dbFileVers)); |
| 42347 | 43279 | } |
| 42348 | 43280 | |
| 42349 | 43281 | if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ |
| 42350 | 43282 | pager_reset(pPager); |
| 43283 | + |
| 43284 | + /* Unmap the database file. It is possible that external processes |
| 43285 | + ** may have truncated the database file and then extended it back |
| 43286 | + ** to its original size while this process was not holding a lock. |
| 43287 | + ** In this case there may exist a Pager.pMap mapping that appears |
| 43288 | + ** to be the right size but is not actually valid. Avoid this |
| 43289 | + ** possibility by unmapping the db here. */ |
| 43290 | + if( USEFETCH(pPager) ){ |
| 43291 | + sqlite3OsUnfetch(pPager->fd, 0, 0); |
| 43292 | + } |
| 42351 | 43293 | } |
| 42352 | 43294 | } |
| 42353 | 43295 | |
| 42354 | 43296 | /* If there is a WAL file in the file-system, open this database in WAL |
| 42355 | 43297 | ** mode. Otherwise, the following function call is a no-op. |
| | @@ -42387,11 +43329,11 @@ |
| 42387 | 43329 | ** Except, in locking_mode=EXCLUSIVE when there is nothing to in |
| 42388 | 43330 | ** the rollback journal, the unlock is not performed and there is |
| 42389 | 43331 | ** nothing to rollback, so this routine is a no-op. |
| 42390 | 43332 | */ |
| 42391 | 43333 | static void pagerUnlockIfUnused(Pager *pPager){ |
| 42392 | | - if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ |
| 43334 | + if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ |
| 42393 | 43335 | pagerUnlockAndRollback(pPager); |
| 42394 | 43336 | } |
| 42395 | 43337 | } |
| 42396 | 43338 | |
| 42397 | 43339 | /* |
| | @@ -42446,17 +43388,31 @@ |
| 42446 | 43388 | */ |
| 42447 | 43389 | SQLITE_PRIVATE int sqlite3PagerAcquire( |
| 42448 | 43390 | Pager *pPager, /* The pager open on the database file */ |
| 42449 | 43391 | Pgno pgno, /* Page number to fetch */ |
| 42450 | 43392 | DbPage **ppPage, /* Write a pointer to the page here */ |
| 42451 | | - int noContent /* Do not bother reading content from disk if true */ |
| 43393 | + int flags /* PAGER_ACQUIRE_XXX flags */ |
| 42452 | 43394 | ){ |
| 42453 | | - int rc; |
| 42454 | | - PgHdr *pPg; |
| 43395 | + int rc = SQLITE_OK; |
| 43396 | + PgHdr *pPg = 0; |
| 43397 | + u32 iFrame = 0; /* Frame to read from WAL file */ |
| 43398 | + const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT); |
| 43399 | + |
| 43400 | + /* It is acceptable to use a read-only (mmap) page for any page except |
| 43401 | + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY |
| 43402 | + ** flag was specified by the caller. And so long as the db is not a |
| 43403 | + ** temporary or in-memory database. */ |
| 43404 | + const int bMmapOk = (pgno!=1 && USEFETCH(pPager) |
| 43405 | + && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY)) |
| 43406 | +#ifdef SQLITE_HAS_CODEC |
| 43407 | + && pPager->xCodec==0 |
| 43408 | +#endif |
| 43409 | + ); |
| 42455 | 43410 | |
| 42456 | 43411 | assert( pPager->eState>=PAGER_READER ); |
| 42457 | 43412 | assert( assert_pager_state(pPager) ); |
| 43413 | + assert( noContent==0 || bMmapOk==0 ); |
| 42458 | 43414 | |
| 42459 | 43415 | if( pgno==0 ){ |
| 42460 | 43416 | return SQLITE_CORRUPT_BKPT; |
| 42461 | 43417 | } |
| 42462 | 43418 | |
| | @@ -42463,10 +43419,43 @@ |
| 42463 | 43419 | /* If the pager is in the error state, return an error immediately. |
| 42464 | 43420 | ** Otherwise, request the page from the PCache layer. */ |
| 42465 | 43421 | if( pPager->errCode!=SQLITE_OK ){ |
| 42466 | 43422 | rc = pPager->errCode; |
| 42467 | 43423 | }else{ |
| 43424 | + |
| 43425 | + if( bMmapOk && pagerUseWal(pPager) ){ |
| 43426 | + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 43427 | + if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 43428 | + } |
| 43429 | + |
| 43430 | + if( iFrame==0 && bMmapOk ){ |
| 43431 | + void *pData = 0; |
| 43432 | + |
| 43433 | + rc = sqlite3OsFetch(pPager->fd, |
| 43434 | + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData |
| 43435 | + ); |
| 43436 | + |
| 43437 | + if( rc==SQLITE_OK && pData ){ |
| 43438 | + if( pPager->eState>PAGER_READER ){ |
| 43439 | + (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); |
| 43440 | + } |
| 43441 | + if( pPg==0 ){ |
| 43442 | + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); |
| 43443 | + }else{ |
| 43444 | + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); |
| 43445 | + } |
| 43446 | + if( pPg ){ |
| 43447 | + assert( rc==SQLITE_OK ); |
| 43448 | + *ppPage = pPg; |
| 43449 | + return SQLITE_OK; |
| 43450 | + } |
| 43451 | + } |
| 43452 | + if( rc!=SQLITE_OK ){ |
| 43453 | + goto pager_acquire_err; |
| 43454 | + } |
| 43455 | + } |
| 43456 | + |
| 42468 | 43457 | rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); |
| 42469 | 43458 | } |
| 42470 | 43459 | |
| 42471 | 43460 | if( rc!=SQLITE_OK ){ |
| 42472 | 43461 | /* Either the call to sqlite3PcacheFetch() returned an error or the |
| | @@ -42521,13 +43510,17 @@ |
| 42521 | 43510 | sqlite3EndBenignMalloc(); |
| 42522 | 43511 | } |
| 42523 | 43512 | memset(pPg->pData, 0, pPager->pageSize); |
| 42524 | 43513 | IOTRACE(("ZERO %p %d\n", pPager, pgno)); |
| 42525 | 43514 | }else{ |
| 43515 | + if( pagerUseWal(pPager) && bMmapOk==0 ){ |
| 43516 | + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 43517 | + if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 43518 | + } |
| 42526 | 43519 | assert( pPg->pPager==pPager ); |
| 42527 | 43520 | pPager->aStat[PAGER_STAT_MISS]++; |
| 42528 | | - rc = readDbPage(pPg); |
| 43521 | + rc = readDbPage(pPg, iFrame); |
| 42529 | 43522 | if( rc!=SQLITE_OK ){ |
| 42530 | 43523 | goto pager_acquire_err; |
| 42531 | 43524 | } |
| 42532 | 43525 | } |
| 42533 | 43526 | pager_set_pagehash(pPg); |
| | @@ -42576,11 +43569,15 @@ |
| 42576 | 43569 | ** removed. |
| 42577 | 43570 | */ |
| 42578 | 43571 | SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ |
| 42579 | 43572 | if( pPg ){ |
| 42580 | 43573 | Pager *pPager = pPg->pPager; |
| 42581 | | - sqlite3PcacheRelease(pPg); |
| 43574 | + if( pPg->flags & PGHDR_MMAP ){ |
| 43575 | + pagerReleaseMapPage(pPg); |
| 43576 | + }else{ |
| 43577 | + sqlite3PcacheRelease(pPg); |
| 43578 | + } |
| 42582 | 43579 | pagerUnlockIfUnused(pPager); |
| 42583 | 43580 | } |
| 42584 | 43581 | } |
| 42585 | 43582 | |
| 42586 | 43583 | /* |
| | @@ -42911,10 +43908,11 @@ |
| 42911 | 43908 | |
| 42912 | 43909 | PgHdr *pPg = pDbPage; |
| 42913 | 43910 | Pager *pPager = pPg->pPager; |
| 42914 | 43911 | Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 42915 | 43912 | |
| 43913 | + assert( (pPg->flags & PGHDR_MMAP)==0 ); |
| 42916 | 43914 | assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
| 42917 | 43915 | assert( pPager->eState!=PAGER_ERROR ); |
| 42918 | 43916 | assert( assert_pager_state(pPager) ); |
| 42919 | 43917 | |
| 42920 | 43918 | if( nPagePerSector>1 ){ |
| | @@ -43467,11 +44465,11 @@ |
| 43467 | 44465 | }else{ |
| 43468 | 44466 | rc = pager_playback(pPager, 0); |
| 43469 | 44467 | } |
| 43470 | 44468 | |
| 43471 | 44469 | assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); |
| 43472 | | - assert( rc==SQLITE_OK || rc==SQLITE_FULL |
| 44470 | + assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT |
| 43473 | 44471 | || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR ); |
| 43474 | 44472 | |
| 43475 | 44473 | /* If an error occurs during a ROLLBACK, we can no longer trust the pager |
| 43476 | 44474 | ** cache. So call pager_error() on the way out to make any error persistent. |
| 43477 | 44475 | */ |
| | @@ -44201,15 +45199,16 @@ |
| 44201 | 45199 | |
| 44202 | 45200 | /* Open the connection to the log file. If this operation fails, |
| 44203 | 45201 | ** (e.g. due to malloc() failure), return an error code. |
| 44204 | 45202 | */ |
| 44205 | 45203 | if( rc==SQLITE_OK ){ |
| 44206 | | - rc = sqlite3WalOpen(pPager->pVfs, |
| 45204 | + rc = sqlite3WalOpen(pPager->pVfs, |
| 44207 | 45205 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 44208 | 45206 | pPager->journalSizeLimit, &pPager->pWal |
| 44209 | 45207 | ); |
| 44210 | 45208 | } |
| 45209 | + pagerFixMaplimit(pPager); |
| 44211 | 45210 | |
| 44212 | 45211 | return rc; |
| 44213 | 45212 | } |
| 44214 | 45213 | |
| 44215 | 45214 | |
| | @@ -44296,10 +45295,11 @@ |
| 44296 | 45295 | rc = pagerExclusiveLock(pPager); |
| 44297 | 45296 | if( rc==SQLITE_OK ){ |
| 44298 | 45297 | rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, |
| 44299 | 45298 | pPager->pageSize, (u8*)pPager->pTmpSpace); |
| 44300 | 45299 | pPager->pWal = 0; |
| 45300 | + pagerFixMaplimit(pPager); |
| 44301 | 45301 | } |
| 44302 | 45302 | } |
| 44303 | 45303 | return rc; |
| 44304 | 45304 | } |
| 44305 | 45305 | |
| | @@ -45544,12 +46544,13 @@ |
| 45544 | 46544 | ** event via sqlite3_log(). This is to help with identifying performance |
| 45545 | 46545 | ** problems caused by applications routinely shutting down without |
| 45546 | 46546 | ** checkpointing the log file. |
| 45547 | 46547 | */ |
| 45548 | 46548 | if( pWal->hdr.nPage ){ |
| 45549 | | - sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s", |
| 45550 | | - pWal->hdr.nPage, pWal->zWalName |
| 46549 | + sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, |
| 46550 | + "recovered %d frames from WAL file %s", |
| 46551 | + pWal->hdr.mxFrame, pWal->zWalName |
| 45551 | 46552 | ); |
| 45552 | 46553 | } |
| 45553 | 46554 | } |
| 45554 | 46555 | |
| 45555 | 46556 | recovery_error: |
| | @@ -46059,20 +47060,21 @@ |
| 46059 | 47060 | /* Sync the WAL to disk */ |
| 46060 | 47061 | if( sync_flags ){ |
| 46061 | 47062 | rc = sqlite3OsSync(pWal->pWalFd, sync_flags); |
| 46062 | 47063 | } |
| 46063 | 47064 | |
| 46064 | | - /* If the database file may grow as a result of this checkpoint, hint |
| 46065 | | - ** about the eventual size of the db file to the VFS layer. |
| 47065 | + /* If the database may grow as a result of this checkpoint, hint |
| 47066 | + ** about the eventual size of the db file to the VFS layer. |
| 46066 | 47067 | */ |
| 46067 | 47068 | if( rc==SQLITE_OK ){ |
| 46068 | 47069 | i64 nReq = ((i64)mxPage * szPage); |
| 46069 | 47070 | rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); |
| 46070 | 47071 | if( rc==SQLITE_OK && nSize<nReq ){ |
| 46071 | 47072 | sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); |
| 46072 | 47073 | } |
| 46073 | 47074 | } |
| 47075 | + |
| 46074 | 47076 | |
| 46075 | 47077 | /* Iterate through the contents of the WAL, copying data to the db file. */ |
| 46076 | 47078 | while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ |
| 46077 | 47079 | i64 iOffset; |
| 46078 | 47080 | assert( walFramePgno(pWal, iFrame)==iDbpage ); |
| | @@ -46624,23 +47626,21 @@ |
| 46624 | 47626 | pWal->readLock = -1; |
| 46625 | 47627 | } |
| 46626 | 47628 | } |
| 46627 | 47629 | |
| 46628 | 47630 | /* |
| 46629 | | -** Read a page from the WAL, if it is present in the WAL and if the |
| 46630 | | -** current read transaction is configured to use the WAL. |
| 47631 | +** Search the wal file for page pgno. If found, set *piRead to the frame that |
| 47632 | +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead |
| 47633 | +** to zero. |
| 46631 | 47634 | ** |
| 46632 | | -** The *pInWal is set to 1 if the requested page is in the WAL and |
| 46633 | | -** has been loaded. Or *pInWal is set to 0 if the page was not in |
| 46634 | | -** the WAL and needs to be read out of the database. |
| 47635 | +** Return SQLITE_OK if successful, or an error code if an error occurs. If an |
| 47636 | +** error does occur, the final value of *piRead is undefined. |
| 46635 | 47637 | */ |
| 46636 | | -SQLITE_PRIVATE int sqlite3WalRead( |
| 47638 | +SQLITE_PRIVATE int sqlite3WalFindFrame( |
| 46637 | 47639 | Wal *pWal, /* WAL handle */ |
| 46638 | 47640 | Pgno pgno, /* Database page number to read data for */ |
| 46639 | | - int *pInWal, /* OUT: True if data is read from WAL */ |
| 46640 | | - int nOut, /* Size of buffer pOut in bytes */ |
| 46641 | | - u8 *pOut /* Buffer to write page data to */ |
| 47641 | + u32 *piRead /* OUT: Frame number (or zero) */ |
| 46642 | 47642 | ){ |
| 46643 | 47643 | u32 iRead = 0; /* If !=0, WAL frame to return data from */ |
| 46644 | 47644 | u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ |
| 46645 | 47645 | int iHash; /* Used to loop through N hash tables */ |
| 46646 | 47646 | |
| | @@ -46652,11 +47652,11 @@ |
| 46652 | 47652 | ** in this case as an optimization. Likewise, if pWal->readLock==0, |
| 46653 | 47653 | ** then the WAL is ignored by the reader so return early, as if the |
| 46654 | 47654 | ** WAL were empty. |
| 46655 | 47655 | */ |
| 46656 | 47656 | if( iLast==0 || pWal->readLock==0 ){ |
| 46657 | | - *pInWal = 0; |
| 47657 | + *piRead = 0; |
| 46658 | 47658 | return SQLITE_OK; |
| 46659 | 47659 | } |
| 46660 | 47660 | |
| 46661 | 47661 | /* Search the hash table or tables for an entry matching page number |
| 46662 | 47662 | ** pgno. Each iteration of the following for() loop searches one |
| | @@ -46723,30 +47723,35 @@ |
| 46723 | 47723 | } |
| 46724 | 47724 | assert( iRead==iRead2 ); |
| 46725 | 47725 | } |
| 46726 | 47726 | #endif |
| 46727 | 47727 | |
| 46728 | | - /* If iRead is non-zero, then it is the log frame number that contains the |
| 46729 | | - ** required page. Read and return data from the log file. |
| 46730 | | - */ |
| 46731 | | - if( iRead ){ |
| 46732 | | - int sz; |
| 46733 | | - i64 iOffset; |
| 46734 | | - sz = pWal->hdr.szPage; |
| 46735 | | - sz = (sz&0xfe00) + ((sz&0x0001)<<16); |
| 46736 | | - testcase( sz<=32768 ); |
| 46737 | | - testcase( sz>=65536 ); |
| 46738 | | - iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; |
| 46739 | | - *pInWal = 1; |
| 46740 | | - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 46741 | | - return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); |
| 46742 | | - } |
| 46743 | | - |
| 46744 | | - *pInWal = 0; |
| 47728 | + *piRead = iRead; |
| 46745 | 47729 | return SQLITE_OK; |
| 46746 | 47730 | } |
| 46747 | 47731 | |
| 47732 | +/* |
| 47733 | +** Read the contents of frame iRead from the wal file into buffer pOut |
| 47734 | +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an |
| 47735 | +** error code otherwise. |
| 47736 | +*/ |
| 47737 | +SQLITE_PRIVATE int sqlite3WalReadFrame( |
| 47738 | + Wal *pWal, /* WAL handle */ |
| 47739 | + u32 iRead, /* Frame to read */ |
| 47740 | + int nOut, /* Size of buffer pOut in bytes */ |
| 47741 | + u8 *pOut /* Buffer to write page data to */ |
| 47742 | +){ |
| 47743 | + int sz; |
| 47744 | + i64 iOffset; |
| 47745 | + sz = pWal->hdr.szPage; |
| 47746 | + sz = (sz&0xfe00) + ((sz&0x0001)<<16); |
| 47747 | + testcase( sz<=32768 ); |
| 47748 | + testcase( sz>=65536 ); |
| 47749 | + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; |
| 47750 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 47751 | + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); |
| 47752 | +} |
| 46748 | 47753 | |
| 46749 | 47754 | /* |
| 46750 | 47755 | ** Return the size of the database in pages (or zero, if unknown). |
| 46751 | 47756 | */ |
| 46752 | 47757 | SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ |
| | @@ -47289,10 +48294,13 @@ |
| 47289 | 48294 | } |
| 47290 | 48295 | |
| 47291 | 48296 | /* Read the wal-index header. */ |
| 47292 | 48297 | if( rc==SQLITE_OK ){ |
| 47293 | 48298 | rc = walIndexReadHdr(pWal, &isChanged); |
| 48299 | + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ |
| 48300 | + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); |
| 48301 | + } |
| 47294 | 48302 | } |
| 47295 | 48303 | |
| 47296 | 48304 | /* Copy data from the log to the database file. */ |
| 47297 | 48305 | if( rc==SQLITE_OK ){ |
| 47298 | 48306 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ |
| | @@ -49960,17 +50968,21 @@ |
| 49960 | 50968 | */ |
| 49961 | 50969 | static int btreeGetPage( |
| 49962 | 50970 | BtShared *pBt, /* The btree */ |
| 49963 | 50971 | Pgno pgno, /* Number of the page to fetch */ |
| 49964 | 50972 | MemPage **ppPage, /* Return the page in this parameter */ |
| 49965 | | - int noContent /* Do not load page content if true */ |
| 50973 | + int noContent, /* Do not load page content if true */ |
| 50974 | + int bReadonly /* True if a read-only (mmap) page is ok */ |
| 49966 | 50975 | ){ |
| 49967 | 50976 | int rc; |
| 49968 | 50977 | DbPage *pDbPage; |
| 50978 | + int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0) |
| 50979 | + | (bReadonly ? PAGER_ACQUIRE_READONLY : 0); |
| 49969 | 50980 | |
| 50981 | + assert( noContent==0 || bReadonly==0 ); |
| 49970 | 50982 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 49971 | | - rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); |
| 50983 | + rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); |
| 49972 | 50984 | if( rc ) return rc; |
| 49973 | 50985 | *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); |
| 49974 | 50986 | return SQLITE_OK; |
| 49975 | 50987 | } |
| 49976 | 50988 | |
| | @@ -50009,21 +51021,22 @@ |
| 50009 | 51021 | ** |
| 50010 | 51022 | ** If an error occurs, then the value *ppPage is set to is undefined. It |
| 50011 | 51023 | ** may remain unchanged, or it may be set to an invalid value. |
| 50012 | 51024 | */ |
| 50013 | 51025 | static int getAndInitPage( |
| 50014 | | - BtShared *pBt, /* The database file */ |
| 50015 | | - Pgno pgno, /* Number of the page to get */ |
| 50016 | | - MemPage **ppPage /* Write the page pointer here */ |
| 51026 | + BtShared *pBt, /* The database file */ |
| 51027 | + Pgno pgno, /* Number of the page to get */ |
| 51028 | + MemPage **ppPage, /* Write the page pointer here */ |
| 51029 | + int bReadonly /* True if a read-only (mmap) page is ok */ |
| 50017 | 51030 | ){ |
| 50018 | 51031 | int rc; |
| 50019 | 51032 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 50020 | 51033 | |
| 50021 | 51034 | if( pgno>btreePagecount(pBt) ){ |
| 50022 | 51035 | rc = SQLITE_CORRUPT_BKPT; |
| 50023 | 51036 | }else{ |
| 50024 | | - rc = btreeGetPage(pBt, pgno, ppPage, 0); |
| 51037 | + rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly); |
| 50025 | 51038 | if( rc==SQLITE_OK ){ |
| 50026 | 51039 | rc = btreeInitPage(*ppPage); |
| 50027 | 51040 | if( rc!=SQLITE_OK ){ |
| 50028 | 51041 | releasePage(*ppPage); |
| 50029 | 51042 | } |
| | @@ -50250,10 +51263,11 @@ |
| 50250 | 51263 | goto btree_open_out; |
| 50251 | 51264 | } |
| 50252 | 51265 | rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, |
| 50253 | 51266 | EXTRA_SIZE, flags, vfsFlags, pageReinit); |
| 50254 | 51267 | if( rc==SQLITE_OK ){ |
| 51268 | + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); |
| 50255 | 51269 | rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); |
| 50256 | 51270 | } |
| 50257 | 51271 | if( rc!=SQLITE_OK ){ |
| 50258 | 51272 | goto btree_open_out; |
| 50259 | 51273 | } |
| | @@ -50515,10 +51529,23 @@ |
| 50515 | 51529 | sqlite3BtreeEnter(p); |
| 50516 | 51530 | sqlite3PagerSetCachesize(pBt->pPager, mxPage); |
| 50517 | 51531 | sqlite3BtreeLeave(p); |
| 50518 | 51532 | return SQLITE_OK; |
| 50519 | 51533 | } |
| 51534 | + |
| 51535 | +/* |
| 51536 | +** Change the limit on the amount of the database file that may be |
| 51537 | +** memory mapped. |
| 51538 | +*/ |
| 51539 | +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ |
| 51540 | + BtShared *pBt = p->pBt; |
| 51541 | + assert( sqlite3_mutex_held(p->db->mutex) ); |
| 51542 | + sqlite3BtreeEnter(p); |
| 51543 | + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); |
| 51544 | + sqlite3BtreeLeave(p); |
| 51545 | + return SQLITE_OK; |
| 51546 | +} |
| 50520 | 51547 | |
| 50521 | 51548 | /* |
| 50522 | 51549 | ** Change the way data is synced to disk in order to increase or decrease |
| 50523 | 51550 | ** how well the database resists damage due to OS crashes and power |
| 50524 | 51551 | ** failures. Level 1 is the same as asynchronous (no syncs() occur and |
| | @@ -50741,11 +51768,11 @@ |
| 50741 | 51768 | |
| 50742 | 51769 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 50743 | 51770 | assert( pBt->pPage1==0 ); |
| 50744 | 51771 | rc = sqlite3PagerSharedLock(pBt->pPager); |
| 50745 | 51772 | if( rc!=SQLITE_OK ) return rc; |
| 50746 | | - rc = btreeGetPage(pBt, 1, &pPage1, 0); |
| 51773 | + rc = btreeGetPage(pBt, 1, &pPage1, 0, 0); |
| 50747 | 51774 | if( rc!=SQLITE_OK ) return rc; |
| 50748 | 51775 | |
| 50749 | 51776 | /* Do some checking to help insure the file we opened really is |
| 50750 | 51777 | ** a valid database file. |
| 50751 | 51778 | */ |
| | @@ -51300,11 +52327,11 @@ |
| 51300 | 52327 | /* Fix the database pointer on page iPtrPage that pointed at iDbPage so |
| 51301 | 52328 | ** that it points at iFreePage. Also fix the pointer map entry for |
| 51302 | 52329 | ** iPtrPage. |
| 51303 | 52330 | */ |
| 51304 | 52331 | if( eType!=PTRMAP_ROOTPAGE ){ |
| 51305 | | - rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); |
| 52332 | + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0); |
| 51306 | 52333 | if( rc!=SQLITE_OK ){ |
| 51307 | 52334 | return rc; |
| 51308 | 52335 | } |
| 51309 | 52336 | rc = sqlite3PagerWrite(pPtrPage->pDbPage); |
| 51310 | 52337 | if( rc!=SQLITE_OK ){ |
| | @@ -51384,11 +52411,11 @@ |
| 51384 | 52411 | Pgno iFreePg; /* Index of free page to move pLastPg to */ |
| 51385 | 52412 | MemPage *pLastPg; |
| 51386 | 52413 | u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ |
| 51387 | 52414 | Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ |
| 51388 | 52415 | |
| 51389 | | - rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); |
| 52416 | + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0); |
| 51390 | 52417 | if( rc!=SQLITE_OK ){ |
| 51391 | 52418 | return rc; |
| 51392 | 52419 | } |
| 51393 | 52420 | |
| 51394 | 52421 | /* If bCommit is zero, this loop runs exactly once and page pLastPg |
| | @@ -51476,12 +52503,15 @@ |
| 51476 | 52503 | Pgno nFin = finalDbSize(pBt, nOrig, nFree); |
| 51477 | 52504 | |
| 51478 | 52505 | if( nOrig<nFin ){ |
| 51479 | 52506 | rc = SQLITE_CORRUPT_BKPT; |
| 51480 | 52507 | }else if( nFree>0 ){ |
| 51481 | | - invalidateAllOverflowCache(pBt); |
| 51482 | | - rc = incrVacuumStep(pBt, nFin, nOrig, 0); |
| 52508 | + rc = saveAllCursors(pBt, 0, 0); |
| 52509 | + if( rc==SQLITE_OK ){ |
| 52510 | + invalidateAllOverflowCache(pBt); |
| 52511 | + rc = incrVacuumStep(pBt, nFin, nOrig, 0); |
| 52512 | + } |
| 51483 | 52513 | if( rc==SQLITE_OK ){ |
| 51484 | 52514 | rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); |
| 51485 | 52515 | put4byte(&pBt->pPage1->aData[28], pBt->nPage); |
| 51486 | 52516 | } |
| 51487 | 52517 | }else{ |
| | @@ -51525,11 +52555,13 @@ |
| 51525 | 52555 | } |
| 51526 | 52556 | |
| 51527 | 52557 | nFree = get4byte(&pBt->pPage1->aData[36]); |
| 51528 | 52558 | nFin = finalDbSize(pBt, nOrig, nFree); |
| 51529 | 52559 | if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; |
| 51530 | | - |
| 52560 | + if( nFin<nOrig ){ |
| 52561 | + rc = saveAllCursors(pBt, 0, 0); |
| 52562 | + } |
| 51531 | 52563 | for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){ |
| 51532 | 52564 | rc = incrVacuumStep(pBt, nFin, iFree, 1); |
| 51533 | 52565 | } |
| 51534 | 52566 | if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ |
| 51535 | 52567 | rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); |
| | @@ -51542,11 +52574,11 @@ |
| 51542 | 52574 | if( rc!=SQLITE_OK ){ |
| 51543 | 52575 | sqlite3PagerRollback(pPager); |
| 51544 | 52576 | } |
| 51545 | 52577 | } |
| 51546 | 52578 | |
| 51547 | | - assert( nRef==sqlite3PagerRefcount(pPager) ); |
| 52579 | + assert( nRef>=sqlite3PagerRefcount(pPager) ); |
| 51548 | 52580 | return rc; |
| 51549 | 52581 | } |
| 51550 | 52582 | |
| 51551 | 52583 | #else /* ifndef SQLITE_OMIT_AUTOVACUUM */ |
| 51552 | 52584 | # define setChildPtrmaps(x) SQLITE_OK |
| | @@ -51798,11 +52830,11 @@ |
| 51798 | 52830 | } |
| 51799 | 52831 | |
| 51800 | 52832 | /* The rollback may have destroyed the pPage1->aData value. So |
| 51801 | 52833 | ** call btreeGetPage() on page 1 again to make |
| 51802 | 52834 | ** sure pPage1->aData is set correctly. */ |
| 51803 | | - if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ |
| 52835 | + if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){ |
| 51804 | 52836 | int nPage = get4byte(28+(u8*)pPage1->aData); |
| 51805 | 52837 | testcase( nPage==0 ); |
| 51806 | 52838 | if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); |
| 51807 | 52839 | testcase( pBt->nPage!=nPage ); |
| 51808 | 52840 | pBt->nPage = nPage; |
| | @@ -52232,11 +53264,11 @@ |
| 52232 | 53264 | } |
| 52233 | 53265 | #endif |
| 52234 | 53266 | |
| 52235 | 53267 | assert( next==0 || rc==SQLITE_DONE ); |
| 52236 | 53268 | if( rc==SQLITE_OK ){ |
| 52237 | | - rc = btreeGetPage(pBt, ovfl, &pPage, 0); |
| 53269 | + rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0)); |
| 52238 | 53270 | assert( rc==SQLITE_OK || pPage==0 ); |
| 52239 | 53271 | if( rc==SQLITE_OK ){ |
| 52240 | 53272 | next = get4byte(pPage->aData); |
| 52241 | 53273 | } |
| 52242 | 53274 | } |
| | @@ -52453,11 +53485,13 @@ |
| 52453 | 53485 | }else |
| 52454 | 53486 | #endif |
| 52455 | 53487 | |
| 52456 | 53488 | { |
| 52457 | 53489 | DbPage *pDbPage; |
| 52458 | | - rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); |
| 53490 | + rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, |
| 53491 | + (eOp==0 ? PAGER_ACQUIRE_READONLY : 0) |
| 53492 | + ); |
| 52459 | 53493 | if( rc==SQLITE_OK ){ |
| 52460 | 53494 | aPayload = sqlite3PagerGetData(pDbPage); |
| 52461 | 53495 | nextPage = get4byte(aPayload); |
| 52462 | 53496 | rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); |
| 52463 | 53497 | sqlite3PagerUnref(pDbPage); |
| | @@ -52632,14 +53666,15 @@ |
| 52632 | 53666 | BtShared *pBt = pCur->pBt; |
| 52633 | 53667 | |
| 52634 | 53668 | assert( cursorHoldsMutex(pCur) ); |
| 52635 | 53669 | assert( pCur->eState==CURSOR_VALID ); |
| 52636 | 53670 | assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); |
| 53671 | + assert( pCur->iPage>=0 ); |
| 52637 | 53672 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ |
| 52638 | 53673 | return SQLITE_CORRUPT_BKPT; |
| 52639 | 53674 | } |
| 52640 | | - rc = getAndInitPage(pBt, newPgno, &pNewPage); |
| 53675 | + rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0)); |
| 52641 | 53676 | if( rc ) return rc; |
| 52642 | 53677 | pCur->apPage[i+1] = pNewPage; |
| 52643 | 53678 | pCur->aiIdx[i+1] = 0; |
| 52644 | 53679 | pCur->iPage++; |
| 52645 | 53680 | |
| | @@ -52752,11 +53787,11 @@ |
| 52752 | 53787 | pCur->iPage = 0; |
| 52753 | 53788 | }else if( pCur->pgnoRoot==0 ){ |
| 52754 | 53789 | pCur->eState = CURSOR_INVALID; |
| 52755 | 53790 | return SQLITE_OK; |
| 52756 | 53791 | }else{ |
| 52757 | | - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]); |
| 53792 | + rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0); |
| 52758 | 53793 | if( rc!=SQLITE_OK ){ |
| 52759 | 53794 | pCur->eState = CURSOR_INVALID; |
| 52760 | 53795 | return rc; |
| 52761 | 53796 | } |
| 52762 | 53797 | pCur->iPage = 0; |
| | @@ -53366,11 +54401,11 @@ |
| 53366 | 54401 | } |
| 53367 | 54402 | testcase( iTrunk==mxPage ); |
| 53368 | 54403 | if( iTrunk>mxPage ){ |
| 53369 | 54404 | rc = SQLITE_CORRUPT_BKPT; |
| 53370 | 54405 | }else{ |
| 53371 | | - rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); |
| 54406 | + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0); |
| 53372 | 54407 | } |
| 53373 | 54408 | if( rc ){ |
| 53374 | 54409 | pTrunk = 0; |
| 53375 | 54410 | goto end_allocate_page; |
| 53376 | 54411 | } |
| | @@ -53430,11 +54465,11 @@ |
| 53430 | 54465 | if( iNewTrunk>mxPage ){ |
| 53431 | 54466 | rc = SQLITE_CORRUPT_BKPT; |
| 53432 | 54467 | goto end_allocate_page; |
| 53433 | 54468 | } |
| 53434 | 54469 | testcase( iNewTrunk==mxPage ); |
| 53435 | | - rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); |
| 54470 | + rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0); |
| 53436 | 54471 | if( rc!=SQLITE_OK ){ |
| 53437 | 54472 | goto end_allocate_page; |
| 53438 | 54473 | } |
| 53439 | 54474 | rc = sqlite3PagerWrite(pNewTrunk->pDbPage); |
| 53440 | 54475 | if( rc!=SQLITE_OK ){ |
| | @@ -53510,11 +54545,11 @@ |
| 53510 | 54545 | if( closest<k-1 ){ |
| 53511 | 54546 | memcpy(&aData[8+closest*4], &aData[4+k*4], 4); |
| 53512 | 54547 | } |
| 53513 | 54548 | put4byte(&aData[4], k-1); |
| 53514 | 54549 | noContent = !btreeGetHasContent(pBt, *pPgno); |
| 53515 | | - rc = btreeGetPage(pBt, *pPgno, ppPage, noContent); |
| 54550 | + rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0); |
| 53516 | 54551 | if( rc==SQLITE_OK ){ |
| 53517 | 54552 | rc = sqlite3PagerWrite((*ppPage)->pDbPage); |
| 53518 | 54553 | if( rc!=SQLITE_OK ){ |
| 53519 | 54554 | releasePage(*ppPage); |
| 53520 | 54555 | } |
| | @@ -53558,11 +54593,11 @@ |
| 53558 | 54593 | ** becomes a new pointer-map page, the second is used by the caller. |
| 53559 | 54594 | */ |
| 53560 | 54595 | MemPage *pPg = 0; |
| 53561 | 54596 | TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); |
| 53562 | 54597 | assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); |
| 53563 | | - rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent); |
| 54598 | + rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0); |
| 53564 | 54599 | if( rc==SQLITE_OK ){ |
| 53565 | 54600 | rc = sqlite3PagerWrite(pPg->pDbPage); |
| 53566 | 54601 | releasePage(pPg); |
| 53567 | 54602 | } |
| 53568 | 54603 | if( rc ) return rc; |
| | @@ -53572,11 +54607,11 @@ |
| 53572 | 54607 | #endif |
| 53573 | 54608 | put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); |
| 53574 | 54609 | *pPgno = pBt->nPage; |
| 53575 | 54610 | |
| 53576 | 54611 | assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); |
| 53577 | | - rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent); |
| 54612 | + rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0); |
| 53578 | 54613 | if( rc ) return rc; |
| 53579 | 54614 | rc = sqlite3PagerWrite((*ppPage)->pDbPage); |
| 53580 | 54615 | if( rc!=SQLITE_OK ){ |
| 53581 | 54616 | releasePage(*ppPage); |
| 53582 | 54617 | } |
| | @@ -53640,11 +54675,11 @@ |
| 53640 | 54675 | |
| 53641 | 54676 | if( pBt->btsFlags & BTS_SECURE_DELETE ){ |
| 53642 | 54677 | /* If the secure_delete option is enabled, then |
| 53643 | 54678 | ** always fully overwrite deleted information with zeros. |
| 53644 | 54679 | */ |
| 53645 | | - if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) |
| 54680 | + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) ) |
| 53646 | 54681 | || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) |
| 53647 | 54682 | ){ |
| 53648 | 54683 | goto freepage_out; |
| 53649 | 54684 | } |
| 53650 | 54685 | memset(pPage->aData, 0, pPage->pBt->pageSize); |
| | @@ -53667,11 +54702,11 @@ |
| 53667 | 54702 | */ |
| 53668 | 54703 | if( nFree!=0 ){ |
| 53669 | 54704 | u32 nLeaf; /* Initial number of leaf cells on trunk page */ |
| 53670 | 54705 | |
| 53671 | 54706 | iTrunk = get4byte(&pPage1->aData[32]); |
| 53672 | | - rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); |
| 54707 | + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0); |
| 53673 | 54708 | if( rc!=SQLITE_OK ){ |
| 53674 | 54709 | goto freepage_out; |
| 53675 | 54710 | } |
| 53676 | 54711 | |
| 53677 | 54712 | nLeaf = get4byte(&pTrunk->aData[4]); |
| | @@ -53713,11 +54748,11 @@ |
| 53713 | 54748 | ** the page being freed as a leaf page of the first trunk in the free-list. |
| 53714 | 54749 | ** Possibly because the free-list is empty, or possibly because the |
| 53715 | 54750 | ** first trunk in the free-list is full. Either way, the page being freed |
| 53716 | 54751 | ** will become the new first trunk page in the free-list. |
| 53717 | 54752 | */ |
| 53718 | | - if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ |
| 54753 | + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){ |
| 53719 | 54754 | goto freepage_out; |
| 53720 | 54755 | } |
| 53721 | 54756 | rc = sqlite3PagerWrite(pPage->pDbPage); |
| 53722 | 54757 | if( rc!=SQLITE_OK ){ |
| 53723 | 54758 | goto freepage_out; |
| | @@ -54514,11 +55549,11 @@ |
| 54514 | 55549 | }else{ |
| 54515 | 55550 | pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); |
| 54516 | 55551 | } |
| 54517 | 55552 | pgno = get4byte(pRight); |
| 54518 | 55553 | while( 1 ){ |
| 54519 | | - rc = getAndInitPage(pBt, pgno, &apOld[i]); |
| 55554 | + rc = getAndInitPage(pBt, pgno, &apOld[i], 0); |
| 54520 | 55555 | if( rc ){ |
| 54521 | 55556 | memset(apOld, 0, (i+1)*sizeof(MemPage*)); |
| 54522 | 55557 | goto balance_cleanup; |
| 54523 | 55558 | } |
| 54524 | 55559 | nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; |
| | @@ -55602,14 +56637,21 @@ |
| 55602 | 56637 | ** is already journaled. |
| 55603 | 56638 | */ |
| 55604 | 56639 | u8 eType = 0; |
| 55605 | 56640 | Pgno iPtrPage = 0; |
| 55606 | 56641 | |
| 56642 | + /* Save the positions of any open cursors. This is required in |
| 56643 | + ** case they are holding a reference to an xFetch reference |
| 56644 | + ** corresponding to page pgnoRoot. */ |
| 56645 | + rc = saveAllCursors(pBt, 0, 0); |
| 55607 | 56646 | releasePage(pPageMove); |
| 56647 | + if( rc!=SQLITE_OK ){ |
| 56648 | + return rc; |
| 56649 | + } |
| 55608 | 56650 | |
| 55609 | 56651 | /* Move the page currently at pgnoRoot to pgnoMove. */ |
| 55610 | | - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); |
| 56652 | + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0); |
| 55611 | 56653 | if( rc!=SQLITE_OK ){ |
| 55612 | 56654 | return rc; |
| 55613 | 56655 | } |
| 55614 | 56656 | rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); |
| 55615 | 56657 | if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ |
| | @@ -55626,11 +56668,11 @@ |
| 55626 | 56668 | |
| 55627 | 56669 | /* Obtain the page at pgnoRoot */ |
| 55628 | 56670 | if( rc!=SQLITE_OK ){ |
| 55629 | 56671 | return rc; |
| 55630 | 56672 | } |
| 55631 | | - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); |
| 56673 | + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0); |
| 55632 | 56674 | if( rc!=SQLITE_OK ){ |
| 55633 | 56675 | return rc; |
| 55634 | 56676 | } |
| 55635 | 56677 | rc = sqlite3PagerWrite(pRoot->pDbPage); |
| 55636 | 56678 | if( rc!=SQLITE_OK ){ |
| | @@ -55702,11 +56744,11 @@ |
| 55702 | 56744 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 55703 | 56745 | if( pgno>btreePagecount(pBt) ){ |
| 55704 | 56746 | return SQLITE_CORRUPT_BKPT; |
| 55705 | 56747 | } |
| 55706 | 56748 | |
| 55707 | | - rc = getAndInitPage(pBt, pgno, &pPage); |
| 56749 | + rc = getAndInitPage(pBt, pgno, &pPage, 0); |
| 55708 | 56750 | if( rc ) return rc; |
| 55709 | 56751 | for(i=0; i<pPage->nCell; i++){ |
| 55710 | 56752 | pCell = findCell(pPage, i); |
| 55711 | 56753 | if( !pPage->leaf ){ |
| 55712 | 56754 | rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); |
| | @@ -55804,11 +56846,11 @@ |
| 55804 | 56846 | if( NEVER(pBt->pCursor) ){ |
| 55805 | 56847 | sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); |
| 55806 | 56848 | return SQLITE_LOCKED_SHAREDCACHE; |
| 55807 | 56849 | } |
| 55808 | 56850 | |
| 55809 | | - rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); |
| 56851 | + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0); |
| 55810 | 56852 | if( rc ) return rc; |
| 55811 | 56853 | rc = sqlite3BtreeClearTable(p, iTable, 0); |
| 55812 | 56854 | if( rc ){ |
| 55813 | 56855 | releasePage(pPage); |
| 55814 | 56856 | return rc; |
| | @@ -55839,21 +56881,21 @@ |
| 55839 | 56881 | ** number in the database. So move the page that does into the |
| 55840 | 56882 | ** gap left by the deleted root-page. |
| 55841 | 56883 | */ |
| 55842 | 56884 | MemPage *pMove; |
| 55843 | 56885 | releasePage(pPage); |
| 55844 | | - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); |
| 56886 | + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0); |
| 55845 | 56887 | if( rc!=SQLITE_OK ){ |
| 55846 | 56888 | return rc; |
| 55847 | 56889 | } |
| 55848 | 56890 | rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); |
| 55849 | 56891 | releasePage(pMove); |
| 55850 | 56892 | if( rc!=SQLITE_OK ){ |
| 55851 | 56893 | return rc; |
| 55852 | 56894 | } |
| 55853 | 56895 | pMove = 0; |
| 55854 | | - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); |
| 56896 | + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0); |
| 55855 | 56897 | freePage(pMove, &rc); |
| 55856 | 56898 | releasePage(pMove); |
| 55857 | 56899 | if( rc!=SQLITE_OK ){ |
| 55858 | 56900 | return rc; |
| 55859 | 56901 | } |
| | @@ -56261,11 +57303,11 @@ |
| 56261 | 57303 | */ |
| 56262 | 57304 | pBt = pCheck->pBt; |
| 56263 | 57305 | usableSize = pBt->usableSize; |
| 56264 | 57306 | if( iPage==0 ) return 0; |
| 56265 | 57307 | if( checkRef(pCheck, iPage, zParentContext) ) return 0; |
| 56266 | | - if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ |
| 57308 | + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){ |
| 56267 | 57309 | checkAppendMsg(pCheck, zContext, |
| 56268 | 57310 | "unable to get the page. error code=%d", rc); |
| 56269 | 57311 | return 0; |
| 56270 | 57312 | } |
| 56271 | 57313 | |
| | @@ -56732,10 +57774,21 @@ |
| 56732 | 57774 | } |
| 56733 | 57775 | assert( pCsr->eState!=CURSOR_REQUIRESEEK ); |
| 56734 | 57776 | if( pCsr->eState!=CURSOR_VALID ){ |
| 56735 | 57777 | return SQLITE_ABORT; |
| 56736 | 57778 | } |
| 57779 | + |
| 57780 | + /* Save the positions of all other cursors open on this table. This is |
| 57781 | + ** required in case any of them are holding references to an xFetch |
| 57782 | + ** version of the b-tree page modified by the accessPayload call below. |
| 57783 | + ** |
| 57784 | + ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition() |
| 57785 | + ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence |
| 57786 | + ** saveAllCursors can only return SQLITE_OK. |
| 57787 | + */ |
| 57788 | + VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); |
| 57789 | + assert( rc==SQLITE_OK ); |
| 56737 | 57790 | |
| 56738 | 57791 | /* Check some assumptions: |
| 56739 | 57792 | ** (a) the cursor is open for writing, |
| 56740 | 57793 | ** (b) there is a read/write transaction open, |
| 56741 | 57794 | ** (c) the connection holds a write-lock on the table (if required), |
| | @@ -57214,11 +58267,12 @@ |
| 57214 | 58267 | assert( nSrcPage>=0 ); |
| 57215 | 58268 | for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){ |
| 57216 | 58269 | const Pgno iSrcPg = p->iNext; /* Source page number */ |
| 57217 | 58270 | if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ |
| 57218 | 58271 | DbPage *pSrcPg; /* Source page object */ |
| 57219 | | - rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg); |
| 58272 | + rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg, |
| 58273 | + PAGER_ACQUIRE_READONLY); |
| 57220 | 58274 | if( rc==SQLITE_OK ){ |
| 57221 | 58275 | rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); |
| 57222 | 58276 | sqlite3PagerUnref(pSrcPg); |
| 57223 | 58277 | } |
| 57224 | 58278 | } |
| | @@ -62437,18 +63491,10 @@ |
| 62437 | 63491 | rc = sqlite3VdbeTransferError(p); |
| 62438 | 63492 | } |
| 62439 | 63493 | return (rc&db->errMask); |
| 62440 | 63494 | } |
| 62441 | 63495 | |
| 62442 | | -/* |
| 62443 | | -** The maximum number of times that a statement will try to reparse |
| 62444 | | -** itself before giving up and returning SQLITE_SCHEMA. |
| 62445 | | -*/ |
| 62446 | | -#ifndef SQLITE_MAX_SCHEMA_RETRY |
| 62447 | | -# define SQLITE_MAX_SCHEMA_RETRY 5 |
| 62448 | | -#endif |
| 62449 | | - |
| 62450 | 63496 | /* |
| 62451 | 63497 | ** This is the top-level implementation of sqlite3_step(). Call |
| 62452 | 63498 | ** sqlite3Step() to do most of the work. If a schema error occurs, |
| 62453 | 63499 | ** call sqlite3Reprepare() and try again. |
| 62454 | 63500 | */ |
| | @@ -63347,10 +64393,15 @@ |
| 63347 | 64393 | ** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the |
| 63348 | 64394 | ** string contains a copy of zRawSql but with host parameters expanded to |
| 63349 | 64395 | ** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, |
| 63350 | 64396 | ** then the returned string holds a copy of zRawSql with "-- " prepended |
| 63351 | 64397 | ** to each line of text. |
| 64398 | +** |
| 64399 | +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then |
| 64400 | +** then long strings and blobs are truncated to that many bytes. This |
| 64401 | +** can be used to prevent unreasonably large trace strings when dealing |
| 64402 | +** with large (multi-megabyte) strings and blobs. |
| 63352 | 64403 | ** |
| 63353 | 64404 | ** The calling function is responsible for making sure the memory returned |
| 63354 | 64405 | ** is eventually freed. |
| 63355 | 64406 | ** |
| 63356 | 64407 | ** ALGORITHM: Scan the input string looking for host parameters in any of |
| | @@ -63418,34 +64469,53 @@ |
| 63418 | 64469 | }else if( pVar->flags & MEM_Int ){ |
| 63419 | 64470 | sqlite3XPrintf(&out, "%lld", pVar->u.i); |
| 63420 | 64471 | }else if( pVar->flags & MEM_Real ){ |
| 63421 | 64472 | sqlite3XPrintf(&out, "%!.15g", pVar->r); |
| 63422 | 64473 | }else if( pVar->flags & MEM_Str ){ |
| 64474 | + int nOut; /* Number of bytes of the string text to include in output */ |
| 63423 | 64475 | #ifndef SQLITE_OMIT_UTF16 |
| 63424 | 64476 | u8 enc = ENC(db); |
| 64477 | + Mem utf8; |
| 63425 | 64478 | if( enc!=SQLITE_UTF8 ){ |
| 63426 | | - Mem utf8; |
| 63427 | 64479 | memset(&utf8, 0, sizeof(utf8)); |
| 63428 | 64480 | utf8.db = db; |
| 63429 | 64481 | sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); |
| 63430 | 64482 | sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); |
| 63431 | | - sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z); |
| 63432 | | - sqlite3VdbeMemRelease(&utf8); |
| 63433 | | - }else |
| 64483 | + pVar = &utf8; |
| 64484 | + } |
| 63434 | 64485 | #endif |
| 63435 | | - { |
| 63436 | | - sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z); |
| 64486 | + nOut = pVar->n; |
| 64487 | +#ifdef SQLITE_TRACE_SIZE_LIMIT |
| 64488 | + if( n>SQLITE_TRACE_SIZE_LIMIT ){ |
| 64489 | + nOut = SQLITE_TRACE_SIZE_LIMIT; |
| 64490 | + while( nOut<pVar->n && (pVar->z[n]&0xc0)==0x80 ){ n++; } |
| 63437 | 64491 | } |
| 64492 | +#endif |
| 64493 | + sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); |
| 64494 | +#ifdef SQLITE_TRACE_SIZE_LIMIT |
| 64495 | + if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n); |
| 64496 | +#endif |
| 64497 | +#ifndef SQLITE_OMIT_UTF16 |
| 64498 | + if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); |
| 64499 | +#endif |
| 63438 | 64500 | }else if( pVar->flags & MEM_Zero ){ |
| 63439 | 64501 | sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); |
| 63440 | 64502 | }else{ |
| 64503 | + int nOut; /* Number of bytes of the blob to include in output */ |
| 63441 | 64504 | assert( pVar->flags & MEM_Blob ); |
| 63442 | 64505 | sqlite3StrAccumAppend(&out, "x'", 2); |
| 63443 | | - for(i=0; i<pVar->n; i++){ |
| 64506 | + nOut = pVar->n; |
| 64507 | +#ifdef SQLITE_TRACE_SIZE_LIMIT |
| 64508 | + if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; |
| 64509 | +#endif |
| 64510 | + for(i=0; i<nOut; i++){ |
| 63444 | 64511 | sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); |
| 63445 | 64512 | } |
| 63446 | 64513 | sqlite3StrAccumAppend(&out, "'", 1); |
| 64514 | +#ifdef SQLITE_TRACE_SIZE_LIMIT |
| 64515 | + if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-n); |
| 64516 | +#endif |
| 63447 | 64517 | } |
| 63448 | 64518 | } |
| 63449 | 64519 | } |
| 63450 | 64520 | return sqlite3StrAccumFinish(&out); |
| 63451 | 64521 | } |
| | @@ -67658,11 +68728,11 @@ |
| 67658 | 68728 | ** u.bc.r.flags = UNPACKED_INCRKEY; |
| 67659 | 68729 | ** }else{ |
| 67660 | 68730 | ** u.bc.r.flags = 0; |
| 67661 | 68731 | ** } |
| 67662 | 68732 | */ |
| 67663 | | - u.bc.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt))); |
| 68733 | + u.bc.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt))); |
| 67664 | 68734 | assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY ); |
| 67665 | 68735 | assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY ); |
| 67666 | 68736 | assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 ); |
| 67667 | 68737 | assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 ); |
| 67668 | 68738 | |
| | @@ -70783,11 +71853,11 @@ |
| 70783 | 71853 | if( db->mallocFailed ){ |
| 70784 | 71854 | goto blob_open_out; |
| 70785 | 71855 | } |
| 70786 | 71856 | sqlite3_bind_int64(pBlob->pStmt, 1, iRow); |
| 70787 | 71857 | rc = blobSeekToRow(pBlob, iRow, &zErr); |
| 70788 | | - } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA ); |
| 71858 | + } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA ); |
| 70789 | 71859 | |
| 70790 | 71860 | blob_open_out: |
| 70791 | 71861 | if( rc==SQLITE_OK && db->mallocFailed==0 ){ |
| 70792 | 71862 | *ppBlob = (sqlite3_blob *)pBlob; |
| 70793 | 71863 | }else{ |
| | @@ -72468,11 +73538,13 @@ |
| 72468 | 73538 | 0, /* xSectorSize */ |
| 72469 | 73539 | 0, /* xDeviceCharacteristics */ |
| 72470 | 73540 | 0, /* xShmMap */ |
| 72471 | 73541 | 0, /* xShmLock */ |
| 72472 | 73542 | 0, /* xShmBarrier */ |
| 72473 | | - 0 /* xShmUnlock */ |
| 73543 | + 0, /* xShmUnmap */ |
| 73544 | + 0, /* xFetch */ |
| 73545 | + 0 /* xUnfetch */ |
| 72474 | 73546 | }; |
| 72475 | 73547 | |
| 72476 | 73548 | /* |
| 72477 | 73549 | ** Open a journal file. |
| 72478 | 73550 | */ |
| | @@ -72612,11 +73684,13 @@ |
| 72612 | 73684 | } |
| 72613 | 73685 | |
| 72614 | 73686 | /* |
| 72615 | 73687 | ** Call sqlite3WalkExpr() for every expression in Select statement p. |
| 72616 | 73688 | ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and |
| 72617 | | -** on the compound select chain, p->pPrior. |
| 73689 | +** on the compound select chain, p->pPrior. Invoke the xSelectCallback() |
| 73690 | +** either before or after the walk of expressions and FROM clause, depending |
| 73691 | +** on whether pWalker->bSelectDepthFirst is false or true, respectively. |
| 72618 | 73692 | ** |
| 72619 | 73693 | ** Return WRC_Continue under normal conditions. Return WRC_Abort if |
| 72620 | 73694 | ** there is an abort request. |
| 72621 | 73695 | ** |
| 72622 | 73696 | ** If the Walker does not have an xSelectCallback() then this routine |
| | @@ -72626,17 +73700,26 @@ |
| 72626 | 73700 | int rc; |
| 72627 | 73701 | if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; |
| 72628 | 73702 | rc = WRC_Continue; |
| 72629 | 73703 | pWalker->walkerDepth++; |
| 72630 | 73704 | while( p ){ |
| 72631 | | - rc = pWalker->xSelectCallback(pWalker, p); |
| 72632 | | - if( rc ) break; |
| 73705 | + if( !pWalker->bSelectDepthFirst ){ |
| 73706 | + rc = pWalker->xSelectCallback(pWalker, p); |
| 73707 | + if( rc ) break; |
| 73708 | + } |
| 72633 | 73709 | if( sqlite3WalkSelectExpr(pWalker, p) |
| 72634 | 73710 | || sqlite3WalkSelectFrom(pWalker, p) |
| 72635 | 73711 | ){ |
| 72636 | 73712 | pWalker->walkerDepth--; |
| 72637 | 73713 | return WRC_Abort; |
| 73714 | + } |
| 73715 | + if( pWalker->bSelectDepthFirst ){ |
| 73716 | + rc = pWalker->xSelectCallback(pWalker, p); |
| 73717 | + /* Depth-first search is currently only used for |
| 73718 | + ** selectAddSubqueryTypeInfo() and that routine always returns |
| 73719 | + ** WRC_Continue (0). So the following branch is never taken. */ |
| 73720 | + if( NEVER(rc) ) break; |
| 72638 | 73721 | } |
| 72639 | 73722 | p = p->pPrior; |
| 72640 | 73723 | } |
| 72641 | 73724 | pWalker->walkerDepth--; |
| 72642 | 73725 | return rc & WRC_Abort; |
| | @@ -73031,11 +74114,14 @@ |
| 73031 | 74114 | ** In cases like this, replace pExpr with a copy of the expression that |
| 73032 | 74115 | ** forms the result set entry ("a+b" in the example) and return immediately. |
| 73033 | 74116 | ** Note that the expression in the result set should have already been |
| 73034 | 74117 | ** resolved by the time the WHERE clause is resolved. |
| 73035 | 74118 | */ |
| 73036 | | - if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){ |
| 74119 | + if( (pEList = pNC->pEList)!=0 |
| 74120 | + && zTab==0 |
| 74121 | + && ((pNC->ncFlags & NC_AsMaybe)==0 || cnt==0) |
| 74122 | + ){ |
| 73037 | 74123 | for(j=0; j<pEList->nExpr; j++){ |
| 73038 | 74124 | char *zAs = pEList->a[j].zName; |
| 73039 | 74125 | if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ |
| 73040 | 74126 | Expr *pOrig; |
| 73041 | 74127 | assert( pExpr->pLeft==0 && pExpr->pRight==0 ); |
| | @@ -73122,11 +74208,13 @@ |
| 73122 | 74208 | pExpr->pRight = 0; |
| 73123 | 74209 | pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); |
| 73124 | 74210 | lookupname_end: |
| 73125 | 74211 | if( cnt==1 ){ |
| 73126 | 74212 | assert( pNC!=0 ); |
| 73127 | | - sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); |
| 74213 | + if( pExpr->op!=TK_AS ){ |
| 74214 | + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); |
| 74215 | + } |
| 73128 | 74216 | /* Increment the nRef value on all name contexts from TopNC up to |
| 73129 | 74217 | ** the point where the name matched. */ |
| 73130 | 74218 | for(;;){ |
| 73131 | 74219 | assert( pTopNC!=0 ); |
| 73132 | 74220 | pTopNC->nRef++; |
| | @@ -73797,15 +74885,14 @@ |
| 73797 | 74885 | ** |
| 73798 | 74886 | ** Minor point: If this is the case, then the expression will be |
| 73799 | 74887 | ** re-evaluated for each reference to it. |
| 73800 | 74888 | */ |
| 73801 | 74889 | sNC.pEList = p->pEList; |
| 73802 | | - if( sqlite3ResolveExprNames(&sNC, p->pWhere) || |
| 73803 | | - sqlite3ResolveExprNames(&sNC, p->pHaving) |
| 73804 | | - ){ |
| 73805 | | - return WRC_Abort; |
| 73806 | | - } |
| 74890 | + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; |
| 74891 | + sNC.ncFlags |= NC_AsMaybe; |
| 74892 | + if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; |
| 74893 | + sNC.ncFlags &= ~NC_AsMaybe; |
| 73807 | 74894 | |
| 73808 | 74895 | /* The ORDER BY and GROUP BY clauses may not refer to terms in |
| 73809 | 74896 | ** outer queries |
| 73810 | 74897 | */ |
| 73811 | 74898 | sNC.pNext = 0; |
| | @@ -73922,10 +75009,11 @@ |
| 73922 | 75009 | pParse->nHeight += pExpr->nHeight; |
| 73923 | 75010 | } |
| 73924 | 75011 | #endif |
| 73925 | 75012 | savedHasAgg = pNC->ncFlags & NC_HasAgg; |
| 73926 | 75013 | pNC->ncFlags &= ~NC_HasAgg; |
| 75014 | + memset(&w, 0, sizeof(w)); |
| 73927 | 75015 | w.xExprCallback = resolveExprStep; |
| 73928 | 75016 | w.xSelectCallback = resolveSelectStep; |
| 73929 | 75017 | w.pParse = pNC->pParse; |
| 73930 | 75018 | w.u.pNC = pNC; |
| 73931 | 75019 | sqlite3WalkExpr(&w, pExpr); |
| | @@ -73962,10 +75050,11 @@ |
| 73962 | 75050 | NameContext *pOuterNC /* Name context for parent SELECT statement */ |
| 73963 | 75051 | ){ |
| 73964 | 75052 | Walker w; |
| 73965 | 75053 | |
| 73966 | 75054 | assert( p!=0 ); |
| 75055 | + memset(&w, 0, sizeof(w)); |
| 73967 | 75056 | w.xExprCallback = resolveExprStep; |
| 73968 | 75057 | w.xSelectCallback = resolveSelectStep; |
| 73969 | 75058 | w.pParse = pParse; |
| 73970 | 75059 | w.u.pNC = pOuterNC; |
| 73971 | 75060 | sqlite3WalkSelect(&w, p); |
| | @@ -75186,10 +76275,11 @@ |
| 75186 | 76275 | pWalker->u.i = 0; |
| 75187 | 76276 | return WRC_Abort; |
| 75188 | 76277 | } |
| 75189 | 76278 | static int exprIsConst(Expr *p, int initFlag){ |
| 75190 | 76279 | Walker w; |
| 76280 | + memset(&w, 0, sizeof(w)); |
| 75191 | 76281 | w.u.i = initFlag; |
| 75192 | 76282 | w.xExprCallback = exprNodeIsConstant; |
| 75193 | 76283 | w.xSelectCallback = selectNodeIsConstant; |
| 75194 | 76284 | sqlite3WalkExpr(&w, p); |
| 75195 | 76285 | return w.u.i; |
| | @@ -77400,12 +78490,12 @@ |
| 77400 | 78490 | */ |
| 77401 | 78491 | SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ |
| 77402 | 78492 | Walker w; |
| 77403 | 78493 | if( pParse->cookieGoto ) return; |
| 77404 | 78494 | if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return; |
| 78495 | + memset(&w, 0, sizeof(w)); |
| 77405 | 78496 | w.xExprCallback = evalConstExpr; |
| 77406 | | - w.xSelectCallback = 0; |
| 77407 | 78497 | w.pParse = pParse; |
| 77408 | 78498 | sqlite3WalkExpr(&w, pExpr); |
| 77409 | 78499 | } |
| 77410 | 78500 | |
| 77411 | 78501 | |
| | @@ -86603,10 +87693,17 @@ |
| 86603 | 87693 | prevEscape = 0; |
| 86604 | 87694 | } |
| 86605 | 87695 | } |
| 86606 | 87696 | return *zString==0; |
| 86607 | 87697 | } |
| 87698 | + |
| 87699 | +/* |
| 87700 | +** The sqlite3_strglob() interface. |
| 87701 | +*/ |
| 87702 | +SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ |
| 87703 | + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0; |
| 87704 | +} |
| 86608 | 87705 | |
| 86609 | 87706 | /* |
| 86610 | 87707 | ** Count the number of times that the LIKE operator (or GLOB which is |
| 86611 | 87708 | ** just a variation of LIKE) gets called. This is used for testing |
| 86612 | 87709 | ** only. |
| | @@ -90804,24 +91901,23 @@ |
| 90804 | 91901 | ){ |
| 90805 | 91902 | int rc = SQLITE_OK; /* Return code */ |
| 90806 | 91903 | const char *zLeftover; /* Tail of unprocessed SQL */ |
| 90807 | 91904 | sqlite3_stmt *pStmt = 0; /* The current SQL statement */ |
| 90808 | 91905 | char **azCols = 0; /* Names of result columns */ |
| 90809 | | - int nRetry = 0; /* Number of retry attempts */ |
| 90810 | 91906 | int callbackIsInit; /* True if callback data is initialized */ |
| 90811 | 91907 | |
| 90812 | 91908 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 90813 | 91909 | if( zSql==0 ) zSql = ""; |
| 90814 | 91910 | |
| 90815 | 91911 | sqlite3_mutex_enter(db->mutex); |
| 90816 | 91912 | sqlite3Error(db, SQLITE_OK, 0); |
| 90817 | | - while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){ |
| 91913 | + while( rc==SQLITE_OK && zSql[0] ){ |
| 90818 | 91914 | int nCol; |
| 90819 | 91915 | char **azVals = 0; |
| 90820 | 91916 | |
| 90821 | 91917 | pStmt = 0; |
| 90822 | | - rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover); |
| 91918 | + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); |
| 90823 | 91919 | assert( rc==SQLITE_OK || pStmt==0 ); |
| 90824 | 91920 | if( rc!=SQLITE_OK ){ |
| 90825 | 91921 | continue; |
| 90826 | 91922 | } |
| 90827 | 91923 | if( !pStmt ){ |
| | @@ -90874,15 +91970,12 @@ |
| 90874 | 91970 | } |
| 90875 | 91971 | |
| 90876 | 91972 | if( rc!=SQLITE_ROW ){ |
| 90877 | 91973 | rc = sqlite3VdbeFinalize((Vdbe *)pStmt); |
| 90878 | 91974 | pStmt = 0; |
| 90879 | | - if( rc!=SQLITE_SCHEMA ){ |
| 90880 | | - nRetry = 0; |
| 90881 | | - zSql = zLeftover; |
| 90882 | | - while( sqlite3Isspace(zSql[0]) ) zSql++; |
| 90883 | | - } |
| 91975 | + zSql = zLeftover; |
| 91976 | + while( sqlite3Isspace(zSql[0]) ) zSql++; |
| 90884 | 91977 | break; |
| 90885 | 91978 | } |
| 90886 | 91979 | } |
| 90887 | 91980 | |
| 90888 | 91981 | sqlite3DbFree(db, azCols); |
| | @@ -91402,12 +92495,21 @@ |
| 91402 | 92495 | #define sqlite3_uri_parameter sqlite3_api->uri_parameter |
| 91403 | 92496 | #define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf |
| 91404 | 92497 | #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 |
| 91405 | 92498 | #endif /* SQLITE_CORE */ |
| 91406 | 92499 | |
| 91407 | | -#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0; |
| 91408 | | -#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; |
| 92500 | +#ifndef SQLITE_CORE |
| 92501 | + /* This case when the file really is being compiled as a loadable |
| 92502 | + ** extension */ |
| 92503 | +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; |
| 92504 | +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
| 92505 | +#else |
| 92506 | + /* This case when the file is being statically linked into the |
| 92507 | + ** application */ |
| 92508 | +# define SQLITE_EXTENSION_INIT1 /*no-op*/ |
| 92509 | +# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ |
| 92510 | +#endif |
| 91409 | 92511 | |
| 91410 | 92512 | #endif /* _SQLITE3EXT_H_ */ |
| 91411 | 92513 | |
| 91412 | 92514 | /************** End of sqlite3ext.h ******************************************/ |
| 91413 | 92515 | /************** Continuing where we left off in loadext.c ********************/ |
| | @@ -91806,12 +92908,27 @@ |
| 91806 | 92908 | ){ |
| 91807 | 92909 | sqlite3_vfs *pVfs = db->pVfs; |
| 91808 | 92910 | void *handle; |
| 91809 | 92911 | int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); |
| 91810 | 92912 | char *zErrmsg = 0; |
| 92913 | + const char *zEntry; |
| 92914 | + char *zAltEntry = 0; |
| 91811 | 92915 | void **aHandle; |
| 91812 | 92916 | int nMsg = 300 + sqlite3Strlen30(zFile); |
| 92917 | + int ii; |
| 92918 | + |
| 92919 | + /* Shared library endings to try if zFile cannot be loaded as written */ |
| 92920 | + static const char *azEndings[] = { |
| 92921 | +#if SQLITE_OS_WIN |
| 92922 | + "dll" |
| 92923 | +#elif defined(__APPLE__) |
| 92924 | + "dylib" |
| 92925 | +#else |
| 92926 | + "so" |
| 92927 | +#endif |
| 92928 | + }; |
| 92929 | + |
| 91813 | 92930 | |
| 91814 | 92931 | if( pzErrMsg ) *pzErrMsg = 0; |
| 91815 | 92932 | |
| 91816 | 92933 | /* Ticket #1863. To avoid a creating security problems for older |
| 91817 | 92934 | ** applications that relink against newer versions of SQLite, the |
| | @@ -91824,15 +92941,21 @@ |
| 91824 | 92941 | *pzErrMsg = sqlite3_mprintf("not authorized"); |
| 91825 | 92942 | } |
| 91826 | 92943 | return SQLITE_ERROR; |
| 91827 | 92944 | } |
| 91828 | 92945 | |
| 91829 | | - if( zProc==0 ){ |
| 91830 | | - zProc = "sqlite3_extension_init"; |
| 91831 | | - } |
| 92946 | + zEntry = zProc ? zProc : "sqlite3_extension_init"; |
| 91832 | 92947 | |
| 91833 | 92948 | handle = sqlite3OsDlOpen(pVfs, zFile); |
| 92949 | +#if SQLITE_OS_UNIX || SQLITE_OS_WIN |
| 92950 | + for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){ |
| 92951 | + char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]); |
| 92952 | + if( zAltFile==0 ) return SQLITE_NOMEM; |
| 92953 | + handle = sqlite3OsDlOpen(pVfs, zAltFile); |
| 92954 | + sqlite3_free(zAltFile); |
| 92955 | + } |
| 92956 | +#endif |
| 91834 | 92957 | if( handle==0 ){ |
| 91835 | 92958 | if( pzErrMsg ){ |
| 91836 | 92959 | *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); |
| 91837 | 92960 | if( zErrmsg ){ |
| 91838 | 92961 | sqlite3_snprintf(nMsg, zErrmsg, |
| | @@ -91841,24 +92964,61 @@ |
| 91841 | 92964 | } |
| 91842 | 92965 | } |
| 91843 | 92966 | return SQLITE_ERROR; |
| 91844 | 92967 | } |
| 91845 | 92968 | xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) |
| 91846 | | - sqlite3OsDlSym(pVfs, handle, zProc); |
| 92969 | + sqlite3OsDlSym(pVfs, handle, zEntry); |
| 92970 | + |
| 92971 | + /* If no entry point was specified and the default legacy |
| 92972 | + ** entry point name "sqlite3_extension_init" was not found, then |
| 92973 | + ** construct an entry point name "sqlite3_X_init" where the X is |
| 92974 | + ** replaced by the lowercase value of every ASCII alphabetic |
| 92975 | + ** character in the filename after the last "/" upto the first ".", |
| 92976 | + ** and eliding the first three characters if they are "lib". |
| 92977 | + ** Examples: |
| 92978 | + ** |
| 92979 | + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init |
| 92980 | + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init |
| 92981 | + */ |
| 92982 | + if( xInit==0 && zProc==0 ){ |
| 92983 | + int iFile, iEntry, c; |
| 92984 | + int ncFile = sqlite3Strlen30(zFile); |
| 92985 | + zAltEntry = sqlite3_malloc(ncFile+30); |
| 92986 | + if( zAltEntry==0 ){ |
| 92987 | + sqlite3OsDlClose(pVfs, handle); |
| 92988 | + return SQLITE_NOMEM; |
| 92989 | + } |
| 92990 | + memcpy(zAltEntry, "sqlite3_", 8); |
| 92991 | + for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} |
| 92992 | + iFile++; |
| 92993 | + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; |
| 92994 | + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ |
| 92995 | + if( sqlite3Isalpha(c) ){ |
| 92996 | + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; |
| 92997 | + } |
| 92998 | + } |
| 92999 | + memcpy(zAltEntry+iEntry, "_init", 6); |
| 93000 | + zEntry = zAltEntry; |
| 93001 | + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) |
| 93002 | + sqlite3OsDlSym(pVfs, handle, zEntry); |
| 93003 | + } |
| 91847 | 93004 | if( xInit==0 ){ |
| 91848 | 93005 | if( pzErrMsg ){ |
| 91849 | | - nMsg += sqlite3Strlen30(zProc); |
| 93006 | + nMsg += sqlite3Strlen30(zEntry); |
| 91850 | 93007 | *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg); |
| 91851 | 93008 | if( zErrmsg ){ |
| 91852 | 93009 | sqlite3_snprintf(nMsg, zErrmsg, |
| 91853 | | - "no entry point [%s] in shared library [%s]", zProc,zFile); |
| 93010 | + "no entry point [%s] in shared library [%s]", zEntry, zFile); |
| 91854 | 93011 | sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); |
| 91855 | 93012 | } |
| 91856 | | - sqlite3OsDlClose(pVfs, handle); |
| 91857 | 93013 | } |
| 93014 | + sqlite3OsDlClose(pVfs, handle); |
| 93015 | + sqlite3_free(zAltEntry); |
| 91858 | 93016 | return SQLITE_ERROR; |
| 91859 | | - }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){ |
| 93017 | + } |
| 93018 | + sqlite3_free(zAltEntry); |
| 93019 | + if( xInit(db, &zErrmsg, &sqlite3Apis) ){ |
| 91860 | 93020 | if( pzErrMsg ){ |
| 91861 | 93021 | *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); |
| 91862 | 93022 | } |
| 91863 | 93023 | sqlite3_free(zErrmsg); |
| 91864 | 93024 | sqlite3OsDlClose(pVfs, handle); |
| | @@ -92383,11 +93543,11 @@ |
| 92383 | 93543 | int iDb; /* Database index for <database> */ |
| 92384 | 93544 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 92385 | 93545 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 92386 | 93546 | sqlite3 *db = pParse->db; /* The database connection */ |
| 92387 | 93547 | Db *pDb; /* The specific database being pragmaed */ |
| 92388 | | - Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */ |
| 93548 | + Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 92389 | 93549 | |
| 92390 | 93550 | if( v==0 ) return; |
| 92391 | 93551 | sqlite3VdbeRunOnlyOnce(v); |
| 92392 | 93552 | pParse->nMem = 2; |
| 92393 | 93553 | |
| | @@ -92466,15 +93626,16 @@ |
| 92466 | 93626 | */ |
| 92467 | 93627 | if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ |
| 92468 | 93628 | static const VdbeOpList getCacheSize[] = { |
| 92469 | 93629 | { OP_Transaction, 0, 0, 0}, /* 0 */ |
| 92470 | 93630 | { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ |
| 92471 | | - { OP_IfPos, 1, 7, 0}, |
| 93631 | + { OP_IfPos, 1, 8, 0}, |
| 92472 | 93632 | { OP_Integer, 0, 2, 0}, |
| 92473 | 93633 | { OP_Subtract, 1, 2, 1}, |
| 92474 | | - { OP_IfPos, 1, 7, 0}, |
| 93634 | + { OP_IfPos, 1, 8, 0}, |
| 92475 | 93635 | { OP_Integer, 0, 1, 0}, /* 6 */ |
| 93636 | + { OP_Noop, 0, 0, 0}, |
| 92476 | 93637 | { OP_ResultRow, 1, 1, 0}, |
| 92477 | 93638 | }; |
| 92478 | 93639 | int addr; |
| 92479 | 93640 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 92480 | 93641 | sqlite3VdbeUsesBtree(v, iDb); |
| | @@ -92808,10 +93969,47 @@ |
| 92808 | 93969 | pDb->pSchema->cache_size = size; |
| 92809 | 93970 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 92810 | 93971 | } |
| 92811 | 93972 | }else |
| 92812 | 93973 | |
| 93974 | + /* |
| 93975 | + ** PRAGMA [database.]mmap_size(N) |
| 93976 | + ** |
| 93977 | + ** Used to set mapping size limit. The mapping size limit is |
| 93978 | + ** used to limit the aggregate size of all memory mapped regions of the |
| 93979 | + ** database file. If this parameter is set to zero, then memory mapping |
| 93980 | + ** is not used at all. If N is negative, then the default memory map |
| 93981 | + ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. |
| 93982 | + ** The parameter N is measured in bytes. |
| 93983 | + ** |
| 93984 | + ** This value is advisory. The underlying VFS is free to memory map |
| 93985 | + ** as little or as much as it wants. Except, if N is set to 0 then the |
| 93986 | + ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 93987 | + */ |
| 93988 | + if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 93989 | + sqlite3_int64 sz; |
| 93990 | + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 93991 | + if( zRight ){ |
| 93992 | + int ii; |
| 93993 | + sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8); |
| 93994 | + if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 93995 | + if( pId2->n==0 ) db->szMmap = sz; |
| 93996 | + for(ii=db->nDb-1; ii>=0; ii--){ |
| 93997 | + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 93998 | + sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| 93999 | + } |
| 94000 | + } |
| 94001 | + } |
| 94002 | + sz = -1; |
| 94003 | + if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_SIZE,&sz)==SQLITE_OK ){ |
| 94004 | +#if SQLITE_MAX_MMAP_SIZE==0 |
| 94005 | + sz = 0; |
| 94006 | +#endif |
| 94007 | + returnSingleInt(pParse, "mmap_size", sz); |
| 94008 | + } |
| 94009 | + }else |
| 94010 | + |
| 92813 | 94011 | /* |
| 92814 | 94012 | ** PRAGMA temp_store |
| 92815 | 94013 | ** PRAGMA temp_store = "default"|"memory"|"file" |
| 92816 | 94014 | ** |
| 92817 | 94015 | ** Return or set the local value of the temp_store flag. Changing |
| | @@ -94498,11 +95696,10 @@ |
| 94498 | 95696 | azColName[i], SQLITE_STATIC); |
| 94499 | 95697 | } |
| 94500 | 95698 | } |
| 94501 | 95699 | #endif |
| 94502 | 95700 | |
| 94503 | | - assert( db->init.busy==0 || saveSqlFlag==0 ); |
| 94504 | 95701 | if( db->init.busy==0 ){ |
| 94505 | 95702 | Vdbe *pVdbe = pParse->pVdbe; |
| 94506 | 95703 | sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); |
| 94507 | 95704 | } |
| 94508 | 95705 | if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ |
| | @@ -98290,10 +99487,11 @@ |
| 98290 | 99487 | ** The calling function can detect the problem by looking at pParse->nErr |
| 98291 | 99488 | ** and/or pParse->db->mallocFailed. |
| 98292 | 99489 | */ |
| 98293 | 99490 | static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ |
| 98294 | 99491 | Walker w; |
| 99492 | + memset(&w, 0, sizeof(w)); |
| 98295 | 99493 | w.xSelectCallback = selectExpander; |
| 98296 | 99494 | w.xExprCallback = exprWalkNoop; |
| 98297 | 99495 | w.pParse = pParse; |
| 98298 | 99496 | sqlite3WalkSelect(&w, pSelect); |
| 98299 | 99497 | } |
| | @@ -98348,13 +99546,15 @@ |
| 98348 | 99546 | ** Use this routine after name resolution. |
| 98349 | 99547 | */ |
| 98350 | 99548 | static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ |
| 98351 | 99549 | #ifndef SQLITE_OMIT_SUBQUERY |
| 98352 | 99550 | Walker w; |
| 99551 | + memset(&w, 0, sizeof(w)); |
| 98353 | 99552 | w.xSelectCallback = selectAddSubqueryTypeInfo; |
| 98354 | 99553 | w.xExprCallback = exprWalkNoop; |
| 98355 | 99554 | w.pParse = pParse; |
| 99555 | + w.bSelectDepthFirst = 1; |
| 98356 | 99556 | sqlite3WalkSelect(&w, pSelect); |
| 98357 | 99557 | #endif |
| 98358 | 99558 | } |
| 98359 | 99559 | |
| 98360 | 99560 | |
| | @@ -98761,11 +99961,11 @@ |
| 98761 | 99961 | pItem->regReturn = ++pParse->nMem; |
| 98762 | 99962 | topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); |
| 98763 | 99963 | pItem->addrFillSub = topAddr+1; |
| 98764 | 99964 | VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); |
| 98765 | 99965 | if( pItem->isCorrelated==0 ){ |
| 98766 | | - /* If the subquery is no correlated and if we are not inside of |
| 99966 | + /* If the subquery is not correlated and if we are not inside of |
| 98767 | 99967 | ** a trigger, then we only need to compute the value of the subquery |
| 98768 | 99968 | ** once. */ |
| 98769 | 99969 | onceAddr = sqlite3CodeOnce(pParse); |
| 98770 | 99970 | } |
| 98771 | 99971 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| | @@ -105219,13 +106419,12 @@ |
| 105219 | 106419 | Table *pTab = pSrc->pTab; |
| 105220 | 106420 | sqlite3_index_info *pIdxInfo; |
| 105221 | 106421 | struct sqlite3_index_constraint *pIdxCons; |
| 105222 | 106422 | struct sqlite3_index_constraint_usage *pUsage; |
| 105223 | 106423 | WhereTerm *pTerm; |
| 105224 | | - int i, j, k; |
| 106424 | + int i, j; |
| 105225 | 106425 | int nOrderBy; |
| 105226 | | - int sortOrder; /* Sort order for IN clauses */ |
| 105227 | 106426 | int bAllowIN; /* Allow IN optimizations */ |
| 105228 | 106427 | double rCost; |
| 105229 | 106428 | |
| 105230 | 106429 | /* Make sure wsFlags is initialized to some sane value. Otherwise, if the |
| 105231 | 106430 | ** malloc in allocateIndexInfo() fails and this function returns leaving |
| | @@ -105320,11 +106519,10 @@ |
| 105320 | 106519 | |
| 105321 | 106520 | if( vtabBestIndex(pParse, pTab, pIdxInfo) ){ |
| 105322 | 106521 | return; |
| 105323 | 106522 | } |
| 105324 | 106523 | |
| 105325 | | - sortOrder = SQLITE_SO_ASC; |
| 105326 | 106524 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 105327 | 106525 | for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ |
| 105328 | 106526 | if( pUsage[i].argvIndex>0 ){ |
| 105329 | 106527 | j = pIdxCons->iTermOffset; |
| 105330 | 106528 | pTerm = &pWC->a[j]; |
| | @@ -105335,21 +106533,32 @@ |
| 105335 | 106533 | ** says that the equivalent EQ constraint cannot be safely omitted. |
| 105336 | 106534 | ** If we do attempt to use such a constraint, some rows might be |
| 105337 | 106535 | ** repeated in the output. */ |
| 105338 | 106536 | break; |
| 105339 | 106537 | } |
| 105340 | | - for(k=0; k<pIdxInfo->nOrderBy; k++){ |
| 105341 | | - if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){ |
| 105342 | | - sortOrder = pIdxInfo->aOrderBy[k].desc; |
| 105343 | | - break; |
| 105344 | | - } |
| 105345 | | - } |
| 106538 | + /* A virtual table that is constrained by an IN clause may not |
| 106539 | + ** consume the ORDER BY clause because (1) the order of IN terms |
| 106540 | + ** is not necessarily related to the order of output terms and |
| 106541 | + ** (2) Multiple outputs from a single IN value will not merge |
| 106542 | + ** together. */ |
| 106543 | + pIdxInfo->orderByConsumed = 0; |
| 105346 | 106544 | } |
| 105347 | 106545 | } |
| 105348 | 106546 | } |
| 105349 | 106547 | if( i>=pIdxInfo->nConstraint ) break; |
| 105350 | 106548 | } |
| 106549 | + |
| 106550 | + /* The orderByConsumed signal is only valid if all outer loops collectively |
| 106551 | + ** generate just a single row of output. |
| 106552 | + */ |
| 106553 | + if( pIdxInfo->orderByConsumed ){ |
| 106554 | + for(i=0; i<p->i; i++){ |
| 106555 | + if( (p->aLevel[i].plan.wsFlags & WHERE_UNIQUE)==0 ){ |
| 106556 | + pIdxInfo->orderByConsumed = 0; |
| 106557 | + } |
| 106558 | + } |
| 106559 | + } |
| 105351 | 106560 | |
| 105352 | 106561 | /* If there is an ORDER BY clause, and the selected virtual table index |
| 105353 | 106562 | ** does not satisfy it, increase the cost of the scan accordingly. This |
| 105354 | 106563 | ** matches the processing for non-virtual tables in bestBtreeIndex(). |
| 105355 | 106564 | */ |
| | @@ -105370,12 +106579,11 @@ |
| 105370 | 106579 | }else{ |
| 105371 | 106580 | p->cost.rCost = rCost; |
| 105372 | 106581 | } |
| 105373 | 106582 | p->cost.plan.u.pVtabIdx = pIdxInfo; |
| 105374 | 106583 | if( pIdxInfo->orderByConsumed ){ |
| 105375 | | - assert( sortOrder==0 || sortOrder==1 ); |
| 105376 | | - p->cost.plan.wsFlags |= WHERE_ORDERED + sortOrder*WHERE_REVERSE; |
| 106584 | + p->cost.plan.wsFlags |= WHERE_ORDERED; |
| 105377 | 106585 | p->cost.plan.nOBSat = nOrderBy; |
| 105378 | 106586 | }else{ |
| 105379 | 106587 | p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0; |
| 105380 | 106588 | } |
| 105381 | 106589 | p->cost.plan.nEq = 0; |
| | @@ -107108,10 +108316,11 @@ |
| 107108 | 108316 | struct SrcList_item *pTabItem; /* FROM clause term being coded */ |
| 107109 | 108317 | int addrBrk; /* Jump here to break out of the loop */ |
| 107110 | 108318 | int addrCont; /* Jump here to continue with next cycle */ |
| 107111 | 108319 | int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ |
| 107112 | 108320 | int iReleaseReg = 0; /* Temp register to free before returning */ |
| 108321 | + Bitmask newNotReady; /* Return value */ |
| 107113 | 108322 | |
| 107114 | 108323 | pParse = pWInfo->pParse; |
| 107115 | 108324 | v = pParse->pVdbe; |
| 107116 | 108325 | pWC = pWInfo->pWC; |
| 107117 | 108326 | pLevel = &pWInfo->a[iLevel]; |
| | @@ -107118,10 +108327,11 @@ |
| 107118 | 108327 | pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; |
| 107119 | 108328 | iCur = pTabItem->iCursor; |
| 107120 | 108329 | bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; |
| 107121 | 108330 | omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 |
| 107122 | 108331 | && (wctrlFlags & WHERE_FORCE_TABLE)==0; |
| 108332 | + VdbeNoopComment((v, "Begin Join Loop %d", iLevel)); |
| 107123 | 108333 | |
| 107124 | 108334 | /* Create labels for the "break" and "continue" instructions |
| 107125 | 108335 | ** for the current loop. Jump to addrBrk to break out of a loop. |
| 107126 | 108336 | ** Jump to cont to go immediately to the next iteration of the |
| 107127 | 108337 | ** loop. |
| | @@ -107768,11 +108978,11 @@ |
| 107768 | 108978 | pLevel->op = aStep[bRev]; |
| 107769 | 108979 | pLevel->p1 = iCur; |
| 107770 | 108980 | pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); |
| 107771 | 108981 | pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 107772 | 108982 | } |
| 107773 | | - notReady &= ~getMask(pWC->pMaskSet, iCur); |
| 108983 | + newNotReady = notReady & ~getMask(pWC->pMaskSet, iCur); |
| 107774 | 108984 | |
| 107775 | 108985 | /* Insert code to test every subexpression that can be completely |
| 107776 | 108986 | ** computed using the current set of tables. |
| 107777 | 108987 | ** |
| 107778 | 108988 | ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through |
| | @@ -107782,11 +108992,11 @@ |
| 107782 | 108992 | for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ |
| 107783 | 108993 | Expr *pE; |
| 107784 | 108994 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ |
| 107785 | 108995 | testcase( pTerm->wtFlags & TERM_CODED ); |
| 107786 | 108996 | if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 107787 | | - if( (pTerm->prereqAll & notReady)!=0 ){ |
| 108997 | + if( (pTerm->prereqAll & newNotReady)!=0 ){ |
| 107788 | 108998 | testcase( pWInfo->untestedTerms==0 |
| 107789 | 108999 | && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ); |
| 107790 | 109000 | pWInfo->untestedTerms = 1; |
| 107791 | 109001 | continue; |
| 107792 | 109002 | } |
| | @@ -107796,10 +109006,36 @@ |
| 107796 | 109006 | continue; |
| 107797 | 109007 | } |
| 107798 | 109008 | sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); |
| 107799 | 109009 | pTerm->wtFlags |= TERM_CODED; |
| 107800 | 109010 | } |
| 109011 | + |
| 109012 | + /* Insert code to test for implied constraints based on transitivity |
| 109013 | + ** of the "==" operator. |
| 109014 | + ** |
| 109015 | + ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" |
| 109016 | + ** and we are coding the t1 loop and the t2 loop has not yet coded, |
| 109017 | + ** then we cannot use the "t1.a=t2.b" constraint, but we can code |
| 109018 | + ** the implied "t1.a=123" constraint. |
| 109019 | + */ |
| 109020 | + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ |
| 109021 | + Expr *pE; |
| 109022 | + WhereTerm *pAlt; |
| 109023 | + Expr sEq; |
| 109024 | + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 109025 | + if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; |
| 109026 | + if( pTerm->leftCursor!=iCur ) continue; |
| 109027 | + pE = pTerm->pExpr; |
| 109028 | + assert( !ExprHasProperty(pE, EP_FromJoin) ); |
| 109029 | + assert( (pTerm->prereqRight & newNotReady)!=0 ); |
| 109030 | + pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0); |
| 109031 | + if( pAlt==0 ) continue; |
| 109032 | + VdbeNoopComment((v, "begin transitive constraint")); |
| 109033 | + sEq = *pAlt->pExpr; |
| 109034 | + sEq.pLeft = pE->pLeft; |
| 109035 | + sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL); |
| 109036 | + } |
| 107801 | 109037 | |
| 107802 | 109038 | /* For a LEFT OUTER JOIN, generate code that will record the fact that |
| 107803 | 109039 | ** at least one row of the right table has matched the left table. |
| 107804 | 109040 | */ |
| 107805 | 109041 | if( pLevel->iLeftJoin ){ |
| | @@ -107809,11 +109045,11 @@ |
| 107809 | 109045 | sqlite3ExprCacheClear(pParse); |
| 107810 | 109046 | for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){ |
| 107811 | 109047 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ |
| 107812 | 109048 | testcase( pTerm->wtFlags & TERM_CODED ); |
| 107813 | 109049 | if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 107814 | | - if( (pTerm->prereqAll & notReady)!=0 ){ |
| 109050 | + if( (pTerm->prereqAll & newNotReady)!=0 ){ |
| 107815 | 109051 | assert( pWInfo->untestedTerms ); |
| 107816 | 109052 | continue; |
| 107817 | 109053 | } |
| 107818 | 109054 | assert( pTerm->pExpr ); |
| 107819 | 109055 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); |
| | @@ -107820,11 +109056,11 @@ |
| 107820 | 109056 | pTerm->wtFlags |= TERM_CODED; |
| 107821 | 109057 | } |
| 107822 | 109058 | } |
| 107823 | 109059 | sqlite3ReleaseTempReg(pParse, iReleaseReg); |
| 107824 | 109060 | |
| 107825 | | - return notReady; |
| 109061 | + return newNotReady; |
| 107826 | 109062 | } |
| 107827 | 109063 | |
| 107828 | 109064 | #if defined(SQLITE_TEST) |
| 107829 | 109065 | /* |
| 107830 | 109066 | ** The following variable holds a text description of query plan generated |
| | @@ -113805,10 +115041,23 @@ |
| 113805 | 115041 | sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); |
| 113806 | 115042 | sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); |
| 113807 | 115043 | break; |
| 113808 | 115044 | } |
| 113809 | 115045 | #endif |
| 115046 | + |
| 115047 | + case SQLITE_CONFIG_MMAP_SIZE: { |
| 115048 | + sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); |
| 115049 | + sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); |
| 115050 | + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ |
| 115051 | + mxMmap = SQLITE_MAX_MMAP_SIZE; |
| 115052 | + } |
| 115053 | + sqlite3GlobalConfig.mxMmap = mxMmap; |
| 115054 | + if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; |
| 115055 | + if( szMmap>mxMmap) szMmap = mxMmap; |
| 115056 | + sqlite3GlobalConfig.szMmap = szMmap; |
| 115057 | + break; |
| 115058 | + } |
| 113810 | 115059 | |
| 113811 | 115060 | default: { |
| 113812 | 115061 | rc = SQLITE_ERROR; |
| 113813 | 115062 | break; |
| 113814 | 115063 | } |
| | @@ -115626,10 +116875,11 @@ |
| 115626 | 116875 | |
| 115627 | 116876 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); |
| 115628 | 116877 | memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); |
| 115629 | 116878 | db->autoCommit = 1; |
| 115630 | 116879 | db->nextAutovac = -1; |
| 116880 | + db->szMmap = sqlite3GlobalConfig.szMmap; |
| 115631 | 116881 | db->nextPagesize = 0; |
| 115632 | 116882 | db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger |
| 115633 | 116883 | #if SQLITE_DEFAULT_FILE_FORMAT<4 |
| 115634 | 116884 | | SQLITE_LegacyFileFmt |
| 115635 | 116885 | #endif |
| | @@ -117967,10 +119217,13 @@ |
| 117967 | 119217 | Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); |
| 117968 | 119218 | SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); |
| 117969 | 119219 | SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); |
| 117970 | 119220 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); |
| 117971 | 119221 | |
| 119222 | +/* fts3_tokenize_vtab.c */ |
| 119223 | +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*); |
| 119224 | + |
| 117972 | 119225 | /* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 117973 | 119226 | #ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 117974 | 119227 | SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 117975 | 119228 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 117976 | 119229 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| | @@ -121281,10 +122534,13 @@ |
| 121281 | 122534 | #endif |
| 121282 | 122535 | |
| 121283 | 122536 | rc = sqlite3Fts3InitAux(db); |
| 121284 | 122537 | if( rc!=SQLITE_OK ) return rc; |
| 121285 | 122538 | |
| 122539 | + rc = sqlite3Fts3InitTok(db); |
| 122540 | + if( rc!=SQLITE_OK ) return rc; |
| 122541 | + |
| 121286 | 122542 | sqlite3Fts3SimpleTokenizerModule(&pSimple); |
| 121287 | 122543 | sqlite3Fts3PorterTokenizerModule(&pPorter); |
| 121288 | 122544 | |
| 121289 | 122545 | /* Allocate and initialize the hash-table used to store tokenizers. */ |
| 121290 | 122546 | pHash = sqlite3_malloc(sizeof(Fts3Hash)); |
| | @@ -123110,21 +124366,30 @@ |
| 123110 | 124366 | int rc; /* value returned by declare_vtab() */ |
| 123111 | 124367 | Fts3auxTable *p; /* Virtual table object to return */ |
| 123112 | 124368 | |
| 123113 | 124369 | UNUSED_PARAMETER(pUnused); |
| 123114 | 124370 | |
| 123115 | | - /* The user should specify a single argument - the name of an fts3 table. */ |
| 123116 | | - if( argc!=4 ){ |
| 123117 | | - *pzErr = sqlite3_mprintf( |
| 123118 | | - "wrong number of arguments to fts4aux constructor" |
| 123119 | | - ); |
| 123120 | | - return SQLITE_ERROR; |
| 123121 | | - } |
| 124371 | + /* The user should invoke this in one of two forms: |
| 124372 | + ** |
| 124373 | + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table); |
| 124374 | + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table); |
| 124375 | + */ |
| 124376 | + if( argc!=4 && argc!=5 ) goto bad_args; |
| 123122 | 124377 | |
| 123123 | 124378 | zDb = argv[1]; |
| 123124 | 124379 | nDb = (int)strlen(zDb); |
| 123125 | | - zFts3 = argv[3]; |
| 124380 | + if( argc==5 ){ |
| 124381 | + if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ |
| 124382 | + zDb = argv[3]; |
| 124383 | + nDb = (int)strlen(zDb); |
| 124384 | + zFts3 = argv[4]; |
| 124385 | + }else{ |
| 124386 | + goto bad_args; |
| 124387 | + } |
| 124388 | + }else{ |
| 124389 | + zFts3 = argv[3]; |
| 124390 | + } |
| 123126 | 124391 | nFts3 = (int)strlen(zFts3); |
| 123127 | 124392 | |
| 123128 | 124393 | rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA); |
| 123129 | 124394 | if( rc!=SQLITE_OK ) return rc; |
| 123130 | 124395 | |
| | @@ -123143,10 +124408,14 @@ |
| 123143 | 124408 | memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); |
| 123144 | 124409 | sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); |
| 123145 | 124410 | |
| 123146 | 124411 | *ppVtab = (sqlite3_vtab *)p; |
| 123147 | 124412 | return SQLITE_OK; |
| 124413 | + |
| 124414 | + bad_args: |
| 124415 | + *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor"); |
| 124416 | + return SQLITE_ERROR; |
| 123148 | 124417 | } |
| 123149 | 124418 | |
| 123150 | 124419 | /* |
| 123151 | 124420 | ** This function does the work for both the xDisconnect and xDestroy methods. |
| 123152 | 124421 | ** These tables have no persistent representation of their own, so xDisconnect |
| | @@ -126285,10 +127554,476 @@ |
| 126285 | 127554 | } |
| 126286 | 127555 | |
| 126287 | 127556 | #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 126288 | 127557 | |
| 126289 | 127558 | /************** End of fts3_tokenizer1.c *************************************/ |
| 127559 | +/************** Begin file fts3_tokenize_vtab.c ******************************/ |
| 127560 | +/* |
| 127561 | +** 2013 Apr 22 |
| 127562 | +** |
| 127563 | +** The author disclaims copyright to this source code. In place of |
| 127564 | +** a legal notice, here is a blessing: |
| 127565 | +** |
| 127566 | +** May you do good and not evil. |
| 127567 | +** May you find forgiveness for yourself and forgive others. |
| 127568 | +** May you share freely, never taking more than you give. |
| 127569 | +** |
| 127570 | +****************************************************************************** |
| 127571 | +** |
| 127572 | +** This file contains code for the "fts3tokenize" virtual table module. |
| 127573 | +** An fts3tokenize virtual table is created as follows: |
| 127574 | +** |
| 127575 | +** CREATE VIRTUAL TABLE <tbl> USING fts3tokenize( |
| 127576 | +** <tokenizer-name>, <arg-1>, ... |
| 127577 | +** ); |
| 127578 | +** |
| 127579 | +** The table created has the following schema: |
| 127580 | +** |
| 127581 | +** CREATE TABLE <tbl>(input, token, start, end, position) |
| 127582 | +** |
| 127583 | +** When queried, the query must include a WHERE clause of type: |
| 127584 | +** |
| 127585 | +** input = <string> |
| 127586 | +** |
| 127587 | +** The virtual table module tokenizes this <string>, using the FTS3 |
| 127588 | +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE |
| 127589 | +** statement and returns one row for each token in the result. With |
| 127590 | +** fields set as follows: |
| 127591 | +** |
| 127592 | +** input: Always set to a copy of <string> |
| 127593 | +** token: A token from the input. |
| 127594 | +** start: Byte offset of the token within the input <string>. |
| 127595 | +** end: Byte offset of the byte immediately following the end of the |
| 127596 | +** token within the input string. |
| 127597 | +** pos: Token offset of token within input. |
| 127598 | +** |
| 127599 | +*/ |
| 127600 | +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 127601 | + |
| 127602 | +/* #include <string.h> */ |
| 127603 | +/* #include <assert.h> */ |
| 127604 | + |
| 127605 | +typedef struct Fts3tokTable Fts3tokTable; |
| 127606 | +typedef struct Fts3tokCursor Fts3tokCursor; |
| 127607 | + |
| 127608 | +/* |
| 127609 | +** Virtual table structure. |
| 127610 | +*/ |
| 127611 | +struct Fts3tokTable { |
| 127612 | + sqlite3_vtab base; /* Base class used by SQLite core */ |
| 127613 | + const sqlite3_tokenizer_module *pMod; |
| 127614 | + sqlite3_tokenizer *pTok; |
| 127615 | +}; |
| 127616 | + |
| 127617 | +/* |
| 127618 | +** Virtual table cursor structure. |
| 127619 | +*/ |
| 127620 | +struct Fts3tokCursor { |
| 127621 | + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ |
| 127622 | + char *zInput; /* Input string */ |
| 127623 | + sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ |
| 127624 | + int iRowid; /* Current 'rowid' value */ |
| 127625 | + const char *zToken; /* Current 'token' value */ |
| 127626 | + int nToken; /* Size of zToken in bytes */ |
| 127627 | + int iStart; /* Current 'start' value */ |
| 127628 | + int iEnd; /* Current 'end' value */ |
| 127629 | + int iPos; /* Current 'pos' value */ |
| 127630 | +}; |
| 127631 | + |
| 127632 | +/* |
| 127633 | +** Query FTS for the tokenizer implementation named zName. |
| 127634 | +*/ |
| 127635 | +static int fts3tokQueryTokenizer( |
| 127636 | + sqlite3 *db, |
| 127637 | + const char *zName, |
| 127638 | + const sqlite3_tokenizer_module **pp |
| 127639 | +){ |
| 127640 | + int rc; |
| 127641 | + sqlite3_stmt *pStmt; |
| 127642 | + const char *zSql = "SELECT fts3_tokenizer(?)"; |
| 127643 | + |
| 127644 | + *pp = 0; |
| 127645 | + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| 127646 | + if( rc!=SQLITE_OK ){ |
| 127647 | + return rc; |
| 127648 | + } |
| 127649 | + |
| 127650 | + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); |
| 127651 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 127652 | + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ |
| 127653 | + memcpy((void*)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); |
| 127654 | + } |
| 127655 | + } |
| 127656 | + |
| 127657 | + return sqlite3_finalize(pStmt); |
| 127658 | +} |
| 127659 | + |
| 127660 | +/* |
| 127661 | +** The second argument, argv[], is an array of pointers to nul-terminated |
| 127662 | +** strings. This function makes a copy of the array and strings into a |
| 127663 | +** single block of memory. It then dequotes any of the strings that appear |
| 127664 | +** to be quoted. |
| 127665 | +** |
| 127666 | +** If successful, output parameter *pazDequote is set to point at the |
| 127667 | +** array of dequoted strings and SQLITE_OK is returned. The caller is |
| 127668 | +** responsible for eventually calling sqlite3_free() to free the array |
| 127669 | +** in this case. Or, if an error occurs, an SQLite error code is returned. |
| 127670 | +** The final value of *pazDequote is undefined in this case. |
| 127671 | +*/ |
| 127672 | +static int fts3tokDequoteArray( |
| 127673 | + int argc, /* Number of elements in argv[] */ |
| 127674 | + const char * const *argv, /* Input array */ |
| 127675 | + char ***pazDequote /* Output array */ |
| 127676 | +){ |
| 127677 | + int rc = SQLITE_OK; /* Return code */ |
| 127678 | + if( argc==0 ){ |
| 127679 | + *pazDequote = 0; |
| 127680 | + }else{ |
| 127681 | + int i; |
| 127682 | + int nByte = 0; |
| 127683 | + char **azDequote; |
| 127684 | + |
| 127685 | + for(i=0; i<argc; i++){ |
| 127686 | + nByte += (int)(strlen(argv[i]) + 1); |
| 127687 | + } |
| 127688 | + |
| 127689 | + *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte); |
| 127690 | + if( azDequote==0 ){ |
| 127691 | + rc = SQLITE_NOMEM; |
| 127692 | + }else{ |
| 127693 | + char *pSpace = (char *)&azDequote[argc]; |
| 127694 | + for(i=0; i<argc; i++){ |
| 127695 | + int n = (int)strlen(argv[i]); |
| 127696 | + azDequote[i] = pSpace; |
| 127697 | + memcpy(pSpace, argv[i], n+1); |
| 127698 | + sqlite3Fts3Dequote(pSpace); |
| 127699 | + pSpace += (n+1); |
| 127700 | + } |
| 127701 | + } |
| 127702 | + } |
| 127703 | + |
| 127704 | + return rc; |
| 127705 | +} |
| 127706 | + |
| 127707 | +/* |
| 127708 | +** Schema of the tokenizer table. |
| 127709 | +*/ |
| 127710 | +#define FTS3_TOK_SCHEMA "CREATE TABLE x(input, token, start, end, position)" |
| 127711 | + |
| 127712 | +/* |
| 127713 | +** This function does all the work for both the xConnect and xCreate methods. |
| 127714 | +** These tables have no persistent representation of their own, so xConnect |
| 127715 | +** and xCreate are identical operations. |
| 127716 | +** |
| 127717 | +** argv[0]: module name |
| 127718 | +** argv[1]: database name |
| 127719 | +** argv[2]: table name |
| 127720 | +** argv[3]: first argument (tokenizer name) |
| 127721 | +*/ |
| 127722 | +static int fts3tokConnectMethod( |
| 127723 | + sqlite3 *db, /* Database connection */ |
| 127724 | + void *pUnused, /* Unused */ |
| 127725 | + int argc, /* Number of elements in argv array */ |
| 127726 | + const char * const *argv, /* xCreate/xConnect argument array */ |
| 127727 | + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
| 127728 | + char **pzErr /* OUT: sqlite3_malloc'd error message */ |
| 127729 | +){ |
| 127730 | + Fts3tokTable *pTab; |
| 127731 | + const sqlite3_tokenizer_module *pMod = 0; |
| 127732 | + sqlite3_tokenizer *pTok = 0; |
| 127733 | + int rc; |
| 127734 | + char **azDequote = 0; |
| 127735 | + int nDequote; |
| 127736 | + UNUSED_PARAMETER(pUnused); |
| 127737 | + |
| 127738 | + rc = sqlite3_declare_vtab(db, FTS3_TOK_SCHEMA); |
| 127739 | + if( rc!=SQLITE_OK ) return rc; |
| 127740 | + |
| 127741 | + nDequote = argc-3; |
| 127742 | + rc = fts3tokDequoteArray(nDequote, &argv[3], &azDequote); |
| 127743 | + |
| 127744 | + if( rc==SQLITE_OK ){ |
| 127745 | + const char *zModule; |
| 127746 | + if( nDequote<1 ){ |
| 127747 | + zModule = "simple"; |
| 127748 | + }else{ |
| 127749 | + zModule = azDequote[0]; |
| 127750 | + } |
| 127751 | + rc = fts3tokQueryTokenizer(db, zModule, &pMod); |
| 127752 | + } |
| 127753 | + |
| 127754 | + if( rc!=SQLITE_OK ){ |
| 127755 | + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); |
| 127756 | + }else if( pMod==0 ){ |
| 127757 | + rc = SQLITE_ERROR; |
| 127758 | + }else{ |
| 127759 | + const char * const *azArg = (const char * const *)&azDequote[1]; |
| 127760 | + rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok); |
| 127761 | + } |
| 127762 | + |
| 127763 | + if( rc==SQLITE_OK ){ |
| 127764 | + pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); |
| 127765 | + if( pTab==0 ){ |
| 127766 | + rc = SQLITE_NOMEM; |
| 127767 | + } |
| 127768 | + } |
| 127769 | + |
| 127770 | + if( rc==SQLITE_OK ){ |
| 127771 | + memset(pTab, 0, sizeof(Fts3tokTable)); |
| 127772 | + pTab->pMod = pMod; |
| 127773 | + pTab->pTok = pTok; |
| 127774 | + *ppVtab = &pTab->base; |
| 127775 | + }else{ |
| 127776 | + if( pTok ){ |
| 127777 | + pMod->xDestroy(pTok); |
| 127778 | + } |
| 127779 | + } |
| 127780 | + |
| 127781 | + sqlite3_free(azDequote); |
| 127782 | + return rc; |
| 127783 | +} |
| 127784 | + |
| 127785 | +/* |
| 127786 | +** This function does the work for both the xDisconnect and xDestroy methods. |
| 127787 | +** These tables have no persistent representation of their own, so xDisconnect |
| 127788 | +** and xDestroy are identical operations. |
| 127789 | +*/ |
| 127790 | +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ |
| 127791 | + Fts3tokTable *pTab = (Fts3tokTable *)pVtab; |
| 127792 | + |
| 127793 | + pTab->pMod->xDestroy(pTab->pTok); |
| 127794 | + sqlite3_free(pTab); |
| 127795 | + return SQLITE_OK; |
| 127796 | +} |
| 127797 | + |
| 127798 | +/* |
| 127799 | +** xBestIndex - Analyze a WHERE and ORDER BY clause. |
| 127800 | +*/ |
| 127801 | +static int fts3tokBestIndexMethod( |
| 127802 | + sqlite3_vtab *pVTab, |
| 127803 | + sqlite3_index_info *pInfo |
| 127804 | +){ |
| 127805 | + int i; |
| 127806 | + UNUSED_PARAMETER(pVTab); |
| 127807 | + |
| 127808 | + for(i=0; i<pInfo->nConstraint; i++){ |
| 127809 | + if( pInfo->aConstraint[i].usable |
| 127810 | + && pInfo->aConstraint[i].iColumn==0 |
| 127811 | + && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ |
| 127812 | + ){ |
| 127813 | + pInfo->idxNum = 1; |
| 127814 | + pInfo->aConstraintUsage[i].argvIndex = 1; |
| 127815 | + pInfo->aConstraintUsage[i].omit = 1; |
| 127816 | + pInfo->estimatedCost = 1; |
| 127817 | + return SQLITE_OK; |
| 127818 | + } |
| 127819 | + } |
| 127820 | + |
| 127821 | + pInfo->idxNum = 0; |
| 127822 | + assert( pInfo->estimatedCost>1000000.0 ); |
| 127823 | + |
| 127824 | + return SQLITE_OK; |
| 127825 | +} |
| 127826 | + |
| 127827 | +/* |
| 127828 | +** xOpen - Open a cursor. |
| 127829 | +*/ |
| 127830 | +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ |
| 127831 | + Fts3tokCursor *pCsr; |
| 127832 | + UNUSED_PARAMETER(pVTab); |
| 127833 | + |
| 127834 | + pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); |
| 127835 | + if( pCsr==0 ){ |
| 127836 | + return SQLITE_NOMEM; |
| 127837 | + } |
| 127838 | + memset(pCsr, 0, sizeof(Fts3tokCursor)); |
| 127839 | + |
| 127840 | + *ppCsr = (sqlite3_vtab_cursor *)pCsr; |
| 127841 | + return SQLITE_OK; |
| 127842 | +} |
| 127843 | + |
| 127844 | +/* |
| 127845 | +** Reset the tokenizer cursor passed as the only argument. As if it had |
| 127846 | +** just been returned by fts3tokOpenMethod(). |
| 127847 | +*/ |
| 127848 | +static void fts3tokResetCursor(Fts3tokCursor *pCsr){ |
| 127849 | + if( pCsr->pCsr ){ |
| 127850 | + Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab); |
| 127851 | + pTab->pMod->xClose(pCsr->pCsr); |
| 127852 | + pCsr->pCsr = 0; |
| 127853 | + } |
| 127854 | + sqlite3_free(pCsr->zInput); |
| 127855 | + pCsr->zInput = 0; |
| 127856 | + pCsr->zToken = 0; |
| 127857 | + pCsr->nToken = 0; |
| 127858 | + pCsr->iStart = 0; |
| 127859 | + pCsr->iEnd = 0; |
| 127860 | + pCsr->iPos = 0; |
| 127861 | + pCsr->iRowid = 0; |
| 127862 | +} |
| 127863 | + |
| 127864 | +/* |
| 127865 | +** xClose - Close a cursor. |
| 127866 | +*/ |
| 127867 | +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ |
| 127868 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127869 | + |
| 127870 | + fts3tokResetCursor(pCsr); |
| 127871 | + sqlite3_free(pCsr); |
| 127872 | + return SQLITE_OK; |
| 127873 | +} |
| 127874 | + |
| 127875 | +/* |
| 127876 | +** xNext - Advance the cursor to the next row, if any. |
| 127877 | +*/ |
| 127878 | +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ |
| 127879 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127880 | + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); |
| 127881 | + int rc; /* Return code */ |
| 127882 | + |
| 127883 | + pCsr->iRowid++; |
| 127884 | + rc = pTab->pMod->xNext(pCsr->pCsr, |
| 127885 | + &pCsr->zToken, &pCsr->nToken, |
| 127886 | + &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos |
| 127887 | + ); |
| 127888 | + |
| 127889 | + if( rc!=SQLITE_OK ){ |
| 127890 | + fts3tokResetCursor(pCsr); |
| 127891 | + if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 127892 | + } |
| 127893 | + |
| 127894 | + return rc; |
| 127895 | +} |
| 127896 | + |
| 127897 | +/* |
| 127898 | +** xFilter - Initialize a cursor to point at the start of its data. |
| 127899 | +*/ |
| 127900 | +static int fts3tokFilterMethod( |
| 127901 | + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ |
| 127902 | + int idxNum, /* Strategy index */ |
| 127903 | + const char *idxStr, /* Unused */ |
| 127904 | + int nVal, /* Number of elements in apVal */ |
| 127905 | + sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 127906 | +){ |
| 127907 | + int rc = SQLITE_ERROR; |
| 127908 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127909 | + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); |
| 127910 | + UNUSED_PARAMETER(idxStr); |
| 127911 | + UNUSED_PARAMETER(nVal); |
| 127912 | + |
| 127913 | + fts3tokResetCursor(pCsr); |
| 127914 | + if( idxNum==1 ){ |
| 127915 | + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); |
| 127916 | + int nByte = sqlite3_value_bytes(apVal[0]); |
| 127917 | + pCsr->zInput = sqlite3_malloc(nByte+1); |
| 127918 | + if( pCsr->zInput==0 ){ |
| 127919 | + rc = SQLITE_NOMEM; |
| 127920 | + }else{ |
| 127921 | + memcpy(pCsr->zInput, zByte, nByte); |
| 127922 | + pCsr->zInput[nByte] = 0; |
| 127923 | + rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); |
| 127924 | + if( rc==SQLITE_OK ){ |
| 127925 | + pCsr->pCsr->pTokenizer = pTab->pTok; |
| 127926 | + } |
| 127927 | + } |
| 127928 | + } |
| 127929 | + |
| 127930 | + if( rc!=SQLITE_OK ) return rc; |
| 127931 | + return fts3tokNextMethod(pCursor); |
| 127932 | +} |
| 127933 | + |
| 127934 | +/* |
| 127935 | +** xEof - Return true if the cursor is at EOF, or false otherwise. |
| 127936 | +*/ |
| 127937 | +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ |
| 127938 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127939 | + return (pCsr->zToken==0); |
| 127940 | +} |
| 127941 | + |
| 127942 | +/* |
| 127943 | +** xColumn - Return a column value. |
| 127944 | +*/ |
| 127945 | +static int fts3tokColumnMethod( |
| 127946 | + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ |
| 127947 | + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ |
| 127948 | + int iCol /* Index of column to read value from */ |
| 127949 | +){ |
| 127950 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127951 | + |
| 127952 | + /* CREATE TABLE x(input, token, start, end, position) */ |
| 127953 | + switch( iCol ){ |
| 127954 | + case 0: |
| 127955 | + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); |
| 127956 | + break; |
| 127957 | + case 1: |
| 127958 | + sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); |
| 127959 | + break; |
| 127960 | + case 2: |
| 127961 | + sqlite3_result_int(pCtx, pCsr->iStart); |
| 127962 | + break; |
| 127963 | + case 3: |
| 127964 | + sqlite3_result_int(pCtx, pCsr->iEnd); |
| 127965 | + break; |
| 127966 | + default: |
| 127967 | + assert( iCol==4 ); |
| 127968 | + sqlite3_result_int(pCtx, pCsr->iPos); |
| 127969 | + break; |
| 127970 | + } |
| 127971 | + return SQLITE_OK; |
| 127972 | +} |
| 127973 | + |
| 127974 | +/* |
| 127975 | +** xRowid - Return the current rowid for the cursor. |
| 127976 | +*/ |
| 127977 | +static int fts3tokRowidMethod( |
| 127978 | + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ |
| 127979 | + sqlite_int64 *pRowid /* OUT: Rowid value */ |
| 127980 | +){ |
| 127981 | + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; |
| 127982 | + *pRowid = (sqlite3_int64)pCsr->iRowid; |
| 127983 | + return SQLITE_OK; |
| 127984 | +} |
| 127985 | + |
| 127986 | +/* |
| 127987 | +** Register the fts3tok module with database connection db. Return SQLITE_OK |
| 127988 | +** if successful or an error code if sqlite3_create_module() fails. |
| 127989 | +*/ |
| 127990 | +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db){ |
| 127991 | + static const sqlite3_module fts3tok_module = { |
| 127992 | + 0, /* iVersion */ |
| 127993 | + fts3tokConnectMethod, /* xCreate */ |
| 127994 | + fts3tokConnectMethod, /* xConnect */ |
| 127995 | + fts3tokBestIndexMethod, /* xBestIndex */ |
| 127996 | + fts3tokDisconnectMethod, /* xDisconnect */ |
| 127997 | + fts3tokDisconnectMethod, /* xDestroy */ |
| 127998 | + fts3tokOpenMethod, /* xOpen */ |
| 127999 | + fts3tokCloseMethod, /* xClose */ |
| 128000 | + fts3tokFilterMethod, /* xFilter */ |
| 128001 | + fts3tokNextMethod, /* xNext */ |
| 128002 | + fts3tokEofMethod, /* xEof */ |
| 128003 | + fts3tokColumnMethod, /* xColumn */ |
| 128004 | + fts3tokRowidMethod, /* xRowid */ |
| 128005 | + 0, /* xUpdate */ |
| 128006 | + 0, /* xBegin */ |
| 128007 | + 0, /* xSync */ |
| 128008 | + 0, /* xCommit */ |
| 128009 | + 0, /* xRollback */ |
| 128010 | + 0, /* xFindFunction */ |
| 128011 | + 0, /* xRename */ |
| 128012 | + 0, /* xSavepoint */ |
| 128013 | + 0, /* xRelease */ |
| 128014 | + 0 /* xRollbackTo */ |
| 128015 | + }; |
| 128016 | + int rc; /* Return code */ |
| 128017 | + |
| 128018 | + rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, 0); |
| 128019 | + return rc; |
| 128020 | +} |
| 128021 | + |
| 128022 | +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 128023 | + |
| 128024 | +/************** End of fts3_tokenize_vtab.c **********************************/ |
| 126290 | 128025 | /************** Begin file fts3_write.c **************************************/ |
| 126291 | 128026 | /* |
| 126292 | 128027 | ** 2009 Oct 23 |
| 126293 | 128028 | ** |
| 126294 | 128029 | ** The author disclaims copyright to this source code. In place of |
| 126295 | 128030 | |