| | @@ -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.12. By combining all the individual C code files into this |
| 3 | +** version 3.7.13. 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. |
| | @@ -441,18 +441,25 @@ |
| 441 | 441 | #if defined(SQLITE_TCL) || defined(TCLSH) |
| 442 | 442 | # include <tcl.h> |
| 443 | 443 | #endif |
| 444 | 444 | |
| 445 | 445 | /* |
| 446 | | -** Many people are failing to set -DNDEBUG=1 when compiling SQLite. |
| 447 | | -** Setting NDEBUG makes the code smaller and run faster. So the following |
| 448 | | -** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 |
| 449 | | -** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out |
| 446 | +** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that |
| 447 | +** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, |
| 448 | +** make it true by defining or undefining NDEBUG. |
| 449 | +** |
| 450 | +** Setting NDEBUG makes the code smaller and run faster by disabling the |
| 451 | +** number assert() statements in the code. So we want the default action |
| 452 | +** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG |
| 453 | +** is set. Thus NDEBUG becomes an opt-in rather than an opt-out |
| 450 | 454 | ** feature. |
| 451 | 455 | */ |
| 452 | 456 | #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 453 | 457 | # define NDEBUG 1 |
| 458 | +#endif |
| 459 | +#if defined(NDEBUG) && defined(SQLITE_DEBUG) |
| 460 | +# undef NDEBUG |
| 454 | 461 | #endif |
| 455 | 462 | |
| 456 | 463 | /* |
| 457 | 464 | ** The testcase() macro is used to aid in coverage testing. When |
| 458 | 465 | ** doing coverage testing, the condition inside the argument to |
| | @@ -655,13 +662,13 @@ |
| 655 | 662 | ** |
| 656 | 663 | ** See also: [sqlite3_libversion()], |
| 657 | 664 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 658 | 665 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 659 | 666 | */ |
| 660 | | -#define SQLITE_VERSION "3.7.12" |
| 661 | | -#define SQLITE_VERSION_NUMBER 3007012 |
| 662 | | -#define SQLITE_SOURCE_ID "2012-05-12 18:29:53 e536ac041815b118c461ceee798f9b7283269f58" |
| 667 | +#define SQLITE_VERSION "3.7.13" |
| 668 | +#define SQLITE_VERSION_NUMBER 3007013 |
| 669 | +#define SQLITE_SOURCE_ID "2012-06-07 07:24:04 506008f000ba4af0b35da023b8c52f7a3f5033bd" |
| 663 | 670 | |
| 664 | 671 | /* |
| 665 | 672 | ** CAPI3REF: Run-Time Library Version Numbers |
| 666 | 673 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 667 | 674 | ** |
| | @@ -1026,10 +1033,11 @@ |
| 1026 | 1033 | #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ |
| 1027 | 1034 | #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ |
| 1028 | 1035 | #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ |
| 1029 | 1036 | #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ |
| 1030 | 1037 | #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ |
| 1038 | +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ |
| 1031 | 1039 | #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ |
| 1032 | 1040 | #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ |
| 1033 | 1041 | #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ |
| 1034 | 1042 | #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ |
| 1035 | 1043 | #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ |
| | @@ -1320,11 +1328,11 @@ |
| 1320 | 1328 | ** into the array entry, allowing the current retry settings to be |
| 1321 | 1329 | ** interrogated. The zDbName parameter is ignored. |
| 1322 | 1330 | ** |
| 1323 | 1331 | ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] |
| 1324 | 1332 | ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the |
| 1325 | | -** persistent [WAL | Write AHead Log] setting. By default, the auxiliary |
| 1333 | +** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary |
| 1326 | 1334 | ** write ahead log and shared memory files used for transaction control |
| 1327 | 1335 | ** are automatically deleted when the latest connection to the database |
| 1328 | 1336 | ** closes. Setting persistent WAL mode causes those files to persist after |
| 1329 | 1337 | ** close. Persisting the files is useful when other processes that do not |
| 1330 | 1338 | ** have write permission on the directory containing the database file want |
| | @@ -2717,16 +2725,16 @@ |
| 2717 | 2725 | ** In SQLite version 3.5.0 and 3.5.1, it was possible to define |
| 2718 | 2726 | ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in |
| 2719 | 2727 | ** implementation of these routines to be omitted. That capability |
| 2720 | 2728 | ** is no longer provided. Only built-in memory allocators can be used. |
| 2721 | 2729 | ** |
| 2722 | | -** The Windows OS interface layer calls |
| 2730 | +** Prior to SQLite version 3.7.10, the Windows OS interface layer called |
| 2723 | 2731 | ** the system malloc() and free() directly when converting |
| 2724 | 2732 | ** filenames between the UTF-8 encoding used by SQLite |
| 2725 | 2733 | ** and whatever filename encoding is used by the particular Windows |
| 2726 | | -** installation. Memory allocation errors are detected, but |
| 2727 | | -** they are reported back as [SQLITE_CANTOPEN] or |
| 2734 | +** installation. Memory allocation errors were detected, but |
| 2735 | +** they were reported back as [SQLITE_CANTOPEN] or |
| 2728 | 2736 | ** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. |
| 2729 | 2737 | ** |
| 2730 | 2738 | ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] |
| 2731 | 2739 | ** must be either NULL or else pointers obtained from a prior |
| 2732 | 2740 | ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have |
| | @@ -3123,22 +3131,24 @@ |
| 3123 | 3131 | ** an empty string the default VFS object is used. ^Specifying an unknown |
| 3124 | 3132 | ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is |
| 3125 | 3133 | ** present, then the VFS specified by the option takes precedence over |
| 3126 | 3134 | ** the value passed as the fourth parameter to sqlite3_open_v2(). |
| 3127 | 3135 | ** |
| 3128 | | -** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or |
| 3129 | | -** "rwc". Attempting to set it to any other value is an error)^. |
| 3136 | +** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", |
| 3137 | +** "rwc", or "memory". Attempting to set it to any other value is |
| 3138 | +** an error)^. |
| 3130 | 3139 | ** ^If "ro" is specified, then the database is opened for read-only |
| 3131 | 3140 | ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the |
| 3132 | 3141 | ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to |
| 3133 | 3142 | ** "rw", then the database is opened for read-write (but not create) |
| 3134 | 3143 | ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had |
| 3135 | 3144 | ** been set. ^Value "rwc" is equivalent to setting both |
| 3136 | | -** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is |
| 3137 | | -** used, it is an error to specify a value for the mode parameter that is |
| 3138 | | -** less restrictive than that specified by the flags passed as the third |
| 3139 | | -** parameter. |
| 3145 | +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is |
| 3146 | +** set to "memory" then a pure [in-memory database] that never reads |
| 3147 | +** or writes from disk is used. ^It is an error to specify a value for |
| 3148 | +** the mode parameter that is less restrictive than that specified by |
| 3149 | +** the flags passed in the third parameter to sqlite3_open_v2(). |
| 3140 | 3150 | ** |
| 3141 | 3151 | ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or |
| 3142 | 3152 | ** "private". ^Setting it to "shared" is equivalent to setting the |
| 3143 | 3153 | ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to |
| 3144 | 3154 | ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is |
| | @@ -4997,10 +5007,46 @@ |
| 4997 | 5007 | ** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 4998 | 5008 | ** or else the use of the [temp_store_directory pragma] should be avoided. |
| 4999 | 5009 | */ |
| 5000 | 5010 | SQLITE_API char *sqlite3_temp_directory; |
| 5001 | 5011 | |
| 5012 | +/* |
| 5013 | +** CAPI3REF: Name Of The Folder Holding Database Files |
| 5014 | +** |
| 5015 | +** ^(If this global variable is made to point to a string which is |
| 5016 | +** the name of a folder (a.k.a. directory), then all database files |
| 5017 | +** specified with a relative pathname and created or accessed by |
| 5018 | +** SQLite when using a built-in [sqlite3_vfs | VFS] will be assumed |
| 5019 | +** to be relative to that directory.)^ ^If this variable is a NULL |
| 5020 | +** pointer, then SQLite assumes that all database files specified |
| 5021 | +** with a relative pathname are relative to the current directory |
| 5022 | +** for the process. |
| 5023 | +** |
| 5024 | +** Changing the value of this variable while a database connection is |
| 5025 | +** open can result in a corrupt database. |
| 5026 | +** |
| 5027 | +** It is not safe to read or modify this variable in more than one |
| 5028 | +** thread at a time. It is not safe to read or modify this variable |
| 5029 | +** if a [database connection] is being used at the same time in a separate |
| 5030 | +** thread. |
| 5031 | +** It is intended that this variable be set once |
| 5032 | +** as part of process initialization and before any SQLite interface |
| 5033 | +** routines have been called and that this variable remain unchanged |
| 5034 | +** thereafter. |
| 5035 | +** |
| 5036 | +** ^The [data_store_directory pragma] may modify this variable and cause |
| 5037 | +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, |
| 5038 | +** the [data_store_directory pragma] always assumes that any string |
| 5039 | +** that this variable points to is held in memory obtained from |
| 5040 | +** [sqlite3_malloc] and the pragma may attempt to free that memory |
| 5041 | +** using [sqlite3_free]. |
| 5042 | +** Hence, if this variable is modified directly, either it should be |
| 5043 | +** made NULL or made to point to memory obtained from [sqlite3_malloc] |
| 5044 | +** or else the use of the [data_store_directory pragma] should be avoided. |
| 5045 | +*/ |
| 5046 | +SQLITE_API char *sqlite3_data_directory; |
| 5047 | + |
| 5002 | 5048 | /* |
| 5003 | 5049 | ** CAPI3REF: Test For Auto-Commit Mode |
| 5004 | 5050 | ** KEYWORDS: {autocommit mode} |
| 5005 | 5051 | ** |
| 5006 | 5052 | ** ^The sqlite3_get_autocommit() interface returns non-zero or |
| | @@ -5175,11 +5221,10 @@ |
| 5175 | 5221 | void* |
| 5176 | 5222 | ); |
| 5177 | 5223 | |
| 5178 | 5224 | /* |
| 5179 | 5225 | ** CAPI3REF: Enable Or Disable Shared Pager Cache |
| 5180 | | -** KEYWORDS: {shared cache} |
| 5181 | 5226 | ** |
| 5182 | 5227 | ** ^(This routine enables or disables the sharing of the database cache |
| 5183 | 5228 | ** and schema data structures between [database connection | connections] |
| 5184 | 5229 | ** to the same database. Sharing is enabled if the argument is true |
| 5185 | 5230 | ** and disabled if the argument is false.)^ |
| | @@ -9014,11 +9059,11 @@ |
| 9014 | 9059 | |
| 9015 | 9060 | /* Functions used to query pager state and configuration. */ |
| 9016 | 9061 | SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); |
| 9017 | 9062 | SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); |
| 9018 | 9063 | SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); |
| 9019 | | -SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*); |
| 9064 | +SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int); |
| 9020 | 9065 | SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); |
| 9021 | 9066 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); |
| 9022 | 9067 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); |
| 9023 | 9068 | SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); |
| 9024 | 9069 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); |
| | @@ -9284,17 +9329,15 @@ |
| 9284 | 9329 | # ifndef SQLITE_OS_WIN |
| 9285 | 9330 | # define SQLITE_OS_WIN 0 |
| 9286 | 9331 | # endif |
| 9287 | 9332 | #endif |
| 9288 | 9333 | |
| 9289 | | -/* |
| 9290 | | -** Define the maximum size of a temporary filename |
| 9291 | | -*/ |
| 9292 | 9334 | #if SQLITE_OS_WIN |
| 9293 | 9335 | # include <windows.h> |
| 9294 | | -# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) |
| 9295 | | -#elif SQLITE_OS_OS2 |
| 9336 | +#endif |
| 9337 | + |
| 9338 | +#if SQLITE_OS_OS2 |
| 9296 | 9339 | # if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) |
| 9297 | 9340 | # include <os2safe.h> /* has to be included before os2.h for linking to work */ |
| 9298 | 9341 | # endif |
| 9299 | 9342 | # define INCL_DOSDATETIME |
| 9300 | 9343 | # define INCL_DOSFILEMGR |
| | @@ -9303,13 +9346,10 @@ |
| 9303 | 9346 | # define INCL_DOSPROCESS |
| 9304 | 9347 | # define INCL_DOSMODULEMGR |
| 9305 | 9348 | # define INCL_DOSSEMAPHORES |
| 9306 | 9349 | # include <os2.h> |
| 9307 | 9350 | # include <uconv.h> |
| 9308 | | -# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) |
| 9309 | | -#else |
| 9310 | | -# define SQLITE_TEMPNAME_SIZE 200 |
| 9311 | 9351 | #endif |
| 9312 | 9352 | |
| 9313 | 9353 | /* |
| 9314 | 9354 | ** Determine if we are dealing with Windows NT. |
| 9315 | 9355 | ** |
| | @@ -9339,10 +9379,26 @@ |
| 9339 | 9379 | # define SQLITE_OS_WINCE 1 |
| 9340 | 9380 | #else |
| 9341 | 9381 | # define SQLITE_OS_WINCE 0 |
| 9342 | 9382 | #endif |
| 9343 | 9383 | |
| 9384 | +/* |
| 9385 | +** Determine if we are dealing with WindowsRT (Metro) as this has a different and |
| 9386 | +** incompatible API from win32. |
| 9387 | +*/ |
| 9388 | +#if !defined(SQLITE_OS_WINRT) |
| 9389 | +# define SQLITE_OS_WINRT 0 |
| 9390 | +#endif |
| 9391 | + |
| 9392 | +/* |
| 9393 | +** When compiled for WinCE or WinRT, there is no concept of the current |
| 9394 | +** directory. |
| 9395 | + */ |
| 9396 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 9397 | +# define SQLITE_CURDIR 1 |
| 9398 | +#endif |
| 9399 | + |
| 9344 | 9400 | /* If the SET_FULLSYNC macro is not defined above, then make it |
| 9345 | 9401 | ** a no-op |
| 9346 | 9402 | */ |
| 9347 | 9403 | #ifndef SET_FULLSYNC |
| 9348 | 9404 | # define SET_FULLSYNC(x,y) |
| | @@ -10933,19 +10989,25 @@ |
| 10933 | 10989 | */ |
| 10934 | 10990 | struct NameContext { |
| 10935 | 10991 | Parse *pParse; /* The parser */ |
| 10936 | 10992 | SrcList *pSrcList; /* One or more tables used to resolve names */ |
| 10937 | 10993 | ExprList *pEList; /* Optional list of named expressions */ |
| 10994 | + AggInfo *pAggInfo; /* Information about aggregates at this level */ |
| 10995 | + NameContext *pNext; /* Next outer name context. NULL for outermost */ |
| 10938 | 10996 | int nRef; /* Number of names resolved by this context */ |
| 10939 | 10997 | int nErr; /* Number of errors encountered while resolving names */ |
| 10940 | | - u8 allowAgg; /* Aggregate functions allowed here */ |
| 10941 | | - u8 hasAgg; /* True if aggregates are seen */ |
| 10942 | | - u8 isCheck; /* True if resolving names in a CHECK constraint */ |
| 10943 | | - AggInfo *pAggInfo; /* Information about aggregates at this level */ |
| 10944 | | - NameContext *pNext; /* Next outer name context. NULL for outermost */ |
| 10998 | + u8 ncFlags; /* Zero or more NC_* flags defined below */ |
| 10945 | 10999 | }; |
| 10946 | 11000 | |
| 11001 | +/* |
| 11002 | +** Allowed values for the NameContext, ncFlags field. |
| 11003 | +*/ |
| 11004 | +#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */ |
| 11005 | +#define NC_HasAgg 0x02 /* One or more aggregate functions seen */ |
| 11006 | +#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */ |
| 11007 | +#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */ |
| 11008 | + |
| 10947 | 11009 | /* |
| 10948 | 11010 | ** An instance of the following structure contains all information |
| 10949 | 11011 | ** needed to generate code for a single SELECT statement. |
| 10950 | 11012 | ** |
| 10951 | 11013 | ** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0. |
| | @@ -11623,11 +11685,13 @@ |
| 11623 | 11685 | SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); |
| 11624 | 11686 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); |
| 11625 | 11687 | SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); |
| 11626 | 11688 | SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); |
| 11627 | 11689 | SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); |
| 11628 | | -SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3*, int); |
| 11690 | +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); |
| 11691 | +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); |
| 11692 | +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); |
| 11629 | 11693 | SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int); |
| 11630 | 11694 | SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); |
| 11631 | 11695 | SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*); |
| 11632 | 11696 | SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); |
| 11633 | 11697 | SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); |
| | @@ -12028,10 +12092,11 @@ |
| 12028 | 12092 | # define sqlite3VtabUnlockList(X) |
| 12029 | 12093 | # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK |
| 12030 | 12094 | # define sqlite3GetVTable(X,Y) ((VTable*)0) |
| 12031 | 12095 | #else |
| 12032 | 12096 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); |
| 12097 | +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); |
| 12033 | 12098 | SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); |
| 12034 | 12099 | SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); |
| 12035 | 12100 | SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); |
| 12036 | 12101 | SQLITE_PRIVATE void sqlite3VtabLock(VTable *); |
| 12037 | 12102 | SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); |
| | @@ -12481,10 +12546,13 @@ |
| 12481 | 12546 | #ifdef SQLITE_CHECK_PAGES |
| 12482 | 12547 | "CHECK_PAGES", |
| 12483 | 12548 | #endif |
| 12484 | 12549 | #ifdef SQLITE_COVERAGE_TEST |
| 12485 | 12550 | "COVERAGE_TEST", |
| 12551 | +#endif |
| 12552 | +#ifdef SQLITE_CURDIR |
| 12553 | + "CURDIR", |
| 12486 | 12554 | #endif |
| 12487 | 12555 | #ifdef SQLITE_DEBUG |
| 12488 | 12556 | "DEBUG", |
| 12489 | 12557 | #endif |
| 12490 | 12558 | #ifdef SQLITE_DEFAULT_LOCKING_MODE |
| | @@ -18335,11 +18403,11 @@ |
| 18335 | 18403 | ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only |
| 18336 | 18404 | ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef |
| 18337 | 18405 | ** this out as well. |
| 18338 | 18406 | */ |
| 18339 | 18407 | #if 0 |
| 18340 | | -#if SQLITE_OS_WINCE |
| 18408 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 18341 | 18409 | # define mutexIsNT() (1) |
| 18342 | 18410 | #else |
| 18343 | 18411 | static int mutexIsNT(void){ |
| 18344 | 18412 | static int osType = 0; |
| 18345 | 18413 | if( osType==0 ){ |
| | @@ -18388,22 +18456,28 @@ |
| 18388 | 18456 | ** processing, the "interlocked" magic is probably not |
| 18389 | 18457 | ** strictly necessary. |
| 18390 | 18458 | */ |
| 18391 | 18459 | static long winMutex_lock = 0; |
| 18392 | 18460 | |
| 18461 | +SQLITE_API extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18462 | + |
| 18393 | 18463 | static int winMutexInit(void){ |
| 18394 | 18464 | /* The first to increment to 1 does actual initialization */ |
| 18395 | 18465 | if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |
| 18396 | 18466 | int i; |
| 18397 | 18467 | for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |
| 18468 | +#if SQLITE_OS_WINRT |
| 18469 | + InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0); |
| 18470 | +#else |
| 18398 | 18471 | InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |
| 18472 | +#endif |
| 18399 | 18473 | } |
| 18400 | 18474 | winMutex_isInit = 1; |
| 18401 | 18475 | }else{ |
| 18402 | 18476 | /* Someone else is in the process of initing the static mutexes */ |
| 18403 | 18477 | while( !winMutex_isInit ){ |
| 18404 | | - Sleep(1); |
| 18478 | + sqlite3_win32_sleep(1); |
| 18405 | 18479 | } |
| 18406 | 18480 | } |
| 18407 | 18481 | return SQLITE_OK; |
| 18408 | 18482 | } |
| 18409 | 18483 | |
| | @@ -18473,11 +18547,15 @@ |
| 18473 | 18547 | p = sqlite3MallocZero( sizeof(*p) ); |
| 18474 | 18548 | if( p ){ |
| 18475 | 18549 | #ifdef SQLITE_DEBUG |
| 18476 | 18550 | p->id = iType; |
| 18477 | 18551 | #endif |
| 18552 | +#if SQLITE_OS_WINRT |
| 18553 | + InitializeCriticalSectionEx(&p->mutex, 0, 0); |
| 18554 | +#else |
| 18478 | 18555 | InitializeCriticalSection(&p->mutex); |
| 18556 | +#endif |
| 18479 | 18557 | } |
| 18480 | 18558 | break; |
| 18481 | 18559 | } |
| 18482 | 18560 | default: { |
| 18483 | 18561 | assert( winMutex_isInit==1 ); |
| | @@ -19104,10 +19182,14 @@ |
| 19104 | 19182 | *db->pnBytesFreed += sqlite3DbMallocSize(db, p); |
| 19105 | 19183 | return; |
| 19106 | 19184 | } |
| 19107 | 19185 | if( isLookaside(db, p) ){ |
| 19108 | 19186 | LookasideSlot *pBuf = (LookasideSlot*)p; |
| 19187 | +#if SQLITE_DEBUG |
| 19188 | + /* Trash all content in the buffer being freed */ |
| 19189 | + memset(p, 0xaa, db->lookaside.sz); |
| 19190 | +#endif |
| 19109 | 19191 | pBuf->pNext = db->lookaside.pFree; |
| 19110 | 19192 | db->lookaside.pFree = pBuf; |
| 19111 | 19193 | db->lookaside.nOut--; |
| 19112 | 19194 | return; |
| 19113 | 19195 | } |
| | @@ -25062,11 +25144,11 @@ |
| 25062 | 25144 | unsigned fsFlags; /* cached details from statfs() */ |
| 25063 | 25145 | #endif |
| 25064 | 25146 | #if OS_VXWORKS |
| 25065 | 25147 | struct vxworksFileId *pId; /* Unique file ID */ |
| 25066 | 25148 | #endif |
| 25067 | | -#ifndef NDEBUG |
| 25149 | +#ifdef SQLITE_DEBUG |
| 25068 | 25150 | /* The next group of variables are used to track whether or not the |
| 25069 | 25151 | ** transaction counter in bytes 24-27 of database files are updated |
| 25070 | 25152 | ** whenever any part of the database changes. An assertion fault will |
| 25071 | 25153 | ** occur if a file is updated without also updating the transaction |
| 25072 | 25154 | ** counter. This test is made to avoid new problems similar to the |
| | @@ -25097,11 +25179,10 @@ |
| 25097 | 25179 | #endif |
| 25098 | 25180 | #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ |
| 25099 | 25181 | #define UNIXFILE_DELETE 0x20 /* Delete on close */ |
| 25100 | 25182 | #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ |
| 25101 | 25183 | #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ |
| 25102 | | -#define UNIXFILE_CHOWN 0x100 /* File ownership was changed */ |
| 25103 | 25184 | |
| 25104 | 25185 | /* |
| 25105 | 25186 | ** Include code that is common to all os_*.c files |
| 25106 | 25187 | */ |
| 25107 | 25188 | /************** Include os_common.h in the middle of os_unix.c ***************/ |
| | @@ -25350,10 +25431,19 @@ |
| 25350 | 25431 | ** which always has the same well-defined interface. |
| 25351 | 25432 | */ |
| 25352 | 25433 | static int posixOpen(const char *zFile, int flags, int mode){ |
| 25353 | 25434 | return open(zFile, flags, mode); |
| 25354 | 25435 | } |
| 25436 | + |
| 25437 | +/* |
| 25438 | +** On some systems, calls to fchown() will trigger a message in a security |
| 25439 | +** log if they come from non-root processes. So avoid calling fchown() if |
| 25440 | +** we are not running as root. |
| 25441 | +*/ |
| 25442 | +static int posixFchown(int fd, uid_t uid, gid_t gid){ |
| 25443 | + return geteuid() ? 0 : fchown(fd,uid,gid); |
| 25444 | +} |
| 25355 | 25445 | |
| 25356 | 25446 | /* Forward reference */ |
| 25357 | 25447 | static int openDirectory(const char*, int*); |
| 25358 | 25448 | |
| 25359 | 25449 | /* |
| | @@ -25462,11 +25552,11 @@ |
| 25462 | 25552 | #define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) |
| 25463 | 25553 | |
| 25464 | 25554 | { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, |
| 25465 | 25555 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 25466 | 25556 | |
| 25467 | | - { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, |
| 25557 | + { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 25468 | 25558 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 25469 | 25559 | |
| 25470 | 25560 | { "umask", (sqlite3_syscall_ptr)umask, 0 }, |
| 25471 | 25561 | #define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent) |
| 25472 | 25562 | |
| | @@ -26606,11 +26696,11 @@ |
| 26606 | 26696 | } |
| 26607 | 26697 | } |
| 26608 | 26698 | } |
| 26609 | 26699 | |
| 26610 | 26700 | |
| 26611 | | -#ifndef NDEBUG |
| 26701 | +#ifdef SQLITE_DEBUG |
| 26612 | 26702 | /* Set up the transaction-counter change checking flags when |
| 26613 | 26703 | ** transitioning from a SHARED to a RESERVED lock. The change |
| 26614 | 26704 | ** from SHARED to RESERVED marks the beginning of a normal |
| 26615 | 26705 | ** write operation (not a hot journal rollback). |
| 26616 | 26706 | */ |
| | @@ -26685,11 +26775,11 @@ |
| 26685 | 26775 | pInode = pFile->pInode; |
| 26686 | 26776 | assert( pInode->nShared!=0 ); |
| 26687 | 26777 | if( pFile->eFileLock>SHARED_LOCK ){ |
| 26688 | 26778 | assert( pInode->eFileLock==pFile->eFileLock ); |
| 26689 | 26779 | |
| 26690 | | -#ifndef NDEBUG |
| 26780 | +#ifdef SQLITE_DEBUG |
| 26691 | 26781 | /* When reducing a lock such that other processes can start |
| 26692 | 26782 | ** reading the database file again, make sure that the |
| 26693 | 26783 | ** transaction counter was updated if any part of the database |
| 26694 | 26784 | ** file changed. If the transaction counter is not updated, |
| 26695 | 26785 | ** other connections to the same file might not realize that |
| | @@ -27884,11 +27974,11 @@ |
| 27884 | 27974 | assert( pInode->eFileLock==pFile->eFileLock ); |
| 27885 | 27975 | SimulateIOErrorBenign(1); |
| 27886 | 27976 | SimulateIOError( h=(-1) ) |
| 27887 | 27977 | SimulateIOErrorBenign(0); |
| 27888 | 27978 | |
| 27889 | | -#ifndef NDEBUG |
| 27979 | +#ifdef SQLITE_DEBUG |
| 27890 | 27980 | /* When reducing a lock such that other processes can start |
| 27891 | 27981 | ** reading the database file again, make sure that the |
| 27892 | 27982 | ** transaction counter was updated if any part of the database |
| 27893 | 27983 | ** file changed. If the transaction counter is not updated, |
| 27894 | 27984 | ** other connections to the same file might not realize that |
| | @@ -28188,11 +28278,11 @@ |
| 28188 | 28278 | || offset>=PENDING_BYTE+512 |
| 28189 | 28279 | || offset+amt<=PENDING_BYTE |
| 28190 | 28280 | ); |
| 28191 | 28281 | #endif |
| 28192 | 28282 | |
| 28193 | | -#ifndef NDEBUG |
| 28283 | +#ifdef SQLITE_DEBUG |
| 28194 | 28284 | /* If we are doing a normal write to a database file (as opposed to |
| 28195 | 28285 | ** doing a hot-journal rollback or a write to some file other than a |
| 28196 | 28286 | ** normal database file) then record the fact that the database |
| 28197 | 28287 | ** has changed. If the transaction counter is modified, record that |
| 28198 | 28288 | ** fact too. |
| | @@ -28479,11 +28569,11 @@ |
| 28479 | 28569 | rc = robust_ftruncate(pFile->h, (off_t)nByte); |
| 28480 | 28570 | if( rc ){ |
| 28481 | 28571 | pFile->lastErrno = errno; |
| 28482 | 28572 | return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); |
| 28483 | 28573 | }else{ |
| 28484 | | -#ifndef NDEBUG |
| 28574 | +#ifdef SQLITE_DEBUG |
| 28485 | 28575 | /* If we are doing a normal write to a database file (as opposed to |
| 28486 | 28576 | ** doing a hot-journal rollback or a write to some file other than a |
| 28487 | 28577 | ** normal database file) and we truncate the file to zero length, |
| 28488 | 28578 | ** that effectively updates the change counter. This might happen |
| 28489 | 28579 | ** when restoring a database using the backup API from a zero-length |
| | @@ -28636,11 +28726,11 @@ |
| 28636 | 28726 | } |
| 28637 | 28727 | case SQLITE_FCNTL_VFSNAME: { |
| 28638 | 28728 | *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); |
| 28639 | 28729 | return SQLITE_OK; |
| 28640 | 28730 | } |
| 28641 | | -#ifndef NDEBUG |
| 28731 | +#ifdef SQLITE_DEBUG |
| 28642 | 28732 | /* The pager calls this method to signal that it has done |
| 28643 | 28733 | ** a rollback and that the database is therefore unchanged and |
| 28644 | 28734 | ** it hence it is OK for the transaction change counter to be |
| 28645 | 28735 | ** unchanged. |
| 28646 | 28736 | */ |
| | @@ -28987,18 +29077,13 @@ |
| 28987 | 29077 | goto shm_open_err; |
| 28988 | 29078 | } |
| 28989 | 29079 | |
| 28990 | 29080 | /* If this process is running as root, make sure that the SHM file |
| 28991 | 29081 | ** is owned by the same user that owns the original database. Otherwise, |
| 28992 | | - ** the original owner will not be able to connect. If this process is |
| 28993 | | - ** not root, the following fchown() will fail, but we don't care. The |
| 28994 | | - ** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler |
| 28995 | | - ** warnings. |
| 29082 | + ** the original owner will not be able to connect. |
| 28996 | 29083 | */ |
| 28997 | | - if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){ |
| 28998 | | - pDbFd->ctrlFlags |= UNIXFILE_CHOWN; |
| 28999 | | - } |
| 29084 | + osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); |
| 29000 | 29085 | |
| 29001 | 29086 | /* Check to see if another process is holding the dead-man switch. |
| 29002 | 29087 | ** If not, truncate the file to zero length. |
| 29003 | 29088 | */ |
| 29004 | 29089 | rc = SQLITE_OK; |
| | @@ -30200,17 +30285,14 @@ |
| 30200 | 30285 | goto open_finished; |
| 30201 | 30286 | } |
| 30202 | 30287 | |
| 30203 | 30288 | /* If this process is running as root and if creating a new rollback |
| 30204 | 30289 | ** journal or WAL file, set the ownership of the journal or WAL to be |
| 30205 | | - ** the same as the original database. If we are not running as root, |
| 30206 | | - ** then the fchown() call will fail, but that's ok. The "if(){}" and |
| 30207 | | - ** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler |
| 30208 | | - ** warnings from gcc. |
| 30290 | + ** the same as the original database. |
| 30209 | 30291 | */ |
| 30210 | 30292 | if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ |
| 30211 | | - if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; } |
| 30293 | + osFchown(fd, uid, gid); |
| 30212 | 30294 | } |
| 30213 | 30295 | } |
| 30214 | 30296 | assert( fd>=0 ); |
| 30215 | 30297 | if( pOutFlags ){ |
| 30216 | 30298 | *pOutFlags = flags; |
| | @@ -32167,16 +32249,31 @@ |
| 32167 | 32249 | #endif /* !defined(_OS_COMMON_H_) */ |
| 32168 | 32250 | |
| 32169 | 32251 | /************** End of os_common.h *******************************************/ |
| 32170 | 32252 | /************** Continuing where we left off in os_win.c *********************/ |
| 32171 | 32253 | |
| 32254 | +/* |
| 32255 | +** Macro to find the minimum of two numeric values. |
| 32256 | +*/ |
| 32257 | +#ifndef MIN |
| 32258 | +# define MIN(x,y) ((x)<(y)?(x):(y)) |
| 32259 | +#endif |
| 32260 | + |
| 32172 | 32261 | /* |
| 32173 | 32262 | ** Some Microsoft compilers lack this definition. |
| 32174 | 32263 | */ |
| 32175 | 32264 | #ifndef INVALID_FILE_ATTRIBUTES |
| 32176 | 32265 | # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) |
| 32177 | 32266 | #endif |
| 32267 | + |
| 32268 | +#ifndef FILE_FLAG_MASK |
| 32269 | +# define FILE_FLAG_MASK (0xFF3C0000) |
| 32270 | +#endif |
| 32271 | + |
| 32272 | +#ifndef FILE_ATTRIBUTE_MASK |
| 32273 | +# define FILE_ATTRIBUTE_MASK (0x0003FFF7) |
| 32274 | +#endif |
| 32178 | 32275 | |
| 32179 | 32276 | /* Forward references */ |
| 32180 | 32277 | typedef struct winShm winShm; /* A connection to shared-memory */ |
| 32181 | 32278 | typedef struct winShmNode winShmNode; /* A region of shared-memory */ |
| 32182 | 32279 | |
| | @@ -32222,15 +32319,41 @@ |
| 32222 | 32319 | ** Allowed values for winFile.ctrlFlags |
| 32223 | 32320 | */ |
| 32224 | 32321 | #define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ |
| 32225 | 32322 | #define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ |
| 32226 | 32323 | |
| 32324 | +/* |
| 32325 | + * The size of the buffer used by sqlite3_win32_write_debug(). |
| 32326 | + */ |
| 32327 | +#ifndef SQLITE_WIN32_DBG_BUF_SIZE |
| 32328 | +# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) |
| 32329 | +#endif |
| 32330 | + |
| 32227 | 32331 | /* |
| 32228 | 32332 | * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the |
| 32229 | 32333 | * various Win32 API heap functions instead of our own. |
| 32230 | 32334 | */ |
| 32231 | 32335 | #ifdef SQLITE_WIN32_MALLOC |
| 32336 | + |
| 32337 | +/* |
| 32338 | + * If this is non-zero, an isolated heap will be created by the native Win32 |
| 32339 | + * allocator subsystem; otherwise, the default process heap will be used. This |
| 32340 | + * setting has no effect when compiling for WinRT. By default, this is enabled |
| 32341 | + * and an isolated heap will be created to store all allocated data. |
| 32342 | + * |
| 32343 | + ****************************************************************************** |
| 32344 | + * WARNING: It is important to note that when this setting is non-zero and the |
| 32345 | + * winMemShutdown function is called (e.g. by the sqlite3_shutdown |
| 32346 | + * function), all data that was allocated using the isolated heap will |
| 32347 | + * be freed immediately and any attempt to access any of that freed |
| 32348 | + * data will almost certainly result in an immediate access violation. |
| 32349 | + ****************************************************************************** |
| 32350 | + */ |
| 32351 | +#ifndef SQLITE_WIN32_HEAP_CREATE |
| 32352 | +# define SQLITE_WIN32_HEAP_CREATE (TRUE) |
| 32353 | +#endif |
| 32354 | + |
| 32232 | 32355 | /* |
| 32233 | 32356 | * The initial size of the Win32-specific heap. This value may be zero. |
| 32234 | 32357 | */ |
| 32235 | 32358 | #ifndef SQLITE_WIN32_HEAP_INIT_SIZE |
| 32236 | 32359 | # define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ |
| | @@ -32311,61 +32434,50 @@ |
| 32311 | 32434 | SQLITE_API int sqlite3_os_type = 0; |
| 32312 | 32435 | #else |
| 32313 | 32436 | static int sqlite3_os_type = 0; |
| 32314 | 32437 | #endif |
| 32315 | 32438 | |
| 32316 | | -/* |
| 32317 | | -** Many system calls are accessed through pointer-to-functions so that |
| 32318 | | -** they may be overridden at runtime to facilitate fault injection during |
| 32319 | | -** testing and sandboxing. The following array holds the names and pointers |
| 32320 | | -** to all overrideable system calls. |
| 32321 | | -*/ |
| 32322 | | -#if !SQLITE_OS_WINCE |
| 32439 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 32323 | 32440 | # define SQLITE_WIN32_HAS_ANSI |
| 32324 | 32441 | #endif |
| 32325 | 32442 | |
| 32326 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINNT |
| 32443 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 32327 | 32444 | # define SQLITE_WIN32_HAS_WIDE |
| 32328 | 32445 | #endif |
| 32329 | 32446 | |
| 32330 | 32447 | #ifndef SYSCALL |
| 32331 | 32448 | # define SYSCALL sqlite3_syscall_ptr |
| 32332 | 32449 | #endif |
| 32333 | 32450 | |
| 32334 | | -#if SQLITE_OS_WINCE |
| 32335 | | -/* |
| 32336 | | -** These macros are necessary because Windows CE does not natively support the |
| 32337 | | -** Win32 APIs LockFile, UnlockFile, and LockFileEx. |
| 32338 | | - */ |
| 32339 | | - |
| 32340 | | -# define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) |
| 32341 | | -# define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) |
| 32342 | | -# define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) |
| 32343 | | - |
| 32344 | | -/* |
| 32345 | | -** These are the special syscall hacks for Windows CE. The locking related |
| 32346 | | -** defines here refer to the macros defined just above. |
| 32347 | | - */ |
| 32348 | | - |
| 32349 | | -# define osAreFileApisANSI() 1 |
| 32350 | | -# define osLockFile LockFile |
| 32351 | | -# define osUnlockFile UnlockFile |
| 32352 | | -# define osLockFileEx LockFileEx |
| 32353 | | -#endif |
| 32354 | | - |
| 32451 | +/* |
| 32452 | +** This function is not available on Windows CE or WinRT. |
| 32453 | + */ |
| 32454 | + |
| 32455 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 32456 | +# define osAreFileApisANSI() 1 |
| 32457 | +#endif |
| 32458 | + |
| 32459 | +/* |
| 32460 | +** Many system calls are accessed through pointer-to-functions so that |
| 32461 | +** they may be overridden at runtime to facilitate fault injection during |
| 32462 | +** testing and sandboxing. The following array holds the names and pointers |
| 32463 | +** to all overrideable system calls. |
| 32464 | +*/ |
| 32355 | 32465 | static struct win_syscall { |
| 32356 | 32466 | const char *zName; /* Name of the sytem call */ |
| 32357 | 32467 | sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ |
| 32358 | 32468 | sqlite3_syscall_ptr pDefault; /* Default value */ |
| 32359 | 32469 | } aSyscall[] = { |
| 32360 | | -#if !SQLITE_OS_WINCE |
| 32470 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 32361 | 32471 | { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, |
| 32362 | | - |
| 32363 | | -#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) |
| 32364 | 32472 | #else |
| 32365 | 32473 | { "AreFileApisANSI", (SYSCALL)0, 0 }, |
| 32366 | 32474 | #endif |
| 32475 | + |
| 32476 | +#ifndef osAreFileApisANSI |
| 32477 | +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) |
| 32478 | +#endif |
| 32367 | 32479 | |
| 32368 | 32480 | #if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) |
| 32369 | 32481 | { "CharLowerW", (SYSCALL)CharLowerW, 0 }, |
| 32370 | 32482 | #else |
| 32371 | 32483 | { "CharLowerW", (SYSCALL)0, 0 }, |
| | @@ -32392,174 +32504,173 @@ |
| 32392 | 32504 | #endif |
| 32393 | 32505 | |
| 32394 | 32506 | #define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ |
| 32395 | 32507 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) |
| 32396 | 32508 | |
| 32397 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32509 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32398 | 32510 | { "CreateFileW", (SYSCALL)CreateFileW, 0 }, |
| 32399 | 32511 | #else |
| 32400 | 32512 | { "CreateFileW", (SYSCALL)0, 0 }, |
| 32401 | 32513 | #endif |
| 32402 | 32514 | |
| 32403 | 32515 | #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
| 32404 | 32516 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) |
| 32405 | 32517 | |
| 32406 | | - { "CreateFileMapping", (SYSCALL)CreateFileMapping, 0 }, |
| 32407 | | - |
| 32408 | | -#define osCreateFileMapping ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ |
| 32409 | | - DWORD,DWORD,DWORD,LPCTSTR))aSyscall[6].pCurrent) |
| 32410 | | - |
| 32411 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32518 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32412 | 32519 | { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, |
| 32413 | 32520 | #else |
| 32414 | 32521 | { "CreateFileMappingW", (SYSCALL)0, 0 }, |
| 32415 | 32522 | #endif |
| 32416 | 32523 | |
| 32417 | 32524 | #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ |
| 32418 | | - DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) |
| 32525 | + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent) |
| 32419 | 32526 | |
| 32420 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32527 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32421 | 32528 | { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, |
| 32422 | 32529 | #else |
| 32423 | 32530 | { "CreateMutexW", (SYSCALL)0, 0 }, |
| 32424 | 32531 | #endif |
| 32425 | 32532 | |
| 32426 | 32533 | #define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ |
| 32427 | | - LPCWSTR))aSyscall[8].pCurrent) |
| 32534 | + LPCWSTR))aSyscall[7].pCurrent) |
| 32428 | 32535 | |
| 32429 | 32536 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32430 | 32537 | { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, |
| 32431 | 32538 | #else |
| 32432 | 32539 | { "DeleteFileA", (SYSCALL)0, 0 }, |
| 32433 | 32540 | #endif |
| 32434 | 32541 | |
| 32435 | | -#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) |
| 32542 | +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent) |
| 32436 | 32543 | |
| 32437 | 32544 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 32438 | 32545 | { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, |
| 32439 | 32546 | #else |
| 32440 | 32547 | { "DeleteFileW", (SYSCALL)0, 0 }, |
| 32441 | 32548 | #endif |
| 32442 | 32549 | |
| 32443 | | -#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) |
| 32550 | +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent) |
| 32444 | 32551 | |
| 32445 | 32552 | #if SQLITE_OS_WINCE |
| 32446 | 32553 | { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, |
| 32447 | 32554 | #else |
| 32448 | 32555 | { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, |
| 32449 | 32556 | #endif |
| 32450 | 32557 | |
| 32451 | 32558 | #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ |
| 32452 | | - LPFILETIME))aSyscall[11].pCurrent) |
| 32559 | + LPFILETIME))aSyscall[10].pCurrent) |
| 32453 | 32560 | |
| 32454 | 32561 | #if SQLITE_OS_WINCE |
| 32455 | 32562 | { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, |
| 32456 | 32563 | #else |
| 32457 | 32564 | { "FileTimeToSystemTime", (SYSCALL)0, 0 }, |
| 32458 | 32565 | #endif |
| 32459 | 32566 | |
| 32460 | 32567 | #define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ |
| 32461 | | - LPSYSTEMTIME))aSyscall[12].pCurrent) |
| 32568 | + LPSYSTEMTIME))aSyscall[11].pCurrent) |
| 32462 | 32569 | |
| 32463 | 32570 | { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, |
| 32464 | 32571 | |
| 32465 | | -#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) |
| 32572 | +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent) |
| 32466 | 32573 | |
| 32467 | 32574 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32468 | 32575 | { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, |
| 32469 | 32576 | #else |
| 32470 | 32577 | { "FormatMessageA", (SYSCALL)0, 0 }, |
| 32471 | 32578 | #endif |
| 32472 | 32579 | |
| 32473 | 32580 | #define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ |
| 32474 | | - DWORD,va_list*))aSyscall[14].pCurrent) |
| 32581 | + DWORD,va_list*))aSyscall[13].pCurrent) |
| 32475 | 32582 | |
| 32476 | 32583 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 32477 | 32584 | { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, |
| 32478 | 32585 | #else |
| 32479 | 32586 | { "FormatMessageW", (SYSCALL)0, 0 }, |
| 32480 | 32587 | #endif |
| 32481 | 32588 | |
| 32482 | 32589 | #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ |
| 32483 | | - DWORD,va_list*))aSyscall[15].pCurrent) |
| 32590 | + DWORD,va_list*))aSyscall[14].pCurrent) |
| 32484 | 32591 | |
| 32485 | 32592 | { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, |
| 32486 | 32593 | |
| 32487 | | -#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) |
| 32594 | +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent) |
| 32488 | 32595 | |
| 32489 | 32596 | { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, |
| 32490 | 32597 | |
| 32491 | | -#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) |
| 32598 | +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent) |
| 32492 | 32599 | |
| 32493 | 32600 | #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) |
| 32494 | 32601 | { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, |
| 32495 | 32602 | #else |
| 32496 | 32603 | { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, |
| 32497 | 32604 | #endif |
| 32498 | 32605 | |
| 32499 | 32606 | #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ |
| 32500 | | - LPDWORD))aSyscall[18].pCurrent) |
| 32607 | + LPDWORD))aSyscall[17].pCurrent) |
| 32501 | 32608 | |
| 32502 | | -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) |
| 32609 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32503 | 32610 | { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, |
| 32504 | 32611 | #else |
| 32505 | 32612 | { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, |
| 32506 | 32613 | #endif |
| 32507 | 32614 | |
| 32508 | 32615 | #define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ |
| 32509 | | - LPDWORD))aSyscall[19].pCurrent) |
| 32616 | + LPDWORD))aSyscall[18].pCurrent) |
| 32510 | 32617 | |
| 32511 | 32618 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32512 | 32619 | { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, |
| 32513 | 32620 | #else |
| 32514 | 32621 | { "GetFileAttributesA", (SYSCALL)0, 0 }, |
| 32515 | 32622 | #endif |
| 32516 | 32623 | |
| 32517 | | -#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) |
| 32624 | +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent) |
| 32518 | 32625 | |
| 32519 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32626 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32520 | 32627 | { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, |
| 32521 | 32628 | #else |
| 32522 | 32629 | { "GetFileAttributesW", (SYSCALL)0, 0 }, |
| 32523 | 32630 | #endif |
| 32524 | 32631 | |
| 32525 | | -#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) |
| 32632 | +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent) |
| 32526 | 32633 | |
| 32527 | 32634 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 32528 | 32635 | { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, |
| 32529 | 32636 | #else |
| 32530 | 32637 | { "GetFileAttributesExW", (SYSCALL)0, 0 }, |
| 32531 | 32638 | #endif |
| 32532 | 32639 | |
| 32533 | 32640 | #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ |
| 32534 | | - LPVOID))aSyscall[22].pCurrent) |
| 32641 | + LPVOID))aSyscall[21].pCurrent) |
| 32535 | 32642 | |
| 32643 | +#if !SQLITE_OS_WINRT |
| 32536 | 32644 | { "GetFileSize", (SYSCALL)GetFileSize, 0 }, |
| 32645 | +#else |
| 32646 | + { "GetFileSize", (SYSCALL)0, 0 }, |
| 32647 | +#endif |
| 32537 | 32648 | |
| 32538 | | -#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) |
| 32649 | +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent) |
| 32539 | 32650 | |
| 32540 | 32651 | #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) |
| 32541 | 32652 | { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, |
| 32542 | 32653 | #else |
| 32543 | 32654 | { "GetFullPathNameA", (SYSCALL)0, 0 }, |
| 32544 | 32655 | #endif |
| 32545 | 32656 | |
| 32546 | 32657 | #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ |
| 32547 | | - LPSTR*))aSyscall[24].pCurrent) |
| 32658 | + LPSTR*))aSyscall[23].pCurrent) |
| 32548 | 32659 | |
| 32549 | | -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) |
| 32660 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32550 | 32661 | { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, |
| 32551 | 32662 | #else |
| 32552 | 32663 | { "GetFullPathNameW", (SYSCALL)0, 0 }, |
| 32553 | 32664 | #endif |
| 32554 | 32665 | |
| 32555 | 32666 | #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ |
| 32556 | | - LPWSTR*))aSyscall[25].pCurrent) |
| 32667 | + LPWSTR*))aSyscall[24].pCurrent) |
| 32557 | 32668 | |
| 32558 | 32669 | { "GetLastError", (SYSCALL)GetLastError, 0 }, |
| 32559 | 32670 | |
| 32560 | | -#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) |
| 32671 | +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent) |
| 32561 | 32672 | |
| 32562 | 32673 | #if SQLITE_OS_WINCE |
| 32563 | 32674 | /* The GetProcAddressA() routine is only available on Windows CE. */ |
| 32564 | 32675 | { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, |
| 32565 | 32676 | #else |
| | @@ -32567,198 +32678,358 @@ |
| 32567 | 32678 | ** an ANSI string regardless of the _UNICODE setting */ |
| 32568 | 32679 | { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, |
| 32569 | 32680 | #endif |
| 32570 | 32681 | |
| 32571 | 32682 | #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ |
| 32572 | | - LPCSTR))aSyscall[27].pCurrent) |
| 32683 | + LPCSTR))aSyscall[26].pCurrent) |
| 32573 | 32684 | |
| 32685 | +#if !SQLITE_OS_WINRT |
| 32574 | 32686 | { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, |
| 32687 | +#else |
| 32688 | + { "GetSystemInfo", (SYSCALL)0, 0 }, |
| 32689 | +#endif |
| 32575 | 32690 | |
| 32576 | | -#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) |
| 32691 | +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent) |
| 32577 | 32692 | |
| 32578 | 32693 | { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, |
| 32579 | 32694 | |
| 32580 | | -#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) |
| 32695 | +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent) |
| 32581 | 32696 | |
| 32582 | 32697 | #if !SQLITE_OS_WINCE |
| 32583 | 32698 | { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, |
| 32584 | 32699 | #else |
| 32585 | 32700 | { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, |
| 32586 | 32701 | #endif |
| 32587 | 32702 | |
| 32588 | 32703 | #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ |
| 32589 | | - LPFILETIME))aSyscall[30].pCurrent) |
| 32704 | + LPFILETIME))aSyscall[29].pCurrent) |
| 32590 | 32705 | |
| 32591 | 32706 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32592 | 32707 | { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, |
| 32593 | 32708 | #else |
| 32594 | 32709 | { "GetTempPathA", (SYSCALL)0, 0 }, |
| 32595 | 32710 | #endif |
| 32596 | 32711 | |
| 32597 | | -#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) |
| 32712 | +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent) |
| 32598 | 32713 | |
| 32599 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32714 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32600 | 32715 | { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, |
| 32601 | 32716 | #else |
| 32602 | 32717 | { "GetTempPathW", (SYSCALL)0, 0 }, |
| 32603 | 32718 | #endif |
| 32604 | 32719 | |
| 32605 | | -#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) |
| 32720 | +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent) |
| 32606 | 32721 | |
| 32722 | +#if !SQLITE_OS_WINRT |
| 32607 | 32723 | { "GetTickCount", (SYSCALL)GetTickCount, 0 }, |
| 32724 | +#else |
| 32725 | + { "GetTickCount", (SYSCALL)0, 0 }, |
| 32726 | +#endif |
| 32608 | 32727 | |
| 32609 | | -#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) |
| 32728 | +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent) |
| 32610 | 32729 | |
| 32611 | 32730 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32612 | 32731 | { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, |
| 32613 | 32732 | #else |
| 32614 | 32733 | { "GetVersionExA", (SYSCALL)0, 0 }, |
| 32615 | 32734 | #endif |
| 32616 | 32735 | |
| 32617 | 32736 | #define osGetVersionExA ((BOOL(WINAPI*)( \ |
| 32618 | | - LPOSVERSIONINFOA))aSyscall[34].pCurrent) |
| 32737 | + LPOSVERSIONINFOA))aSyscall[33].pCurrent) |
| 32619 | 32738 | |
| 32620 | 32739 | { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, |
| 32621 | 32740 | |
| 32622 | 32741 | #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ |
| 32623 | | - SIZE_T))aSyscall[35].pCurrent) |
| 32742 | + SIZE_T))aSyscall[34].pCurrent) |
| 32624 | 32743 | |
| 32744 | +#if !SQLITE_OS_WINRT |
| 32625 | 32745 | { "HeapCreate", (SYSCALL)HeapCreate, 0 }, |
| 32746 | +#else |
| 32747 | + { "HeapCreate", (SYSCALL)0, 0 }, |
| 32748 | +#endif |
| 32626 | 32749 | |
| 32627 | 32750 | #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ |
| 32628 | | - SIZE_T))aSyscall[36].pCurrent) |
| 32751 | + SIZE_T))aSyscall[35].pCurrent) |
| 32629 | 32752 | |
| 32753 | +#if !SQLITE_OS_WINRT |
| 32630 | 32754 | { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, |
| 32755 | +#else |
| 32756 | + { "HeapDestroy", (SYSCALL)0, 0 }, |
| 32757 | +#endif |
| 32631 | 32758 | |
| 32632 | | -#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) |
| 32759 | +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent) |
| 32633 | 32760 | |
| 32634 | 32761 | { "HeapFree", (SYSCALL)HeapFree, 0 }, |
| 32635 | 32762 | |
| 32636 | | -#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) |
| 32763 | +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent) |
| 32637 | 32764 | |
| 32638 | 32765 | { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, |
| 32639 | 32766 | |
| 32640 | 32767 | #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ |
| 32641 | | - SIZE_T))aSyscall[39].pCurrent) |
| 32768 | + SIZE_T))aSyscall[38].pCurrent) |
| 32642 | 32769 | |
| 32643 | 32770 | { "HeapSize", (SYSCALL)HeapSize, 0 }, |
| 32644 | 32771 | |
| 32645 | 32772 | #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ |
| 32646 | | - LPCVOID))aSyscall[40].pCurrent) |
| 32773 | + LPCVOID))aSyscall[39].pCurrent) |
| 32647 | 32774 | |
| 32775 | +#if !SQLITE_OS_WINRT |
| 32648 | 32776 | { "HeapValidate", (SYSCALL)HeapValidate, 0 }, |
| 32777 | +#else |
| 32778 | + { "HeapValidate", (SYSCALL)0, 0 }, |
| 32779 | +#endif |
| 32649 | 32780 | |
| 32650 | 32781 | #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ |
| 32651 | | - LPCVOID))aSyscall[41].pCurrent) |
| 32782 | + LPCVOID))aSyscall[40].pCurrent) |
| 32652 | 32783 | |
| 32653 | 32784 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 32654 | 32785 | { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, |
| 32655 | 32786 | #else |
| 32656 | 32787 | { "LoadLibraryA", (SYSCALL)0, 0 }, |
| 32657 | 32788 | #endif |
| 32658 | 32789 | |
| 32659 | | -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) |
| 32790 | +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent) |
| 32660 | 32791 | |
| 32661 | | -#if defined(SQLITE_WIN32_HAS_WIDE) |
| 32792 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 32662 | 32793 | { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, |
| 32663 | 32794 | #else |
| 32664 | 32795 | { "LoadLibraryW", (SYSCALL)0, 0 }, |
| 32665 | 32796 | #endif |
| 32666 | 32797 | |
| 32667 | | -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) |
| 32798 | +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent) |
| 32668 | 32799 | |
| 32800 | +#if !SQLITE_OS_WINRT |
| 32669 | 32801 | { "LocalFree", (SYSCALL)LocalFree, 0 }, |
| 32670 | | - |
| 32671 | | -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) |
| 32672 | | - |
| 32673 | | -#if !SQLITE_OS_WINCE |
| 32674 | | - { "LockFile", (SYSCALL)LockFile, 0 }, |
| 32675 | | - |
| 32676 | | -#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32677 | | - DWORD))aSyscall[45].pCurrent) |
| 32802 | +#else |
| 32803 | + { "LocalFree", (SYSCALL)0, 0 }, |
| 32804 | +#endif |
| 32805 | + |
| 32806 | +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent) |
| 32807 | + |
| 32808 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 32809 | + { "LockFile", (SYSCALL)LockFile, 0 }, |
| 32678 | 32810 | #else |
| 32679 | 32811 | { "LockFile", (SYSCALL)0, 0 }, |
| 32680 | 32812 | #endif |
| 32813 | + |
| 32814 | +#ifndef osLockFile |
| 32815 | +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32816 | + DWORD))aSyscall[44].pCurrent) |
| 32817 | +#endif |
| 32681 | 32818 | |
| 32682 | 32819 | #if !SQLITE_OS_WINCE |
| 32683 | 32820 | { "LockFileEx", (SYSCALL)LockFileEx, 0 }, |
| 32684 | | - |
| 32685 | | -#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 32686 | | - LPOVERLAPPED))aSyscall[46].pCurrent) |
| 32687 | 32821 | #else |
| 32688 | 32822 | { "LockFileEx", (SYSCALL)0, 0 }, |
| 32689 | 32823 | #endif |
| 32690 | 32824 | |
| 32825 | +#ifndef osLockFileEx |
| 32826 | +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 32827 | + LPOVERLAPPED))aSyscall[45].pCurrent) |
| 32828 | +#endif |
| 32829 | + |
| 32830 | +#if !SQLITE_OS_WINRT |
| 32691 | 32831 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 32832 | +#else |
| 32833 | + { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 32834 | +#endif |
| 32692 | 32835 | |
| 32693 | 32836 | #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32694 | | - SIZE_T))aSyscall[47].pCurrent) |
| 32837 | + SIZE_T))aSyscall[46].pCurrent) |
| 32695 | 32838 | |
| 32696 | 32839 | { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, |
| 32697 | 32840 | |
| 32698 | 32841 | #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ |
| 32699 | | - int))aSyscall[48].pCurrent) |
| 32842 | + int))aSyscall[47].pCurrent) |
| 32700 | 32843 | |
| 32701 | 32844 | { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, |
| 32702 | 32845 | |
| 32703 | 32846 | #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ |
| 32704 | | - LARGE_INTEGER*))aSyscall[49].pCurrent) |
| 32847 | + LARGE_INTEGER*))aSyscall[48].pCurrent) |
| 32705 | 32848 | |
| 32706 | 32849 | { "ReadFile", (SYSCALL)ReadFile, 0 }, |
| 32707 | 32850 | |
| 32708 | 32851 | #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ |
| 32709 | | - LPOVERLAPPED))aSyscall[50].pCurrent) |
| 32852 | + LPOVERLAPPED))aSyscall[49].pCurrent) |
| 32710 | 32853 | |
| 32711 | 32854 | { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, |
| 32712 | 32855 | |
| 32713 | | -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) |
| 32856 | +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent) |
| 32714 | 32857 | |
| 32858 | +#if !SQLITE_OS_WINRT |
| 32715 | 32859 | { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, |
| 32860 | +#else |
| 32861 | + { "SetFilePointer", (SYSCALL)0, 0 }, |
| 32862 | +#endif |
| 32716 | 32863 | |
| 32717 | 32864 | #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ |
| 32718 | | - DWORD))aSyscall[52].pCurrent) |
| 32865 | + DWORD))aSyscall[51].pCurrent) |
| 32719 | 32866 | |
| 32867 | +#if !SQLITE_OS_WINRT |
| 32720 | 32868 | { "Sleep", (SYSCALL)Sleep, 0 }, |
| 32869 | +#else |
| 32870 | + { "Sleep", (SYSCALL)0, 0 }, |
| 32871 | +#endif |
| 32721 | 32872 | |
| 32722 | | -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) |
| 32873 | +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent) |
| 32723 | 32874 | |
| 32724 | 32875 | { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, |
| 32725 | 32876 | |
| 32726 | 32877 | #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ |
| 32727 | | - LPFILETIME))aSyscall[54].pCurrent) |
| 32878 | + LPFILETIME))aSyscall[53].pCurrent) |
| 32728 | 32879 | |
| 32729 | | -#if !SQLITE_OS_WINCE |
| 32880 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 32730 | 32881 | { "UnlockFile", (SYSCALL)UnlockFile, 0 }, |
| 32731 | | - |
| 32732 | | -#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32733 | | - DWORD))aSyscall[55].pCurrent) |
| 32734 | 32882 | #else |
| 32735 | 32883 | { "UnlockFile", (SYSCALL)0, 0 }, |
| 32736 | 32884 | #endif |
| 32885 | + |
| 32886 | +#ifndef osUnlockFile |
| 32887 | +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32888 | + DWORD))aSyscall[54].pCurrent) |
| 32889 | +#endif |
| 32737 | 32890 | |
| 32738 | 32891 | #if !SQLITE_OS_WINCE |
| 32739 | 32892 | { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, |
| 32740 | | - |
| 32741 | | -#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32742 | | - LPOVERLAPPED))aSyscall[56].pCurrent) |
| 32743 | 32893 | #else |
| 32744 | 32894 | { "UnlockFileEx", (SYSCALL)0, 0 }, |
| 32745 | 32895 | #endif |
| 32896 | + |
| 32897 | +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 32898 | + LPOVERLAPPED))aSyscall[55].pCurrent) |
| 32746 | 32899 | |
| 32747 | 32900 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 32748 | 32901 | |
| 32749 | | -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) |
| 32902 | +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) |
| 32750 | 32903 | |
| 32751 | 32904 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 32752 | 32905 | |
| 32753 | 32906 | #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ |
| 32754 | | - LPCSTR,LPBOOL))aSyscall[58].pCurrent) |
| 32907 | + LPCSTR,LPBOOL))aSyscall[57].pCurrent) |
| 32755 | 32908 | |
| 32756 | 32909 | { "WriteFile", (SYSCALL)WriteFile, 0 }, |
| 32757 | 32910 | |
| 32758 | 32911 | #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ |
| 32759 | | - LPOVERLAPPED))aSyscall[59].pCurrent) |
| 32912 | + LPOVERLAPPED))aSyscall[58].pCurrent) |
| 32913 | + |
| 32914 | +#if SQLITE_OS_WINRT |
| 32915 | + { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, |
| 32916 | +#else |
| 32917 | + { "CreateEventExW", (SYSCALL)0, 0 }, |
| 32918 | +#endif |
| 32919 | + |
| 32920 | +#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ |
| 32921 | + DWORD,DWORD))aSyscall[59].pCurrent) |
| 32922 | + |
| 32923 | +#if !SQLITE_OS_WINRT |
| 32924 | + { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, |
| 32925 | +#else |
| 32926 | + { "WaitForSingleObject", (SYSCALL)0, 0 }, |
| 32927 | +#endif |
| 32928 | + |
| 32929 | +#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 32930 | + DWORD))aSyscall[60].pCurrent) |
| 32931 | + |
| 32932 | +#if !SQLITE_OS_WINCE |
| 32933 | + { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 32934 | +#else |
| 32935 | + { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 32936 | +#endif |
| 32937 | + |
| 32938 | +#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 32939 | + BOOL))aSyscall[61].pCurrent) |
| 32940 | + |
| 32941 | +#if !SQLITE_OS_WINCE |
| 32942 | + { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 32943 | +#else |
| 32944 | + { "SetFilePointerEx", (SYSCALL)0, 0 }, |
| 32945 | +#endif |
| 32946 | + |
| 32947 | +#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ |
| 32948 | + PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent) |
| 32949 | + |
| 32950 | +#if SQLITE_OS_WINRT |
| 32951 | + { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, |
| 32952 | +#else |
| 32953 | + { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, |
| 32954 | +#endif |
| 32955 | + |
| 32956 | +#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ |
| 32957 | + FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) |
| 32958 | + |
| 32959 | +#if SQLITE_OS_WINRT |
| 32960 | + { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 32961 | +#else |
| 32962 | + { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 32963 | +#endif |
| 32964 | + |
| 32965 | +#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ |
| 32966 | + SIZE_T))aSyscall[64].pCurrent) |
| 32967 | + |
| 32968 | +#if SQLITE_OS_WINRT |
| 32969 | + { "CreateFile2", (SYSCALL)CreateFile2, 0 }, |
| 32970 | +#else |
| 32971 | + { "CreateFile2", (SYSCALL)0, 0 }, |
| 32972 | +#endif |
| 32973 | + |
| 32974 | +#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ |
| 32975 | + LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent) |
| 32976 | + |
| 32977 | +#if SQLITE_OS_WINRT |
| 32978 | + { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, |
| 32979 | +#else |
| 32980 | + { "LoadPackagedLibrary", (SYSCALL)0, 0 }, |
| 32981 | +#endif |
| 32982 | + |
| 32983 | +#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ |
| 32984 | + DWORD))aSyscall[66].pCurrent) |
| 32985 | + |
| 32986 | +#if SQLITE_OS_WINRT |
| 32987 | + { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, |
| 32988 | +#else |
| 32989 | + { "GetTickCount64", (SYSCALL)0, 0 }, |
| 32990 | +#endif |
| 32991 | + |
| 32992 | +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent) |
| 32993 | + |
| 32994 | +#if SQLITE_OS_WINRT |
| 32995 | + { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, |
| 32996 | +#else |
| 32997 | + { "GetNativeSystemInfo", (SYSCALL)0, 0 }, |
| 32998 | +#endif |
| 32999 | + |
| 33000 | +#define osGetNativeSystemInfo ((VOID(WINAPI*)( \ |
| 33001 | + LPSYSTEM_INFO))aSyscall[68].pCurrent) |
| 33002 | + |
| 33003 | +#if defined(SQLITE_WIN32_HAS_ANSI) |
| 33004 | + { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, |
| 33005 | +#else |
| 33006 | + { "OutputDebugStringA", (SYSCALL)0, 0 }, |
| 33007 | +#endif |
| 33008 | + |
| 33009 | +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent) |
| 33010 | + |
| 33011 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 33012 | + { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, |
| 33013 | +#else |
| 33014 | + { "OutputDebugStringW", (SYSCALL)0, 0 }, |
| 33015 | +#endif |
| 33016 | + |
| 33017 | +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent) |
| 33018 | + |
| 33019 | + { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 33020 | + |
| 33021 | +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) |
| 33022 | + |
| 33023 | +#if SQLITE_OS_WINRT |
| 33024 | + { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, |
| 33025 | +#else |
| 33026 | + { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 33027 | +#endif |
| 33028 | + |
| 33029 | +#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 33030 | + LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent) |
| 32760 | 33031 | |
| 32761 | 33032 | }; /* End of the overrideable system calls */ |
| 32762 | 33033 | |
| 32763 | 33034 | /* |
| 32764 | 33035 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -32840,10 +33111,68 @@ |
| 32840 | 33111 | for(i++; i<ArraySize(aSyscall); i++){ |
| 32841 | 33112 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 32842 | 33113 | } |
| 32843 | 33114 | return 0; |
| 32844 | 33115 | } |
| 33116 | + |
| 33117 | +/* |
| 33118 | +** This function outputs the specified (ANSI) string to the Win32 debugger |
| 33119 | +** (if available). |
| 33120 | +*/ |
| 33121 | + |
| 33122 | +SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){ |
| 33123 | + char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; |
| 33124 | + int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ |
| 33125 | + if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ |
| 33126 | + assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE ); |
| 33127 | +#if defined(SQLITE_WIN32_HAS_ANSI) |
| 33128 | + if( nMin>0 ){ |
| 33129 | + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); |
| 33130 | + memcpy(zDbgBuf, zBuf, nMin); |
| 33131 | + osOutputDebugStringA(zDbgBuf); |
| 33132 | + }else{ |
| 33133 | + osOutputDebugStringA(zBuf); |
| 33134 | + } |
| 33135 | +#elif defined(SQLITE_WIN32_HAS_WIDE) |
| 33136 | + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); |
| 33137 | + if ( osMultiByteToWideChar( |
| 33138 | + osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, |
| 33139 | + nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ |
| 33140 | + return; |
| 33141 | + } |
| 33142 | + osOutputDebugStringW((LPCWSTR)zDbgBuf); |
| 33143 | +#else |
| 33144 | + if( nMin>0 ){ |
| 33145 | + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); |
| 33146 | + memcpy(zDbgBuf, zBuf, nMin); |
| 33147 | + fprintf(stderr, "%s", zDbgBuf); |
| 33148 | + }else{ |
| 33149 | + fprintf(stderr, "%s", zBuf); |
| 33150 | + } |
| 33151 | +#endif |
| 33152 | +} |
| 33153 | + |
| 33154 | +/* |
| 33155 | +** The following routine suspends the current thread for at least ms |
| 33156 | +** milliseconds. This is equivalent to the Win32 Sleep() interface. |
| 33157 | +*/ |
| 33158 | +#if SQLITE_OS_WINRT |
| 33159 | +static HANDLE sleepObj = NULL; |
| 33160 | +#endif |
| 33161 | + |
| 33162 | +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ |
| 33163 | +#if SQLITE_OS_WINRT |
| 33164 | + if ( sleepObj==NULL ){ |
| 33165 | + sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, |
| 33166 | + SYNCHRONIZE); |
| 33167 | + } |
| 33168 | + assert( sleepObj!=NULL ); |
| 33169 | + osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); |
| 33170 | +#else |
| 33171 | + osSleep(milliseconds); |
| 33172 | +#endif |
| 33173 | +} |
| 32845 | 33174 | |
| 32846 | 33175 | /* |
| 32847 | 33176 | ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
| 32848 | 33177 | ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
| 32849 | 33178 | ** |
| | @@ -32852,11 +33181,11 @@ |
| 32852 | 33181 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 32853 | 33182 | ** this routine is used to determine if the host is Win95/98/ME or |
| 32854 | 33183 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 32855 | 33184 | ** the LockFileEx() API. |
| 32856 | 33185 | */ |
| 32857 | | -#if SQLITE_OS_WINCE |
| 33186 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 32858 | 33187 | # define isNT() (1) |
| 32859 | 33188 | #else |
| 32860 | 33189 | static int isNT(void){ |
| 32861 | 33190 | if( sqlite3_os_type==0 ){ |
| 32862 | 33191 | OSVERSIONINFOA sInfo; |
| | @@ -32878,11 +33207,11 @@ |
| 32878 | 33207 | |
| 32879 | 33208 | winMemAssertMagic(); |
| 32880 | 33209 | hHeap = winMemGetHeap(); |
| 32881 | 33210 | assert( hHeap!=0 ); |
| 32882 | 33211 | assert( hHeap!=INVALID_HANDLE_VALUE ); |
| 32883 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33212 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32884 | 33213 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 32885 | 33214 | #endif |
| 32886 | 33215 | assert( nBytes>=0 ); |
| 32887 | 33216 | p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); |
| 32888 | 33217 | if( !p ){ |
| | @@ -32900,11 +33229,11 @@ |
| 32900 | 33229 | |
| 32901 | 33230 | winMemAssertMagic(); |
| 32902 | 33231 | hHeap = winMemGetHeap(); |
| 32903 | 33232 | assert( hHeap!=0 ); |
| 32904 | 33233 | assert( hHeap!=INVALID_HANDLE_VALUE ); |
| 32905 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33234 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32906 | 33235 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); |
| 32907 | 33236 | #endif |
| 32908 | 33237 | if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ |
| 32909 | 33238 | if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ |
| 32910 | 33239 | sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", |
| | @@ -32921,11 +33250,11 @@ |
| 32921 | 33250 | |
| 32922 | 33251 | winMemAssertMagic(); |
| 32923 | 33252 | hHeap = winMemGetHeap(); |
| 32924 | 33253 | assert( hHeap!=0 ); |
| 32925 | 33254 | assert( hHeap!=INVALID_HANDLE_VALUE ); |
| 32926 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33255 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32927 | 33256 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); |
| 32928 | 33257 | #endif |
| 32929 | 33258 | assert( nBytes>=0 ); |
| 32930 | 33259 | if( !pPrior ){ |
| 32931 | 33260 | p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); |
| | @@ -32949,11 +33278,11 @@ |
| 32949 | 33278 | |
| 32950 | 33279 | winMemAssertMagic(); |
| 32951 | 33280 | hHeap = winMemGetHeap(); |
| 32952 | 33281 | assert( hHeap!=0 ); |
| 32953 | 33282 | assert( hHeap!=INVALID_HANDLE_VALUE ); |
| 32954 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33283 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32955 | 33284 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 32956 | 33285 | #endif |
| 32957 | 33286 | if( !p ) return 0; |
| 32958 | 33287 | n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); |
| 32959 | 33288 | if( n==(SIZE_T)-1 ){ |
| | @@ -32977,10 +33306,12 @@ |
| 32977 | 33306 | static int winMemInit(void *pAppData){ |
| 32978 | 33307 | winMemData *pWinMemData = (winMemData *)pAppData; |
| 32979 | 33308 | |
| 32980 | 33309 | if( !pWinMemData ) return SQLITE_ERROR; |
| 32981 | 33310 | assert( pWinMemData->magic==WINMEM_MAGIC ); |
| 33311 | + |
| 33312 | +#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE |
| 32982 | 33313 | if( !pWinMemData->hHeap ){ |
| 32983 | 33314 | pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, |
| 32984 | 33315 | SQLITE_WIN32_HEAP_INIT_SIZE, |
| 32985 | 33316 | SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32986 | 33317 | if( !pWinMemData->hHeap ){ |
| | @@ -32989,14 +33320,25 @@ |
| 32989 | 33320 | osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, |
| 32990 | 33321 | SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32991 | 33322 | return SQLITE_NOMEM; |
| 32992 | 33323 | } |
| 32993 | 33324 | pWinMemData->bOwned = TRUE; |
| 33325 | + assert( pWinMemData->bOwned ); |
| 32994 | 33326 | } |
| 33327 | +#else |
| 33328 | + pWinMemData->hHeap = osGetProcessHeap(); |
| 33329 | + if( !pWinMemData->hHeap ){ |
| 33330 | + sqlite3_log(SQLITE_NOMEM, |
| 33331 | + "failed to GetProcessHeap (%d)", osGetLastError()); |
| 33332 | + return SQLITE_NOMEM; |
| 33333 | + } |
| 33334 | + pWinMemData->bOwned = FALSE; |
| 33335 | + assert( !pWinMemData->bOwned ); |
| 33336 | +#endif |
| 32995 | 33337 | assert( pWinMemData->hHeap!=0 ); |
| 32996 | 33338 | assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); |
| 32997 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33339 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32998 | 33340 | assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 32999 | 33341 | #endif |
| 33000 | 33342 | return SQLITE_OK; |
| 33001 | 33343 | } |
| 33002 | 33344 | |
| | @@ -33007,11 +33349,11 @@ |
| 33007 | 33349 | winMemData *pWinMemData = (winMemData *)pAppData; |
| 33008 | 33350 | |
| 33009 | 33351 | if( !pWinMemData ) return; |
| 33010 | 33352 | if( pWinMemData->hHeap ){ |
| 33011 | 33353 | assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); |
| 33012 | | -#ifdef SQLITE_WIN32_MALLOC_VALIDATE |
| 33354 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 33013 | 33355 | assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 33014 | 33356 | #endif |
| 33015 | 33357 | if( pWinMemData->bOwned ){ |
| 33016 | 33358 | if( !osHeapDestroy(pWinMemData->hHeap) ){ |
| 33017 | 33359 | sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", |
| | @@ -33207,10 +33549,21 @@ |
| 33207 | 33549 | */ |
| 33208 | 33550 | DWORD dwLen = 0; |
| 33209 | 33551 | char *zOut = 0; |
| 33210 | 33552 | |
| 33211 | 33553 | if( isNT() ){ |
| 33554 | +#if SQLITE_OS_WINRT |
| 33555 | + WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */ |
| 33556 | + dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 33557 | + FORMAT_MESSAGE_IGNORE_INSERTS, |
| 33558 | + NULL, |
| 33559 | + lastErrno, |
| 33560 | + 0, |
| 33561 | + zTempWide, |
| 33562 | + MAX_PATH, |
| 33563 | + 0); |
| 33564 | +#else |
| 33212 | 33565 | LPWSTR zTempWide = NULL; |
| 33213 | 33566 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 33214 | 33567 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 33215 | 33568 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 33216 | 33569 | NULL, |
| | @@ -33217,24 +33570,24 @@ |
| 33217 | 33570 | lastErrno, |
| 33218 | 33571 | 0, |
| 33219 | 33572 | (LPWSTR) &zTempWide, |
| 33220 | 33573 | 0, |
| 33221 | 33574 | 0); |
| 33575 | +#endif |
| 33222 | 33576 | if( dwLen > 0 ){ |
| 33223 | 33577 | /* allocate a buffer and convert to UTF8 */ |
| 33224 | 33578 | sqlite3BeginBenignMalloc(); |
| 33225 | 33579 | zOut = unicodeToUtf8(zTempWide); |
| 33226 | 33580 | sqlite3EndBenignMalloc(); |
| 33581 | +#if !SQLITE_OS_WINRT |
| 33227 | 33582 | /* free the system buffer allocated by FormatMessage */ |
| 33228 | 33583 | osLocalFree(zTempWide); |
| 33584 | +#endif |
| 33229 | 33585 | } |
| 33230 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 33231 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 33232 | | -** it's important to not reference them for WINCE builds. |
| 33233 | | -*/ |
| 33234 | | -#if SQLITE_OS_WINCE==0 |
| 33235 | | - }else{ |
| 33586 | + } |
| 33587 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 33588 | + else{ |
| 33236 | 33589 | char *zTemp = NULL; |
| 33237 | 33590 | dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 33238 | 33591 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 33239 | 33592 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 33240 | 33593 | NULL, |
| | @@ -33249,12 +33602,12 @@ |
| 33249 | 33602 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 33250 | 33603 | sqlite3EndBenignMalloc(); |
| 33251 | 33604 | /* free the system buffer allocated by FormatMessage */ |
| 33252 | 33605 | osLocalFree(zTemp); |
| 33253 | 33606 | } |
| 33607 | + } |
| 33254 | 33608 | #endif |
| 33255 | | - } |
| 33256 | 33609 | if( 0 == dwLen ){ |
| 33257 | 33610 | sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); |
| 33258 | 33611 | }else{ |
| 33259 | 33612 | /* copy a maximum of nBuf chars to output buffer */ |
| 33260 | 33613 | sqlite3_snprintf(nBuf, zBuf, "%s", zOut); |
| | @@ -33333,11 +33686,11 @@ |
| 33333 | 33686 | return 0; |
| 33334 | 33687 | } |
| 33335 | 33688 | if( e==ERROR_ACCESS_DENIED || |
| 33336 | 33689 | e==ERROR_LOCK_VIOLATION || |
| 33337 | 33690 | e==ERROR_SHARING_VIOLATION ){ |
| 33338 | | - osSleep(win32IoerrRetryDelay*(1+*pnRetry)); |
| 33691 | + sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry)); |
| 33339 | 33692 | ++*pnRetry; |
| 33340 | 33693 | return 1; |
| 33341 | 33694 | } |
| 33342 | 33695 | if( pError ){ |
| 33343 | 33696 | *pError = e; |
| | @@ -33394,11 +33747,11 @@ |
| 33394 | 33747 | ** Acquire a lock on the handle h |
| 33395 | 33748 | */ |
| 33396 | 33749 | static void winceMutexAcquire(HANDLE h){ |
| 33397 | 33750 | DWORD dwErr; |
| 33398 | 33751 | do { |
| 33399 | | - dwErr = WaitForSingleObject(h, INFINITE); |
| 33752 | + dwErr = osWaitForSingleObject(h, INFINITE); |
| 33400 | 33753 | } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); |
| 33401 | 33754 | } |
| 33402 | 33755 | /* |
| 33403 | 33756 | ** Release a lock acquired by winceMutexAcquire() |
| 33404 | 33757 | */ |
| | @@ -33525,11 +33878,11 @@ |
| 33525 | 33878 | |
| 33526 | 33879 | /* |
| 33527 | 33880 | ** An implementation of the LockFile() API of Windows for CE |
| 33528 | 33881 | */ |
| 33529 | 33882 | static BOOL winceLockFile( |
| 33530 | | - HANDLE *phFile, |
| 33883 | + LPHANDLE phFile, |
| 33531 | 33884 | DWORD dwFileOffsetLow, |
| 33532 | 33885 | DWORD dwFileOffsetHigh, |
| 33533 | 33886 | DWORD nNumberOfBytesToLockLow, |
| 33534 | 33887 | DWORD nNumberOfBytesToLockHigh |
| 33535 | 33888 | ){ |
| | @@ -33589,11 +33942,11 @@ |
| 33589 | 33942 | |
| 33590 | 33943 | /* |
| 33591 | 33944 | ** An implementation of the UnlockFile API of Windows for CE |
| 33592 | 33945 | */ |
| 33593 | 33946 | static BOOL winceUnlockFile( |
| 33594 | | - HANDLE *phFile, |
| 33947 | + LPHANDLE phFile, |
| 33595 | 33948 | DWORD dwFileOffsetLow, |
| 33596 | 33949 | DWORD dwFileOffsetHigh, |
| 33597 | 33950 | DWORD nNumberOfBytesToUnlockLow, |
| 33598 | 33951 | DWORD nNumberOfBytesToUnlockHigh |
| 33599 | 33952 | ){ |
| | @@ -33646,38 +33999,77 @@ |
| 33646 | 33999 | } |
| 33647 | 34000 | |
| 33648 | 34001 | winceMutexRelease(pFile->hMutex); |
| 33649 | 34002 | return bReturn; |
| 33650 | 34003 | } |
| 33651 | | - |
| 33652 | | -/* |
| 33653 | | -** An implementation of the LockFileEx() API of Windows for CE |
| 33654 | | -*/ |
| 33655 | | -static BOOL winceLockFileEx( |
| 33656 | | - HANDLE *phFile, |
| 33657 | | - DWORD dwFlags, |
| 33658 | | - DWORD dwReserved, |
| 33659 | | - DWORD nNumberOfBytesToLockLow, |
| 33660 | | - DWORD nNumberOfBytesToLockHigh, |
| 33661 | | - LPOVERLAPPED lpOverlapped |
| 33662 | | -){ |
| 33663 | | - UNUSED_PARAMETER(dwReserved); |
| 33664 | | - UNUSED_PARAMETER(nNumberOfBytesToLockHigh); |
| 33665 | | - |
| 33666 | | - /* If the caller wants a shared read lock, forward this call |
| 33667 | | - ** to winceLockFile */ |
| 33668 | | - if (lpOverlapped->Offset == (DWORD)SHARED_FIRST && |
| 33669 | | - dwFlags == 1 && |
| 33670 | | - nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ |
| 33671 | | - return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); |
| 33672 | | - } |
| 33673 | | - return FALSE; |
| 33674 | | -} |
| 33675 | 34004 | /* |
| 33676 | 34005 | ** End of the special code for wince |
| 33677 | 34006 | *****************************************************************************/ |
| 33678 | 34007 | #endif /* SQLITE_OS_WINCE */ |
| 34008 | + |
| 34009 | +/* |
| 34010 | +** Lock a file region. |
| 34011 | +*/ |
| 34012 | +static BOOL winLockFile( |
| 34013 | + LPHANDLE phFile, |
| 34014 | + DWORD flags, |
| 34015 | + DWORD offsetLow, |
| 34016 | + DWORD offsetHigh, |
| 34017 | + DWORD numBytesLow, |
| 34018 | + DWORD numBytesHigh |
| 34019 | +){ |
| 34020 | +#if SQLITE_OS_WINCE |
| 34021 | + /* |
| 34022 | + ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 34023 | + ** API LockFile. |
| 34024 | + */ |
| 34025 | + return winceLockFile(phFile, offsetLow, offsetHigh, |
| 34026 | + numBytesLow, numBytesHigh); |
| 34027 | +#else |
| 34028 | + if( isNT() ){ |
| 34029 | + OVERLAPPED ovlp; |
| 34030 | + memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 34031 | + ovlp.Offset = offsetLow; |
| 34032 | + ovlp.OffsetHigh = offsetHigh; |
| 34033 | + return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| 34034 | + }else{ |
| 34035 | + return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, |
| 34036 | + numBytesHigh); |
| 34037 | + } |
| 34038 | +#endif |
| 34039 | +} |
| 34040 | + |
| 34041 | +/* |
| 34042 | +** Unlock a file region. |
| 34043 | + */ |
| 34044 | +static BOOL winUnlockFile( |
| 34045 | + LPHANDLE phFile, |
| 34046 | + DWORD offsetLow, |
| 34047 | + DWORD offsetHigh, |
| 34048 | + DWORD numBytesLow, |
| 34049 | + DWORD numBytesHigh |
| 34050 | +){ |
| 34051 | +#if SQLITE_OS_WINCE |
| 34052 | + /* |
| 34053 | + ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 34054 | + ** API UnlockFile. |
| 34055 | + */ |
| 34056 | + return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 34057 | + numBytesLow, numBytesHigh); |
| 34058 | +#else |
| 34059 | + if( isNT() ){ |
| 34060 | + OVERLAPPED ovlp; |
| 34061 | + memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 34062 | + ovlp.Offset = offsetLow; |
| 34063 | + ovlp.OffsetHigh = offsetHigh; |
| 34064 | + return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| 34065 | + }else{ |
| 34066 | + return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, |
| 34067 | + numBytesHigh); |
| 34068 | + } |
| 34069 | +#endif |
| 34070 | +} |
| 33679 | 34071 | |
| 33680 | 34072 | /***************************************************************************** |
| 33681 | 34073 | ** The next group of routines implement the I/O methods specified |
| 33682 | 34074 | ** by the sqlite3_io_methods object. |
| 33683 | 34075 | ******************************************************************************/ |
| | @@ -33693,10 +34085,11 @@ |
| 33693 | 34085 | ** Move the current position of the file handle passed as the first |
| 33694 | 34086 | ** argument to offset iOffset within the file. If successful, return 0. |
| 33695 | 34087 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 33696 | 34088 | */ |
| 33697 | 34089 | static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 34090 | +#if !SQLITE_OS_WINRT |
| 33698 | 34091 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 33699 | 34092 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 33700 | 34093 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 33701 | 34094 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| 33702 | 34095 | |
| | @@ -33719,10 +34112,30 @@ |
| 33719 | 34112 | "seekWinFile", pFile->zPath); |
| 33720 | 34113 | return 1; |
| 33721 | 34114 | } |
| 33722 | 34115 | |
| 33723 | 34116 | return 0; |
| 34117 | +#else |
| 34118 | + /* |
| 34119 | + ** Same as above, except that this implementation works for WinRT. |
| 34120 | + */ |
| 34121 | + |
| 34122 | + LARGE_INTEGER x; /* The new offset */ |
| 34123 | + BOOL bRet; /* Value returned by SetFilePointerEx() */ |
| 34124 | + |
| 34125 | + x.QuadPart = iOffset; |
| 34126 | + bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 34127 | + |
| 34128 | + if(!bRet){ |
| 34129 | + pFile->lastErrno = osGetLastError(); |
| 34130 | + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 34131 | + "seekWinFile", pFile->zPath); |
| 34132 | + return 1; |
| 34133 | + } |
| 34134 | + |
| 34135 | + return 0; |
| 34136 | +#endif |
| 33724 | 34137 | } |
| 33725 | 34138 | |
| 33726 | 34139 | /* |
| 33727 | 34140 | ** Close a file. |
| 33728 | 34141 | ** |
| | @@ -33742,11 +34155,11 @@ |
| 33742 | 34155 | assert( pFile->pShm==0 ); |
| 33743 | 34156 | OSTRACE(("CLOSE %d\n", pFile->h)); |
| 33744 | 34157 | do{ |
| 33745 | 34158 | rc = osCloseHandle(pFile->h); |
| 33746 | 34159 | /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ |
| 33747 | | - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); |
| 34160 | + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); |
| 33748 | 34161 | #if SQLITE_OS_WINCE |
| 33749 | 34162 | #define WINCE_DELETION_ATTEMPTS 3 |
| 33750 | 34163 | winceDestroyLock(pFile); |
| 33751 | 34164 | if( pFile->zDeleteOnClose ){ |
| 33752 | 34165 | int cnt = 0; |
| | @@ -33753,11 +34166,11 @@ |
| 33753 | 34166 | while( |
| 33754 | 34167 | osDeleteFileW(pFile->zDeleteOnClose)==0 |
| 33755 | 34168 | && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff |
| 33756 | 34169 | && cnt++ < WINCE_DELETION_ATTEMPTS |
| 33757 | 34170 | ){ |
| 33758 | | - osSleep(100); /* Wait a little before trying again */ |
| 34171 | + sqlite3_win32_sleep(100); /* Wait a little before trying again */ |
| 33759 | 34172 | } |
| 33760 | 34173 | sqlite3_free(pFile->zDeleteOnClose); |
| 33761 | 34174 | } |
| 33762 | 34175 | #endif |
| 33763 | 34176 | OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); |
| | @@ -34008,60 +34421,105 @@ |
| 34008 | 34421 | |
| 34009 | 34422 | /* |
| 34010 | 34423 | ** Determine the current size of a file in bytes |
| 34011 | 34424 | */ |
| 34012 | 34425 | static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ |
| 34013 | | - DWORD upperBits; |
| 34014 | | - DWORD lowerBits; |
| 34015 | 34426 | winFile *pFile = (winFile*)id; |
| 34016 | | - DWORD lastErrno; |
| 34427 | + int rc = SQLITE_OK; |
| 34017 | 34428 | |
| 34018 | 34429 | assert( id!=0 ); |
| 34019 | 34430 | SimulateIOError(return SQLITE_IOERR_FSTAT); |
| 34020 | | - lowerBits = osGetFileSize(pFile->h, &upperBits); |
| 34021 | | - if( (lowerBits == INVALID_FILE_SIZE) |
| 34022 | | - && ((lastErrno = osGetLastError())!=NO_ERROR) ) |
| 34431 | +#if SQLITE_OS_WINRT |
| 34432 | + { |
| 34433 | + FILE_STANDARD_INFO info; |
| 34434 | + if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, |
| 34435 | + &info, sizeof(info)) ){ |
| 34436 | + *pSize = info.EndOfFile.QuadPart; |
| 34437 | + }else{ |
| 34438 | + pFile->lastErrno = osGetLastError(); |
| 34439 | + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 34440 | + "winFileSize", pFile->zPath); |
| 34441 | + } |
| 34442 | + } |
| 34443 | +#else |
| 34023 | 34444 | { |
| 34024 | | - pFile->lastErrno = lastErrno; |
| 34025 | | - return winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 34445 | + DWORD upperBits; |
| 34446 | + DWORD lowerBits; |
| 34447 | + DWORD lastErrno; |
| 34448 | + |
| 34449 | + lowerBits = osGetFileSize(pFile->h, &upperBits); |
| 34450 | + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 34451 | + if( (lowerBits == INVALID_FILE_SIZE) |
| 34452 | + && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 34453 | + pFile->lastErrno = lastErrno; |
| 34454 | + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 34026 | 34455 | "winFileSize", pFile->zPath); |
| 34456 | + } |
| 34027 | 34457 | } |
| 34028 | | - *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 34029 | | - return SQLITE_OK; |
| 34458 | +#endif |
| 34459 | + return rc; |
| 34030 | 34460 | } |
| 34031 | 34461 | |
| 34032 | 34462 | /* |
| 34033 | 34463 | ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. |
| 34034 | 34464 | */ |
| 34035 | 34465 | #ifndef LOCKFILE_FAIL_IMMEDIATELY |
| 34036 | 34466 | # define LOCKFILE_FAIL_IMMEDIATELY 1 |
| 34037 | 34467 | #endif |
| 34468 | + |
| 34469 | +#ifndef LOCKFILE_EXCLUSIVE_LOCK |
| 34470 | +# define LOCKFILE_EXCLUSIVE_LOCK 2 |
| 34471 | +#endif |
| 34472 | + |
| 34473 | +/* |
| 34474 | +** Historically, SQLite has used both the LockFile and LockFileEx functions. |
| 34475 | +** When the LockFile function was used, it was always expected to fail |
| 34476 | +** immediately if the lock could not be obtained. Also, it always expected to |
| 34477 | +** obtain an exclusive lock. These flags are used with the LockFileEx function |
| 34478 | +** and reflect those expectations; therefore, they should not be changed. |
| 34479 | +*/ |
| 34480 | +#ifndef SQLITE_LOCKFILE_FLAGS |
| 34481 | +# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ |
| 34482 | + LOCKFILE_EXCLUSIVE_LOCK) |
| 34483 | +#endif |
| 34484 | + |
| 34485 | +/* |
| 34486 | +** Currently, SQLite never calls the LockFileEx function without wanting the |
| 34487 | +** call to fail immediately if the lock cannot be obtained. |
| 34488 | +*/ |
| 34489 | +#ifndef SQLITE_LOCKFILEEX_FLAGS |
| 34490 | +# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) |
| 34491 | +#endif |
| 34038 | 34492 | |
| 34039 | 34493 | /* |
| 34040 | 34494 | ** Acquire a reader lock. |
| 34041 | 34495 | ** Different API routines are called depending on whether or not this |
| 34042 | 34496 | ** is Win9x or WinNT. |
| 34043 | 34497 | */ |
| 34044 | 34498 | static int getReadLock(winFile *pFile){ |
| 34045 | 34499 | int res; |
| 34046 | 34500 | if( isNT() ){ |
| 34047 | | - OVERLAPPED ovlp; |
| 34048 | | - ovlp.Offset = SHARED_FIRST; |
| 34049 | | - ovlp.OffsetHigh = 0; |
| 34050 | | - ovlp.hEvent = 0; |
| 34051 | | - res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, |
| 34052 | | - 0, SHARED_SIZE, 0, &ovlp); |
| 34053 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 34054 | | -*/ |
| 34055 | | -#if SQLITE_OS_WINCE==0 |
| 34056 | | - }else{ |
| 34501 | +#if SQLITE_OS_WINCE |
| 34502 | + /* |
| 34503 | + ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 34504 | + ** API LockFileEx. |
| 34505 | + */ |
| 34506 | + res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); |
| 34507 | +#else |
| 34508 | + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, |
| 34509 | + SHARED_SIZE, 0); |
| 34510 | +#endif |
| 34511 | + } |
| 34512 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 34513 | + else{ |
| 34057 | 34514 | int lk; |
| 34058 | 34515 | sqlite3_randomness(sizeof(lk), &lk); |
| 34059 | 34516 | pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); |
| 34060 | | - res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| 34517 | + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, |
| 34518 | + SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| 34519 | + } |
| 34061 | 34520 | #endif |
| 34062 | | - } |
| 34063 | 34521 | if( res == 0 ){ |
| 34064 | 34522 | pFile->lastErrno = osGetLastError(); |
| 34065 | 34523 | /* No need to log a failure to lock */ |
| 34066 | 34524 | } |
| 34067 | 34525 | return res; |
| | @@ -34072,18 +34530,17 @@ |
| 34072 | 34530 | */ |
| 34073 | 34531 | static int unlockReadLock(winFile *pFile){ |
| 34074 | 34532 | int res; |
| 34075 | 34533 | DWORD lastErrno; |
| 34076 | 34534 | if( isNT() ){ |
| 34077 | | - res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 34078 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 34079 | | -*/ |
| 34080 | | -#if SQLITE_OS_WINCE==0 |
| 34081 | | - }else{ |
| 34082 | | - res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); |
| 34535 | + res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 34536 | + } |
| 34537 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 34538 | + else{ |
| 34539 | + res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| 34540 | + } |
| 34083 | 34541 | #endif |
| 34084 | | - } |
| 34085 | 34542 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 34086 | 34543 | pFile->lastErrno = lastErrno; |
| 34087 | 34544 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 34088 | 34545 | "unlockReadLock", pFile->zPath); |
| 34089 | 34546 | } |
| | @@ -34150,19 +34607,20 @@ |
| 34150 | 34607 | if( (pFile->locktype==NO_LOCK) |
| 34151 | 34608 | || ( (locktype==EXCLUSIVE_LOCK) |
| 34152 | 34609 | && (pFile->locktype==RESERVED_LOCK)) |
| 34153 | 34610 | ){ |
| 34154 | 34611 | int cnt = 3; |
| 34155 | | - while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ |
| 34612 | + while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, |
| 34613 | + PENDING_BYTE, 0, 1, 0))==0 ){ |
| 34156 | 34614 | /* Try 3 times to get the pending lock. This is needed to work |
| 34157 | 34615 | ** around problems caused by indexing and/or anti-virus software on |
| 34158 | 34616 | ** Windows systems. |
| 34159 | 34617 | ** If you are using this code as a model for alternative VFSes, do not |
| 34160 | 34618 | ** copy this retry logic. It is a hack intended for Windows only. |
| 34161 | 34619 | */ |
| 34162 | 34620 | OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); |
| 34163 | | - if( cnt ) osSleep(1); |
| 34621 | + if( cnt ) sqlite3_win32_sleep(1); |
| 34164 | 34622 | } |
| 34165 | 34623 | gotPendingLock = res; |
| 34166 | 34624 | if( !res ){ |
| 34167 | 34625 | lastErrno = osGetLastError(); |
| 34168 | 34626 | } |
| | @@ -34182,11 +34640,11 @@ |
| 34182 | 34640 | |
| 34183 | 34641 | /* Acquire a RESERVED lock |
| 34184 | 34642 | */ |
| 34185 | 34643 | if( locktype==RESERVED_LOCK && res ){ |
| 34186 | 34644 | assert( pFile->locktype==SHARED_LOCK ); |
| 34187 | | - res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34645 | + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); |
| 34188 | 34646 | if( res ){ |
| 34189 | 34647 | newLocktype = RESERVED_LOCK; |
| 34190 | 34648 | }else{ |
| 34191 | 34649 | lastErrno = osGetLastError(); |
| 34192 | 34650 | } |
| | @@ -34203,11 +34661,12 @@ |
| 34203 | 34661 | */ |
| 34204 | 34662 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 34205 | 34663 | assert( pFile->locktype>=SHARED_LOCK ); |
| 34206 | 34664 | res = unlockReadLock(pFile); |
| 34207 | 34665 | OSTRACE(("unreadlock = %d\n", res)); |
| 34208 | | - res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 34666 | + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 34667 | + SHARED_SIZE, 0); |
| 34209 | 34668 | if( res ){ |
| 34210 | 34669 | newLocktype = EXCLUSIVE_LOCK; |
| 34211 | 34670 | }else{ |
| 34212 | 34671 | lastErrno = osGetLastError(); |
| 34213 | 34672 | OSTRACE(("error-code = %d\n", lastErrno)); |
| | @@ -34217,11 +34676,11 @@ |
| 34217 | 34676 | |
| 34218 | 34677 | /* If we are holding a PENDING lock that ought to be released, then |
| 34219 | 34678 | ** release it now. |
| 34220 | 34679 | */ |
| 34221 | 34680 | if( gotPendingLock && locktype==SHARED_LOCK ){ |
| 34222 | | - osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); |
| 34681 | + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 34223 | 34682 | } |
| 34224 | 34683 | |
| 34225 | 34684 | /* Update the state of the lock has held in the file descriptor then |
| 34226 | 34685 | ** return the appropriate result code. |
| 34227 | 34686 | */ |
| | @@ -34251,13 +34710,13 @@ |
| 34251 | 34710 | assert( id!=0 ); |
| 34252 | 34711 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 34253 | 34712 | rc = 1; |
| 34254 | 34713 | OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); |
| 34255 | 34714 | }else{ |
| 34256 | | - rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34715 | + rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); |
| 34257 | 34716 | if( rc ){ |
| 34258 | | - osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34717 | + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34259 | 34718 | } |
| 34260 | 34719 | rc = !rc; |
| 34261 | 34720 | OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); |
| 34262 | 34721 | } |
| 34263 | 34722 | *pResOut = rc; |
| | @@ -34283,26 +34742,26 @@ |
| 34283 | 34742 | assert( locktype<=SHARED_LOCK ); |
| 34284 | 34743 | OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, |
| 34285 | 34744 | pFile->locktype, pFile->sharedLockByte)); |
| 34286 | 34745 | type = pFile->locktype; |
| 34287 | 34746 | if( type>=EXCLUSIVE_LOCK ){ |
| 34288 | | - osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 34747 | + winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 34289 | 34748 | if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 34290 | 34749 | /* This should never happen. We should always be able to |
| 34291 | 34750 | ** reacquire the read lock */ |
| 34292 | 34751 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 34293 | 34752 | "winUnlock", pFile->zPath); |
| 34294 | 34753 | } |
| 34295 | 34754 | } |
| 34296 | 34755 | if( type>=RESERVED_LOCK ){ |
| 34297 | | - osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34756 | + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34298 | 34757 | } |
| 34299 | 34758 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 34300 | 34759 | unlockReadLock(pFile); |
| 34301 | 34760 | } |
| 34302 | 34761 | if( type>=PENDING_LOCK ){ |
| 34303 | | - osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); |
| 34762 | + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 34304 | 34763 | } |
| 34305 | 34764 | pFile->locktype = (u8)locktype; |
| 34306 | 34765 | return rc; |
| 34307 | 34766 | } |
| 34308 | 34767 | |
| | @@ -34536,29 +34995,23 @@ |
| 34536 | 34995 | winShmNode *pFile, /* Apply locks to this open shared-memory segment */ |
| 34537 | 34996 | int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ |
| 34538 | 34997 | int ofst, /* Offset to first byte to be locked/unlocked */ |
| 34539 | 34998 | int nByte /* Number of bytes to lock or unlock */ |
| 34540 | 34999 | ){ |
| 34541 | | - OVERLAPPED ovlp; |
| 34542 | | - DWORD dwFlags; |
| 34543 | 35000 | int rc = 0; /* Result code form Lock/UnlockFileEx() */ |
| 34544 | 35001 | |
| 34545 | 35002 | /* Access to the winShmNode object is serialized by the caller */ |
| 34546 | 35003 | assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); |
| 34547 | 35004 | |
| 34548 | | - /* Initialize the locking parameters */ |
| 34549 | | - dwFlags = LOCKFILE_FAIL_IMMEDIATELY; |
| 34550 | | - if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; |
| 34551 | | - |
| 34552 | | - memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 34553 | | - ovlp.Offset = ofst; |
| 34554 | | - |
| 34555 | 35005 | /* Release/Acquire the system-level lock */ |
| 34556 | 35006 | if( lockType==_SHM_UNLCK ){ |
| 34557 | | - rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); |
| 35007 | + rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); |
| 34558 | 35008 | }else{ |
| 34559 | | - rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); |
| 35009 | + /* Initialize the locking parameters */ |
| 35010 | + DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; |
| 35011 | + if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; |
| 35012 | + rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); |
| 34560 | 35013 | } |
| 34561 | 35014 | |
| 34562 | 35015 | if( rc!= 0 ){ |
| 34563 | 35016 | rc = SQLITE_OK; |
| 34564 | 35017 | }else{ |
| | @@ -34992,22 +35445,34 @@ |
| 34992 | 35445 | |
| 34993 | 35446 | while( pShmNode->nRegion<=iRegion ){ |
| 34994 | 35447 | HANDLE hMap; /* file-mapping handle */ |
| 34995 | 35448 | void *pMap = 0; /* Mapped memory region */ |
| 34996 | 35449 | |
| 34997 | | - hMap = osCreateFileMapping(pShmNode->hFile.h, |
| 35450 | +#if SQLITE_OS_WINRT |
| 35451 | + hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, |
| 35452 | + NULL, PAGE_READWRITE, nByte, NULL |
| 35453 | + ); |
| 35454 | +#else |
| 35455 | + hMap = osCreateFileMappingW(pShmNode->hFile.h, |
| 34998 | 35456 | NULL, PAGE_READWRITE, 0, nByte, NULL |
| 34999 | 35457 | ); |
| 35458 | +#endif |
| 35000 | 35459 | OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", |
| 35001 | 35460 | (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, |
| 35002 | 35461 | hMap ? "ok" : "failed")); |
| 35003 | 35462 | if( hMap ){ |
| 35004 | 35463 | int iOffset = pShmNode->nRegion*szRegion; |
| 35005 | 35464 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 35465 | +#if SQLITE_OS_WINRT |
| 35466 | + pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 35467 | + iOffset - iOffsetShift, szRegion + iOffsetShift |
| 35468 | + ); |
| 35469 | +#else |
| 35006 | 35470 | pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 35007 | 35471 | 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 35008 | 35472 | ); |
| 35473 | +#endif |
| 35009 | 35474 | OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", |
| 35010 | 35475 | (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, |
| 35011 | 35476 | szRegion, pMap ? "ok" : "failed")); |
| 35012 | 35477 | } |
| 35013 | 35478 | if( !pMap ){ |
| | @@ -35089,17 +35554,16 @@ |
| 35089 | 35554 | */ |
| 35090 | 35555 | static void *convertUtf8Filename(const char *zFilename){ |
| 35091 | 35556 | void *zConverted = 0; |
| 35092 | 35557 | if( isNT() ){ |
| 35093 | 35558 | zConverted = utf8ToUnicode(zFilename); |
| 35094 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35095 | | -*/ |
| 35096 | | -#if SQLITE_OS_WINCE==0 |
| 35097 | | - }else{ |
| 35559 | + } |
| 35560 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 35561 | + else{ |
| 35098 | 35562 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 35563 | + } |
| 35099 | 35564 | #endif |
| 35100 | | - } |
| 35101 | 35565 | /* caller will handle out of memory */ |
| 35102 | 35566 | return zConverted; |
| 35103 | 35567 | } |
| 35104 | 35568 | |
| 35105 | 35569 | /* |
| | @@ -35110,21 +35574,26 @@ |
| 35110 | 35574 | static char zChars[] = |
| 35111 | 35575 | "abcdefghijklmnopqrstuvwxyz" |
| 35112 | 35576 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 35113 | 35577 | "0123456789"; |
| 35114 | 35578 | size_t i, j; |
| 35579 | + int nTempPath; |
| 35115 | 35580 | char zTempPath[MAX_PATH+2]; |
| 35116 | 35581 | |
| 35117 | 35582 | /* It's odd to simulate an io-error here, but really this is just |
| 35118 | 35583 | ** using the io-error infrastructure to test that SQLite handles this |
| 35119 | 35584 | ** function failing. |
| 35120 | 35585 | */ |
| 35121 | 35586 | SimulateIOError( return SQLITE_IOERR ); |
| 35122 | 35587 | |
| 35588 | + memset(zTempPath, 0, MAX_PATH+2); |
| 35589 | + |
| 35123 | 35590 | if( sqlite3_temp_directory ){ |
| 35124 | 35591 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); |
| 35125 | | - }else if( isNT() ){ |
| 35592 | + } |
| 35593 | +#if !SQLITE_OS_WINRT |
| 35594 | + else if( isNT() ){ |
| 35126 | 35595 | char *zMulti; |
| 35127 | 35596 | WCHAR zWidePath[MAX_PATH]; |
| 35128 | 35597 | osGetTempPathW(MAX_PATH-30, zWidePath); |
| 35129 | 35598 | zMulti = unicodeToUtf8(zWidePath); |
| 35130 | 35599 | if( zMulti ){ |
| | @@ -35131,16 +35600,13 @@ |
| 35131 | 35600 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); |
| 35132 | 35601 | sqlite3_free(zMulti); |
| 35133 | 35602 | }else{ |
| 35134 | 35603 | return SQLITE_IOERR_NOMEM; |
| 35135 | 35604 | } |
| 35136 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35137 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 35138 | | -** it's important to not reference them for WINCE builds. |
| 35139 | | -*/ |
| 35140 | | -#if SQLITE_OS_WINCE==0 |
| 35141 | | - }else{ |
| 35605 | + } |
| 35606 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 35607 | + else{ |
| 35142 | 35608 | char *zUtf8; |
| 35143 | 35609 | char zMbcsPath[MAX_PATH]; |
| 35144 | 35610 | osGetTempPathA(MAX_PATH-30, zMbcsPath); |
| 35145 | 35611 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 35146 | 35612 | if( zUtf8 ){ |
| | @@ -35147,25 +35613,29 @@ |
| 35147 | 35613 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 35148 | 35614 | sqlite3_free(zUtf8); |
| 35149 | 35615 | }else{ |
| 35150 | 35616 | return SQLITE_IOERR_NOMEM; |
| 35151 | 35617 | } |
| 35618 | + } |
| 35152 | 35619 | #endif |
| 35153 | | - } |
| 35620 | +#endif |
| 35154 | 35621 | |
| 35155 | 35622 | /* Check that the output buffer is large enough for the temporary file |
| 35156 | 35623 | ** name. If it is not, return SQLITE_ERROR. |
| 35157 | 35624 | */ |
| 35158 | | - if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 35625 | + nTempPath = sqlite3Strlen30(zTempPath); |
| 35626 | + |
| 35627 | + if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 35159 | 35628 | return SQLITE_ERROR; |
| 35160 | 35629 | } |
| 35161 | 35630 | |
| 35162 | | - for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} |
| 35631 | + for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 35163 | 35632 | zTempPath[i] = 0; |
| 35164 | 35633 | |
| 35165 | | - sqlite3_snprintf(nBuf-18, zBuf, |
| 35166 | | - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); |
| 35634 | + sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ? |
| 35635 | + "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX, |
| 35636 | + zTempPath); |
| 35167 | 35637 | j = sqlite3Strlen30(zBuf); |
| 35168 | 35638 | sqlite3_randomness(15, &zBuf[j]); |
| 35169 | 35639 | for(i=0; i<15; i++, j++){ |
| 35170 | 35640 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 35171 | 35641 | } |
| | @@ -35357,33 +35827,52 @@ |
| 35357 | 35827 | #if SQLITE_OS_WINCE |
| 35358 | 35828 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 35359 | 35829 | #endif |
| 35360 | 35830 | |
| 35361 | 35831 | if( isNT() ){ |
| 35832 | +#if SQLITE_OS_WINRT |
| 35833 | + CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 35834 | + extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 35835 | + extendedParameters.dwFileAttributes = |
| 35836 | + dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| 35837 | + extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; |
| 35838 | + extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; |
| 35839 | + extendedParameters.lpSecurityAttributes = NULL; |
| 35840 | + extendedParameters.hTemplateFile = NULL; |
| 35841 | + while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 35842 | + dwDesiredAccess, |
| 35843 | + dwShareMode, |
| 35844 | + dwCreationDisposition, |
| 35845 | + &extendedParameters))==INVALID_HANDLE_VALUE && |
| 35846 | + retryIoerr(&cnt, &lastErrno) ){ |
| 35847 | + /* Noop */ |
| 35848 | + } |
| 35849 | +#else |
| 35362 | 35850 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 35363 | 35851 | dwDesiredAccess, |
| 35364 | 35852 | dwShareMode, NULL, |
| 35365 | 35853 | dwCreationDisposition, |
| 35366 | 35854 | dwFlagsAndAttributes, |
| 35367 | 35855 | NULL))==INVALID_HANDLE_VALUE && |
| 35368 | 35856 | retryIoerr(&cnt, &lastErrno) ){ |
| 35369 | 35857 | /* Noop */ |
| 35370 | 35858 | } |
| 35371 | | -#if SQLITE_OS_WINCE==0 |
| 35372 | | - }else{ |
| 35859 | +#endif |
| 35860 | + } |
| 35861 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 35862 | + else{ |
| 35373 | 35863 | while( (h = osCreateFileA((LPCSTR)zConverted, |
| 35374 | 35864 | dwDesiredAccess, |
| 35375 | 35865 | dwShareMode, NULL, |
| 35376 | 35866 | dwCreationDisposition, |
| 35377 | 35867 | dwFlagsAndAttributes, |
| 35378 | 35868 | NULL))==INVALID_HANDLE_VALUE && |
| 35379 | 35869 | retryIoerr(&cnt, &lastErrno) ){ |
| 35380 | 35870 | /* Noop */ |
| 35381 | 35871 | } |
| 35872 | + } |
| 35382 | 35873 | #endif |
| 35383 | | - } |
| 35384 | | - |
| 35385 | 35874 | logIoerr(cnt); |
| 35386 | 35875 | |
| 35387 | 35876 | OSTRACE(("OPEN %d %s 0x%lx %s\n", |
| 35388 | 35877 | h, zName, dwDesiredAccess, |
| 35389 | 35878 | h==INVALID_HANDLE_VALUE ? "failed" : "ok")); |
| | @@ -35469,11 +35958,23 @@ |
| 35469 | 35958 | if( zConverted==0 ){ |
| 35470 | 35959 | return SQLITE_IOERR_NOMEM; |
| 35471 | 35960 | } |
| 35472 | 35961 | if( isNT() ){ |
| 35473 | 35962 | do { |
| 35963 | +#if SQLITE_OS_WINRT |
| 35964 | + WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35965 | + memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35966 | + if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| 35967 | + &sAttrData) ){ |
| 35968 | + attr = sAttrData.dwFileAttributes; |
| 35969 | + }else{ |
| 35970 | + rc = SQLITE_OK; /* Already gone? */ |
| 35971 | + break; |
| 35972 | + } |
| 35973 | +#else |
| 35474 | 35974 | attr = osGetFileAttributesW(zConverted); |
| 35975 | +#endif |
| 35475 | 35976 | if ( attr==INVALID_FILE_ATTRIBUTES ){ |
| 35476 | 35977 | rc = SQLITE_OK; /* Already gone? */ |
| 35477 | 35978 | break; |
| 35478 | 35979 | } |
| 35479 | 35980 | if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ |
| | @@ -35487,16 +35988,13 @@ |
| 35487 | 35988 | if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35488 | 35989 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35489 | 35990 | break; |
| 35490 | 35991 | } |
| 35491 | 35992 | } while(1); |
| 35492 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35493 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 35494 | | -** it's important to not reference them for WINCE builds. |
| 35495 | | -*/ |
| 35496 | | -#if SQLITE_OS_WINCE==0 |
| 35497 | | - }else{ |
| 35993 | + } |
| 35994 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 35995 | + else{ |
| 35498 | 35996 | do { |
| 35499 | 35997 | attr = osGetFileAttributesA(zConverted); |
| 35500 | 35998 | if ( attr==INVALID_FILE_ATTRIBUTES ){ |
| 35501 | 35999 | rc = SQLITE_OK; /* Already gone? */ |
| 35502 | 36000 | break; |
| | @@ -35512,12 +36010,12 @@ |
| 35512 | 36010 | if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35513 | 36011 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35514 | 36012 | break; |
| 35515 | 36013 | } |
| 35516 | 36014 | } while(1); |
| 36015 | + } |
| 35517 | 36016 | #endif |
| 35518 | | - } |
| 35519 | 36017 | if( rc ){ |
| 35520 | 36018 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35521 | 36019 | "winDelete", zFilename); |
| 35522 | 36020 | }else{ |
| 35523 | 36021 | logIoerr(cnt); |
| | @@ -35573,19 +36071,16 @@ |
| 35573 | 36071 | return SQLITE_IOERR_ACCESS; |
| 35574 | 36072 | }else{ |
| 35575 | 36073 | attr = INVALID_FILE_ATTRIBUTES; |
| 35576 | 36074 | } |
| 35577 | 36075 | } |
| 35578 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35579 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 35580 | | -** it's important to not reference them for WINCE builds. |
| 35581 | | -*/ |
| 35582 | | -#if SQLITE_OS_WINCE==0 |
| 35583 | | - }else{ |
| 36076 | + } |
| 36077 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 36078 | + else{ |
| 35584 | 36079 | attr = osGetFileAttributesA((char*)zConverted); |
| 36080 | + } |
| 35585 | 36081 | #endif |
| 35586 | | - } |
| 35587 | 36082 | sqlite3_free(zConverted); |
| 35588 | 36083 | switch( flags ){ |
| 35589 | 36084 | case SQLITE_ACCESS_READ: |
| 35590 | 36085 | case SQLITE_ACCESS_EXISTS: |
| 35591 | 36086 | rc = attr!=INVALID_FILE_ATTRIBUTES; |
| | @@ -35599,10 +36094,47 @@ |
| 35599 | 36094 | } |
| 35600 | 36095 | *pResOut = rc; |
| 35601 | 36096 | return SQLITE_OK; |
| 35602 | 36097 | } |
| 35603 | 36098 | |
| 36099 | + |
| 36100 | +/* |
| 36101 | +** Returns non-zero if the specified path name should be used verbatim. If |
| 36102 | +** non-zero is returned from this function, the calling function must simply |
| 36103 | +** use the provided path name verbatim -OR- resolve it into a full path name |
| 36104 | +** using the GetFullPathName Win32 API function (if available). |
| 36105 | +*/ |
| 36106 | +static BOOL winIsVerbatimPathname( |
| 36107 | + const char *zPathname |
| 36108 | +){ |
| 36109 | + /* |
| 36110 | + ** If the path name starts with a forward slash or a backslash, it is either |
| 36111 | + ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 36112 | + ** "Unix" format on Windows. There is no easy way to differentiate between |
| 36113 | + ** the final two cases; therefore, we return the safer return value of TRUE |
| 36114 | + ** so that callers of this function will simply use it verbatim. |
| 36115 | + */ |
| 36116 | + if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ |
| 36117 | + return TRUE; |
| 36118 | + } |
| 36119 | + |
| 36120 | + /* |
| 36121 | + ** If the path name starts with a letter and a colon it is either a volume |
| 36122 | + ** relative path or an absolute path. Callers of this function must not |
| 36123 | + ** attempt to treat it as a relative path name (i.e. they should simply use |
| 36124 | + ** it verbatim). |
| 36125 | + */ |
| 36126 | + if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){ |
| 36127 | + return TRUE; |
| 36128 | + } |
| 36129 | + |
| 36130 | + /* |
| 36131 | + ** If we get to this point, the path name should almost certainly be a purely |
| 36132 | + ** relative one (i.e. not a UNC name, not absolute, and not volume relative). |
| 36133 | + */ |
| 36134 | + return FALSE; |
| 36135 | +} |
| 35604 | 36136 | |
| 35605 | 36137 | /* |
| 35606 | 36138 | ** Turn a relative pathname into a full pathname. Write the full |
| 35607 | 36139 | ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname |
| 35608 | 36140 | ** bytes in size. |
| | @@ -35615,23 +36147,55 @@ |
| 35615 | 36147 | ){ |
| 35616 | 36148 | |
| 35617 | 36149 | #if defined(__CYGWIN__) |
| 35618 | 36150 | SimulateIOError( return SQLITE_ERROR ); |
| 35619 | 36151 | UNUSED_PARAMETER(nFull); |
| 35620 | | - cygwin_conv_to_full_win32_path(zRelative, zFull); |
| 36152 | + assert( pVfs->mxPathname>=MAX_PATH ); |
| 36153 | + assert( nFull>=pVfs->mxPathname ); |
| 36154 | + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 36155 | + /* |
| 36156 | + ** NOTE: We are dealing with a relative path name and the data |
| 36157 | + ** directory has been set. Therefore, use it as the basis |
| 36158 | + ** for converting the relative path name to an absolute |
| 36159 | + ** one by prepending the data directory and a slash. |
| 36160 | + */ |
| 36161 | + char zOut[MAX_PATH+1]; |
| 36162 | + memset(zOut, 0, MAX_PATH+1); |
| 36163 | + cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */ |
| 36164 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 36165 | + sqlite3_data_directory, zOut); |
| 36166 | + }else{ |
| 36167 | + /* |
| 36168 | + ** NOTE: The Cygwin docs state that the maximum length needed |
| 36169 | + ** for the buffer passed to cygwin_conv_to_full_win32_path |
| 36170 | + ** is MAX_PATH. |
| 36171 | + */ |
| 36172 | + cygwin_conv_to_full_win32_path(zRelative, zFull); |
| 36173 | + } |
| 35621 | 36174 | return SQLITE_OK; |
| 35622 | 36175 | #endif |
| 35623 | 36176 | |
| 35624 | | -#if SQLITE_OS_WINCE |
| 36177 | +#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) |
| 35625 | 36178 | SimulateIOError( return SQLITE_ERROR ); |
| 35626 | | - UNUSED_PARAMETER(nFull); |
| 35627 | 36179 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 35628 | | - sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); |
| 36180 | + /* WinRT has no way to convert a relative path to an absolute one. */ |
| 36181 | + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 36182 | + /* |
| 36183 | + ** NOTE: We are dealing with a relative path name and the data |
| 36184 | + ** directory has been set. Therefore, use it as the basis |
| 36185 | + ** for converting the relative path name to an absolute |
| 36186 | + ** one by prepending the data directory and a backslash. |
| 36187 | + */ |
| 36188 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 36189 | + sqlite3_data_directory, zRelative); |
| 36190 | + }else{ |
| 36191 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 36192 | + } |
| 35629 | 36193 | return SQLITE_OK; |
| 35630 | 36194 | #endif |
| 35631 | 36195 | |
| 35632 | | -#if !SQLITE_OS_WINCE && !defined(__CYGWIN__) |
| 36196 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
| 35633 | 36197 | int nByte; |
| 35634 | 36198 | void *zConverted; |
| 35635 | 36199 | char *zOut; |
| 35636 | 36200 | |
| 35637 | 36201 | /* If this path name begins with "/X:", where "X" is any alphabetic |
| | @@ -35645,11 +36209,21 @@ |
| 35645 | 36209 | ** using the io-error infrastructure to test that SQLite handles this |
| 35646 | 36210 | ** function failing. This function could fail if, for example, the |
| 35647 | 36211 | ** current working directory has been unlinked. |
| 35648 | 36212 | */ |
| 35649 | 36213 | SimulateIOError( return SQLITE_ERROR ); |
| 35650 | | - UNUSED_PARAMETER(nFull); |
| 36214 | + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 36215 | + /* |
| 36216 | + ** NOTE: We are dealing with a relative path name and the data |
| 36217 | + ** directory has been set. Therefore, use it as the basis |
| 36218 | + ** for converting the relative path name to an absolute |
| 36219 | + ** one by prepending the data directory and a backslash. |
| 36220 | + */ |
| 36221 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 36222 | + sqlite3_data_directory, zRelative); |
| 36223 | + return SQLITE_OK; |
| 36224 | + } |
| 35651 | 36225 | zConverted = convertUtf8Filename(zRelative); |
| 35652 | 36226 | if( zConverted==0 ){ |
| 35653 | 36227 | return SQLITE_IOERR_NOMEM; |
| 35654 | 36228 | } |
| 35655 | 36229 | if( isNT() ){ |
| | @@ -35662,16 +36236,13 @@ |
| 35662 | 36236 | } |
| 35663 | 36237 | osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 35664 | 36238 | sqlite3_free(zConverted); |
| 35665 | 36239 | zOut = unicodeToUtf8(zTemp); |
| 35666 | 36240 | sqlite3_free(zTemp); |
| 35667 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35668 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 35669 | | -** it's important to not reference them for WINCE builds. |
| 35670 | | -*/ |
| 35671 | | -#if SQLITE_OS_WINCE==0 |
| 35672 | | - }else{ |
| 36241 | + } |
| 36242 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 36243 | + else{ |
| 35673 | 36244 | char *zTemp; |
| 35674 | 36245 | nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; |
| 35675 | 36246 | zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); |
| 35676 | 36247 | if( zTemp==0 ){ |
| 35677 | 36248 | sqlite3_free(zConverted); |
| | @@ -35679,14 +36250,14 @@ |
| 35679 | 36250 | } |
| 35680 | 36251 | osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
| 35681 | 36252 | sqlite3_free(zConverted); |
| 35682 | 36253 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 35683 | 36254 | sqlite3_free(zTemp); |
| 36255 | + } |
| 35684 | 36256 | #endif |
| 35685 | | - } |
| 35686 | 36257 | if( zOut ){ |
| 35687 | | - sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); |
| 36258 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); |
| 35688 | 36259 | sqlite3_free(zOut); |
| 35689 | 36260 | return SQLITE_OK; |
| 35690 | 36261 | }else{ |
| 35691 | 36262 | return SQLITE_IOERR_NOMEM; |
| 35692 | 36263 | } |
| | @@ -35708,20 +36279,21 @@ |
| 35708 | 36279 | UNUSED_PARAMETER(pVfs); |
| 35709 | 36280 | if( zConverted==0 ){ |
| 35710 | 36281 | return 0; |
| 35711 | 36282 | } |
| 35712 | 36283 | if( isNT() ){ |
| 36284 | +#if SQLITE_OS_WINRT |
| 36285 | + h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 36286 | +#else |
| 35713 | 36287 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35714 | | -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 35715 | | -** Since the ANSI version of these Windows API do not exist for WINCE, |
| 35716 | | -** it's important to not reference them for WINCE builds. |
| 35717 | | -*/ |
| 35718 | | -#if SQLITE_OS_WINCE==0 |
| 35719 | | - }else{ |
| 36288 | +#endif |
| 36289 | + } |
| 36290 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 36291 | + else{ |
| 35720 | 36292 | h = osLoadLibraryA((char*)zConverted); |
| 36293 | + } |
| 35721 | 36294 | #endif |
| 35722 | | - } |
| 35723 | 36295 | sqlite3_free(zConverted); |
| 35724 | 36296 | return (void*)h; |
| 35725 | 36297 | } |
| 35726 | 36298 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35727 | 36299 | UNUSED_PARAMETER(pVfs); |
| | @@ -35762,15 +36334,23 @@ |
| 35762 | 36334 | if( sizeof(DWORD)<=nBuf-n ){ |
| 35763 | 36335 | DWORD pid = osGetCurrentProcessId(); |
| 35764 | 36336 | memcpy(&zBuf[n], &pid, sizeof(pid)); |
| 35765 | 36337 | n += sizeof(pid); |
| 35766 | 36338 | } |
| 36339 | +#if SQLITE_OS_WINRT |
| 36340 | + if( sizeof(ULONGLONG)<=nBuf-n ){ |
| 36341 | + ULONGLONG cnt = osGetTickCount64(); |
| 36342 | + memcpy(&zBuf[n], &cnt, sizeof(cnt)); |
| 36343 | + n += sizeof(cnt); |
| 36344 | + } |
| 36345 | +#else |
| 35767 | 36346 | if( sizeof(DWORD)<=nBuf-n ){ |
| 35768 | 36347 | DWORD cnt = osGetTickCount(); |
| 35769 | 36348 | memcpy(&zBuf[n], &cnt, sizeof(cnt)); |
| 35770 | 36349 | n += sizeof(cnt); |
| 35771 | 36350 | } |
| 36351 | +#endif |
| 35772 | 36352 | if( sizeof(LARGE_INTEGER)<=nBuf-n ){ |
| 35773 | 36353 | LARGE_INTEGER i; |
| 35774 | 36354 | osQueryPerformanceCounter(&i); |
| 35775 | 36355 | memcpy(&zBuf[n], &i, sizeof(i)); |
| 35776 | 36356 | n += sizeof(i); |
| | @@ -35782,11 +36362,11 @@ |
| 35782 | 36362 | |
| 35783 | 36363 | /* |
| 35784 | 36364 | ** Sleep for a little while. Return the amount of time slept. |
| 35785 | 36365 | */ |
| 35786 | 36366 | static int winSleep(sqlite3_vfs *pVfs, int microsec){ |
| 35787 | | - osSleep((microsec+999)/1000); |
| 36367 | + sqlite3_win32_sleep((microsec+999)/1000); |
| 35788 | 36368 | UNUSED_PARAMETER(pVfs); |
| 35789 | 36369 | return ((microsec+999)/1000)*1000; |
| 35790 | 36370 | } |
| 35791 | 36371 | |
| 35792 | 36372 | /* |
| | @@ -35924,24 +36504,34 @@ |
| 35924 | 36504 | winNextSystemCall, /* xNextSystemCall */ |
| 35925 | 36505 | }; |
| 35926 | 36506 | |
| 35927 | 36507 | /* Double-check that the aSyscall[] array has been constructed |
| 35928 | 36508 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35929 | | - assert( ArraySize(aSyscall)==60 ); |
| 36509 | + assert( ArraySize(aSyscall)==73 ); |
| 35930 | 36510 | |
| 35931 | 36511 | #ifndef SQLITE_OMIT_WAL |
| 35932 | 36512 | /* get memory map allocation granularity */ |
| 35933 | 36513 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 36514 | +#if SQLITE_OS_WINRT |
| 36515 | + osGetNativeSystemInfo(&winSysInfo); |
| 36516 | +#else |
| 35934 | 36517 | osGetSystemInfo(&winSysInfo); |
| 36518 | +#endif |
| 35935 | 36519 | assert(winSysInfo.dwAllocationGranularity > 0); |
| 35936 | 36520 | #endif |
| 35937 | 36521 | |
| 35938 | 36522 | sqlite3_vfs_register(&winVfs, 1); |
| 35939 | 36523 | return SQLITE_OK; |
| 35940 | 36524 | } |
| 35941 | 36525 | |
| 35942 | 36526 | SQLITE_API int sqlite3_os_end(void){ |
| 36527 | +#if SQLITE_OS_WINRT |
| 36528 | + if( sleepObj != NULL ){ |
| 36529 | + osCloseHandle(sleepObj); |
| 36530 | + sleepObj = NULL; |
| 36531 | + } |
| 36532 | +#endif |
| 35943 | 36533 | return SQLITE_OK; |
| 35944 | 36534 | } |
| 35945 | 36535 | |
| 35946 | 36536 | #endif /* SQLITE_OS_WIN */ |
| 35947 | 36537 | |
| | @@ -37189,16 +37779,18 @@ |
| 37189 | 37779 | if( p==0 ){ |
| 37190 | 37780 | /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get |
| 37191 | 37781 | ** it from sqlite3Malloc instead. |
| 37192 | 37782 | */ |
| 37193 | 37783 | p = sqlite3Malloc(nByte); |
| 37784 | +#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS |
| 37194 | 37785 | if( p ){ |
| 37195 | 37786 | int sz = sqlite3MallocSize(p); |
| 37196 | 37787 | sqlite3_mutex_enter(pcache1.mutex); |
| 37197 | 37788 | sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); |
| 37198 | 37789 | sqlite3_mutex_leave(pcache1.mutex); |
| 37199 | 37790 | } |
| 37791 | +#endif |
| 37200 | 37792 | sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); |
| 37201 | 37793 | } |
| 37202 | 37794 | return p; |
| 37203 | 37795 | } |
| 37204 | 37796 | |
| | @@ -37221,13 +37813,15 @@ |
| 37221 | 37813 | sqlite3_mutex_leave(pcache1.mutex); |
| 37222 | 37814 | }else{ |
| 37223 | 37815 | assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); |
| 37224 | 37816 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 37225 | 37817 | nFreed = sqlite3MallocSize(p); |
| 37818 | +#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS |
| 37226 | 37819 | sqlite3_mutex_enter(pcache1.mutex); |
| 37227 | 37820 | sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed); |
| 37228 | 37821 | sqlite3_mutex_leave(pcache1.mutex); |
| 37822 | +#endif |
| 37229 | 37823 | sqlite3_free(p); |
| 37230 | 37824 | } |
| 37231 | 37825 | return nFreed; |
| 37232 | 37826 | } |
| 37233 | 37827 | |
| | @@ -43006,11 +43600,16 @@ |
| 43006 | 43600 | *ppPager = 0; |
| 43007 | 43601 | |
| 43008 | 43602 | #ifndef SQLITE_OMIT_MEMORYDB |
| 43009 | 43603 | if( flags & PAGER_MEMORY ){ |
| 43010 | 43604 | memDb = 1; |
| 43011 | | - zFilename = 0; |
| 43605 | + if( zFilename && zFilename[0] ){ |
| 43606 | + zPathname = sqlite3DbStrDup(0, zFilename); |
| 43607 | + if( zPathname==0 ) return SQLITE_NOMEM; |
| 43608 | + nPathname = sqlite3Strlen30(zPathname); |
| 43609 | + zFilename = 0; |
| 43610 | + } |
| 43012 | 43611 | } |
| 43013 | 43612 | #endif |
| 43014 | 43613 | |
| 43015 | 43614 | /* Compute and store the full pathname in an allocated buffer pointed |
| 43016 | 43615 | ** to by zPathname, length nPathname. Or, if this is a temporary file, |
| | @@ -43017,11 +43616,11 @@ |
| 43017 | 43616 | ** leave both nPathname and zPathname set to 0. |
| 43018 | 43617 | */ |
| 43019 | 43618 | if( zFilename && zFilename[0] ){ |
| 43020 | 43619 | const char *z; |
| 43021 | 43620 | nPathname = pVfs->mxPathname+1; |
| 43022 | | - zPathname = sqlite3Malloc(nPathname*2); |
| 43621 | + zPathname = sqlite3DbMallocRaw(0, nPathname*2); |
| 43023 | 43622 | if( zPathname==0 ){ |
| 43024 | 43623 | return SQLITE_NOMEM; |
| 43025 | 43624 | } |
| 43026 | 43625 | zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ |
| 43027 | 43626 | rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); |
| | @@ -43041,11 +43640,11 @@ |
| 43041 | 43640 | ** check for a hot-journal before reading. |
| 43042 | 43641 | */ |
| 43043 | 43642 | rc = SQLITE_CANTOPEN_BKPT; |
| 43044 | 43643 | } |
| 43045 | 43644 | if( rc!=SQLITE_OK ){ |
| 43046 | | - sqlite3_free(zPathname); |
| 43645 | + sqlite3DbFree(0, zPathname); |
| 43047 | 43646 | return rc; |
| 43048 | 43647 | } |
| 43049 | 43648 | } |
| 43050 | 43649 | |
| 43051 | 43650 | /* Allocate memory for the Pager structure, PCache object, the |
| | @@ -43071,11 +43670,11 @@ |
| 43071 | 43670 | + nPathname + 4 + 2 /* zWal */ |
| 43072 | 43671 | #endif |
| 43073 | 43672 | ); |
| 43074 | 43673 | assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); |
| 43075 | 43674 | if( !pPtr ){ |
| 43076 | | - sqlite3_free(zPathname); |
| 43675 | + sqlite3DbFree(0, zPathname); |
| 43077 | 43676 | return SQLITE_NOMEM; |
| 43078 | 43677 | } |
| 43079 | 43678 | pPager = (Pager*)(pPtr); |
| 43080 | 43679 | pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); |
| 43081 | 43680 | pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); |
| | @@ -43087,21 +43686,21 @@ |
| 43087 | 43686 | /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ |
| 43088 | 43687 | if( zPathname ){ |
| 43089 | 43688 | assert( nPathname>0 ); |
| 43090 | 43689 | pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); |
| 43091 | 43690 | memcpy(pPager->zFilename, zPathname, nPathname); |
| 43092 | | - memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); |
| 43691 | + if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); |
| 43093 | 43692 | memcpy(pPager->zJournal, zPathname, nPathname); |
| 43094 | 43693 | memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1); |
| 43095 | 43694 | sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); |
| 43096 | 43695 | #ifndef SQLITE_OMIT_WAL |
| 43097 | 43696 | pPager->zWal = &pPager->zJournal[nPathname+8+1]; |
| 43098 | 43697 | memcpy(pPager->zWal, zPathname, nPathname); |
| 43099 | 43698 | memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); |
| 43100 | 43699 | sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); |
| 43101 | 43700 | #endif |
| 43102 | | - sqlite3_free(zPathname); |
| 43701 | + sqlite3DbFree(0, zPathname); |
| 43103 | 43702 | } |
| 43104 | 43703 | pPager->pVfs = pVfs; |
| 43105 | 43704 | pPager->vfsFlags = vfsFlags; |
| 43106 | 43705 | |
| 43107 | 43706 | /* Open the pager file. |
| | @@ -44942,13 +45541,20 @@ |
| 44942 | 45541 | return rc; |
| 44943 | 45542 | } |
| 44944 | 45543 | |
| 44945 | 45544 | /* |
| 44946 | 45545 | ** Return the full pathname of the database file. |
| 45546 | +** |
| 45547 | +** Except, if the pager is in-memory only, then return an empty string if |
| 45548 | +** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when |
| 45549 | +** used to report the filename to the user, for compatibility with legacy |
| 45550 | +** behavior. But when the Btree needs to know the filename for matching to |
| 45551 | +** shared cache, it uses nullIfMemDb==0 so that in-memory databases can |
| 45552 | +** participate in shared-cache. |
| 44947 | 45553 | */ |
| 44948 | | -SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager){ |
| 44949 | | - return pPager->zFilename; |
| 45554 | +SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ |
| 45555 | + return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; |
| 44950 | 45556 | } |
| 44951 | 45557 | |
| 44952 | 45558 | /* |
| 44953 | 45559 | ** Return the VFS structure for the pager. |
| 44954 | 45560 | */ |
| | @@ -51329,11 +51935,12 @@ |
| 51329 | 51935 | */ |
| 51330 | 51936 | #ifdef SQLITE_OMIT_MEMORYDB |
| 51331 | 51937 | const int isMemdb = 0; |
| 51332 | 51938 | #else |
| 51333 | 51939 | const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) |
| 51334 | | - || (isTempDb && sqlite3TempInMemory(db)); |
| 51940 | + || (isTempDb && sqlite3TempInMemory(db)) |
| 51941 | + || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; |
| 51335 | 51942 | #endif |
| 51336 | 51943 | |
| 51337 | 51944 | assert( db!=0 ); |
| 51338 | 51945 | assert( pVfs!=0 ); |
| 51339 | 51946 | assert( sqlite3_mutex_held(db->mutex) ); |
| | @@ -51365,35 +51972,40 @@ |
| 51365 | 51972 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) |
| 51366 | 51973 | /* |
| 51367 | 51974 | ** If this Btree is a candidate for shared cache, try to find an |
| 51368 | 51975 | ** existing BtShared object that we can share with |
| 51369 | 51976 | */ |
| 51370 | | - if( isMemdb==0 && isTempDb==0 ){ |
| 51977 | + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ |
| 51371 | 51978 | if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ |
| 51372 | 51979 | int nFullPathname = pVfs->mxPathname+1; |
| 51373 | 51980 | char *zFullPathname = sqlite3Malloc(nFullPathname); |
| 51374 | 51981 | MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) |
| 51375 | 51982 | p->sharable = 1; |
| 51376 | 51983 | if( !zFullPathname ){ |
| 51377 | 51984 | sqlite3_free(p); |
| 51378 | 51985 | return SQLITE_NOMEM; |
| 51379 | 51986 | } |
| 51380 | | - rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); |
| 51381 | | - if( rc ){ |
| 51382 | | - sqlite3_free(zFullPathname); |
| 51383 | | - sqlite3_free(p); |
| 51384 | | - return rc; |
| 51987 | + if( isMemdb ){ |
| 51988 | + memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1); |
| 51989 | + }else{ |
| 51990 | + rc = sqlite3OsFullPathname(pVfs, zFilename, |
| 51991 | + nFullPathname, zFullPathname); |
| 51992 | + if( rc ){ |
| 51993 | + sqlite3_free(zFullPathname); |
| 51994 | + sqlite3_free(p); |
| 51995 | + return rc; |
| 51996 | + } |
| 51385 | 51997 | } |
| 51386 | 51998 | #if SQLITE_THREADSAFE |
| 51387 | 51999 | mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); |
| 51388 | 52000 | sqlite3_mutex_enter(mutexOpen); |
| 51389 | 52001 | mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
| 51390 | 52002 | sqlite3_mutex_enter(mutexShared); |
| 51391 | 52003 | #endif |
| 51392 | 52004 | for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ |
| 51393 | 52005 | assert( pBt->nRef>0 ); |
| 51394 | | - if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) |
| 52006 | + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) |
| 51395 | 52007 | && sqlite3PagerVfs(pBt->pPager)==pVfs ){ |
| 51396 | 52008 | int iDb; |
| 51397 | 52009 | for(iDb=db->nDb-1; iDb>=0; iDb--){ |
| 51398 | 52010 | Btree *pExisting = db->aDb[iDb].pBt; |
| 51399 | 52011 | if( pExisting && pExisting->pBt==pBt ){ |
| | @@ -57654,18 +58266,19 @@ |
| 57654 | 58266 | return sqlite3StrAccumFinish(&sCheck.errMsg); |
| 57655 | 58267 | } |
| 57656 | 58268 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 57657 | 58269 | |
| 57658 | 58270 | /* |
| 57659 | | -** Return the full pathname of the underlying database file. |
| 58271 | +** Return the full pathname of the underlying database file. Return |
| 58272 | +** an empty string if the database is in-memory or a TEMP database. |
| 57660 | 58273 | ** |
| 57661 | 58274 | ** The pager filename is invariant as long as the pager is |
| 57662 | 58275 | ** open so it is safe to access without the BtShared mutex. |
| 57663 | 58276 | */ |
| 57664 | 58277 | SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ |
| 57665 | 58278 | assert( p->pBt->pPager!=0 ); |
| 57666 | | - return sqlite3PagerFilename(p->pBt->pPager); |
| 58279 | + return sqlite3PagerFilename(p->pBt->pPager, 1); |
| 57667 | 58280 | } |
| 57668 | 58281 | |
| 57669 | 58282 | /* |
| 57670 | 58283 | ** Return the pathname of the journal file for this database. The return |
| 57671 | 58284 | ** value of this routine is the same regardless of whether the journal file |
| | @@ -58312,11 +58925,11 @@ |
| 58312 | 58925 | */ |
| 58313 | 58926 | if( rc==SQLITE_DONE ){ |
| 58314 | 58927 | rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); |
| 58315 | 58928 | if( rc==SQLITE_OK ){ |
| 58316 | 58929 | if( p->pDestDb ){ |
| 58317 | | - sqlite3ResetInternalSchema(p->pDestDb, -1); |
| 58930 | + sqlite3ResetAllSchemasOfConnection(p->pDestDb); |
| 58318 | 58931 | } |
| 58319 | 58932 | if( destMode==PAGER_JOURNALMODE_WAL ){ |
| 58320 | 58933 | rc = sqlite3BtreeSetVersion(p->pDest, 2); |
| 58321 | 58934 | } |
| 58322 | 58935 | } |
| | @@ -64497,12 +65110,13 @@ |
| 64497 | 65110 | /* |
| 64498 | 65111 | ** Allocate a new Explain object |
| 64499 | 65112 | */ |
| 64500 | 65113 | SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){ |
| 64501 | 65114 | if( pVdbe ){ |
| 65115 | + Explain *p; |
| 64502 | 65116 | sqlite3BeginBenignMalloc(); |
| 64503 | | - Explain *p = sqlite3_malloc( sizeof(Explain) ); |
| 65117 | + p = sqlite3_malloc( sizeof(Explain) ); |
| 64504 | 65118 | if( p ){ |
| 64505 | 65119 | memset(p, 0, sizeof(*p)); |
| 64506 | 65120 | p->pVdbe = pVdbe; |
| 64507 | 65121 | sqlite3_free(pVdbe->pExplain); |
| 64508 | 65122 | pVdbe->pExplain = p; |
| | @@ -67896,11 +68510,11 @@ |
| 67896 | 68510 | goto abort_due_to_error; |
| 67897 | 68511 | } |
| 67898 | 68512 | } |
| 67899 | 68513 | if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ |
| 67900 | 68514 | sqlite3ExpirePreparedStatements(db); |
| 67901 | | - sqlite3ResetInternalSchema(db, -1); |
| 68515 | + sqlite3ResetAllSchemasOfConnection(db); |
| 67902 | 68516 | db->flags = (db->flags | SQLITE_InternChanges); |
| 67903 | 68517 | } |
| 67904 | 68518 | } |
| 67905 | 68519 | |
| 67906 | 68520 | /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all |
| | @@ -68210,11 +68824,11 @@ |
| 68210 | 68824 | ** v-table would have to be ready for the sqlite3_vtab structure itself |
| 68211 | 68825 | ** to be invalidated whenever sqlite3_step() is called from within |
| 68212 | 68826 | ** a v-table method. |
| 68213 | 68827 | */ |
| 68214 | 68828 | if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){ |
| 68215 | | - sqlite3ResetInternalSchema(db, pOp->p1); |
| 68829 | + sqlite3ResetOneSchema(db, pOp->p1); |
| 68216 | 68830 | } |
| 68217 | 68831 | |
| 68218 | 68832 | p->expired = 1; |
| 68219 | 68833 | rc = SQLITE_SCHEMA; |
| 68220 | 68834 | } |
| | @@ -70079,11 +70693,11 @@ |
| 70079 | 70693 | if( rc==SQLITE_OK ) rc = u.by.initData.rc; |
| 70080 | 70694 | sqlite3DbFree(db, u.by.zSql); |
| 70081 | 70695 | db->init.busy = 0; |
| 70082 | 70696 | } |
| 70083 | 70697 | } |
| 70084 | | - if( rc ) sqlite3ResetInternalSchema(db, -1); |
| 70698 | + if( rc ) sqlite3ResetAllSchemasOfConnection(db); |
| 70085 | 70699 | if( rc==SQLITE_NOMEM ){ |
| 70086 | 70700 | goto no_mem; |
| 70087 | 70701 | } |
| 70088 | 70702 | break; |
| 70089 | 70703 | } |
| | @@ -70746,11 +71360,11 @@ |
| 70746 | 71360 | u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager); |
| 70747 | 71361 | if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld; |
| 70748 | 71362 | if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld; |
| 70749 | 71363 | |
| 70750 | 71364 | #ifndef SQLITE_OMIT_WAL |
| 70751 | | - u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager); |
| 71365 | + u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager, 1); |
| 70752 | 71366 | |
| 70753 | 71367 | /* Do not allow a transition to journal_mode=WAL for a database |
| 70754 | 71368 | ** in temporary storage or if the VFS does not support shared memory |
| 70755 | 71369 | */ |
| 70756 | 71370 | if( u.ci.eNew==PAGER_JOURNALMODE_WAL |
| | @@ -71412,11 +72026,11 @@ |
| 71412 | 72026 | pc, p->zSql, p->zErrMsg); |
| 71413 | 72027 | sqlite3VdbeHalt(p); |
| 71414 | 72028 | if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; |
| 71415 | 72029 | rc = SQLITE_ERROR; |
| 71416 | 72030 | if( resetSchemaOnFault>0 ){ |
| 71417 | | - sqlite3ResetInternalSchema(db, resetSchemaOnFault-1); |
| 72031 | + sqlite3ResetOneSchema(db, resetSchemaOnFault-1); |
| 71418 | 72032 | } |
| 71419 | 72033 | |
| 71420 | 72034 | /* This is the only way out of this procedure. We have to |
| 71421 | 72035 | ** release the mutexes on btrees that were acquired at the |
| 71422 | 72036 | ** top. */ |
| | @@ -73767,11 +74381,11 @@ |
| 73767 | 74381 | Expr *pOrig; |
| 73768 | 74382 | assert( pExpr->pLeft==0 && pExpr->pRight==0 ); |
| 73769 | 74383 | assert( pExpr->x.pList==0 ); |
| 73770 | 74384 | assert( pExpr->x.pSelect==0 ); |
| 73771 | 74385 | pOrig = pEList->a[j].pExpr; |
| 73772 | | - if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ |
| 74386 | + if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ |
| 73773 | 74387 | sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); |
| 73774 | 74388 | return WRC_Abort; |
| 73775 | 74389 | } |
| 73776 | 74390 | resolveAlias(pParse, pEList, j, pExpr, ""); |
| 73777 | 74391 | cnt = 1; |
| | @@ -74012,11 +74626,11 @@ |
| 74012 | 74626 | pExpr->op = TK_NULL; |
| 74013 | 74627 | return WRC_Prune; |
| 74014 | 74628 | } |
| 74015 | 74629 | } |
| 74016 | 74630 | #endif |
| 74017 | | - if( is_agg && !pNC->allowAgg ){ |
| 74631 | + if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ |
| 74018 | 74632 | sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); |
| 74019 | 74633 | pNC->nErr++; |
| 74020 | 74634 | is_agg = 0; |
| 74021 | 74635 | }else if( no_such_func ){ |
| 74022 | 74636 | sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); |
| | @@ -74026,15 +74640,15 @@ |
| 74026 | 74640 | nId, zId); |
| 74027 | 74641 | pNC->nErr++; |
| 74028 | 74642 | } |
| 74029 | 74643 | if( is_agg ){ |
| 74030 | 74644 | pExpr->op = TK_AGG_FUNCTION; |
| 74031 | | - pNC->hasAgg = 1; |
| 74645 | + pNC->ncFlags |= NC_HasAgg; |
| 74032 | 74646 | } |
| 74033 | | - if( is_agg ) pNC->allowAgg = 0; |
| 74647 | + if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; |
| 74034 | 74648 | sqlite3WalkExprList(pWalker, pList); |
| 74035 | | - if( is_agg ) pNC->allowAgg = 1; |
| 74649 | + if( is_agg ) pNC->ncFlags |= NC_AllowAgg; |
| 74036 | 74650 | /* FIX ME: Compute pExpr->affinity based on the expected return |
| 74037 | 74651 | ** type of the function |
| 74038 | 74652 | */ |
| 74039 | 74653 | return WRC_Prune; |
| 74040 | 74654 | } |
| | @@ -74045,11 +74659,11 @@ |
| 74045 | 74659 | case TK_IN: { |
| 74046 | 74660 | testcase( pExpr->op==TK_IN ); |
| 74047 | 74661 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 74048 | 74662 | int nRef = pNC->nRef; |
| 74049 | 74663 | #ifndef SQLITE_OMIT_CHECK |
| 74050 | | - if( pNC->isCheck ){ |
| 74664 | + if( (pNC->ncFlags & NC_IsCheck)!=0 ){ |
| 74051 | 74665 | sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); |
| 74052 | 74666 | } |
| 74053 | 74667 | #endif |
| 74054 | 74668 | sqlite3WalkSelect(pWalker, pExpr->x.pSelect); |
| 74055 | 74669 | assert( pNC->nRef>=nRef ); |
| | @@ -74059,11 +74673,11 @@ |
| 74059 | 74673 | } |
| 74060 | 74674 | break; |
| 74061 | 74675 | } |
| 74062 | 74676 | #ifndef SQLITE_OMIT_CHECK |
| 74063 | 74677 | case TK_VARIABLE: { |
| 74064 | | - if( pNC->isCheck ){ |
| 74678 | + if( (pNC->ncFlags & NC_IsCheck)!=0 ){ |
| 74065 | 74679 | sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); |
| 74066 | 74680 | } |
| 74067 | 74681 | break; |
| 74068 | 74682 | } |
| 74069 | 74683 | #endif |
| | @@ -74141,11 +74755,11 @@ |
| 74141 | 74755 | */ |
| 74142 | 74756 | memset(&nc, 0, sizeof(nc)); |
| 74143 | 74757 | nc.pParse = pParse; |
| 74144 | 74758 | nc.pSrcList = pSelect->pSrc; |
| 74145 | 74759 | nc.pEList = pEList; |
| 74146 | | - nc.allowAgg = 1; |
| 74760 | + nc.ncFlags = NC_AllowAgg; |
| 74147 | 74761 | nc.nErr = 0; |
| 74148 | 74762 | db = pParse->db; |
| 74149 | 74763 | savedSuppErr = db->suppressErr; |
| 74150 | 74764 | db->suppressErr = 1; |
| 74151 | 74765 | rc = sqlite3ResolveExprNames(&nc, pE); |
| | @@ -74443,11 +75057,11 @@ |
| 74443 | 75057 | } |
| 74444 | 75058 | |
| 74445 | 75059 | /* Set up the local name-context to pass to sqlite3ResolveExprNames() to |
| 74446 | 75060 | ** resolve the result-set expression list. |
| 74447 | 75061 | */ |
| 74448 | | - sNC.allowAgg = 1; |
| 75062 | + sNC.ncFlags = NC_AllowAgg; |
| 74449 | 75063 | sNC.pSrcList = p->pSrc; |
| 74450 | 75064 | sNC.pNext = pOuterNC; |
| 74451 | 75065 | |
| 74452 | 75066 | /* Resolve names in the result set. */ |
| 74453 | 75067 | pEList = p->pEList; |
| | @@ -74489,14 +75103,14 @@ |
| 74489 | 75103 | /* If there are no aggregate functions in the result-set, and no GROUP BY |
| 74490 | 75104 | ** expression, do not allow aggregates in any of the other expressions. |
| 74491 | 75105 | */ |
| 74492 | 75106 | assert( (p->selFlags & SF_Aggregate)==0 ); |
| 74493 | 75107 | pGroupBy = p->pGroupBy; |
| 74494 | | - if( pGroupBy || sNC.hasAgg ){ |
| 75108 | + if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ |
| 74495 | 75109 | p->selFlags |= SF_Aggregate; |
| 74496 | 75110 | }else{ |
| 74497 | | - sNC.allowAgg = 0; |
| 75111 | + sNC.ncFlags &= ~NC_AllowAgg; |
| 74498 | 75112 | } |
| 74499 | 75113 | |
| 74500 | 75114 | /* If a HAVING clause is present, then there must be a GROUP BY clause. |
| 74501 | 75115 | */ |
| 74502 | 75116 | if( p->pHaving && !pGroupBy ){ |
| | @@ -74521,11 +75135,11 @@ |
| 74521 | 75135 | |
| 74522 | 75136 | /* The ORDER BY and GROUP BY clauses may not refer to terms in |
| 74523 | 75137 | ** outer queries |
| 74524 | 75138 | */ |
| 74525 | 75139 | sNC.pNext = 0; |
| 74526 | | - sNC.allowAgg = 1; |
| 75140 | + sNC.ncFlags |= NC_AllowAgg; |
| 74527 | 75141 | |
| 74528 | 75142 | /* Process the ORDER BY clause for singleton SELECT statements. |
| 74529 | 75143 | ** The ORDER BY clause for compounds SELECT statements is handled |
| 74530 | 75144 | ** below, after all of the result-sets for all of the elements of |
| 74531 | 75145 | ** the compound have been resolved. |
| | @@ -74609,11 +75223,11 @@ |
| 74609 | 75223 | ** |
| 74610 | 75224 | ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; |
| 74611 | 75225 | ** |
| 74612 | 75226 | ** Function calls are checked to make sure that the function is |
| 74613 | 75227 | ** defined and that the correct number of arguments are specified. |
| 74614 | | -** If the function is an aggregate function, then the pNC->hasAgg is |
| 75228 | +** If the function is an aggregate function, then the NC_HasAgg flag is |
| 74615 | 75229 | ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. |
| 74616 | 75230 | ** If an expression contains aggregate functions then the EP_Agg |
| 74617 | 75231 | ** property on the expression is set. |
| 74618 | 75232 | ** |
| 74619 | 75233 | ** An error message is left in pParse if anything is amiss. The number |
| | @@ -74621,11 +75235,11 @@ |
| 74621 | 75235 | */ |
| 74622 | 75236 | SQLITE_PRIVATE int sqlite3ResolveExprNames( |
| 74623 | 75237 | NameContext *pNC, /* Namespace to resolve expressions in. */ |
| 74624 | 75238 | Expr *pExpr /* The expression to be analyzed. */ |
| 74625 | 75239 | ){ |
| 74626 | | - int savedHasAgg; |
| 75240 | + u8 savedHasAgg; |
| 74627 | 75241 | Walker w; |
| 74628 | 75242 | |
| 74629 | 75243 | if( pExpr==0 ) return 0; |
| 74630 | 75244 | #if SQLITE_MAX_EXPR_DEPTH>0 |
| 74631 | 75245 | { |
| | @@ -74634,12 +75248,12 @@ |
| 74634 | 75248 | return 1; |
| 74635 | 75249 | } |
| 74636 | 75250 | pParse->nHeight += pExpr->nHeight; |
| 74637 | 75251 | } |
| 74638 | 75252 | #endif |
| 74639 | | - savedHasAgg = pNC->hasAgg; |
| 74640 | | - pNC->hasAgg = 0; |
| 75253 | + savedHasAgg = pNC->ncFlags & NC_HasAgg; |
| 75254 | + pNC->ncFlags &= ~NC_HasAgg; |
| 74641 | 75255 | w.xExprCallback = resolveExprStep; |
| 74642 | 75256 | w.xSelectCallback = resolveSelectStep; |
| 74643 | 75257 | w.pParse = pNC->pParse; |
| 74644 | 75258 | w.u.pNC = pNC; |
| 74645 | 75259 | sqlite3WalkExpr(&w, pExpr); |
| | @@ -74647,14 +75261,14 @@ |
| 74647 | 75261 | pNC->pParse->nHeight -= pExpr->nHeight; |
| 74648 | 75262 | #endif |
| 74649 | 75263 | if( pNC->nErr>0 || w.pParse->nErr>0 ){ |
| 74650 | 75264 | ExprSetProperty(pExpr, EP_Error); |
| 74651 | 75265 | } |
| 74652 | | - if( pNC->hasAgg ){ |
| 75266 | + if( pNC->ncFlags & NC_HasAgg ){ |
| 74653 | 75267 | ExprSetProperty(pExpr, EP_Agg); |
| 74654 | 75268 | }else if( savedHasAgg ){ |
| 74655 | | - pNC->hasAgg = 1; |
| 75269 | + pNC->ncFlags |= NC_HasAgg; |
| 74656 | 75270 | } |
| 74657 | 75271 | return ExprHasProperty(pExpr, EP_Error); |
| 74658 | 75272 | } |
| 74659 | 75273 | |
| 74660 | 75274 | |
| | @@ -78464,11 +79078,11 @@ |
| 78464 | 79078 | if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; |
| 78465 | 79079 | if( ExprHasProperty(pA, EP_IntValue) ){ |
| 78466 | 79080 | if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ |
| 78467 | 79081 | return 2; |
| 78468 | 79082 | } |
| 78469 | | - }else if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ |
| 79083 | + }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){ |
| 78470 | 79084 | if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; |
| 78471 | 79085 | if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ |
| 78472 | 79086 | return 2; |
| 78473 | 79087 | } |
| 78474 | 79088 | } |
| | @@ -78651,11 +79265,13 @@ |
| 78651 | 79265 | } /* end loop over pSrcList */ |
| 78652 | 79266 | } |
| 78653 | 79267 | return WRC_Prune; |
| 78654 | 79268 | } |
| 78655 | 79269 | case TK_AGG_FUNCTION: { |
| 78656 | | - if( !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) ){ |
| 79270 | + if( (pNC->ncFlags & NC_InAggFunc)==0 |
| 79271 | + && !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) |
| 79272 | + ){ |
| 78657 | 79273 | /* Check to see if pExpr is a duplicate of another aggregate |
| 78658 | 79274 | ** function that is already in the pAggInfo structure |
| 78659 | 79275 | */ |
| 78660 | 79276 | struct AggInfo_func *pItem = pAggInfo->aFunc; |
| 78661 | 79277 | for(i=0; i<pAggInfo->nFunc; i++, pItem++){ |
| | @@ -78688,12 +79304,12 @@ |
| 78688 | 79304 | */ |
| 78689 | 79305 | assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 78690 | 79306 | ExprSetIrreducible(pExpr); |
| 78691 | 79307 | pExpr->iAgg = (i16)i; |
| 78692 | 79308 | pExpr->pAggInfo = pAggInfo; |
| 78693 | | - return WRC_Prune; |
| 78694 | 79309 | } |
| 79310 | + return WRC_Prune; |
| 78695 | 79311 | } |
| 78696 | 79312 | } |
| 78697 | 79313 | return WRC_Continue; |
| 78698 | 79314 | } |
| 78699 | 79315 | static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ |
| | @@ -80973,11 +81589,11 @@ |
| 80973 | 81589 | if( db->aDb[iDb].pBt ){ |
| 80974 | 81590 | sqlite3BtreeClose(db->aDb[iDb].pBt); |
| 80975 | 81591 | db->aDb[iDb].pBt = 0; |
| 80976 | 81592 | db->aDb[iDb].pSchema = 0; |
| 80977 | 81593 | } |
| 80978 | | - sqlite3ResetInternalSchema(db, -1); |
| 81594 | + sqlite3ResetAllSchemasOfConnection(db); |
| 80979 | 81595 | db->nDb = iDb; |
| 80980 | 81596 | if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ |
| 80981 | 81597 | db->mallocFailed = 1; |
| 80982 | 81598 | sqlite3DbFree(db, zErrDyn); |
| 80983 | 81599 | zErrDyn = sqlite3MPrintf(db, "out of memory"); |
| | @@ -81045,11 +81661,11 @@ |
| 81045 | 81661 | } |
| 81046 | 81662 | |
| 81047 | 81663 | sqlite3BtreeClose(pDb->pBt); |
| 81048 | 81664 | pDb->pBt = 0; |
| 81049 | 81665 | pDb->pSchema = 0; |
| 81050 | | - sqlite3ResetInternalSchema(db, -1); |
| 81666 | + sqlite3ResetAllSchemasOfConnection(db); |
| 81051 | 81667 | return; |
| 81052 | 81668 | |
| 81053 | 81669 | detach_error: |
| 81054 | 81670 | sqlite3_result_error(context, zErr, -1); |
| 81055 | 81671 | } |
| | @@ -81961,62 +82577,19 @@ |
| 81961 | 82577 | } |
| 81962 | 82578 | db->flags |= SQLITE_InternChanges; |
| 81963 | 82579 | } |
| 81964 | 82580 | |
| 81965 | 82581 | /* |
| 81966 | | -** Erase all schema information from the in-memory hash tables of |
| 81967 | | -** a single database. This routine is called to reclaim memory |
| 81968 | | -** before the database closes. It is also called during a rollback |
| 81969 | | -** if there were schema changes during the transaction or if a |
| 81970 | | -** schema-cookie mismatch occurs. |
| 82582 | +** Look through the list of open database files in db->aDb[] and if |
| 82583 | +** any have been closed, remove them from the list. Reallocate the |
| 82584 | +** db->aDb[] structure to a smaller size, if possible. |
| 81971 | 82585 | ** |
| 81972 | | -** If iDb<0 then reset the internal schema tables for all database |
| 81973 | | -** files. If iDb>=0 then reset the internal schema for only the |
| 81974 | | -** single file indicated. |
| 81975 | | -*/ |
| 81976 | | -SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ |
| 81977 | | - int i, j; |
| 81978 | | - assert( iDb<db->nDb ); |
| 81979 | | - |
| 81980 | | - if( iDb>=0 ){ |
| 81981 | | - /* Case 1: Reset the single schema identified by iDb */ |
| 81982 | | - Db *pDb = &db->aDb[iDb]; |
| 81983 | | - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81984 | | - assert( pDb->pSchema!=0 ); |
| 81985 | | - sqlite3SchemaClear(pDb->pSchema); |
| 81986 | | - |
| 81987 | | - /* If any database other than TEMP is reset, then also reset TEMP |
| 81988 | | - ** since TEMP might be holding triggers that reference tables in the |
| 81989 | | - ** other database. |
| 81990 | | - */ |
| 81991 | | - if( iDb!=1 ){ |
| 81992 | | - pDb = &db->aDb[1]; |
| 81993 | | - assert( pDb->pSchema!=0 ); |
| 81994 | | - sqlite3SchemaClear(pDb->pSchema); |
| 81995 | | - } |
| 81996 | | - return; |
| 81997 | | - } |
| 81998 | | - /* Case 2 (from here to the end): Reset all schemas for all attached |
| 81999 | | - ** databases. */ |
| 82000 | | - assert( iDb<0 ); |
| 82001 | | - sqlite3BtreeEnterAll(db); |
| 82002 | | - for(i=0; i<db->nDb; i++){ |
| 82003 | | - Db *pDb = &db->aDb[i]; |
| 82004 | | - if( pDb->pSchema ){ |
| 82005 | | - sqlite3SchemaClear(pDb->pSchema); |
| 82006 | | - } |
| 82007 | | - } |
| 82008 | | - db->flags &= ~SQLITE_InternChanges; |
| 82009 | | - sqlite3VtabUnlockList(db); |
| 82010 | | - sqlite3BtreeLeaveAll(db); |
| 82011 | | - |
| 82012 | | - /* If one or more of the auxiliary database files has been closed, |
| 82013 | | - ** then remove them from the auxiliary database list. We take the |
| 82014 | | - ** opportunity to do this here since we have just deleted all of the |
| 82015 | | - ** schema hash tables and therefore do not have to make any changes |
| 82016 | | - ** to any of those tables. |
| 82017 | | - */ |
| 82586 | +** Entry 0 (the "main" database) and entry 1 (the "temp" database) |
| 82587 | +** are never candidates for being collapsed. |
| 82588 | +*/ |
| 82589 | +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ |
| 82590 | + int i, j; |
| 82018 | 82591 | for(i=j=2; i<db->nDb; i++){ |
| 82019 | 82592 | struct Db *pDb = &db->aDb[i]; |
| 82020 | 82593 | if( pDb->pBt==0 ){ |
| 82021 | 82594 | sqlite3DbFree(db, pDb->zName); |
| 82022 | 82595 | pDb->zName = 0; |
| | @@ -82033,10 +82606,55 @@ |
| 82033 | 82606 | memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); |
| 82034 | 82607 | sqlite3DbFree(db, db->aDb); |
| 82035 | 82608 | db->aDb = db->aDbStatic; |
| 82036 | 82609 | } |
| 82037 | 82610 | } |
| 82611 | + |
| 82612 | +/* |
| 82613 | +** Reset the schema for the database at index iDb. Also reset the |
| 82614 | +** TEMP schema. |
| 82615 | +*/ |
| 82616 | +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ |
| 82617 | + Db *pDb; |
| 82618 | + assert( iDb<db->nDb ); |
| 82619 | + |
| 82620 | + /* Case 1: Reset the single schema identified by iDb */ |
| 82621 | + pDb = &db->aDb[iDb]; |
| 82622 | + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 82623 | + assert( pDb->pSchema!=0 ); |
| 82624 | + sqlite3SchemaClear(pDb->pSchema); |
| 82625 | + |
| 82626 | + /* If any database other than TEMP is reset, then also reset TEMP |
| 82627 | + ** since TEMP might be holding triggers that reference tables in the |
| 82628 | + ** other database. |
| 82629 | + */ |
| 82630 | + if( iDb!=1 ){ |
| 82631 | + pDb = &db->aDb[1]; |
| 82632 | + assert( pDb->pSchema!=0 ); |
| 82633 | + sqlite3SchemaClear(pDb->pSchema); |
| 82634 | + } |
| 82635 | + return; |
| 82636 | +} |
| 82637 | + |
| 82638 | +/* |
| 82639 | +** Erase all schema information from all attached databases (including |
| 82640 | +** "main" and "temp") for a single database connection. |
| 82641 | +*/ |
| 82642 | +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ |
| 82643 | + int i; |
| 82644 | + sqlite3BtreeEnterAll(db); |
| 82645 | + for(i=0; i<db->nDb; i++){ |
| 82646 | + Db *pDb = &db->aDb[i]; |
| 82647 | + if( pDb->pSchema ){ |
| 82648 | + sqlite3SchemaClear(pDb->pSchema); |
| 82649 | + } |
| 82650 | + } |
| 82651 | + db->flags &= ~SQLITE_InternChanges; |
| 82652 | + sqlite3VtabUnlockList(db); |
| 82653 | + sqlite3BtreeLeaveAll(db); |
| 82654 | + sqlite3CollapseDatabaseArray(db); |
| 82655 | +} |
| 82038 | 82656 | |
| 82039 | 82657 | /* |
| 82040 | 82658 | ** This routine is called when a commit occurs. |
| 82041 | 82659 | */ |
| 82042 | 82660 | SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ |
| | @@ -82069,19 +82687,32 @@ |
| 82069 | 82687 | ** |
| 82070 | 82688 | ** This routine just deletes the data structure. It does not unlink |
| 82071 | 82689 | ** the table data structure from the hash table. But it does destroy |
| 82072 | 82690 | ** memory structures of the indices and foreign keys associated with |
| 82073 | 82691 | ** the table. |
| 82692 | +** |
| 82693 | +** The db parameter is optional. It is needed if the Table object |
| 82694 | +** contains lookaside memory. (Table objects in the schema do not use |
| 82695 | +** lookaside memory, but some ephemeral Table objects do.) Or the |
| 82696 | +** db parameter can be used with db->pnBytesFreed to measure the memory |
| 82697 | +** used by the Table object. |
| 82074 | 82698 | */ |
| 82075 | 82699 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ |
| 82076 | 82700 | Index *pIndex, *pNext; |
| 82701 | + TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ |
| 82077 | 82702 | |
| 82078 | 82703 | assert( !pTable || pTable->nRef>0 ); |
| 82079 | 82704 | |
| 82080 | 82705 | /* Do not delete the table until the reference count reaches zero. */ |
| 82081 | 82706 | if( !pTable ) return; |
| 82082 | 82707 | if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; |
| 82708 | + |
| 82709 | + /* Record the number of outstanding lookaside allocations in schema Tables |
| 82710 | + ** prior to doing any free() operations. Since schema Tables do not use |
| 82711 | + ** lookaside, this number should not change. */ |
| 82712 | + TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? |
| 82713 | + db->lookaside.nOut : 0 ); |
| 82083 | 82714 | |
| 82084 | 82715 | /* Delete all indices associated with this table. */ |
| 82085 | 82716 | for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ |
| 82086 | 82717 | pNext = pIndex->pNext; |
| 82087 | 82718 | assert( pIndex->pSchema==pTable->pSchema ); |
| | @@ -82110,10 +82741,13 @@ |
| 82110 | 82741 | #endif |
| 82111 | 82742 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 82112 | 82743 | sqlite3VtabClear(db, pTable); |
| 82113 | 82744 | #endif |
| 82114 | 82745 | sqlite3DbFree(db, pTable); |
| 82746 | + |
| 82747 | + /* Verify that no lookaside memory was used by schema tables */ |
| 82748 | + assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); |
| 82115 | 82749 | } |
| 82116 | 82750 | |
| 82117 | 82751 | /* |
| 82118 | 82752 | ** Unlink the given table from the hash tables and the delete the |
| 82119 | 82753 | ** table structure with all its indices and foreign keys. |
| | @@ -83058,11 +83692,11 @@ |
| 83058 | 83692 | sSrc.a[0].zName = p->zName; |
| 83059 | 83693 | sSrc.a[0].pTab = p; |
| 83060 | 83694 | sSrc.a[0].iCursor = -1; |
| 83061 | 83695 | sNC.pParse = pParse; |
| 83062 | 83696 | sNC.pSrcList = &sSrc; |
| 83063 | | - sNC.isCheck = 1; |
| 83697 | + sNC.ncFlags = NC_IsCheck; |
| 83064 | 83698 | pList = p->pCheck; |
| 83065 | 83699 | for(i=0; i<pList->nExpr; i++){ |
| 83066 | 83700 | if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ |
| 83067 | 83701 | return; |
| 83068 | 83702 | } |
| | @@ -84314,11 +84948,11 @@ |
| 84314 | 84948 | zExtra += nColl; |
| 84315 | 84949 | nExtra -= nColl; |
| 84316 | 84950 | }else{ |
| 84317 | 84951 | zColl = pTab->aCol[j].zColl; |
| 84318 | 84952 | if( !zColl ){ |
| 84319 | | - zColl = db->pDfltColl->zName; |
| 84953 | + zColl = "BINARY"; |
| 84320 | 84954 | } |
| 84321 | 84955 | } |
| 84322 | 84956 | if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ |
| 84323 | 84957 | goto exit_create_index; |
| 84324 | 84958 | } |
| | @@ -92589,11 +93223,11 @@ |
| 92589 | 93223 | "from within a transaction"); |
| 92590 | 93224 | return SQLITE_ERROR; |
| 92591 | 93225 | } |
| 92592 | 93226 | sqlite3BtreeClose(db->aDb[1].pBt); |
| 92593 | 93227 | db->aDb[1].pBt = 0; |
| 92594 | | - sqlite3ResetInternalSchema(db, -1); |
| 93228 | + sqlite3ResetAllSchemasOfConnection(db); |
| 92595 | 93229 | } |
| 92596 | 93230 | return SQLITE_OK; |
| 92597 | 93231 | } |
| 92598 | 93232 | #endif /* SQLITE_PAGER_PRAGMAS */ |
| 92599 | 93233 | |
| | @@ -93274,10 +93908,54 @@ |
| 93274 | 93908 | sqlite3_temp_directory = 0; |
| 93275 | 93909 | } |
| 93276 | 93910 | #endif /* SQLITE_OMIT_WSD */ |
| 93277 | 93911 | } |
| 93278 | 93912 | }else |
| 93913 | + |
| 93914 | +#if SQLITE_OS_WIN |
| 93915 | + /* |
| 93916 | + ** PRAGMA data_store_directory |
| 93917 | + ** PRAGMA data_store_directory = ""|"directory_name" |
| 93918 | + ** |
| 93919 | + ** Return or set the local value of the data_store_directory flag. Changing |
| 93920 | + ** the value sets a specific directory to be used for database files that |
| 93921 | + ** were specified with a relative pathname. Setting to a null string reverts |
| 93922 | + ** to the default database directory, which for database files specified with |
| 93923 | + ** a relative path will probably be based on the current directory for the |
| 93924 | + ** process. Database file specified with an absolute path are not impacted |
| 93925 | + ** by this setting, regardless of its value. |
| 93926 | + ** |
| 93927 | + */ |
| 93928 | + if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){ |
| 93929 | + if( !zRight ){ |
| 93930 | + if( sqlite3_data_directory ){ |
| 93931 | + sqlite3VdbeSetNumCols(v, 1); |
| 93932 | + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, |
| 93933 | + "data_store_directory", SQLITE_STATIC); |
| 93934 | + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0); |
| 93935 | + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 93936 | + } |
| 93937 | + }else{ |
| 93938 | +#ifndef SQLITE_OMIT_WSD |
| 93939 | + if( zRight[0] ){ |
| 93940 | + int res; |
| 93941 | + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); |
| 93942 | + if( rc!=SQLITE_OK || res==0 ){ |
| 93943 | + sqlite3ErrorMsg(pParse, "not a writable directory"); |
| 93944 | + goto pragma_out; |
| 93945 | + } |
| 93946 | + } |
| 93947 | + sqlite3_free(sqlite3_data_directory); |
| 93948 | + if( zRight[0] ){ |
| 93949 | + sqlite3_data_directory = sqlite3_mprintf("%s", zRight); |
| 93950 | + }else{ |
| 93951 | + sqlite3_data_directory = 0; |
| 93952 | + } |
| 93953 | +#endif /* SQLITE_OMIT_WSD */ |
| 93954 | + } |
| 93955 | + }else |
| 93956 | +#endif |
| 93279 | 93957 | |
| 93280 | 93958 | #if !defined(SQLITE_ENABLE_LOCKING_STYLE) |
| 93281 | 93959 | # if defined(__APPLE__) |
| 93282 | 93960 | # define SQLITE_ENABLE_LOCKING_STYLE 1 |
| 93283 | 93961 | # else |
| | @@ -94307,11 +94985,10 @@ |
| 94307 | 94985 | u8 encoding; |
| 94308 | 94986 | /* If opening the main database, set ENC(db). */ |
| 94309 | 94987 | encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; |
| 94310 | 94988 | if( encoding==0 ) encoding = SQLITE_UTF8; |
| 94311 | 94989 | ENC(db) = encoding; |
| 94312 | | - db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); |
| 94313 | 94990 | }else{ |
| 94314 | 94991 | /* If opening an attached database, the encoding much match ENC(db) */ |
| 94315 | 94992 | if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ |
| 94316 | 94993 | sqlite3SetString(pzErrMsg, db, "attached databases must use the same" |
| 94317 | 94994 | " text encoding as main database"); |
| | @@ -94387,11 +95064,11 @@ |
| 94387 | 95064 | } |
| 94388 | 95065 | #endif |
| 94389 | 95066 | } |
| 94390 | 95067 | if( db->mallocFailed ){ |
| 94391 | 95068 | rc = SQLITE_NOMEM; |
| 94392 | | - sqlite3ResetInternalSchema(db, -1); |
| 95069 | + sqlite3ResetAllSchemasOfConnection(db); |
| 94393 | 95070 | } |
| 94394 | 95071 | if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ |
| 94395 | 95072 | /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider |
| 94396 | 95073 | ** the schema loaded, even if errors occurred. In this situation the |
| 94397 | 95074 | ** current sqlite3_prepare() operation will fail, but the following one |
| | @@ -94440,11 +95117,11 @@ |
| 94440 | 95117 | db->init.busy = 1; |
| 94441 | 95118 | for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ |
| 94442 | 95119 | if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; |
| 94443 | 95120 | rc = sqlite3InitOne(db, i, pzErrMsg); |
| 94444 | 95121 | if( rc ){ |
| 94445 | | - sqlite3ResetInternalSchema(db, i); |
| 95122 | + sqlite3ResetOneSchema(db, i); |
| 94446 | 95123 | } |
| 94447 | 95124 | } |
| 94448 | 95125 | |
| 94449 | 95126 | /* Once all the other databases have been initialised, load the schema |
| 94450 | 95127 | ** for the TEMP database. This is loaded last, as the TEMP database |
| | @@ -94453,11 +95130,11 @@ |
| 94453 | 95130 | #ifndef SQLITE_OMIT_TEMPDB |
| 94454 | 95131 | if( rc==SQLITE_OK && ALWAYS(db->nDb>1) |
| 94455 | 95132 | && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ |
| 94456 | 95133 | rc = sqlite3InitOne(db, 1, pzErrMsg); |
| 94457 | 95134 | if( rc ){ |
| 94458 | | - sqlite3ResetInternalSchema(db, 1); |
| 95135 | + sqlite3ResetOneSchema(db, 1); |
| 94459 | 95136 | } |
| 94460 | 95137 | } |
| 94461 | 95138 | #endif |
| 94462 | 95139 | |
| 94463 | 95140 | db->init.busy = 0; |
| | @@ -94521,11 +95198,11 @@ |
| 94521 | 95198 | ** value stored as part of the in-memory schema representation, |
| 94522 | 95199 | ** set Parse.rc to SQLITE_SCHEMA. */ |
| 94523 | 95200 | sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); |
| 94524 | 95201 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 94525 | 95202 | if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ |
| 94526 | | - sqlite3ResetInternalSchema(db, iDb); |
| 95203 | + sqlite3ResetOneSchema(db, iDb); |
| 94527 | 95204 | pParse->rc = SQLITE_SCHEMA; |
| 94528 | 95205 | } |
| 94529 | 95206 | |
| 94530 | 95207 | /* Close the transaction, if one was opened. */ |
| 94531 | 95208 | if( openedTransaction ){ |
| | @@ -94751,10 +95428,11 @@ |
| 94751 | 95428 | sqlite3_finalize(*ppStmt); |
| 94752 | 95429 | rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); |
| 94753 | 95430 | } |
| 94754 | 95431 | sqlite3BtreeLeaveAll(db); |
| 94755 | 95432 | sqlite3_mutex_leave(db->mutex); |
| 95433 | + assert( rc==SQLITE_OK || *ppStmt==0 ); |
| 94756 | 95434 | return rc; |
| 94757 | 95435 | } |
| 94758 | 95436 | |
| 94759 | 95437 | /* |
| 94760 | 95438 | ** Rerun the compilation of a statement after a schema change. |
| | @@ -98058,10 +98736,11 @@ |
| 98058 | 98736 | pExpr = p->pEList->a[0].pExpr; |
| 98059 | 98737 | assert( pTab && !pTab->pSelect && pExpr ); |
| 98060 | 98738 | |
| 98061 | 98739 | if( IsVirtual(pTab) ) return 0; |
| 98062 | 98740 | if( pExpr->op!=TK_AGG_FUNCTION ) return 0; |
| 98741 | + if( pAggInfo->nFunc==0 ) return 0; |
| 98063 | 98742 | if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; |
| 98064 | 98743 | if( pExpr->flags&EP_Distinct ) return 0; |
| 98065 | 98744 | |
| 98066 | 98745 | return pTab; |
| 98067 | 98746 | } |
| | @@ -99048,11 +99727,13 @@ |
| 99048 | 99727 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); |
| 99049 | 99728 | } |
| 99050 | 99729 | sAggInfo.nAccumulator = sAggInfo.nColumn; |
| 99051 | 99730 | for(i=0; i<sAggInfo.nFunc; i++){ |
| 99052 | 99731 | assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) ); |
| 99732 | + sNC.ncFlags |= NC_InAggFunc; |
| 99053 | 99733 | sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList); |
| 99734 | + sNC.ncFlags &= ~NC_InAggFunc; |
| 99054 | 99735 | } |
| 99055 | 99736 | if( db->mallocFailed ) goto select_end; |
| 99056 | 99737 | |
| 99057 | 99738 | /* Processing for aggregates with GROUP BY is very different and |
| 99058 | 99739 | ** much more complex than aggregates without a GROUP BY. |
| | @@ -101870,11 +102551,11 @@ |
| 101870 | 102551 | pDb->pSchema = 0; |
| 101871 | 102552 | } |
| 101872 | 102553 | |
| 101873 | 102554 | /* This both clears the schemas and reduces the size of the db->aDb[] |
| 101874 | 102555 | ** array. */ |
| 101875 | | - sqlite3ResetInternalSchema(db, -1); |
| 102556 | + sqlite3ResetAllSchemasOfConnection(db); |
| 101876 | 102557 | |
| 101877 | 102558 | return rc; |
| 101878 | 102559 | } |
| 101879 | 102560 | |
| 101880 | 102561 | #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ |
| | @@ -101902,12 +102583,12 @@ |
| 101902 | 102583 | ** this struct allocated on the stack. It is used by the implementation of |
| 101903 | 102584 | ** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which |
| 101904 | 102585 | ** are invoked only from within xCreate and xConnect methods. |
| 101905 | 102586 | */ |
| 101906 | 102587 | struct VtabCtx { |
| 101907 | | - Table *pTab; |
| 101908 | | - VTable *pVTable; |
| 102588 | + VTable *pVTable; /* The virtual table being constructed */ |
| 102589 | + Table *pTab; /* The Table object to which the virtual table belongs */ |
| 101909 | 102590 | }; |
| 101910 | 102591 | |
| 101911 | 102592 | /* |
| 101912 | 102593 | ** The actual function that does the work of creating a new module. |
| 101913 | 102594 | ** This function implements the sqlite3_create_module() and |
| | @@ -101918,37 +102599,39 @@ |
| 101918 | 102599 | const char *zName, /* Name assigned to this module */ |
| 101919 | 102600 | const sqlite3_module *pModule, /* The definition of the module */ |
| 101920 | 102601 | void *pAux, /* Context pointer for xCreate/xConnect */ |
| 101921 | 102602 | void (*xDestroy)(void *) /* Module destructor function */ |
| 101922 | 102603 | ){ |
| 101923 | | - int rc, nName; |
| 101924 | | - Module *pMod; |
| 102604 | + int rc = SQLITE_OK; |
| 102605 | + int nName; |
| 101925 | 102606 | |
| 101926 | 102607 | sqlite3_mutex_enter(db->mutex); |
| 101927 | 102608 | nName = sqlite3Strlen30(zName); |
| 101928 | | - pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); |
| 101929 | | - if( pMod ){ |
| 101930 | | - Module *pDel; |
| 101931 | | - char *zCopy = (char *)(&pMod[1]); |
| 101932 | | - memcpy(zCopy, zName, nName+1); |
| 101933 | | - pMod->zName = zCopy; |
| 101934 | | - pMod->pModule = pModule; |
| 101935 | | - pMod->pAux = pAux; |
| 101936 | | - pMod->xDestroy = xDestroy; |
| 101937 | | - pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); |
| 101938 | | - if( pDel && pDel->xDestroy ){ |
| 101939 | | - sqlite3ResetInternalSchema(db, -1); |
| 101940 | | - pDel->xDestroy(pDel->pAux); |
| 101941 | | - } |
| 101942 | | - sqlite3DbFree(db, pDel); |
| 101943 | | - if( pDel==pMod ){ |
| 101944 | | - db->mallocFailed = 1; |
| 101945 | | - } |
| 101946 | | - }else if( xDestroy ){ |
| 101947 | | - xDestroy(pAux); |
| 101948 | | - } |
| 101949 | | - rc = sqlite3ApiExit(db, SQLITE_OK); |
| 102609 | + if( sqlite3HashFind(&db->aModule, zName, nName) ){ |
| 102610 | + rc = SQLITE_MISUSE_BKPT; |
| 102611 | + }else{ |
| 102612 | + Module *pMod; |
| 102613 | + pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); |
| 102614 | + if( pMod ){ |
| 102615 | + Module *pDel; |
| 102616 | + char *zCopy = (char *)(&pMod[1]); |
| 102617 | + memcpy(zCopy, zName, nName+1); |
| 102618 | + pMod->zName = zCopy; |
| 102619 | + pMod->pModule = pModule; |
| 102620 | + pMod->pAux = pAux; |
| 102621 | + pMod->xDestroy = xDestroy; |
| 102622 | + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod); |
| 102623 | + assert( pDel==0 || pDel==pMod ); |
| 102624 | + if( pDel ){ |
| 102625 | + db->mallocFailed = 1; |
| 102626 | + sqlite3DbFree(db, pDel); |
| 102627 | + } |
| 102628 | + } |
| 102629 | + } |
| 102630 | + rc = sqlite3ApiExit(db, rc); |
| 102631 | + if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); |
| 102632 | + |
| 101950 | 102633 | sqlite3_mutex_leave(db->mutex); |
| 101951 | 102634 | return rc; |
| 101952 | 102635 | } |
| 101953 | 102636 | |
| 101954 | 102637 | |
| | @@ -102059,10 +102742,35 @@ |
| 102059 | 102742 | } |
| 102060 | 102743 | |
| 102061 | 102744 | assert( !db || pRet ); |
| 102062 | 102745 | return pRet; |
| 102063 | 102746 | } |
| 102747 | + |
| 102748 | +/* |
| 102749 | +** Table *p is a virtual table. This function removes the VTable object |
| 102750 | +** for table *p associated with database connection db from the linked |
| 102751 | +** list in p->pVTab. It also decrements the VTable ref count. This is |
| 102752 | +** used when closing database connection db to free all of its VTable |
| 102753 | +** objects without disturbing the rest of the Schema object (which may |
| 102754 | +** be being used by other shared-cache connections). |
| 102755 | +*/ |
| 102756 | +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ |
| 102757 | + VTable **ppVTab; |
| 102758 | + |
| 102759 | + assert( IsVirtual(p) ); |
| 102760 | + assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 102761 | + assert( sqlite3_mutex_held(db->mutex) ); |
| 102762 | + |
| 102763 | + for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ |
| 102764 | + if( (*ppVTab)->db==db ){ |
| 102765 | + VTable *pVTab = *ppVTab; |
| 102766 | + *ppVTab = pVTab->pNext; |
| 102767 | + sqlite3VtabUnlock(pVTab); |
| 102768 | + break; |
| 102769 | + } |
| 102770 | + } |
| 102771 | +} |
| 102064 | 102772 | |
| 102065 | 102773 | |
| 102066 | 102774 | /* |
| 102067 | 102775 | ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. |
| 102068 | 102776 | ** |
| | @@ -112949,10 +113657,19 @@ |
| 112949 | 113657 | ** |
| 112950 | 113658 | ** See also the "PRAGMA temp_store_directory" SQL command. |
| 112951 | 113659 | */ |
| 112952 | 113660 | SQLITE_API char *sqlite3_temp_directory = 0; |
| 112953 | 113661 | |
| 113662 | +/* |
| 113663 | +** If the following global variable points to a string which is the |
| 113664 | +** name of a directory, then that directory will be used to store |
| 113665 | +** all database files specified with a relative pathname. |
| 113666 | +** |
| 113667 | +** See also the "PRAGMA data_store_directory" SQL command. |
| 113668 | +*/ |
| 113669 | +SQLITE_API char *sqlite3_data_directory = 0; |
| 113670 | + |
| 112954 | 113671 | /* |
| 112955 | 113672 | ** Initialize SQLite. |
| 112956 | 113673 | ** |
| 112957 | 113674 | ** This routine must be called to initialize the memory allocation, |
| 112958 | 113675 | ** VFS, and mutex subsystems prior to doing any serious work with |
| | @@ -113147,10 +113864,22 @@ |
| 113147 | 113864 | sqlite3GlobalConfig.isPCacheInit = 0; |
| 113148 | 113865 | } |
| 113149 | 113866 | if( sqlite3GlobalConfig.isMallocInit ){ |
| 113150 | 113867 | sqlite3MallocEnd(); |
| 113151 | 113868 | sqlite3GlobalConfig.isMallocInit = 0; |
| 113869 | + |
| 113870 | +#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES |
| 113871 | + /* The heap subsystem has now been shutdown and these values are supposed |
| 113872 | + ** to be NULL or point to memory that was obtained from sqlite3_malloc(), |
| 113873 | + ** which would rely on that heap subsystem; therefore, make sure these |
| 113874 | + ** values cannot refer to heap memory that was just invalidated when the |
| 113875 | + ** heap subsystem was shutdown. This is only done if the current call to |
| 113876 | + ** this function resulted in the heap subsystem actually being shutdown. |
| 113877 | + */ |
| 113878 | + sqlite3_data_directory = 0; |
| 113879 | + sqlite3_temp_directory = 0; |
| 113880 | +#endif |
| 113152 | 113881 | } |
| 113153 | 113882 | if( sqlite3GlobalConfig.isMutexInit ){ |
| 113154 | 113883 | sqlite3MutexEnd(); |
| 113155 | 113884 | sqlite3GlobalConfig.isMutexInit = 0; |
| 113156 | 113885 | } |
| | @@ -113594,10 +114323,34 @@ |
| 113594 | 114323 | pDestructor->xDestroy(pDestructor->pUserData); |
| 113595 | 114324 | sqlite3DbFree(db, pDestructor); |
| 113596 | 114325 | } |
| 113597 | 114326 | } |
| 113598 | 114327 | } |
| 114328 | + |
| 114329 | +/* |
| 114330 | +** Disconnect all sqlite3_vtab objects that belong to database connection |
| 114331 | +** db. This is called when db is being closed. |
| 114332 | +*/ |
| 114333 | +static void disconnectAllVtab(sqlite3 *db){ |
| 114334 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 114335 | + int i; |
| 114336 | + sqlite3BtreeEnterAll(db); |
| 114337 | + for(i=0; i<db->nDb; i++){ |
| 114338 | + Schema *pSchema = db->aDb[i].pSchema; |
| 114339 | + if( db->aDb[i].pSchema ){ |
| 114340 | + HashElem *p; |
| 114341 | + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ |
| 114342 | + Table *pTab = (Table *)sqliteHashData(p); |
| 114343 | + if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); |
| 114344 | + } |
| 114345 | + } |
| 114346 | + } |
| 114347 | + sqlite3BtreeLeaveAll(db); |
| 114348 | +#else |
| 114349 | + UNUSED_PARAMETER(db); |
| 114350 | +#endif |
| 114351 | +} |
| 113599 | 114352 | |
| 113600 | 114353 | /* |
| 113601 | 114354 | ** Close an existing SQLite database |
| 113602 | 114355 | */ |
| 113603 | 114356 | SQLITE_API int sqlite3_close(sqlite3 *db){ |
| | @@ -113610,14 +114363,14 @@ |
| 113610 | 114363 | if( !sqlite3SafetyCheckSickOrOk(db) ){ |
| 113611 | 114364 | return SQLITE_MISUSE_BKPT; |
| 113612 | 114365 | } |
| 113613 | 114366 | sqlite3_mutex_enter(db->mutex); |
| 113614 | 114367 | |
| 113615 | | - /* Force xDestroy calls on all virtual tables */ |
| 113616 | | - sqlite3ResetInternalSchema(db, -1); |
| 114368 | + /* Force xDisconnect calls on all virtual tables */ |
| 114369 | + disconnectAllVtab(db); |
| 113617 | 114370 | |
| 113618 | | - /* If a transaction is open, the ResetInternalSchema() call above |
| 114371 | + /* If a transaction is open, the disconnectAllVtab() call above |
| 113619 | 114372 | ** will not have called the xDisconnect() method on any virtual |
| 113620 | 114373 | ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() |
| 113621 | 114374 | ** call will do so. We need to do this before the check for active |
| 113622 | 114375 | ** SQL statements below, as the v-table implementation may be storing |
| 113623 | 114376 | ** some prepared statements internally. |
| | @@ -113644,10 +114397,11 @@ |
| 113644 | 114397 | } |
| 113645 | 114398 | |
| 113646 | 114399 | /* Free any outstanding Savepoint structures. */ |
| 113647 | 114400 | sqlite3CloseSavepoints(db); |
| 113648 | 114401 | |
| 114402 | + /* Close all database connections */ |
| 113649 | 114403 | for(j=0; j<db->nDb; j++){ |
| 113650 | 114404 | struct Db *pDb = &db->aDb[j]; |
| 113651 | 114405 | if( pDb->pBt ){ |
| 113652 | 114406 | sqlite3BtreeClose(pDb->pBt); |
| 113653 | 114407 | pDb->pBt = 0; |
| | @@ -113654,19 +114408,26 @@ |
| 113654 | 114408 | if( j!=1 ){ |
| 113655 | 114409 | pDb->pSchema = 0; |
| 113656 | 114410 | } |
| 113657 | 114411 | } |
| 113658 | 114412 | } |
| 113659 | | - sqlite3ResetInternalSchema(db, -1); |
| 114413 | + /* Clear the TEMP schema separately and last */ |
| 114414 | + if( db->aDb[1].pSchema ){ |
| 114415 | + sqlite3SchemaClear(db->aDb[1].pSchema); |
| 114416 | + } |
| 114417 | + sqlite3VtabUnlockList(db); |
| 114418 | + |
| 114419 | + /* Free up the array of auxiliary databases */ |
| 114420 | + sqlite3CollapseDatabaseArray(db); |
| 114421 | + assert( db->nDb<=2 ); |
| 114422 | + assert( db->aDb==db->aDbStatic ); |
| 113660 | 114423 | |
| 113661 | 114424 | /* Tell the code in notify.c that the connection no longer holds any |
| 113662 | 114425 | ** locks and does not require any further unlock-notify callbacks. |
| 113663 | 114426 | */ |
| 113664 | 114427 | sqlite3ConnectionClosed(db); |
| 113665 | 114428 | |
| 113666 | | - assert( db->nDb<=2 ); |
| 113667 | | - assert( db->aDb==db->aDbStatic ); |
| 113668 | 114429 | for(j=0; j<ArraySize(db->aFunc.a); j++){ |
| 113669 | 114430 | FuncDef *pNext, *pHash, *p; |
| 113670 | 114431 | for(p=db->aFunc.a[j]; p; p=pHash){ |
| 113671 | 114432 | pHash = p->pHash; |
| 113672 | 114433 | while( p ){ |
| | @@ -113749,11 +114510,11 @@ |
| 113749 | 114510 | sqlite3VtabRollback(db); |
| 113750 | 114511 | sqlite3EndBenignMalloc(); |
| 113751 | 114512 | |
| 113752 | 114513 | if( db->flags&SQLITE_InternChanges ){ |
| 113753 | 114514 | sqlite3ExpirePreparedStatements(db); |
| 113754 | | - sqlite3ResetInternalSchema(db, -1); |
| 114515 | + sqlite3ResetAllSchemasOfConnection(db); |
| 113755 | 114516 | } |
| 113756 | 114517 | |
| 113757 | 114518 | /* Any deferred constraint violations have now been resolved. */ |
| 113758 | 114519 | db->nDeferredCons = 0; |
| 113759 | 114520 | |
| | @@ -114887,14 +115648,18 @@ |
| 114887 | 115648 | if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ |
| 114888 | 115649 | static struct OpenMode aOpenMode[] = { |
| 114889 | 115650 | { "ro", SQLITE_OPEN_READONLY }, |
| 114890 | 115651 | { "rw", SQLITE_OPEN_READWRITE }, |
| 114891 | 115652 | { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, |
| 115653 | + { "memory", |
| 115654 | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
| 115655 | + | SQLITE_OPEN_MEMORY }, |
| 114892 | 115656 | { 0, 0 } |
| 114893 | 115657 | }; |
| 114894 | 115658 | |
| 114895 | | - mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; |
| 115659 | + mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE |
| 115660 | + | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; |
| 114896 | 115661 | aMode = aOpenMode; |
| 114897 | 115662 | limit = mask & flags; |
| 114898 | 115663 | zModeType = "access"; |
| 114899 | 115664 | } |
| 114900 | 115665 | |
| | @@ -114911,11 +115676,11 @@ |
| 114911 | 115676 | if( mode==0 ){ |
| 114912 | 115677 | *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); |
| 114913 | 115678 | rc = SQLITE_ERROR; |
| 114914 | 115679 | goto parse_uri_out; |
| 114915 | 115680 | } |
| 114916 | | - if( mode>limit ){ |
| 115681 | + if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ |
| 114917 | 115682 | *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", |
| 114918 | 115683 | zModeType, zVal); |
| 114919 | 115684 | rc = SQLITE_PERM; |
| 114920 | 115685 | goto parse_uri_out; |
| 114921 | 115686 | } |
| | @@ -114930,10 +115695,11 @@ |
| 114930 | 115695 | zFile = sqlite3_malloc(nUri+2); |
| 114931 | 115696 | if( !zFile ) return SQLITE_NOMEM; |
| 114932 | 115697 | memcpy(zFile, zUri, nUri); |
| 114933 | 115698 | zFile[nUri] = '\0'; |
| 114934 | 115699 | zFile[nUri+1] = '\0'; |
| 115700 | + flags &= ~SQLITE_OPEN_URI; |
| 114935 | 115701 | } |
| 114936 | 115702 | |
| 114937 | 115703 | *ppVfs = sqlite3_vfs_find(zVfs); |
| 114938 | 115704 | if( *ppVfs==0 ){ |
| 114939 | 115705 | *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); |
| | @@ -117374,10 +118140,17 @@ |
| 117374 | 118140 | SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); |
| 117375 | 118141 | SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); |
| 117376 | 118142 | SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); |
| 117377 | 118143 | |
| 117378 | 118144 | SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); |
| 118145 | + |
| 118146 | +/* fts3_unicode2.c (functions generated by parsing unicode text files) */ |
| 118147 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 118148 | +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); |
| 118149 | +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); |
| 118150 | +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 118151 | +#endif |
| 117379 | 118152 | |
| 117380 | 118153 | #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ |
| 117381 | 118154 | #endif /* _FTSINT_H */ |
| 117382 | 118155 | |
| 117383 | 118156 | /************** End of fts3Int.h *********************************************/ |
| | @@ -120643,10 +121416,13 @@ |
| 120643 | 121416 | ** to by the argument to point to the "simple" tokenizer implementation. |
| 120644 | 121417 | ** And so on. |
| 120645 | 121418 | */ |
| 120646 | 121419 | SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 120647 | 121420 | SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 121421 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 121422 | +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); |
| 121423 | +#endif |
| 120648 | 121424 | #ifdef SQLITE_ENABLE_ICU |
| 120649 | 121425 | SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); |
| 120650 | 121426 | #endif |
| 120651 | 121427 | |
| 120652 | 121428 | /* |
| | @@ -120658,15 +121434,22 @@ |
| 120658 | 121434 | SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ |
| 120659 | 121435 | int rc = SQLITE_OK; |
| 120660 | 121436 | Fts3Hash *pHash = 0; |
| 120661 | 121437 | const sqlite3_tokenizer_module *pSimple = 0; |
| 120662 | 121438 | const sqlite3_tokenizer_module *pPorter = 0; |
| 121439 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 121440 | + const sqlite3_tokenizer_module *pUnicode = 0; |
| 121441 | +#endif |
| 120663 | 121442 | |
| 120664 | 121443 | #ifdef SQLITE_ENABLE_ICU |
| 120665 | 121444 | const sqlite3_tokenizer_module *pIcu = 0; |
| 120666 | 121445 | sqlite3Fts3IcuTokenizerModule(&pIcu); |
| 120667 | 121446 | #endif |
| 121447 | + |
| 121448 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 121449 | + sqlite3Fts3UnicodeTokenizer(&pUnicode); |
| 121450 | +#endif |
| 120668 | 121451 | |
| 120669 | 121452 | #ifdef SQLITE_TEST |
| 120670 | 121453 | rc = sqlite3Fts3InitTerm(db); |
| 120671 | 121454 | if( rc!=SQLITE_OK ) return rc; |
| 120672 | 121455 | #endif |
| | @@ -120687,10 +121470,14 @@ |
| 120687 | 121470 | |
| 120688 | 121471 | /* Load the built-in tokenizers into the hash table */ |
| 120689 | 121472 | if( rc==SQLITE_OK ){ |
| 120690 | 121473 | if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) |
| 120691 | 121474 | || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) |
| 121475 | + |
| 121476 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 121477 | + || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) |
| 121478 | +#endif |
| 120692 | 121479 | #ifdef SQLITE_ENABLE_ICU |
| 120693 | 121480 | || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) |
| 120694 | 121481 | #endif |
| 120695 | 121482 | ){ |
| 120696 | 121483 | rc = SQLITE_NOMEM; |
| | @@ -128839,11 +129626,16 @@ |
| 128839 | 129626 | sqlite3_column_blob(pStmt, 0), |
| 128840 | 129627 | sqlite3_column_bytes(pStmt, 0)); |
| 128841 | 129628 | }else{ |
| 128842 | 129629 | memset(a, 0, sizeof(u32)*(nStat) ); |
| 128843 | 129630 | } |
| 128844 | | - sqlite3_reset(pStmt); |
| 129631 | + rc = sqlite3_reset(pStmt); |
| 129632 | + if( rc!=SQLITE_OK ){ |
| 129633 | + sqlite3_free(a); |
| 129634 | + *pRC = rc; |
| 129635 | + return; |
| 129636 | + } |
| 128845 | 129637 | if( nChng<0 && a[0]<(u32)(-nChng) ){ |
| 128846 | 129638 | a[0] = 0; |
| 128847 | 129639 | }else{ |
| 128848 | 129640 | a[0] += nChng; |
| 128849 | 129641 | } |
| | @@ -132562,10 +133354,655 @@ |
| 132562 | 133354 | } |
| 132563 | 133355 | |
| 132564 | 133356 | #endif |
| 132565 | 133357 | |
| 132566 | 133358 | /************** End of fts3_snippet.c ****************************************/ |
| 133359 | +/************** Begin file fts3_unicode.c ************************************/ |
| 133360 | +/* |
| 133361 | +** 2012 May 24 |
| 133362 | +** |
| 133363 | +** The author disclaims copyright to this source code. In place of |
| 133364 | +** a legal notice, here is a blessing: |
| 133365 | +** |
| 133366 | +** May you do good and not evil. |
| 133367 | +** May you find forgiveness for yourself and forgive others. |
| 133368 | +** May you share freely, never taking more than you give. |
| 133369 | +** |
| 133370 | +****************************************************************************** |
| 133371 | +** |
| 133372 | +** Implementation of the "unicode" full-text-search tokenizer. |
| 133373 | +*/ |
| 133374 | + |
| 133375 | +#ifdef SQLITE_ENABLE_FTS4_UNICODE61 |
| 133376 | + |
| 133377 | +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
| 133378 | + |
| 133379 | +/* #include <assert.h> */ |
| 133380 | +/* #include <stdlib.h> */ |
| 133381 | +/* #include <stdio.h> */ |
| 133382 | +/* #include <string.h> */ |
| 133383 | + |
| 133384 | + |
| 133385 | +/* |
| 133386 | +** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied |
| 133387 | +** from the sqlite3 source file utf.c. If this file is compiled as part |
| 133388 | +** of the amalgamation, they are not required. |
| 133389 | +*/ |
| 133390 | +#ifndef SQLITE_AMALGAMATION |
| 133391 | + |
| 133392 | +static const unsigned char sqlite3Utf8Trans1[] = { |
| 133393 | + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 133394 | + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 133395 | + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
| 133396 | + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
| 133397 | + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 133398 | + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 133399 | + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 133400 | + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, |
| 133401 | +}; |
| 133402 | + |
| 133403 | +#define READ_UTF8(zIn, zTerm, c) \ |
| 133404 | + c = *(zIn++); \ |
| 133405 | + if( c>=0xc0 ){ \ |
| 133406 | + c = sqlite3Utf8Trans1[c-0xc0]; \ |
| 133407 | + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ |
| 133408 | + c = (c<<6) + (0x3f & *(zIn++)); \ |
| 133409 | + } \ |
| 133410 | + if( c<0x80 \ |
| 133411 | + || (c&0xFFFFF800)==0xD800 \ |
| 133412 | + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ |
| 133413 | + } |
| 133414 | + |
| 133415 | +#define WRITE_UTF8(zOut, c) { \ |
| 133416 | + if( c<0x00080 ){ \ |
| 133417 | + *zOut++ = (u8)(c&0xFF); \ |
| 133418 | + } \ |
| 133419 | + else if( c<0x00800 ){ \ |
| 133420 | + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ |
| 133421 | + *zOut++ = 0x80 + (u8)(c & 0x3F); \ |
| 133422 | + } \ |
| 133423 | + else if( c<0x10000 ){ \ |
| 133424 | + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ |
| 133425 | + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ |
| 133426 | + *zOut++ = 0x80 + (u8)(c & 0x3F); \ |
| 133427 | + }else{ \ |
| 133428 | + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ |
| 133429 | + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ |
| 133430 | + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ |
| 133431 | + *zOut++ = 0x80 + (u8)(c & 0x3F); \ |
| 133432 | + } \ |
| 133433 | +} |
| 133434 | + |
| 133435 | +#endif /* ifndef SQLITE_AMALGAMATION */ |
| 133436 | + |
| 133437 | +typedef struct unicode_tokenizer unicode_tokenizer; |
| 133438 | +typedef struct unicode_cursor unicode_cursor; |
| 133439 | + |
| 133440 | +struct unicode_tokenizer { |
| 133441 | + sqlite3_tokenizer base; |
| 133442 | + int bRemoveDiacritic; |
| 133443 | +}; |
| 133444 | + |
| 133445 | +struct unicode_cursor { |
| 133446 | + sqlite3_tokenizer_cursor base; |
| 133447 | + const unsigned char *aInput; /* Input text being tokenized */ |
| 133448 | + int nInput; /* Size of aInput[] in bytes */ |
| 133449 | + int iOff; /* Current offset within aInput[] */ |
| 133450 | + int iToken; /* Index of next token to be returned */ |
| 133451 | + char *zToken; /* storage for current token */ |
| 133452 | + int nAlloc; /* space allocated at zToken */ |
| 133453 | +}; |
| 133454 | + |
| 133455 | +/* |
| 133456 | +** Create a new tokenizer instance. |
| 133457 | +*/ |
| 133458 | +static int unicodeCreate( |
| 133459 | + int nArg, /* Size of array argv[] */ |
| 133460 | + const char * const *azArg, /* Tokenizer creation arguments */ |
| 133461 | + sqlite3_tokenizer **pp /* OUT: New tokenizer handle */ |
| 133462 | +){ |
| 133463 | + unicode_tokenizer *pNew; /* New tokenizer object */ |
| 133464 | + int i; |
| 133465 | + pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); |
| 133466 | + if( pNew==NULL ){ |
| 133467 | + return SQLITE_NOMEM; |
| 133468 | + } |
| 133469 | + memset(pNew, 0, sizeof(unicode_tokenizer)); |
| 133470 | + pNew->bRemoveDiacritic = 1; |
| 133471 | + |
| 133472 | + for(i=0; i<nArg; i++){ |
| 133473 | + const char *z = azArg[i]; |
| 133474 | + int n = strlen(z); |
| 133475 | + |
| 133476 | + if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ |
| 133477 | + pNew->bRemoveDiacritic = 1; |
| 133478 | + } |
| 133479 | + else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ |
| 133480 | + pNew->bRemoveDiacritic = 0; |
| 133481 | + } |
| 133482 | + else{ |
| 133483 | + /* Unrecognized argument */ |
| 133484 | + return SQLITE_ERROR; |
| 133485 | + } |
| 133486 | + } |
| 133487 | + |
| 133488 | + *pp = &pNew->base; |
| 133489 | + return SQLITE_OK; |
| 133490 | +} |
| 133491 | + |
| 133492 | +/* |
| 133493 | +** Destroy a tokenizer allocated by unicodeCreate(). |
| 133494 | +*/ |
| 133495 | +static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ |
| 133496 | + sqlite3_free(pTokenizer); |
| 133497 | + return SQLITE_OK; |
| 133498 | +} |
| 133499 | + |
| 133500 | +/* |
| 133501 | +** Prepare to begin tokenizing a particular string. The input |
| 133502 | +** string to be tokenized is pInput[0..nBytes-1]. A cursor |
| 133503 | +** used to incrementally tokenize this string is returned in |
| 133504 | +** *ppCursor. |
| 133505 | +*/ |
| 133506 | +static int unicodeOpen( |
| 133507 | + sqlite3_tokenizer *p, /* The tokenizer */ |
| 133508 | + const char *aInput, /* Input string */ |
| 133509 | + int nInput, /* Size of string aInput in bytes */ |
| 133510 | + sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ |
| 133511 | +){ |
| 133512 | + unicode_cursor *pCsr; |
| 133513 | + |
| 133514 | + pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); |
| 133515 | + if( pCsr==0 ){ |
| 133516 | + return SQLITE_NOMEM; |
| 133517 | + } |
| 133518 | + memset(pCsr, 0, sizeof(unicode_cursor)); |
| 133519 | + |
| 133520 | + pCsr->aInput = (const unsigned char *)aInput; |
| 133521 | + if( aInput==0 ){ |
| 133522 | + pCsr->nInput = 0; |
| 133523 | + }else if( nInput<0 ){ |
| 133524 | + pCsr->nInput = (int)strlen(aInput); |
| 133525 | + }else{ |
| 133526 | + pCsr->nInput = nInput; |
| 133527 | + } |
| 133528 | + |
| 133529 | + *pp = &pCsr->base; |
| 133530 | + UNUSED_PARAMETER(p); |
| 133531 | + return SQLITE_OK; |
| 133532 | +} |
| 133533 | + |
| 133534 | +/* |
| 133535 | +** Close a tokenization cursor previously opened by a call to |
| 133536 | +** simpleOpen() above. |
| 133537 | +*/ |
| 133538 | +static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ |
| 133539 | + unicode_cursor *pCsr = (unicode_cursor *) pCursor; |
| 133540 | + sqlite3_free(pCsr->zToken); |
| 133541 | + sqlite3_free(pCsr); |
| 133542 | + return SQLITE_OK; |
| 133543 | +} |
| 133544 | + |
| 133545 | +/* |
| 133546 | +** Extract the next token from a tokenization cursor. The cursor must |
| 133547 | +** have been opened by a prior call to simpleOpen(). |
| 133548 | +*/ |
| 133549 | +static int unicodeNext( |
| 133550 | + sqlite3_tokenizer_cursor *p, /* Cursor returned by simpleOpen */ |
| 133551 | + const char **paToken, /* OUT: Token text */ |
| 133552 | + int *pnToken, /* OUT: Number of bytes at *paToken */ |
| 133553 | + int *piStart, /* OUT: Starting offset of token */ |
| 133554 | + int *piEnd, /* OUT: Ending offset of token */ |
| 133555 | + int *piPos /* OUT: Position integer of token */ |
| 133556 | +){ |
| 133557 | + unicode_cursor *pCsr = (unicode_cursor *)p; |
| 133558 | + int iCode; |
| 133559 | + char *zOut; |
| 133560 | + const unsigned char *z = &pCsr->aInput[pCsr->iOff]; |
| 133561 | + const unsigned char *zStart = z; |
| 133562 | + const unsigned char *zEnd; |
| 133563 | + const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput]; |
| 133564 | + |
| 133565 | + /* Scan past any delimiter characters before the start of the next token. |
| 133566 | + ** Return SQLITE_DONE early if this takes us all the way to the end of |
| 133567 | + ** the input. */ |
| 133568 | + while( z<zTerm ){ |
| 133569 | + READ_UTF8(z, zTerm, iCode); |
| 133570 | + if( sqlite3FtsUnicodeIsalnum(iCode) ) break; |
| 133571 | + zStart = z; |
| 133572 | + } |
| 133573 | + if( zStart>=zTerm ) return SQLITE_DONE; |
| 133574 | + |
| 133575 | + zOut = pCsr->zToken; |
| 133576 | + do { |
| 133577 | + int iOut; |
| 133578 | + |
| 133579 | + /* Grow the output buffer if required. */ |
| 133580 | + if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ |
| 133581 | + char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64); |
| 133582 | + if( !zNew ) return SQLITE_NOMEM; |
| 133583 | + zOut = &zNew[zOut - pCsr->zToken]; |
| 133584 | + pCsr->zToken = zNew; |
| 133585 | + pCsr->nAlloc += 64; |
| 133586 | + } |
| 133587 | + |
| 133588 | + /* Write the folded case of the last character read to the output */ |
| 133589 | + zEnd = z; |
| 133590 | + iOut = sqlite3FtsUnicodeFold(iCode, |
| 133591 | + ((unicode_tokenizer *)pCsr->base.pTokenizer)->bRemoveDiacritic |
| 133592 | + ); |
| 133593 | + if( iOut ){ |
| 133594 | + WRITE_UTF8(zOut, iOut); |
| 133595 | + } |
| 133596 | + |
| 133597 | + /* If the cursor is not at EOF, read the next character */ |
| 133598 | + if( z>=zTerm ) break; |
| 133599 | + READ_UTF8(z, zTerm, iCode); |
| 133600 | + }while( sqlite3FtsUnicodeIsalnum(iCode) |
| 133601 | + || sqlite3FtsUnicodeIsdiacritic(iCode) |
| 133602 | + ); |
| 133603 | + |
| 133604 | + /* Set the output variables and return. */ |
| 133605 | + pCsr->iOff = (z - pCsr->aInput); |
| 133606 | + *paToken = pCsr->zToken; |
| 133607 | + *pnToken = zOut - pCsr->zToken; |
| 133608 | + *piStart = (zStart - pCsr->aInput); |
| 133609 | + *piEnd = (zEnd - pCsr->aInput); |
| 133610 | + *piPos = pCsr->iToken++; |
| 133611 | + return SQLITE_OK; |
| 133612 | +} |
| 133613 | + |
| 133614 | +/* |
| 133615 | +** Set *ppModule to a pointer to the sqlite3_tokenizer_module |
| 133616 | +** structure for the unicode tokenizer. |
| 133617 | +*/ |
| 133618 | +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ |
| 133619 | + static const sqlite3_tokenizer_module module = { |
| 133620 | + 0, |
| 133621 | + unicodeCreate, |
| 133622 | + unicodeDestroy, |
| 133623 | + unicodeOpen, |
| 133624 | + unicodeClose, |
| 133625 | + unicodeNext, |
| 133626 | + 0, |
| 133627 | + }; |
| 133628 | + *ppModule = &module; |
| 133629 | +} |
| 133630 | + |
| 133631 | +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ |
| 133632 | +#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */ |
| 133633 | + |
| 133634 | +/************** End of fts3_unicode.c ****************************************/ |
| 133635 | +/************** Begin file fts3_unicode2.c ***********************************/ |
| 133636 | +/* |
| 133637 | +** 2012 May 25 |
| 133638 | +** |
| 133639 | +** The author disclaims copyright to this source code. In place of |
| 133640 | +** a legal notice, here is a blessing: |
| 133641 | +** |
| 133642 | +** May you do good and not evil. |
| 133643 | +** May you find forgiveness for yourself and forgive others. |
| 133644 | +** May you share freely, never taking more than you give. |
| 133645 | +** |
| 133646 | +****************************************************************************** |
| 133647 | +*/ |
| 133648 | + |
| 133649 | +/* |
| 133650 | +** DO NOT EDIT THIS MACHINE GENERATED FILE. |
| 133651 | +*/ |
| 133652 | + |
| 133653 | +#if defined(SQLITE_ENABLE_FTS4_UNICODE61) |
| 133654 | +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 133655 | + |
| 133656 | +/* #include <assert.h> */ |
| 133657 | + |
| 133658 | +/* |
| 133659 | +** Return true if the argument corresponds to a unicode codepoint |
| 133660 | +** classified as either a letter or a number. Otherwise false. |
| 133661 | +** |
| 133662 | +** The results are undefined if the value passed to this function |
| 133663 | +** is less than zero. |
| 133664 | +*/ |
| 133665 | +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ |
| 133666 | + /* Each unsigned integer in the following array corresponds to a contiguous |
| 133667 | + ** range of unicode codepoints that are not either letters or numbers (i.e. |
| 133668 | + ** codepoints for which this function should return 0). |
| 133669 | + ** |
| 133670 | + ** The most significant 22 bits in each 32-bit value contain the first |
| 133671 | + ** codepoint in the range. The least significant 10 bits are used to store |
| 133672 | + ** the size of the range (always at least 1). In other words, the value |
| 133673 | + ** ((C<<22) + N) represents a range of N codepoints starting with codepoint |
| 133674 | + ** C. It is not possible to represent a range larger than 1023 codepoints |
| 133675 | + ** using this format. |
| 133676 | + */ |
| 133677 | + const static unsigned int aEntry[] = { |
| 133678 | + 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, |
| 133679 | + 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, |
| 133680 | + 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, |
| 133681 | + 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, |
| 133682 | + 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, |
| 133683 | + 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, |
| 133684 | + 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, |
| 133685 | + 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, |
| 133686 | + 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, |
| 133687 | + 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, |
| 133688 | + 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, |
| 133689 | + 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, |
| 133690 | + 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, |
| 133691 | + 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, |
| 133692 | + 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, |
| 133693 | + 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, |
| 133694 | + 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, |
| 133695 | + 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, |
| 133696 | + 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, |
| 133697 | + 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, |
| 133698 | + 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, |
| 133699 | + 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, |
| 133700 | + 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, |
| 133701 | + 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, |
| 133702 | + 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, |
| 133703 | + 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, |
| 133704 | + 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, |
| 133705 | + 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, |
| 133706 | + 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, |
| 133707 | + 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, |
| 133708 | + 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, |
| 133709 | + 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, |
| 133710 | + 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, |
| 133711 | + 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, |
| 133712 | + 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, |
| 133713 | + 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, |
| 133714 | + 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, |
| 133715 | + 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, |
| 133716 | + 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, |
| 133717 | + 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, |
| 133718 | + 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, |
| 133719 | + 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, |
| 133720 | + 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, |
| 133721 | + 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, |
| 133722 | + 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, |
| 133723 | + 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, |
| 133724 | + 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, |
| 133725 | + 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, |
| 133726 | + 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, |
| 133727 | + 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, |
| 133728 | + 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, |
| 133729 | + 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, |
| 133730 | + 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, |
| 133731 | + 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, |
| 133732 | + 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, |
| 133733 | + 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, |
| 133734 | + 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, |
| 133735 | + 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, |
| 133736 | + 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, |
| 133737 | + 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, |
| 133738 | + 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, |
| 133739 | + 0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, |
| 133740 | + 0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, |
| 133741 | + 0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, |
| 133742 | + 0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, |
| 133743 | + 0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, |
| 133744 | + 0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, |
| 133745 | + 0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, |
| 133746 | + 0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, |
| 133747 | + 0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, |
| 133748 | + 0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, |
| 133749 | + 0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, |
| 133750 | + 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, |
| 133751 | + 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, |
| 133752 | + 0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, |
| 133753 | + 0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, |
| 133754 | + 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, |
| 133755 | + 0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, |
| 133756 | + 0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, |
| 133757 | + 0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, |
| 133758 | + 0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, |
| 133759 | + 0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001, |
| 133760 | + 0x43FFF401, |
| 133761 | + }; |
| 133762 | + static const unsigned int aAscii[4] = { |
| 133763 | + 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, |
| 133764 | + }; |
| 133765 | + |
| 133766 | + if( c<128 ){ |
| 133767 | + return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); |
| 133768 | + }else if( c<(1<<22) ){ |
| 133769 | + unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; |
| 133770 | + int iRes; |
| 133771 | + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; |
| 133772 | + int iLo = 0; |
| 133773 | + while( iHi>=iLo ){ |
| 133774 | + int iTest = (iHi + iLo) / 2; |
| 133775 | + if( key >= aEntry[iTest] ){ |
| 133776 | + iRes = iTest; |
| 133777 | + iLo = iTest+1; |
| 133778 | + }else{ |
| 133779 | + iHi = iTest-1; |
| 133780 | + } |
| 133781 | + } |
| 133782 | + assert( aEntry[0]<key ); |
| 133783 | + assert( key>=aEntry[iRes] ); |
| 133784 | + return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); |
| 133785 | + } |
| 133786 | + return 1; |
| 133787 | +} |
| 133788 | + |
| 133789 | + |
| 133790 | +/* |
| 133791 | +** If the argument is a codepoint corresponding to a lowercase letter |
| 133792 | +** in the ASCII range with a diacritic added, return the codepoint |
| 133793 | +** of the ASCII letter only. For example, if passed 235 - "LATIN |
| 133794 | +** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER |
| 133795 | +** E"). The resuls of passing a codepoint that corresponds to an |
| 133796 | +** uppercase letter are undefined. |
| 133797 | +*/ |
| 133798 | +static int remove_diacritic(int c){ |
| 133799 | + unsigned short aDia[] = { |
| 133800 | + 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, |
| 133801 | + 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, |
| 133802 | + 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, |
| 133803 | + 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, |
| 133804 | + 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, |
| 133805 | + 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, |
| 133806 | + 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, |
| 133807 | + 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, |
| 133808 | + 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, |
| 133809 | + 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, |
| 133810 | + 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, |
| 133811 | + 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, |
| 133812 | + 62924, 63050, 63082, 63274, 63390, |
| 133813 | + }; |
| 133814 | + char aChar[] = { |
| 133815 | + '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', |
| 133816 | + 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', |
| 133817 | + 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', |
| 133818 | + 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', |
| 133819 | + 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', |
| 133820 | + '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', |
| 133821 | + 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', |
| 133822 | + 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', |
| 133823 | + 'e', 'i', 'o', 'u', 'y', |
| 133824 | + }; |
| 133825 | + |
| 133826 | + unsigned int key = (((unsigned int)c)<<3) | 0x00000007; |
| 133827 | + int iRes = 0; |
| 133828 | + int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; |
| 133829 | + int iLo = 0; |
| 133830 | + while( iHi>=iLo ){ |
| 133831 | + int iTest = (iHi + iLo) / 2; |
| 133832 | + if( key >= aDia[iTest] ){ |
| 133833 | + iRes = iTest; |
| 133834 | + iLo = iTest+1; |
| 133835 | + }else{ |
| 133836 | + iHi = iTest-1; |
| 133837 | + } |
| 133838 | + } |
| 133839 | + assert( key>=aDia[iRes] ); |
| 133840 | + return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]); |
| 133841 | +}; |
| 133842 | + |
| 133843 | + |
| 133844 | +/* |
| 133845 | +** Return true if the argument interpreted as a unicode codepoint |
| 133846 | +** is a diacritical modifier character. |
| 133847 | +*/ |
| 133848 | +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ |
| 133849 | + unsigned int mask0 = 0x08029FDF; |
| 133850 | + unsigned int mask1 = 0x000361F8; |
| 133851 | + if( c<768 || c>817 ) return 0; |
| 133852 | + return (c < 768+32) ? |
| 133853 | + (mask0 & (1 << (c-768))) : |
| 133854 | + (mask1 & (1 << (c-768-32))); |
| 133855 | +} |
| 133856 | + |
| 133857 | + |
| 133858 | +/* |
| 133859 | +** Interpret the argument as a unicode codepoint. If the codepoint |
| 133860 | +** is an upper case character that has a lower case equivalent, |
| 133861 | +** return the codepoint corresponding to the lower case version. |
| 133862 | +** Otherwise, return a copy of the argument. |
| 133863 | +** |
| 133864 | +** The results are undefined if the value passed to this function |
| 133865 | +** is less than zero. |
| 133866 | +*/ |
| 133867 | +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ |
| 133868 | + /* Each entry in the following array defines a rule for folding a range |
| 133869 | + ** of codepoints to lower case. The rule applies to a range of nRange |
| 133870 | + ** codepoints starting at codepoint iCode. |
| 133871 | + ** |
| 133872 | + ** If the least significant bit in flags is clear, then the rule applies |
| 133873 | + ** to all nRange codepoints (i.e. all nRange codepoints are upper case and |
| 133874 | + ** need to be folded). Or, if it is set, then the rule only applies to |
| 133875 | + ** every second codepoint in the range, starting with codepoint C. |
| 133876 | + ** |
| 133877 | + ** The 7 most significant bits in flags are an index into the aiOff[] |
| 133878 | + ** array. If a specific codepoint C does require folding, then its lower |
| 133879 | + ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF). |
| 133880 | + ** |
| 133881 | + ** The contents of this array are generated by parsing the CaseFolding.txt |
| 133882 | + ** file distributed as part of the "Unicode Character Database". See |
| 133883 | + ** http://www.unicode.org for details. |
| 133884 | + */ |
| 133885 | + static const struct TableEntry { |
| 133886 | + unsigned short iCode; |
| 133887 | + unsigned char flags; |
| 133888 | + unsigned char nRange; |
| 133889 | + } aEntry[] = { |
| 133890 | + {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, |
| 133891 | + {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, |
| 133892 | + {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, |
| 133893 | + {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, |
| 133894 | + {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, |
| 133895 | + {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, |
| 133896 | + {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, |
| 133897 | + {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, |
| 133898 | + {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, |
| 133899 | + {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, |
| 133900 | + {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, |
| 133901 | + {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, |
| 133902 | + {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, |
| 133903 | + {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, |
| 133904 | + {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, |
| 133905 | + {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, |
| 133906 | + {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, |
| 133907 | + {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, |
| 133908 | + {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, |
| 133909 | + {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, |
| 133910 | + {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, |
| 133911 | + {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, |
| 133912 | + {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, |
| 133913 | + {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, |
| 133914 | + {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, |
| 133915 | + {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, |
| 133916 | + {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, |
| 133917 | + {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, |
| 133918 | + {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, |
| 133919 | + {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, |
| 133920 | + {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, |
| 133921 | + {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, |
| 133922 | + {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, |
| 133923 | + {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, |
| 133924 | + {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, |
| 133925 | + {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, |
| 133926 | + {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, |
| 133927 | + {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, |
| 133928 | + {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, |
| 133929 | + {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, |
| 133930 | + {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, |
| 133931 | + {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, |
| 133932 | + {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, |
| 133933 | + {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, |
| 133934 | + {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, |
| 133935 | + {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, |
| 133936 | + {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, |
| 133937 | + {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, |
| 133938 | + {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, |
| 133939 | + {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, |
| 133940 | + {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, |
| 133941 | + {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, |
| 133942 | + {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, |
| 133943 | + {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, |
| 133944 | + {65313, 14, 26}, |
| 133945 | + }; |
| 133946 | + static const unsigned short aiOff[] = { |
| 133947 | + 1, 2, 8, 15, 16, 26, 28, 32, |
| 133948 | + 37, 38, 40, 48, 63, 64, 69, 71, |
| 133949 | + 79, 80, 116, 202, 203, 205, 206, 207, |
| 133950 | + 209, 210, 211, 213, 214, 217, 218, 219, |
| 133951 | + 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, |
| 133952 | + 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, |
| 133953 | + 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, |
| 133954 | + 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, |
| 133955 | + 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, |
| 133956 | + 65514, 65521, 65527, 65528, 65529, |
| 133957 | + }; |
| 133958 | + |
| 133959 | + int ret = c; |
| 133960 | + |
| 133961 | + assert( c>=0 ); |
| 133962 | + assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); |
| 133963 | + |
| 133964 | + if( c<128 ){ |
| 133965 | + if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); |
| 133966 | + }else if( c<65536 ){ |
| 133967 | + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; |
| 133968 | + int iLo = 0; |
| 133969 | + int iRes = -1; |
| 133970 | + |
| 133971 | + while( iHi>=iLo ){ |
| 133972 | + int iTest = (iHi + iLo) / 2; |
| 133973 | + int cmp = (c - aEntry[iTest].iCode); |
| 133974 | + if( cmp>=0 ){ |
| 133975 | + iRes = iTest; |
| 133976 | + iLo = iTest+1; |
| 133977 | + }else{ |
| 133978 | + iHi = iTest-1; |
| 133979 | + } |
| 133980 | + } |
| 133981 | + assert( iRes<0 || c>=aEntry[iRes].iCode ); |
| 133982 | + |
| 133983 | + if( iRes>=0 ){ |
| 133984 | + const struct TableEntry *p = &aEntry[iRes]; |
| 133985 | + if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ |
| 133986 | + ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; |
| 133987 | + assert( ret>0 ); |
| 133988 | + } |
| 133989 | + } |
| 133990 | + |
| 133991 | + if( bRemoveDiacritic ) ret = remove_diacritic(ret); |
| 133992 | + } |
| 133993 | + |
| 133994 | + else if( c>=66560 && c<66600 ){ |
| 133995 | + ret = c + 40; |
| 133996 | + } |
| 133997 | + |
| 133998 | + return ret; |
| 133999 | +} |
| 134000 | +#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ |
| 134001 | +#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */ |
| 134002 | + |
| 134003 | +/************** End of fts3_unicode2.c ***************************************/ |
| 132567 | 134004 | /************** Begin file rtree.c *******************************************/ |
| 132568 | 134005 | /* |
| 132569 | 134006 | ** 2001 September 15 |
| 132570 | 134007 | ** |
| 132571 | 134008 | ** The author disclaims copyright to this source code. In place of |
| | @@ -135301,10 +136738,40 @@ |
| 135301 | 136738 | nodeRelease(pRtree, pRoot); |
| 135302 | 136739 | } |
| 135303 | 136740 | |
| 135304 | 136741 | return rc; |
| 135305 | 136742 | } |
| 136743 | + |
| 136744 | +/* |
| 136745 | +** Rounding constants for float->double conversion. |
| 136746 | +*/ |
| 136747 | +#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ |
| 136748 | +#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ |
| 136749 | + |
| 136750 | +#if !defined(SQLITE_RTREE_INT_ONLY) |
| 136751 | +/* |
| 136752 | +** Convert an sqlite3_value into an RtreeValue (presumably a float) |
| 136753 | +** while taking care to round toward negative or positive, respectively. |
| 136754 | +*/ |
| 136755 | +static RtreeValue rtreeValueDown(sqlite3_value *v){ |
| 136756 | + double d = sqlite3_value_double(v); |
| 136757 | + float f = (float)d; |
| 136758 | + if( f>d ){ |
| 136759 | + f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); |
| 136760 | + } |
| 136761 | + return f; |
| 136762 | +} |
| 136763 | +static RtreeValue rtreeValueUp(sqlite3_value *v){ |
| 136764 | + double d = sqlite3_value_double(v); |
| 136765 | + float f = (float)d; |
| 136766 | + if( f<d ){ |
| 136767 | + f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY)); |
| 136768 | + } |
| 136769 | + return f; |
| 136770 | +} |
| 136771 | +#endif /* !defined(SQLITE_RTREE_INT_ONLY) */ |
| 136772 | + |
| 135306 | 136773 | |
| 135307 | 136774 | /* |
| 135308 | 136775 | ** The xUpdate method for rtree module virtual tables. |
| 135309 | 136776 | */ |
| 135310 | 136777 | static int rtreeUpdate( |
| | @@ -135338,12 +136805,12 @@ |
| 135338 | 136805 | /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ |
| 135339 | 136806 | assert( nData==(pRtree->nDim*2 + 3) ); |
| 135340 | 136807 | #ifndef SQLITE_RTREE_INT_ONLY |
| 135341 | 136808 | if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ |
| 135342 | 136809 | for(ii=0; ii<(pRtree->nDim*2); ii+=2){ |
| 135343 | | - cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]); |
| 135344 | | - cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]); |
| 136810 | + cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]); |
| 136811 | + cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]); |
| 135345 | 136812 | if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ |
| 135346 | 136813 | rc = SQLITE_CONSTRAINT; |
| 135347 | 136814 | goto constraint; |
| 135348 | 136815 | } |
| 135349 | 136816 | } |
| 135350 | 136817 | |