| | @@ -650,11 +650,11 @@ |
| 650 | 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | 652 | */ |
| 653 | 653 | #define SQLITE_VERSION "3.7.6" |
| 654 | 654 | #define SQLITE_VERSION_NUMBER 3007006 |
| 655 | | -#define SQLITE_SOURCE_ID "2011-03-06 21:54:33 3bfbf026dd6a0eeef07f8f5f1ebf74c9cfebcd61" |
| 655 | +#define SQLITE_SOURCE_ID "2011-03-24 01:34:03 b6e268fce12829f058f1dfa223731ec8479493f8" |
| 656 | 656 | |
| 657 | 657 | /* |
| 658 | 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | 660 | ** |
| | @@ -1439,14 +1439,27 @@ |
| 1439 | 1439 | ** a 24-hour day). |
| 1440 | 1440 | ** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 1441 | 1441 | ** date and time if that method is available (if iVersion is 2 or |
| 1442 | 1442 | ** greater and the function pointer is not NULL) and will fall back |
| 1443 | 1443 | ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| 1444 | +** |
| 1445 | +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces |
| 1446 | +** are not used by the SQLite core. These optional interfaces are provided |
| 1447 | +** by some VFSes to facilitate testing of the VFS code. By overriding |
| 1448 | +** system calls with functions under its control, a test program can |
| 1449 | +** simulate faults and error conditions that would otherwise be difficult |
| 1450 | +** or impossible to induce. The set of system calls that can be overridden |
| 1451 | +** varies from one VFS to another, and from one version of the same VFS to the |
| 1452 | +** next. Applications that use these interfaces must be prepared for any |
| 1453 | +** or all of these interfaces to be NULL or for their behavior to change |
| 1454 | +** from one release to the next. Applications must not attempt to access |
| 1455 | +** any of these methods if the iVersion of the VFS is less than 3. |
| 1444 | 1456 | */ |
| 1445 | 1457 | typedef struct sqlite3_vfs sqlite3_vfs; |
| 1458 | +typedef void (*sqlite3_syscall_ptr)(void); |
| 1446 | 1459 | struct sqlite3_vfs { |
| 1447 | | - int iVersion; /* Structure version number (currently 2) */ |
| 1460 | + int iVersion; /* Structure version number (currently 3) */ |
| 1448 | 1461 | int szOsFile; /* Size of subclassed sqlite3_file */ |
| 1449 | 1462 | int mxPathname; /* Maximum file pathname length */ |
| 1450 | 1463 | sqlite3_vfs *pNext; /* Next registered VFS */ |
| 1451 | 1464 | const char *zName; /* Name of this virtual file system */ |
| 1452 | 1465 | void *pAppData; /* Pointer to application-specific data */ |
| | @@ -1468,10 +1481,17 @@ |
| 1468 | 1481 | ** definition. Those that follow are added in version 2 or later |
| 1469 | 1482 | */ |
| 1470 | 1483 | int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); |
| 1471 | 1484 | /* |
| 1472 | 1485 | ** The methods above are in versions 1 and 2 of the sqlite_vfs object. |
| 1486 | + ** Those below are for version 3 and greater. |
| 1487 | + */ |
| 1488 | + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); |
| 1489 | + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); |
| 1490 | + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); |
| 1491 | + /* |
| 1492 | + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. |
| 1473 | 1493 | ** New fields may be appended in figure versions. The iVersion |
| 1474 | 1494 | ** value will increment whenever this happens. |
| 1475 | 1495 | */ |
| 1476 | 1496 | }; |
| 1477 | 1497 | |
| | @@ -1652,21 +1672,16 @@ |
| 1652 | 1672 | ** CAPI3REF: Configure database connections |
| 1653 | 1673 | ** |
| 1654 | 1674 | ** The sqlite3_db_config() interface is used to make configuration |
| 1655 | 1675 | ** changes to a [database connection]. The interface is similar to |
| 1656 | 1676 | ** [sqlite3_config()] except that the changes apply to a single |
| 1657 | | -** [database connection] (specified in the first argument). The |
| 1658 | | -** sqlite3_db_config() interface should only be used immediately after |
| 1659 | | -** the database connection is created using [sqlite3_open()], |
| 1660 | | -** [sqlite3_open16()], or [sqlite3_open_v2()]. |
| 1677 | +** [database connection] (specified in the first argument). |
| 1661 | 1678 | ** |
| 1662 | 1679 | ** The second argument to sqlite3_db_config(D,V,...) is the |
| 1663 | | -** configuration verb - an integer code that indicates what |
| 1664 | | -** aspect of the [database connection] is being configured. |
| 1665 | | -** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE]. |
| 1666 | | -** New verbs are likely to be added in future releases of SQLite. |
| 1667 | | -** Additional arguments depend on the verb. |
| 1680 | +** [SQLITE_DBCONIG_LOOKASIDE | configuration verb] - an integer code |
| 1681 | +** that indicates what aspect of the [database connection] is being configured. |
| 1682 | +** Subsequent arguments vary depending on the configuration verb. |
| 1668 | 1683 | ** |
| 1669 | 1684 | ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if |
| 1670 | 1685 | ** the call is considered successful. |
| 1671 | 1686 | */ |
| 1672 | 1687 | SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); |
| | @@ -1887,11 +1902,13 @@ |
| 1887 | 1902 | ** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the |
| 1888 | 1903 | ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or |
| 1889 | 1904 | ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory |
| 1890 | 1905 | ** allocator is engaged to handle all of SQLites memory allocation needs. |
| 1891 | 1906 | ** The first pointer (the memory pointer) must be aligned to an 8-byte |
| 1892 | | -** boundary or subsequent behavior of SQLite will be undefined.</dd> |
| 1907 | +** boundary or subsequent behavior of SQLite will be undefined. |
| 1908 | +** The minimum allocation size is capped at 2^12. Reasonable values |
| 1909 | +** for the minimum allocation size are 2^5 through 2^8.</dd> |
| 1893 | 1910 | ** |
| 1894 | 1911 | ** <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1895 | 1912 | ** <dd> ^(This option takes a single argument which is a pointer to an |
| 1896 | 1913 | ** instance of the [sqlite3_mutex_methods] structure. The argument specifies |
| 1897 | 1914 | ** alternative low-level mutex routines to be used in place |
| | @@ -2008,13 +2025,35 @@ |
| 2008 | 2025 | ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. |
| 2009 | 2026 | ** Any attempt to change the lookaside memory configuration when lookaside |
| 2010 | 2027 | ** memory is in use leaves the configuration unchanged and returns |
| 2011 | 2028 | ** [SQLITE_BUSY].)^</dd> |
| 2012 | 2029 | ** |
| 2030 | +** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt> |
| 2031 | +** <dd> ^This option is used to enable or disable the enforcement of |
| 2032 | +** [foreign key constraints]. There should be two additional arguments. |
| 2033 | +** The first argument is an integer which is 0 to disable FK enforcement, |
| 2034 | +** positive to enable FK enforcement or negative to leave FK enforcement |
| 2035 | +** unchanged. The second parameter is a pointer to an integer into which |
| 2036 | +** is written 0 or 1 to indicate whether FK enforcement is off or on |
| 2037 | +** following this call. The second parameter may be a NULL pointer, in |
| 2038 | +** which case the FK enforcement setting is not reported back. </dd> |
| 2039 | +** |
| 2040 | +** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt> |
| 2041 | +** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers]. |
| 2042 | +** There should be two additional arguments. |
| 2043 | +** The first argument is an integer which is 0 to disable triggers, |
| 2044 | +** positive to enable trigers or negative to leave the setting unchanged. |
| 2045 | +** The second parameter is a pointer to an integer into which |
| 2046 | +** is written 0 or 1 to indicate whether triggers are disabled or enabled |
| 2047 | +** following this call. The second parameter may be a NULL pointer, in |
| 2048 | +** which case the trigger setting is not reported back. </dd> |
| 2049 | +** |
| 2013 | 2050 | ** </dl> |
| 2014 | 2051 | */ |
| 2015 | | -#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ |
| 2052 | +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ |
| 2053 | +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ |
| 2054 | +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ |
| 2016 | 2055 | |
| 2017 | 2056 | |
| 2018 | 2057 | /* |
| 2019 | 2058 | ** CAPI3REF: Enable Or Disable Extended Result Codes |
| 2020 | 2059 | ** |
| | @@ -8974,10 +9013,11 @@ |
| 8974 | 9013 | /* |
| 8975 | 9014 | ** An instance of the following structure stores a database schema. |
| 8976 | 9015 | */ |
| 8977 | 9016 | struct Schema { |
| 8978 | 9017 | int schema_cookie; /* Database schema version number for this file */ |
| 9018 | + int iGeneration; /* Generation counter. Incremented with each change */ |
| 8979 | 9019 | Hash tblHash; /* All tables indexed by name */ |
| 8980 | 9020 | Hash idxHash; /* All (named) indices indexed by name */ |
| 8981 | 9021 | Hash trigHash; /* All triggers indexed by name */ |
| 8982 | 9022 | Hash fkeyHash; /* All foreign keys by referenced table name */ |
| 8983 | 9023 | Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ |
| | @@ -9227,10 +9267,11 @@ |
| 9227 | 9267 | #define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ |
| 9228 | 9268 | #define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ |
| 9229 | 9269 | #define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ |
| 9230 | 9270 | #define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ |
| 9231 | 9271 | #define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ |
| 9272 | +#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ |
| 9232 | 9273 | |
| 9233 | 9274 | /* |
| 9234 | 9275 | ** Bits of the sqlite3.flags field that are used by the |
| 9235 | 9276 | ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. |
| 9236 | 9277 | ** These must be the low-order bits of the flags field. |
| | @@ -9926,11 +9967,11 @@ |
| 9926 | 9967 | u8 op; /* Operation performed by this node */ |
| 9927 | 9968 | char affinity; /* The affinity of the column or 0 if not a column */ |
| 9928 | 9969 | u16 flags; /* Various flags. EP_* See below */ |
| 9929 | 9970 | union { |
| 9930 | 9971 | char *zToken; /* Token value. Zero terminated and dequoted */ |
| 9931 | | - int iValue; /* Integer value if EP_IntValue */ |
| 9972 | + int iValue; /* Non-negative integer value if EP_IntValue */ |
| 9932 | 9973 | } u; |
| 9933 | 9974 | |
| 9934 | 9975 | /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no |
| 9935 | 9976 | ** space is allocated for the fields below this point. An attempt to |
| 9936 | 9977 | ** access them will result in a segfault or malfunction. |
| | @@ -10426,10 +10467,17 @@ |
| 10426 | 10467 | SubProgram *pProgram; /* Program implementing pTrigger/orconf */ |
| 10427 | 10468 | u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ |
| 10428 | 10469 | TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ |
| 10429 | 10470 | }; |
| 10430 | 10471 | |
| 10472 | +/* Datatype for the bitmask of all attached databases */ |
| 10473 | +#if SQLITE_MAX_ATTACHED>30 |
| 10474 | + typedef sqlite3_uint64 tAttachMask; |
| 10475 | +#else |
| 10476 | + typedef unsigned int tAttachMask; |
| 10477 | +#endif |
| 10478 | + |
| 10431 | 10479 | /* |
| 10432 | 10480 | ** An SQL parser context. A copy of this structure is passed through |
| 10433 | 10481 | ** the parser and down into all the parser action routine in order to |
| 10434 | 10482 | ** carry around information that is global to the entire parse. |
| 10435 | 10483 | ** |
| | @@ -10474,12 +10522,12 @@ |
| 10474 | 10522 | u8 tempReg; /* iReg is a temp register that needs to be freed */ |
| 10475 | 10523 | int iLevel; /* Nesting level */ |
| 10476 | 10524 | int iReg; /* Reg with value of this column. 0 means none. */ |
| 10477 | 10525 | int lru; /* Least recently used entry has the smallest value */ |
| 10478 | 10526 | } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ |
| 10479 | | - u32 writeMask; /* Start a write transaction on these databases */ |
| 10480 | | - u32 cookieMask; /* Bitmask of schema verified databases */ |
| 10527 | + tAttachMask writeMask; /* Start a write transaction on these databases */ |
| 10528 | + tAttachMask cookieMask; /* Bitmask of schema verified databases */ |
| 10481 | 10529 | u8 isMultiWrite; /* True if statement may affect/insert multiple rows */ |
| 10482 | 10530 | u8 mayAbort; /* True if statement may throw an ABORT exception */ |
| 10483 | 10531 | int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ |
| 10484 | 10532 | int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ |
| 10485 | 10533 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| | @@ -11209,10 +11257,11 @@ |
| 11209 | 11257 | SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); |
| 11210 | 11258 | SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); |
| 11211 | 11259 | SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); |
| 11212 | 11260 | SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); |
| 11213 | 11261 | SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); |
| 11262 | +SQLITE_PRIVATE int sqlite3AbsInt32(int); |
| 11214 | 11263 | |
| 11215 | 11264 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 11216 | 11265 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 11217 | 11266 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 11218 | 11267 | void(*)(void*)); |
| | @@ -12023,10 +12072,13 @@ |
| 12023 | 12072 | "OMIT_TRIGGER", |
| 12024 | 12073 | #endif |
| 12025 | 12074 | #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION |
| 12026 | 12075 | "OMIT_TRUNCATE_OPTIMIZATION", |
| 12027 | 12076 | #endif |
| 12077 | +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT |
| 12078 | + "OMIT_UNIQUE_ENFORCEMENT", |
| 12079 | +#endif |
| 12028 | 12080 | #ifdef SQLITE_OMIT_UTF16 |
| 12029 | 12081 | "OMIT_UTF16", |
| 12030 | 12082 | #endif |
| 12031 | 12083 | #ifdef SQLITE_OMIT_VACUUM |
| 12032 | 12084 | "OMIT_VACUUM", |
| | @@ -12436,11 +12488,11 @@ |
| 12436 | 12488 | u8 inVtabMethod; /* See comments above */ |
| 12437 | 12489 | u8 usesStmtJournal; /* True if uses a statement journal */ |
| 12438 | 12490 | u8 readOnly; /* True for read-only statements */ |
| 12439 | 12491 | u8 isPrepareV2; /* True if prepared with prepare_v2() */ |
| 12440 | 12492 | int nChange; /* Number of db changes made since last reset */ |
| 12441 | | - int btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 12493 | + tAttachMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 12442 | 12494 | int iStatement; /* Statement number (or 0 if has not opened stmt) */ |
| 12443 | 12495 | int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ |
| 12444 | 12496 | BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ |
| 12445 | 12497 | #ifndef SQLITE_OMIT_TRACE |
| 12446 | 12498 | i64 startTime; /* Time when query started - used for profiling */ |
| | @@ -16155,11 +16207,11 @@ |
| 16155 | 16207 | ** memsys5Log(8) -> 3 |
| 16156 | 16208 | ** memsys5Log(9) -> 4 |
| 16157 | 16209 | */ |
| 16158 | 16210 | static int memsys5Log(int iValue){ |
| 16159 | 16211 | int iLog; |
| 16160 | | - for(iLog=0; (1<<iLog)<iValue; iLog++); |
| 16212 | + for(iLog=0; (iLog<((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++); |
| 16161 | 16213 | return iLog; |
| 16162 | 16214 | } |
| 16163 | 16215 | |
| 16164 | 16216 | /* |
| 16165 | 16217 | ** Initialize the memory allocator. |
| | @@ -16186,10 +16238,11 @@ |
| 16186 | 16238 | |
| 16187 | 16239 | nByte = sqlite3GlobalConfig.nHeap; |
| 16188 | 16240 | zByte = (u8*)sqlite3GlobalConfig.pHeap; |
| 16189 | 16241 | assert( zByte!=0 ); /* sqlite3_config() does not allow otherwise */ |
| 16190 | 16242 | |
| 16243 | + /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */ |
| 16191 | 16244 | nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq); |
| 16192 | 16245 | mem5.szAtom = (1<<nMinLog); |
| 16193 | 16246 | while( (int)sizeof(Mem5Link)>mem5.szAtom ){ |
| 16194 | 16247 | mem5.szAtom = mem5.szAtom << 1; |
| 16195 | 16248 | } |
| | @@ -16689,15 +16742,20 @@ |
| 16689 | 16742 | ** Each recursive mutex is an instance of the following structure. |
| 16690 | 16743 | */ |
| 16691 | 16744 | struct sqlite3_mutex { |
| 16692 | 16745 | HMTX mutex; /* Mutex controlling the lock */ |
| 16693 | 16746 | int id; /* Mutex type */ |
| 16694 | | - int nRef; /* Number of references */ |
| 16695 | | - TID owner; /* Thread holding this mutex */ |
| 16747 | +#ifdef SQLITE_DEBUG |
| 16748 | + int trace; /* True to trace changes */ |
| 16749 | +#endif |
| 16696 | 16750 | }; |
| 16697 | 16751 | |
| 16698 | | -#define OS2_MUTEX_INITIALIZER 0,0,0,0 |
| 16752 | +#ifdef SQLITE_DEBUG |
| 16753 | +#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 } |
| 16754 | +#else |
| 16755 | +#define SQLITE3_MUTEX_INITIALIZER { 0, 0 } |
| 16756 | +#endif |
| 16699 | 16757 | |
| 16700 | 16758 | /* |
| 16701 | 16759 | ** Initialize and deinitialize the mutex subsystem. |
| 16702 | 16760 | */ |
| 16703 | 16761 | static int os2MutexInit(void){ return SQLITE_OK; } |
| | @@ -16709,15 +16767,18 @@ |
| 16709 | 16767 | ** that means that a mutex could not be allocated. |
| 16710 | 16768 | ** SQLite will unwind its stack and return an error. The argument |
| 16711 | 16769 | ** to sqlite3_mutex_alloc() is one of these integer constants: |
| 16712 | 16770 | ** |
| 16713 | 16771 | ** <ul> |
| 16714 | | -** <li> SQLITE_MUTEX_FAST 0 |
| 16715 | | -** <li> SQLITE_MUTEX_RECURSIVE 1 |
| 16716 | | -** <li> SQLITE_MUTEX_STATIC_MASTER 2 |
| 16717 | | -** <li> SQLITE_MUTEX_STATIC_MEM 3 |
| 16718 | | -** <li> SQLITE_MUTEX_STATIC_PRNG 4 |
| 16772 | +** <li> SQLITE_MUTEX_FAST |
| 16773 | +** <li> SQLITE_MUTEX_RECURSIVE |
| 16774 | +** <li> SQLITE_MUTEX_STATIC_MASTER |
| 16775 | +** <li> SQLITE_MUTEX_STATIC_MEM |
| 16776 | +** <li> SQLITE_MUTEX_STATIC_MEM2 |
| 16777 | +** <li> SQLITE_MUTEX_STATIC_PRNG |
| 16778 | +** <li> SQLITE_MUTEX_STATIC_LRU |
| 16779 | +** <li> SQLITE_MUTEX_STATIC_LRU2 |
| 16719 | 16780 | ** </ul> |
| 16720 | 16781 | ** |
| 16721 | 16782 | ** The first two constants cause sqlite3_mutex_alloc() to create |
| 16722 | 16783 | ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
| 16723 | 16784 | ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
| | @@ -16727,11 +16788,11 @@ |
| 16727 | 16788 | ** cases where it really needs one. If a faster non-recursive mutex |
| 16728 | 16789 | ** implementation is available on the host platform, the mutex subsystem |
| 16729 | 16790 | ** might return such a mutex in response to SQLITE_MUTEX_FAST. |
| 16730 | 16791 | ** |
| 16731 | 16792 | ** The other allowed parameters to sqlite3_mutex_alloc() each return |
| 16732 | | -** a pointer to a static preexisting mutex. Three static mutexes are |
| 16793 | +** a pointer to a static preexisting mutex. Six static mutexes are |
| 16733 | 16794 | ** used by the current version of SQLite. Future versions of SQLite |
| 16734 | 16795 | ** may add additional static mutexes. Static mutexes are for internal |
| 16735 | 16796 | ** use by SQLite only. Applications that use SQLite mutexes should |
| 16736 | 16797 | ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |
| 16737 | 16798 | ** SQLITE_MUTEX_RECURSIVE. |
| | @@ -16757,17 +16818,17 @@ |
| 16757 | 16818 | } |
| 16758 | 16819 | break; |
| 16759 | 16820 | } |
| 16760 | 16821 | default: { |
| 16761 | 16822 | static volatile int isInit = 0; |
| 16762 | | - static sqlite3_mutex staticMutexes[] = { |
| 16763 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16764 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16765 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16766 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16767 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16768 | | - { OS2_MUTEX_INITIALIZER, }, |
| 16823 | + static sqlite3_mutex staticMutexes[6] = { |
| 16824 | + SQLITE3_MUTEX_INITIALIZER, |
| 16825 | + SQLITE3_MUTEX_INITIALIZER, |
| 16826 | + SQLITE3_MUTEX_INITIALIZER, |
| 16827 | + SQLITE3_MUTEX_INITIALIZER, |
| 16828 | + SQLITE3_MUTEX_INITIALIZER, |
| 16829 | + SQLITE3_MUTEX_INITIALIZER, |
| 16769 | 16830 | }; |
| 16770 | 16831 | if ( !isInit ){ |
| 16771 | 16832 | APIRET rc; |
| 16772 | 16833 | PTIB ptib; |
| 16773 | 16834 | PPIB ppib; |
| | @@ -16809,13 +16870,18 @@ |
| 16809 | 16870 | /* |
| 16810 | 16871 | ** This routine deallocates a previously allocated mutex. |
| 16811 | 16872 | ** SQLite is careful to deallocate every mutex that it allocates. |
| 16812 | 16873 | */ |
| 16813 | 16874 | static void os2MutexFree(sqlite3_mutex *p){ |
| 16814 | | - if( p==0 ) return; |
| 16815 | | - assert( p->nRef==0 ); |
| 16875 | +#ifdef SQLITE_DEBUG |
| 16876 | + TID tid; |
| 16877 | + PID pid; |
| 16878 | + ULONG ulCount; |
| 16879 | + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16880 | + assert( ulCount==0 ); |
| 16816 | 16881 | assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 16882 | +#endif |
| 16817 | 16883 | DosCloseMutexSem( p->mutex ); |
| 16818 | 16884 | sqlite3_free( p ); |
| 16819 | 16885 | } |
| 16820 | 16886 | |
| 16821 | 16887 | #ifdef SQLITE_DEBUG |
| | @@ -16826,30 +16892,33 @@ |
| 16826 | 16892 | static int os2MutexHeld(sqlite3_mutex *p){ |
| 16827 | 16893 | TID tid; |
| 16828 | 16894 | PID pid; |
| 16829 | 16895 | ULONG ulCount; |
| 16830 | 16896 | PTIB ptib; |
| 16831 | | - if( p!=0 ) { |
| 16832 | | - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16833 | | - } else { |
| 16834 | | - DosGetInfoBlocks(&ptib, NULL); |
| 16835 | | - tid = ptib->tib_ptib2->tib2_ultid; |
| 16836 | | - } |
| 16837 | | - return p==0 || (p->nRef!=0 && p->owner==tid); |
| 16897 | + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16898 | + if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) ) |
| 16899 | + return 0; |
| 16900 | + DosGetInfoBlocks(&ptib, NULL); |
| 16901 | + return tid==ptib->tib_ptib2->tib2_ultid; |
| 16838 | 16902 | } |
| 16839 | 16903 | static int os2MutexNotheld(sqlite3_mutex *p){ |
| 16840 | 16904 | TID tid; |
| 16841 | 16905 | PID pid; |
| 16842 | 16906 | ULONG ulCount; |
| 16843 | 16907 | PTIB ptib; |
| 16844 | | - if( p!= 0 ) { |
| 16845 | | - DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16846 | | - } else { |
| 16847 | | - DosGetInfoBlocks(&ptib, NULL); |
| 16848 | | - tid = ptib->tib_ptib2->tib2_ultid; |
| 16849 | | - } |
| 16850 | | - return p==0 || p->nRef==0 || p->owner!=tid; |
| 16908 | + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16909 | + if( ulCount==0 ) |
| 16910 | + return 1; |
| 16911 | + DosGetInfoBlocks(&ptib, NULL); |
| 16912 | + return tid!=ptib->tib_ptib2->tib2_ultid; |
| 16913 | +} |
| 16914 | +static void os2MutexTrace(sqlite3_mutex *p, char *pAction){ |
| 16915 | + TID tid; |
| 16916 | + PID pid; |
| 16917 | + ULONG ulCount; |
| 16918 | + DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount); |
| 16919 | + printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount); |
| 16851 | 16920 | } |
| 16852 | 16921 | #endif |
| 16853 | 16922 | |
| 16854 | 16923 | /* |
| 16855 | 16924 | ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |
| | @@ -16861,36 +16930,25 @@ |
| 16861 | 16930 | ** mutex must be exited an equal number of times before another thread |
| 16862 | 16931 | ** can enter. If the same thread tries to enter any other kind of mutex |
| 16863 | 16932 | ** more than once, the behavior is undefined. |
| 16864 | 16933 | */ |
| 16865 | 16934 | static void os2MutexEnter(sqlite3_mutex *p){ |
| 16866 | | - TID tid; |
| 16867 | | - PID holder1; |
| 16868 | | - ULONG holder2; |
| 16869 | | - if( p==0 ) return; |
| 16870 | 16935 | assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); |
| 16871 | 16936 | DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT); |
| 16872 | | - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); |
| 16873 | | - p->owner = tid; |
| 16874 | | - p->nRef++; |
| 16937 | +#ifdef SQLITE_DEBUG |
| 16938 | + if( p->trace ) os2MutexTrace(p, "enter"); |
| 16939 | +#endif |
| 16875 | 16940 | } |
| 16876 | 16941 | static int os2MutexTry(sqlite3_mutex *p){ |
| 16877 | | - int rc; |
| 16878 | | - TID tid; |
| 16879 | | - PID holder1; |
| 16880 | | - ULONG holder2; |
| 16881 | | - if( p==0 ) return SQLITE_OK; |
| 16942 | + int rc = SQLITE_BUSY; |
| 16882 | 16943 | assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) ); |
| 16883 | | - if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) { |
| 16884 | | - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); |
| 16885 | | - p->owner = tid; |
| 16886 | | - p->nRef++; |
| 16944 | + if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) { |
| 16887 | 16945 | rc = SQLITE_OK; |
| 16888 | | - } else { |
| 16889 | | - rc = SQLITE_BUSY; |
| 16946 | +#ifdef SQLITE_DEBUG |
| 16947 | + if( p->trace ) os2MutexTrace(p, "try"); |
| 16948 | +#endif |
| 16890 | 16949 | } |
| 16891 | | - |
| 16892 | 16950 | return rc; |
| 16893 | 16951 | } |
| 16894 | 16952 | |
| 16895 | 16953 | /* |
| 16896 | 16954 | ** The sqlite3_mutex_leave() routine exits a mutex that was |
| | @@ -16897,23 +16955,18 @@ |
| 16897 | 16955 | ** previously entered by the same thread. The behavior |
| 16898 | 16956 | ** is undefined if the mutex is not currently entered or |
| 16899 | 16957 | ** is not currently allocated. SQLite will never do either. |
| 16900 | 16958 | */ |
| 16901 | 16959 | static void os2MutexLeave(sqlite3_mutex *p){ |
| 16902 | | - TID tid; |
| 16903 | | - PID holder1; |
| 16904 | | - ULONG holder2; |
| 16905 | | - if( p==0 ) return; |
| 16906 | | - assert( p->nRef>0 ); |
| 16907 | | - DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2); |
| 16908 | | - assert( p->owner==tid ); |
| 16909 | | - p->nRef--; |
| 16910 | | - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 16960 | + assert( os2MutexHeld(p) ); |
| 16911 | 16961 | DosReleaseMutexSem(p->mutex); |
| 16962 | +#ifdef SQLITE_DEBUG |
| 16963 | + if( p->trace ) os2MutexTrace(p, "leave"); |
| 16964 | +#endif |
| 16912 | 16965 | } |
| 16913 | 16966 | |
| 16914 | | -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 16967 | +SQLITE_PRIVATE SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 16915 | 16968 | static const sqlite3_mutex_methods sMutex = { |
| 16916 | 16969 | os2MutexInit, |
| 16917 | 16970 | os2MutexEnd, |
| 16918 | 16971 | os2MutexAlloc, |
| 16919 | 16972 | os2MutexFree, |
| | @@ -16921,10 +16974,13 @@ |
| 16921 | 16974 | os2MutexTry, |
| 16922 | 16975 | os2MutexLeave, |
| 16923 | 16976 | #ifdef SQLITE_DEBUG |
| 16924 | 16977 | os2MutexHeld, |
| 16925 | 16978 | os2MutexNotheld |
| 16979 | +#else |
| 16980 | + 0, |
| 16981 | + 0 |
| 16926 | 16982 | #endif |
| 16927 | 16983 | }; |
| 16928 | 16984 | |
| 16929 | 16985 | return &sMutex; |
| 16930 | 16986 | } |
| | @@ -17564,11 +17620,11 @@ |
| 17564 | 17620 | #else |
| 17565 | 17621 | UNUSED_PARAMETER(p); |
| 17566 | 17622 | #endif |
| 17567 | 17623 | #ifdef SQLITE_DEBUG |
| 17568 | 17624 | if( rc==SQLITE_OK && p->trace ){ |
| 17569 | | - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 17625 | + printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 17570 | 17626 | } |
| 17571 | 17627 | #endif |
| 17572 | 17628 | return rc; |
| 17573 | 17629 | } |
| 17574 | 17630 | |
| | @@ -21270,10 +21326,20 @@ |
| 21270 | 21326 | r *= TWOPOWER32; |
| 21271 | 21327 | if( sqlite3AddInt64(&r, iA0*iB0) ) return 1; |
| 21272 | 21328 | *pA = r; |
| 21273 | 21329 | return 0; |
| 21274 | 21330 | } |
| 21331 | + |
| 21332 | +/* |
| 21333 | +** Compute the absolute value of a 32-bit signed integer, of possible. Or |
| 21334 | +** if the integer has a value of -2147483648, return +2147483647 |
| 21335 | +*/ |
| 21336 | +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ |
| 21337 | + if( x>=0 ) return x; |
| 21338 | + if( x==(int)0x80000000 ) return 0x7fffffff; |
| 21339 | + return -x; |
| 21340 | +} |
| 21275 | 21341 | |
| 21276 | 21342 | /************** End of util.c ************************************************/ |
| 21277 | 21343 | /************** Begin file hash.c ********************************************/ |
| 21278 | 21344 | /* |
| 21279 | 21345 | ** 2001 September 22 |
| | @@ -22560,23 +22626,27 @@ |
| 22560 | 22626 | /* |
| 22561 | 22627 | ** This vector defines all the methods that can operate on an |
| 22562 | 22628 | ** sqlite3_file for os2. |
| 22563 | 22629 | */ |
| 22564 | 22630 | static const sqlite3_io_methods os2IoMethod = { |
| 22565 | | - 1, /* iVersion */ |
| 22566 | | - os2Close, |
| 22567 | | - os2Read, |
| 22568 | | - os2Write, |
| 22569 | | - os2Truncate, |
| 22570 | | - os2Sync, |
| 22571 | | - os2FileSize, |
| 22572 | | - os2Lock, |
| 22573 | | - os2Unlock, |
| 22574 | | - os2CheckReservedLock, |
| 22575 | | - os2FileControl, |
| 22576 | | - os2SectorSize, |
| 22577 | | - os2DeviceCharacteristics |
| 22631 | + 1, /* iVersion */ |
| 22632 | + os2Close, /* xClose */ |
| 22633 | + os2Read, /* xRead */ |
| 22634 | + os2Write, /* xWrite */ |
| 22635 | + os2Truncate, /* xTruncate */ |
| 22636 | + os2Sync, /* xSync */ |
| 22637 | + os2FileSize, /* xFileSize */ |
| 22638 | + os2Lock, /* xLock */ |
| 22639 | + os2Unlock, /* xUnlock */ |
| 22640 | + os2CheckReservedLock, /* xCheckReservedLock */ |
| 22641 | + os2FileControl, /* xFileControl */ |
| 22642 | + os2SectorSize, /* xSectorSize */ |
| 22643 | + os2DeviceCharacteristics, /* xDeviceCharacteristics */ |
| 22644 | + 0, /* xShmMap */ |
| 22645 | + 0, /* xShmLock */ |
| 22646 | + 0, /* xShmBarrier */ |
| 22647 | + 0 /* xShmUnmap */ |
| 22578 | 22648 | }; |
| 22579 | 22649 | |
| 22580 | 22650 | /*************************************************************************** |
| 22581 | 22651 | ** Here ends the I/O methods that form the sqlite3_io_methods object. |
| 22582 | 22652 | ** |
| | @@ -22664,115 +22734,151 @@ |
| 22664 | 22734 | /* |
| 22665 | 22735 | ** Open a file. |
| 22666 | 22736 | */ |
| 22667 | 22737 | static int os2Open( |
| 22668 | 22738 | sqlite3_vfs *pVfs, /* Not used */ |
| 22669 | | - const char *zName, /* Name of the file */ |
| 22739 | + const char *zName, /* Name of the file (UTF-8) */ |
| 22670 | 22740 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 22671 | 22741 | int flags, /* Open mode flags */ |
| 22672 | 22742 | int *pOutFlags /* Status return flags */ |
| 22673 | 22743 | ){ |
| 22674 | 22744 | HFILE h; |
| 22675 | | - ULONG ulFileAttribute = FILE_NORMAL; |
| 22676 | 22745 | ULONG ulOpenFlags = 0; |
| 22677 | 22746 | ULONG ulOpenMode = 0; |
| 22747 | + ULONG ulAction = 0; |
| 22748 | + ULONG rc; |
| 22678 | 22749 | os2File *pFile = (os2File*)id; |
| 22679 | | - APIRET rc = NO_ERROR; |
| 22680 | | - ULONG ulAction; |
| 22750 | + const char *zUtf8Name = zName; |
| 22681 | 22751 | char *zNameCp; |
| 22682 | | - char zTmpname[CCHMAXPATH+1]; /* Buffer to hold name of temp file */ |
| 22752 | + char zTmpname[CCHMAXPATH]; |
| 22753 | + |
| 22754 | + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); |
| 22755 | + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); |
| 22756 | + int isCreate = (flags & SQLITE_OPEN_CREATE); |
| 22757 | + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); |
| 22758 | +#ifndef NDEBUG |
| 22759 | + int isReadonly = (flags & SQLITE_OPEN_READONLY); |
| 22760 | + int eType = (flags & 0xFFFFFF00); |
| 22761 | + int isOpenJournal = (isCreate && ( |
| 22762 | + eType==SQLITE_OPEN_MASTER_JOURNAL |
| 22763 | + || eType==SQLITE_OPEN_MAIN_JOURNAL |
| 22764 | + || eType==SQLITE_OPEN_WAL |
| 22765 | + )); |
| 22766 | +#endif |
| 22767 | + |
| 22768 | + UNUSED_PARAMETER(pVfs); |
| 22769 | + assert( id!=0 ); |
| 22770 | + |
| 22771 | + /* Check the following statements are true: |
| 22772 | + ** |
| 22773 | + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and |
| 22774 | + ** (b) if CREATE is set, then READWRITE must also be set, and |
| 22775 | + ** (c) if EXCLUSIVE is set, then CREATE must also be set. |
| 22776 | + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. |
| 22777 | + */ |
| 22778 | + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); |
| 22779 | + assert(isCreate==0 || isReadWrite); |
| 22780 | + assert(isExclusive==0 || isCreate); |
| 22781 | + assert(isDelete==0 || isCreate); |
| 22782 | + |
| 22783 | + /* The main DB, main journal, WAL file and master journal are never |
| 22784 | + ** automatically deleted. Nor are they ever temporary files. */ |
| 22785 | + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); |
| 22786 | + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); |
| 22787 | + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); |
| 22788 | + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); |
| 22789 | + |
| 22790 | + /* Assert that the upper layer has set one of the "file-type" flags. */ |
| 22791 | + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB |
| 22792 | + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL |
| 22793 | + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL |
| 22794 | + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL |
| 22795 | + ); |
| 22796 | + |
| 22797 | + memset( pFile, 0, sizeof(*pFile) ); |
| 22798 | + pFile->pMethod = &os2IoMethod; |
| 22683 | 22799 | |
| 22684 | 22800 | /* If the second argument to this function is NULL, generate a |
| 22685 | 22801 | ** temporary file name to use |
| 22686 | 22802 | */ |
| 22687 | | - if( !zName ){ |
| 22688 | | - int rc = getTempname(CCHMAXPATH+1, zTmpname); |
| 22803 | + if( !zUtf8Name ){ |
| 22804 | + assert(isDelete && !isOpenJournal); |
| 22805 | + rc = getTempname(CCHMAXPATH, zTmpname); |
| 22689 | 22806 | if( rc!=SQLITE_OK ){ |
| 22690 | 22807 | return rc; |
| 22691 | 22808 | } |
| 22692 | | - zName = zTmpname; |
| 22809 | + zUtf8Name = zTmpname; |
| 22693 | 22810 | } |
| 22694 | 22811 | |
| 22695 | | - |
| 22696 | | - memset( pFile, 0, sizeof(*pFile) ); |
| 22697 | | - |
| 22698 | | - OSTRACE(( "OPEN want %d\n", flags )); |
| 22699 | | - |
| 22700 | | - if( flags & SQLITE_OPEN_READWRITE ){ |
| 22812 | + if( isReadWrite ){ |
| 22701 | 22813 | ulOpenMode |= OPEN_ACCESS_READWRITE; |
| 22702 | | - OSTRACE(( "OPEN read/write\n" )); |
| 22703 | 22814 | }else{ |
| 22704 | 22815 | ulOpenMode |= OPEN_ACCESS_READONLY; |
| 22705 | | - OSTRACE(( "OPEN read only\n" )); |
| 22706 | | - } |
| 22707 | | - |
| 22708 | | - if( flags & SQLITE_OPEN_CREATE ){ |
| 22709 | | - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW; |
| 22710 | | - OSTRACE(( "OPEN open new/create\n" )); |
| 22711 | | - }else{ |
| 22712 | | - ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW; |
| 22713 | | - OSTRACE(( "OPEN open existing\n" )); |
| 22714 | | - } |
| 22715 | | - |
| 22716 | | - if( flags & SQLITE_OPEN_MAIN_DB ){ |
| 22717 | | - ulOpenMode |= OPEN_SHARE_DENYNONE; |
| 22718 | | - OSTRACE(( "OPEN share read/write\n" )); |
| 22719 | | - }else{ |
| 22720 | | - ulOpenMode |= OPEN_SHARE_DENYWRITE; |
| 22721 | | - OSTRACE(( "OPEN share read only\n" )); |
| 22722 | | - } |
| 22723 | | - |
| 22724 | | - if( flags & SQLITE_OPEN_DELETEONCLOSE ){ |
| 22725 | | - char pathUtf8[CCHMAXPATH]; |
| 22726 | | -#ifdef NDEBUG /* when debugging we want to make sure it is deleted */ |
| 22727 | | - ulFileAttribute = FILE_HIDDEN; |
| 22728 | | -#endif |
| 22729 | | - os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 ); |
| 22730 | | - pFile->pathToDel = convertUtf8PathToCp( pathUtf8 ); |
| 22731 | | - OSTRACE(( "OPEN hidden/delete on close file attributes\n" )); |
| 22732 | | - }else{ |
| 22733 | | - pFile->pathToDel = NULL; |
| 22734 | | - OSTRACE(( "OPEN normal file attribute\n" )); |
| 22735 | | - } |
| 22736 | | - |
| 22737 | | - /* always open in random access mode for possibly better speed */ |
| 22816 | + } |
| 22817 | + |
| 22818 | + /* Open in random access mode for possibly better speed. Allow full |
| 22819 | + ** sharing because file locks will provide exclusive access when needed. |
| 22820 | + */ |
| 22738 | 22821 | ulOpenMode |= OPEN_FLAGS_RANDOM; |
| 22739 | 22822 | ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR; |
| 22740 | 22823 | ulOpenMode |= OPEN_FLAGS_NOINHERIT; |
| 22824 | + ulOpenMode |= OPEN_SHARE_DENYNONE; |
| 22741 | 22825 | |
| 22742 | | - zNameCp = convertUtf8PathToCp( zName ); |
| 22826 | + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is |
| 22827 | + ** created. SQLite doesn't use it to indicate "exclusive access" |
| 22828 | + ** as it is usually understood. |
| 22829 | + */ |
| 22830 | + if( isExclusive ){ |
| 22831 | + /* Creates a new file, only if it does not already exist. */ |
| 22832 | + /* If the file exists, it fails. */ |
| 22833 | + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS; |
| 22834 | + }else if( isCreate ){ |
| 22835 | + /* Open existing file, or create if it doesn't exist */ |
| 22836 | + ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; |
| 22837 | + }else{ |
| 22838 | + /* Opens a file, only if it exists. */ |
| 22839 | + ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS; |
| 22840 | + } |
| 22841 | + |
| 22842 | + /* For DELETEONCLOSE, save a pointer to the converted filename */ |
| 22843 | + if( isDelete ){ |
| 22844 | + char pathUtf8[CCHMAXPATH]; |
| 22845 | + os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 ); |
| 22846 | + pFile->pathToDel = convertUtf8PathToCp( pathUtf8 ); |
| 22847 | + } |
| 22848 | + |
| 22849 | + zNameCp = convertUtf8PathToCp( zUtf8Name ); |
| 22743 | 22850 | rc = DosOpen( (PSZ)zNameCp, |
| 22744 | 22851 | &h, |
| 22745 | 22852 | &ulAction, |
| 22746 | 22853 | 0L, |
| 22747 | | - ulFileAttribute, |
| 22854 | + FILE_NORMAL, |
| 22748 | 22855 | ulOpenFlags, |
| 22749 | 22856 | ulOpenMode, |
| 22750 | 22857 | (PEAOP2)NULL ); |
| 22751 | 22858 | free( zNameCp ); |
| 22859 | + |
| 22752 | 22860 | if( rc != NO_ERROR ){ |
| 22753 | | - OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n", |
| 22754 | | - rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode )); |
| 22861 | + OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n", |
| 22862 | + rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode )); |
| 22755 | 22863 | if( pFile->pathToDel ) |
| 22756 | 22864 | free( pFile->pathToDel ); |
| 22757 | 22865 | pFile->pathToDel = NULL; |
| 22758 | | - if( flags & SQLITE_OPEN_READWRITE ){ |
| 22759 | | - OSTRACE(( "OPEN %d Invalid handle\n", |
| 22760 | | - ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) )); |
| 22866 | + |
| 22867 | + if( isReadWrite ){ |
| 22761 | 22868 | return os2Open( pVfs, zName, id, |
| 22762 | | - ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE), |
| 22869 | + ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 22763 | 22870 | pOutFlags ); |
| 22764 | 22871 | }else{ |
| 22765 | 22872 | return SQLITE_CANTOPEN; |
| 22766 | 22873 | } |
| 22767 | 22874 | } |
| 22768 | 22875 | |
| 22769 | 22876 | if( pOutFlags ){ |
| 22770 | | - *pOutFlags = flags & SQLITE_OPEN_READWRITE ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; |
| 22877 | + *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; |
| 22771 | 22878 | } |
| 22772 | 22879 | |
| 22773 | | - pFile->pMethod = &os2IoMethod; |
| 22774 | 22880 | pFile->h = h; |
| 22775 | 22881 | OpenCounter(+1); |
| 22776 | 22882 | OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags )); |
| 22777 | 22883 | return SQLITE_OK; |
| 22778 | 22884 | } |
| | @@ -22783,17 +22889,20 @@ |
| 22783 | 22889 | static int os2Delete( |
| 22784 | 22890 | sqlite3_vfs *pVfs, /* Not used on os2 */ |
| 22785 | 22891 | const char *zFilename, /* Name of file to delete */ |
| 22786 | 22892 | int syncDir /* Not used on os2 */ |
| 22787 | 22893 | ){ |
| 22788 | | - APIRET rc = NO_ERROR; |
| 22789 | | - char *zFilenameCp = convertUtf8PathToCp( zFilename ); |
| 22894 | + APIRET rc; |
| 22895 | + char *zFilenameCp; |
| 22790 | 22896 | SimulateIOError( return SQLITE_IOERR_DELETE ); |
| 22897 | + zFilenameCp = convertUtf8PathToCp( zFilename ); |
| 22791 | 22898 | rc = DosDelete( (PSZ)zFilenameCp ); |
| 22792 | 22899 | free( zFilenameCp ); |
| 22793 | 22900 | OSTRACE(( "DELETE \"%s\"\n", zFilename )); |
| 22794 | | - return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_DELETE; |
| 22901 | + return (rc == NO_ERROR || |
| 22902 | + rc == ERROR_FILE_NOT_FOUND || |
| 22903 | + rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE; |
| 22795 | 22904 | } |
| 22796 | 22905 | |
| 22797 | 22906 | /* |
| 22798 | 22907 | ** Check the existance and status of a file. |
| 22799 | 22908 | */ |
| | @@ -22854,11 +22963,11 @@ |
| 22854 | 22963 | ** os2Dlopen returns zero if DosLoadModule is not successful. |
| 22855 | 22964 | */ |
| 22856 | 22965 | static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 22857 | 22966 | /* no-op */ |
| 22858 | 22967 | } |
| 22859 | | -static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ |
| 22968 | +static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){ |
| 22860 | 22969 | PFN pfn; |
| 22861 | 22970 | APIRET rc; |
| 22862 | 22971 | rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn); |
| 22863 | 22972 | if( rc != NO_ERROR ){ |
| 22864 | 22973 | /* if the symbol itself was not found, search again for the same |
| | @@ -22866,11 +22975,11 @@ |
| 22866 | 22975 | * on the calling convention */ |
| 22867 | 22976 | char _zSymbol[256] = "_"; |
| 22868 | 22977 | strncat(_zSymbol, zSymbol, 255); |
| 22869 | 22978 | rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn); |
| 22870 | 22979 | } |
| 22871 | | - return rc != NO_ERROR ? 0 : (void*)pfn; |
| 22980 | + return rc != NO_ERROR ? 0 : (void(*)(void))pfn; |
| 22872 | 22981 | } |
| 22873 | 22982 | static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){ |
| 22874 | 22983 | DosFreeModule((HMODULE)pHandle); |
| 22875 | 22984 | } |
| 22876 | 22985 | #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ |
| | @@ -22970,14 +23079,15 @@ |
| 22970 | 23079 | ** return 0. Return 1 if the time and date cannot be found. |
| 22971 | 23080 | */ |
| 22972 | 23081 | int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){ |
| 22973 | 23082 | double now; |
| 22974 | 23083 | SHORT minute; /* needs to be able to cope with negative timezone offset */ |
| 22975 | | - USHORT second, hour, |
| 23084 | + USHORT hundredths, second, hour, |
| 22976 | 23085 | day, month, year; |
| 22977 | 23086 | DATETIME dt; |
| 22978 | 23087 | DosGetDateTime( &dt ); |
| 23088 | + hundredths = (USHORT)dt.hundredths; |
| 22979 | 23089 | second = (USHORT)dt.seconds; |
| 22980 | 23090 | minute = (SHORT)dt.minutes + dt.timezone; |
| 22981 | 23091 | hour = (USHORT)dt.hours; |
| 22982 | 23092 | day = (USHORT)dt.day; |
| 22983 | 23093 | month = (USHORT)dt.month; |
| | @@ -22993,18 +23103,35 @@ |
| 22993 | 23103 | |
| 22994 | 23104 | /* Add the fractional hours, mins and seconds */ |
| 22995 | 23105 | now += (hour + 12.0)/24.0; |
| 22996 | 23106 | now += minute/1440.0; |
| 22997 | 23107 | now += second/86400.0; |
| 23108 | + now += hundredths/8640000.0; |
| 22998 | 23109 | *prNow = now; |
| 22999 | 23110 | #ifdef SQLITE_TEST |
| 23000 | 23111 | if( sqlite3_current_time ){ |
| 23001 | 23112 | *prNow = sqlite3_current_time/86400.0 + 2440587.5; |
| 23002 | 23113 | } |
| 23003 | 23114 | #endif |
| 23004 | 23115 | return 0; |
| 23005 | 23116 | } |
| 23117 | + |
| 23118 | +/* |
| 23119 | +** Find the current time (in Universal Coordinated Time). Write into *piNow |
| 23120 | +** the current time and date as a Julian Day number times 86_400_000. In |
| 23121 | +** other words, write into *piNow the number of milliseconds since the Julian |
| 23122 | +** epoch of noon in Greenwich on November 24, 4714 B.C according to the |
| 23123 | +** proleptic Gregorian calendar. |
| 23124 | +** |
| 23125 | +** On success, return 0. Return 1 if the time and date cannot be found. |
| 23126 | +*/ |
| 23127 | +static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ |
| 23128 | + double now; |
| 23129 | + os2CurrentTime(pVfs, &now); |
| 23130 | + *piNow = now * 86400000; |
| 23131 | + return 0; |
| 23132 | +} |
| 23006 | 23133 | |
| 23007 | 23134 | static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 23008 | 23135 | return 0; |
| 23009 | 23136 | } |
| 23010 | 23137 | |
| | @@ -23011,11 +23138,11 @@ |
| 23011 | 23138 | /* |
| 23012 | 23139 | ** Initialize and deinitialize the operating system interface. |
| 23013 | 23140 | */ |
| 23014 | 23141 | SQLITE_API int sqlite3_os_init(void){ |
| 23015 | 23142 | static sqlite3_vfs os2Vfs = { |
| 23016 | | - 1, /* iVersion */ |
| 23143 | + 3, /* iVersion */ |
| 23017 | 23144 | sizeof(os2File), /* szOsFile */ |
| 23018 | 23145 | CCHMAXPATH, /* mxPathname */ |
| 23019 | 23146 | 0, /* pNext */ |
| 23020 | 23147 | "os2", /* zName */ |
| 23021 | 23148 | 0, /* pAppData */ |
| | @@ -23030,10 +23157,14 @@ |
| 23030 | 23157 | os2DlClose, /* xDlClose */ |
| 23031 | 23158 | os2Randomness, /* xRandomness */ |
| 23032 | 23159 | os2Sleep, /* xSleep */ |
| 23033 | 23160 | os2CurrentTime, /* xCurrentTime */ |
| 23034 | 23161 | os2GetLastError, /* xGetLastError */ |
| 23162 | + os2CurrentTimeInt64 /* xCurrentTimeInt64 */ |
| 23163 | + 0, /* xSetSystemCall */ |
| 23164 | + 0, /* xGetSystemCall */ |
| 23165 | + 0, /* xNextSystemCall */ |
| 23035 | 23166 | }; |
| 23036 | 23167 | sqlite3_vfs_register(&os2Vfs, 1); |
| 23037 | 23168 | initUconvObjects(); |
| 23038 | 23169 | return SQLITE_OK; |
| 23039 | 23170 | } |
| | @@ -23249,14 +23380,14 @@ |
| 23249 | 23380 | sqlite3_io_methods const *pMethod; /* Always the first entry */ |
| 23250 | 23381 | unixInodeInfo *pInode; /* Info about locks on this inode */ |
| 23251 | 23382 | int h; /* The file descriptor */ |
| 23252 | 23383 | int dirfd; /* File descriptor for the directory */ |
| 23253 | 23384 | unsigned char eFileLock; /* The type of lock held on this fd */ |
| 23385 | + unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ |
| 23254 | 23386 | int lastErrno; /* The unix errno from last I/O error */ |
| 23255 | 23387 | void *lockingContext; /* Locking style specific state */ |
| 23256 | 23388 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23257 | | - int fileFlags; /* Miscellanous flags */ |
| 23258 | 23389 | const char *zPath; /* Name of the file */ |
| 23259 | 23390 | unixShm *pShm; /* Shared memory segment information */ |
| 23260 | 23391 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23261 | 23392 | #if SQLITE_ENABLE_LOCKING_STYLE |
| 23262 | 23393 | int openFlags; /* The flags specified at open() */ |
| | @@ -23287,13 +23418,14 @@ |
| 23287 | 23418 | char aPadding[32]; |
| 23288 | 23419 | #endif |
| 23289 | 23420 | }; |
| 23290 | 23421 | |
| 23291 | 23422 | /* |
| 23292 | | -** The following macros define bits in unixFile.fileFlags |
| 23423 | +** Allowed values for the unixFile.ctrlFlags bitmask: |
| 23293 | 23424 | */ |
| 23294 | | -#define SQLITE_WHOLE_FILE_LOCKING 0x0001 /* Use whole-file locking */ |
| 23425 | +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ |
| 23426 | +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ |
| 23295 | 23427 | |
| 23296 | 23428 | /* |
| 23297 | 23429 | ** Include code that is common to all os_*.c files |
| 23298 | 23430 | */ |
| 23299 | 23431 | /************** Include os_common.h in the middle of os_unix.c ***************/ |
| | @@ -23518,20 +23650,10 @@ |
| 23518 | 23650 | #endif |
| 23519 | 23651 | #ifndef O_BINARY |
| 23520 | 23652 | # define O_BINARY 0 |
| 23521 | 23653 | #endif |
| 23522 | 23654 | |
| 23523 | | -/* |
| 23524 | | -** The DJGPP compiler environment looks mostly like Unix, but it |
| 23525 | | -** lacks the fcntl() system call. So redefine fcntl() to be something |
| 23526 | | -** that always succeeds. This means that locking does not occur under |
| 23527 | | -** DJGPP. But it is DOS - what did you expect? |
| 23528 | | -*/ |
| 23529 | | -#ifdef __DJGPP__ |
| 23530 | | -# define fcntl(A,B,C) 0 |
| 23531 | | -#endif |
| 23532 | | - |
| 23533 | 23655 | /* |
| 23534 | 23656 | ** The threadid macro resolves to the thread-id or to 0. Used for |
| 23535 | 23657 | ** testing and debugging only. |
| 23536 | 23658 | */ |
| 23537 | 23659 | #if SQLITE_THREADSAFE |
| | @@ -23538,10 +23660,197 @@ |
| 23538 | 23660 | #define threadid pthread_self() |
| 23539 | 23661 | #else |
| 23540 | 23662 | #define threadid 0 |
| 23541 | 23663 | #endif |
| 23542 | 23664 | |
| 23665 | +/* |
| 23666 | +** Many system calls are accessed through pointer-to-functions so that |
| 23667 | +** they may be overridden at runtime to facilitate fault injection during |
| 23668 | +** testing and sandboxing. The following array holds the names and pointers |
| 23669 | +** to all overrideable system calls. |
| 23670 | +*/ |
| 23671 | +static struct unix_syscall { |
| 23672 | + const char *zName; /* Name of the sytem call */ |
| 23673 | + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ |
| 23674 | + sqlite3_syscall_ptr pDefault; /* Default value */ |
| 23675 | +} aSyscall[] = { |
| 23676 | + { "open", (sqlite3_syscall_ptr)open, 0 }, |
| 23677 | +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) |
| 23678 | + |
| 23679 | + { "close", (sqlite3_syscall_ptr)close, 0 }, |
| 23680 | +#define osClose ((int(*)(int))aSyscall[1].pCurrent) |
| 23681 | + |
| 23682 | + { "access", (sqlite3_syscall_ptr)access, 0 }, |
| 23683 | +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) |
| 23684 | + |
| 23685 | + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, |
| 23686 | +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) |
| 23687 | + |
| 23688 | + { "stat", (sqlite3_syscall_ptr)stat, 0 }, |
| 23689 | +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) |
| 23690 | + |
| 23691 | +/* |
| 23692 | +** The DJGPP compiler environment looks mostly like Unix, but it |
| 23693 | +** lacks the fcntl() system call. So redefine fcntl() to be something |
| 23694 | +** that always succeeds. This means that locking does not occur under |
| 23695 | +** DJGPP. But it is DOS - what did you expect? |
| 23696 | +*/ |
| 23697 | +#ifdef __DJGPP__ |
| 23698 | + { "fstat", 0, 0 }, |
| 23699 | +#define osFstat(a,b,c) 0 |
| 23700 | +#else |
| 23701 | + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, |
| 23702 | +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) |
| 23703 | +#endif |
| 23704 | + |
| 23705 | + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, |
| 23706 | +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) |
| 23707 | + |
| 23708 | + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, |
| 23709 | +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) |
| 23710 | + |
| 23711 | + { "read", (sqlite3_syscall_ptr)read, 0 }, |
| 23712 | +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) |
| 23713 | + |
| 23714 | +#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE) |
| 23715 | + { "pread", (sqlite3_syscall_ptr)pread, 0 }, |
| 23716 | +#else |
| 23717 | + { "pread", (sqlite3_syscall_ptr)0, 0 }, |
| 23718 | +#endif |
| 23719 | +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) |
| 23720 | + |
| 23721 | +#if defined(USE_PREAD64) |
| 23722 | + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, |
| 23723 | +#else |
| 23724 | + { "pread64", (sqlite3_syscall_ptr)0, 0 }, |
| 23725 | +#endif |
| 23726 | +#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) |
| 23727 | + |
| 23728 | + { "write", (sqlite3_syscall_ptr)write, 0 }, |
| 23729 | +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) |
| 23730 | + |
| 23731 | +#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE) |
| 23732 | + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, |
| 23733 | +#else |
| 23734 | + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, |
| 23735 | +#endif |
| 23736 | +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ |
| 23737 | + aSyscall[12].pCurrent) |
| 23738 | + |
| 23739 | +#if defined(USE_PREAD64) |
| 23740 | + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, |
| 23741 | +#else |
| 23742 | + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, |
| 23743 | +#endif |
| 23744 | +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ |
| 23745 | + aSyscall[13].pCurrent) |
| 23746 | + |
| 23747 | + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, |
| 23748 | +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) |
| 23749 | + |
| 23750 | +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
| 23751 | + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, |
| 23752 | +#else |
| 23753 | + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, |
| 23754 | +#endif |
| 23755 | +#define osFallocate ((int(*)(int,off_t,off_t)aSyscall[15].pCurrent) |
| 23756 | + |
| 23757 | +}; /* End of the overrideable system calls */ |
| 23758 | + |
| 23759 | +/* |
| 23760 | +** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| 23761 | +** "unix" VFSes. Return SQLITE_OK opon successfully updating the |
| 23762 | +** system call pointer, or SQLITE_NOTFOUND if there is no configurable |
| 23763 | +** system call named zName. |
| 23764 | +*/ |
| 23765 | +static int unixSetSystemCall( |
| 23766 | + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ |
| 23767 | + const char *zName, /* Name of system call to override */ |
| 23768 | + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ |
| 23769 | +){ |
| 23770 | + unsigned int i; |
| 23771 | + int rc = SQLITE_NOTFOUND; |
| 23772 | + |
| 23773 | + UNUSED_PARAMETER(pNotUsed); |
| 23774 | + if( zName==0 ){ |
| 23775 | + /* If no zName is given, restore all system calls to their default |
| 23776 | + ** settings and return NULL |
| 23777 | + */ |
| 23778 | + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ |
| 23779 | + if( aSyscall[i].pDefault ){ |
| 23780 | + aSyscall[i].pCurrent = aSyscall[i].pDefault; |
| 23781 | + rc = SQLITE_OK; |
| 23782 | + } |
| 23783 | + } |
| 23784 | + }else{ |
| 23785 | + /* If zName is specified, operate on only the one system call |
| 23786 | + ** specified. |
| 23787 | + */ |
| 23788 | + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ |
| 23789 | + if( strcmp(zName, aSyscall[i].zName)==0 ){ |
| 23790 | + if( aSyscall[i].pDefault==0 ){ |
| 23791 | + aSyscall[i].pDefault = aSyscall[i].pCurrent; |
| 23792 | + } |
| 23793 | + rc = SQLITE_OK; |
| 23794 | + if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault; |
| 23795 | + aSyscall[i].pCurrent = pNewFunc; |
| 23796 | + break; |
| 23797 | + } |
| 23798 | + } |
| 23799 | + } |
| 23800 | + return rc; |
| 23801 | +} |
| 23802 | + |
| 23803 | +/* |
| 23804 | +** Return the value of a system call. Return NULL if zName is not a |
| 23805 | +** recognized system call name. NULL is also returned if the system call |
| 23806 | +** is currently undefined. |
| 23807 | +*/ |
| 23808 | +static sqlite3_syscall_ptr unixGetSystemCall( |
| 23809 | + sqlite3_vfs *pNotUsed, |
| 23810 | + const char *zName |
| 23811 | +){ |
| 23812 | + unsigned int i; |
| 23813 | + |
| 23814 | + UNUSED_PARAMETER(pNotUsed); |
| 23815 | + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ |
| 23816 | + if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent; |
| 23817 | + } |
| 23818 | + return 0; |
| 23819 | +} |
| 23820 | + |
| 23821 | +/* |
| 23822 | +** Return the name of the first system call after zName. If zName==NULL |
| 23823 | +** then return the name of the first system call. Return NULL if zName |
| 23824 | +** is the last system call or if zName is not the name of a valid |
| 23825 | +** system call. |
| 23826 | +*/ |
| 23827 | +static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){ |
| 23828 | + unsigned int i; |
| 23829 | + |
| 23830 | + UNUSED_PARAMETER(p); |
| 23831 | + if( zName==0 ){ |
| 23832 | + i = -1; |
| 23833 | + }else{ |
| 23834 | + for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0])-1; i++){ |
| 23835 | + if( strcmp(zName, aSyscall[0].zName)==0 ) break; |
| 23836 | + } |
| 23837 | + } |
| 23838 | + for(i++; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){ |
| 23839 | + if( aSyscall[0].pCurrent!=0 ) return aSyscall[0].zName; |
| 23840 | + } |
| 23841 | + return 0; |
| 23842 | +} |
| 23843 | + |
| 23844 | +/* |
| 23845 | +** Retry open() calls that fail due to EINTR |
| 23846 | +*/ |
| 23847 | +static int robust_open(const char *z, int f, int m){ |
| 23848 | + int rc; |
| 23849 | + do{ rc = osOpen(z,f,m); }while( rc<0 && errno==EINTR ); |
| 23850 | + return rc; |
| 23851 | +} |
| 23543 | 23852 | |
| 23544 | 23853 | /* |
| 23545 | 23854 | ** Helper functions to obtain and relinquish the global mutex. The |
| 23546 | 23855 | ** global mutex is used to protect the unixInodeInfo and |
| 23547 | 23856 | ** vxworksFileId objects used by this file, all of which may be |
| | @@ -23602,11 +23911,11 @@ |
| 23602 | 23911 | if( op==F_GETLK ){ |
| 23603 | 23912 | zOpName = "GETLK"; |
| 23604 | 23913 | }else if( op==F_SETLK ){ |
| 23605 | 23914 | zOpName = "SETLK"; |
| 23606 | 23915 | }else{ |
| 23607 | | - s = fcntl(fd, op, p); |
| 23916 | + s = osFcntl(fd, op, p); |
| 23608 | 23917 | sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); |
| 23609 | 23918 | return s; |
| 23610 | 23919 | } |
| 23611 | 23920 | if( p->l_type==F_RDLCK ){ |
| 23612 | 23921 | zType = "RDLCK"; |
| | @@ -23616,19 +23925,19 @@ |
| 23616 | 23925 | zType = "UNLCK"; |
| 23617 | 23926 | }else{ |
| 23618 | 23927 | assert( 0 ); |
| 23619 | 23928 | } |
| 23620 | 23929 | assert( p->l_whence==SEEK_SET ); |
| 23621 | | - s = fcntl(fd, op, p); |
| 23930 | + s = osFcntl(fd, op, p); |
| 23622 | 23931 | savedErrno = errno; |
| 23623 | 23932 | sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", |
| 23624 | 23933 | threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, |
| 23625 | 23934 | (int)p->l_pid, s); |
| 23626 | 23935 | if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ |
| 23627 | 23936 | struct flock l2; |
| 23628 | 23937 | l2 = *p; |
| 23629 | | - fcntl(fd, F_GETLK, &l2); |
| 23938 | + osFcntl(fd, F_GETLK, &l2); |
| 23630 | 23939 | if( l2.l_type==F_RDLCK ){ |
| 23631 | 23940 | zType = "RDLCK"; |
| 23632 | 23941 | }else if( l2.l_type==F_WRLCK ){ |
| 23633 | 23942 | zType = "WRLCK"; |
| 23634 | 23943 | }else if( l2.l_type==F_UNLCK ){ |
| | @@ -23640,27 +23949,22 @@ |
| 23640 | 23949 | zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); |
| 23641 | 23950 | } |
| 23642 | 23951 | errno = savedErrno; |
| 23643 | 23952 | return s; |
| 23644 | 23953 | } |
| 23645 | | -#define fcntl lockTrace |
| 23954 | +#undef osFcntl |
| 23955 | +#define osFcntl lockTrace |
| 23646 | 23956 | #endif /* SQLITE_LOCK_TRACE */ |
| 23647 | | - |
| 23648 | 23957 | |
| 23649 | 23958 | /* |
| 23650 | 23959 | ** Retry ftruncate() calls that fail due to EINTR |
| 23651 | 23960 | */ |
| 23652 | | -#ifdef EINTR |
| 23653 | 23961 | static int robust_ftruncate(int h, sqlite3_int64 sz){ |
| 23654 | 23962 | int rc; |
| 23655 | | - do{ rc = ftruncate(h,sz); }while( rc<0 && errno==EINTR ); |
| 23963 | + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); |
| 23656 | 23964 | return rc; |
| 23657 | 23965 | } |
| 23658 | | -#else |
| 23659 | | -# define robust_ftruncate(a,b) ftruncate(a,b) |
| 23660 | | -#endif |
| 23661 | | - |
| 23662 | 23966 | |
| 23663 | 23967 | /* |
| 23664 | 23968 | ** This routine translates a standard POSIX errno code into something |
| 23665 | 23969 | ** useful to the clients of the sqlite3 functions. Specifically, it is |
| 23666 | 23970 | ** intended to translate a variety of "try again" errors into SQLITE_BUSY |
| | @@ -23978,11 +24282,12 @@ |
| 23978 | 24282 | ** object keeps a count of the number of unixFile pointing to it. |
| 23979 | 24283 | */ |
| 23980 | 24284 | struct unixInodeInfo { |
| 23981 | 24285 | struct unixFileId fileId; /* The lookup key */ |
| 23982 | 24286 | int nShared; /* Number of SHARED locks held */ |
| 23983 | | - int eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ |
| 24287 | + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ |
| 24288 | + unsigned char bProcessLock; /* An exclusive process lock is held */ |
| 23984 | 24289 | int nRef; /* Number of pointers to this structure */ |
| 23985 | 24290 | unixShmNode *pShmNode; /* Shared memory associated with this inode */ |
| 23986 | 24291 | int nLock; /* Number of outstanding file locks */ |
| 23987 | 24292 | UnixUnusedFd *pUnused; /* Unused file descriptors to close */ |
| 23988 | 24293 | unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ |
| | @@ -24083,11 +24388,11 @@ |
| 24083 | 24388 | ** file descriptor might have already been reused by another thread. |
| 24084 | 24389 | ** So we don't even try to recover from an EINTR. Just log the error |
| 24085 | 24390 | ** and move on. |
| 24086 | 24391 | */ |
| 24087 | 24392 | static void robust_close(unixFile *pFile, int h, int lineno){ |
| 24088 | | - if( close(h) ){ |
| 24393 | + if( osClose(h) ){ |
| 24089 | 24394 | unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", |
| 24090 | 24395 | pFile ? pFile->zPath : 0, lineno); |
| 24091 | 24396 | } |
| 24092 | 24397 | } |
| 24093 | 24398 | |
| | @@ -24160,11 +24465,11 @@ |
| 24160 | 24465 | |
| 24161 | 24466 | /* Get low-level information about the file that we can used to |
| 24162 | 24467 | ** create a unique name for the file. |
| 24163 | 24468 | */ |
| 24164 | 24469 | fd = pFile->h; |
| 24165 | | - rc = fstat(fd, &statbuf); |
| 24470 | + rc = osFstat(fd, &statbuf); |
| 24166 | 24471 | if( rc!=0 ){ |
| 24167 | 24472 | pFile->lastErrno = errno; |
| 24168 | 24473 | #ifdef EOVERFLOW |
| 24169 | 24474 | if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; |
| 24170 | 24475 | #endif |
| | @@ -24181,16 +24486,16 @@ |
| 24181 | 24486 | ** in the header of every SQLite database. In this way, if there |
| 24182 | 24487 | ** is a race condition such that another thread has already populated |
| 24183 | 24488 | ** the first page of the database, no damage is done. |
| 24184 | 24489 | */ |
| 24185 | 24490 | if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ |
| 24186 | | - do{ rc = write(fd, "S", 1); }while( rc<0 && errno==EINTR ); |
| 24491 | + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); |
| 24187 | 24492 | if( rc!=1 ){ |
| 24188 | 24493 | pFile->lastErrno = errno; |
| 24189 | 24494 | return SQLITE_IOERR; |
| 24190 | 24495 | } |
| 24191 | | - rc = fstat(fd, &statbuf); |
| 24496 | + rc = osFstat(fd, &statbuf); |
| 24192 | 24497 | if( rc!=0 ){ |
| 24193 | 24498 | pFile->lastErrno = errno; |
| 24194 | 24499 | return SQLITE_IOERR; |
| 24195 | 24500 | } |
| 24196 | 24501 | } |
| | @@ -24249,17 +24554,17 @@ |
| 24249 | 24554 | } |
| 24250 | 24555 | |
| 24251 | 24556 | /* Otherwise see if some other process holds it. |
| 24252 | 24557 | */ |
| 24253 | 24558 | #ifndef __DJGPP__ |
| 24254 | | - if( !reserved ){ |
| 24559 | + if( !reserved && !pFile->pInode->bProcessLock ){ |
| 24255 | 24560 | struct flock lock; |
| 24256 | 24561 | lock.l_whence = SEEK_SET; |
| 24257 | 24562 | lock.l_start = RESERVED_BYTE; |
| 24258 | 24563 | lock.l_len = 1; |
| 24259 | 24564 | lock.l_type = F_WRLCK; |
| 24260 | | - if (-1 == fcntl(pFile->h, F_GETLK, &lock)) { |
| 24565 | + if (-1 == osFcntl(pFile->h, F_GETLK, &lock)) { |
| 24261 | 24566 | int tErrno = errno; |
| 24262 | 24567 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); |
| 24263 | 24568 | pFile->lastErrno = tErrno; |
| 24264 | 24569 | } else if( lock.l_type!=F_UNLCK ){ |
| 24265 | 24570 | reserved = 1; |
| | @@ -24271,10 +24576,54 @@ |
| 24271 | 24576 | OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); |
| 24272 | 24577 | |
| 24273 | 24578 | *pResOut = reserved; |
| 24274 | 24579 | return rc; |
| 24275 | 24580 | } |
| 24581 | + |
| 24582 | +/* |
| 24583 | +** Attempt to set a system-lock on the file pFile. The lock is |
| 24584 | +** described by pLock. |
| 24585 | +** |
| 24586 | +** If the pFile was opened read/write from unix-excl, then the only lock |
| 24587 | +** ever obtained is an exclusive lock, and it is obtained exactly once |
| 24588 | +** the first time any lock is attempted. All subsequent system locking |
| 24589 | +** operations become no-ops. Locking operations still happen internally, |
| 24590 | +** in order to coordinate access between separate database connections |
| 24591 | +** within this process, but all of that is handled in memory and the |
| 24592 | +** operating system does not participate. |
| 24593 | +** |
| 24594 | +** This function is a pass-through to fcntl(F_SETLK) if pFile is using |
| 24595 | +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" |
| 24596 | +** and is read-only. |
| 24597 | +*/ |
| 24598 | +static int unixFileLock(unixFile *pFile, struct flock *pLock){ |
| 24599 | + int rc; |
| 24600 | + unixInodeInfo *pInode = pFile->pInode; |
| 24601 | + assert( unixMutexHeld() ); |
| 24602 | + assert( pInode!=0 ); |
| 24603 | + if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) |
| 24604 | + && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) |
| 24605 | + ){ |
| 24606 | + if( pInode->bProcessLock==0 ){ |
| 24607 | + struct flock lock; |
| 24608 | + assert( pInode->nLock==0 ); |
| 24609 | + lock.l_whence = SEEK_SET; |
| 24610 | + lock.l_start = SHARED_FIRST; |
| 24611 | + lock.l_len = SHARED_SIZE; |
| 24612 | + lock.l_type = F_WRLCK; |
| 24613 | + rc = osFcntl(pFile->h, F_SETLK, &lock); |
| 24614 | + if( rc<0 ) return rc; |
| 24615 | + pInode->bProcessLock = 1; |
| 24616 | + pInode->nLock++; |
| 24617 | + }else{ |
| 24618 | + rc = 0; |
| 24619 | + } |
| 24620 | + }else{ |
| 24621 | + rc = osFcntl(pFile->h, F_SETLK, pLock); |
| 24622 | + } |
| 24623 | + return rc; |
| 24624 | +} |
| 24276 | 24625 | |
| 24277 | 24626 | /* |
| 24278 | 24627 | ** Lock the file with the lock specified by parameter eFileLock - one |
| 24279 | 24628 | ** of the following: |
| 24280 | 24629 | ** |
| | @@ -24408,11 +24757,11 @@ |
| 24408 | 24757 | if( eFileLock==SHARED_LOCK |
| 24409 | 24758 | || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) |
| 24410 | 24759 | ){ |
| 24411 | 24760 | lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); |
| 24412 | 24761 | lock.l_start = PENDING_BYTE; |
| 24413 | | - s = fcntl(pFile->h, F_SETLK, &lock); |
| 24762 | + s = unixFileLock(pFile, &lock); |
| 24414 | 24763 | if( s==(-1) ){ |
| 24415 | 24764 | tErrno = errno; |
| 24416 | 24765 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
| 24417 | 24766 | if( IS_LOCK_ERROR(rc) ){ |
| 24418 | 24767 | pFile->lastErrno = tErrno; |
| | @@ -24430,18 +24779,18 @@ |
| 24430 | 24779 | assert( pInode->eFileLock==0 ); |
| 24431 | 24780 | |
| 24432 | 24781 | /* Now get the read-lock */ |
| 24433 | 24782 | lock.l_start = SHARED_FIRST; |
| 24434 | 24783 | lock.l_len = SHARED_SIZE; |
| 24435 | | - if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){ |
| 24784 | + if( (s = unixFileLock(pFile, &lock))==(-1) ){ |
| 24436 | 24785 | tErrno = errno; |
| 24437 | 24786 | } |
| 24438 | 24787 | /* Drop the temporary PENDING lock */ |
| 24439 | 24788 | lock.l_start = PENDING_BYTE; |
| 24440 | 24789 | lock.l_len = 1L; |
| 24441 | 24790 | lock.l_type = F_UNLCK; |
| 24442 | | - if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ |
| 24791 | + if( unixFileLock(pFile, &lock)!=0 ){ |
| 24443 | 24792 | if( s != -1 ){ |
| 24444 | 24793 | /* This could happen with a network mount */ |
| 24445 | 24794 | tErrno = errno; |
| 24446 | 24795 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
| 24447 | 24796 | if( IS_LOCK_ERROR(rc) ){ |
| | @@ -24480,11 +24829,11 @@ |
| 24480 | 24829 | lock.l_len = SHARED_SIZE; |
| 24481 | 24830 | break; |
| 24482 | 24831 | default: |
| 24483 | 24832 | assert(0); |
| 24484 | 24833 | } |
| 24485 | | - s = fcntl(pFile->h, F_SETLK, &lock); |
| 24834 | + s = unixFileLock(pFile, &lock); |
| 24486 | 24835 | if( s==(-1) ){ |
| 24487 | 24836 | tErrno = errno; |
| 24488 | 24837 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); |
| 24489 | 24838 | if( IS_LOCK_ERROR(rc) ){ |
| 24490 | 24839 | pFile->lastErrno = tErrno; |
| | @@ -24549,11 +24898,11 @@ |
| 24549 | 24898 | ** the byte range is divided into 2 parts and the first part is unlocked then |
| 24550 | 24899 | ** set to a read lock, then the other part is simply unlocked. This works |
| 24551 | 24900 | ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to |
| 24552 | 24901 | ** remove the write lock on a region when a read lock is set. |
| 24553 | 24902 | */ |
| 24554 | | -static int _posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ |
| 24903 | +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ |
| 24555 | 24904 | unixFile *pFile = (unixFile*)id; |
| 24556 | 24905 | unixInodeInfo *pInode; |
| 24557 | 24906 | struct flock lock; |
| 24558 | 24907 | int rc = SQLITE_OK; |
| 24559 | 24908 | int h; |
| | @@ -24605,10 +24954,11 @@ |
| 24605 | 24954 | ** 4: [RRRR.] |
| 24606 | 24955 | */ |
| 24607 | 24956 | if( eFileLock==SHARED_LOCK ){ |
| 24608 | 24957 | |
| 24609 | 24958 | #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE |
| 24959 | + (void)handleNFSUnlock; |
| 24610 | 24960 | assert( handleNFSUnlock==0 ); |
| 24611 | 24961 | #endif |
| 24612 | 24962 | #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
| 24613 | 24963 | if( handleNFSUnlock ){ |
| 24614 | 24964 | off_t divSize = SHARED_SIZE - 1; |
| | @@ -24615,11 +24965,11 @@ |
| 24615 | 24965 | |
| 24616 | 24966 | lock.l_type = F_UNLCK; |
| 24617 | 24967 | lock.l_whence = SEEK_SET; |
| 24618 | 24968 | lock.l_start = SHARED_FIRST; |
| 24619 | 24969 | lock.l_len = divSize; |
| 24620 | | - if( fcntl(h, F_SETLK, &lock)==(-1) ){ |
| 24970 | + if( unixFileLock(pFile,, &lock)==(-1) ){ |
| 24621 | 24971 | tErrno = errno; |
| 24622 | 24972 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
| 24623 | 24973 | if( IS_LOCK_ERROR(rc) ){ |
| 24624 | 24974 | pFile->lastErrno = tErrno; |
| 24625 | 24975 | } |
| | @@ -24627,11 +24977,11 @@ |
| 24627 | 24977 | } |
| 24628 | 24978 | lock.l_type = F_RDLCK; |
| 24629 | 24979 | lock.l_whence = SEEK_SET; |
| 24630 | 24980 | lock.l_start = SHARED_FIRST; |
| 24631 | 24981 | lock.l_len = divSize; |
| 24632 | | - if( fcntl(h, F_SETLK, &lock)==(-1) ){ |
| 24982 | + if( unixFileLock(pFile, &lock)==(-1) ){ |
| 24633 | 24983 | tErrno = errno; |
| 24634 | 24984 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); |
| 24635 | 24985 | if( IS_LOCK_ERROR(rc) ){ |
| 24636 | 24986 | pFile->lastErrno = tErrno; |
| 24637 | 24987 | } |
| | @@ -24639,11 +24989,11 @@ |
| 24639 | 24989 | } |
| 24640 | 24990 | lock.l_type = F_UNLCK; |
| 24641 | 24991 | lock.l_whence = SEEK_SET; |
| 24642 | 24992 | lock.l_start = SHARED_FIRST+divSize; |
| 24643 | 24993 | lock.l_len = SHARED_SIZE-divSize; |
| 24644 | | - if( fcntl(h, F_SETLK, &lock)==(-1) ){ |
| 24994 | + if( unixFileLock(pFile, &lock)==(-1) ){ |
| 24645 | 24995 | tErrno = errno; |
| 24646 | 24996 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
| 24647 | 24997 | if( IS_LOCK_ERROR(rc) ){ |
| 24648 | 24998 | pFile->lastErrno = tErrno; |
| 24649 | 24999 | } |
| | @@ -24654,11 +25004,11 @@ |
| 24654 | 25004 | { |
| 24655 | 25005 | lock.l_type = F_RDLCK; |
| 24656 | 25006 | lock.l_whence = SEEK_SET; |
| 24657 | 25007 | lock.l_start = SHARED_FIRST; |
| 24658 | 25008 | lock.l_len = SHARED_SIZE; |
| 24659 | | - if( fcntl(h, F_SETLK, &lock)==(-1) ){ |
| 25009 | + if( unixFileLock(pFile, &lock)==(-1) ){ |
| 24660 | 25010 | tErrno = errno; |
| 24661 | 25011 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); |
| 24662 | 25012 | if( IS_LOCK_ERROR(rc) ){ |
| 24663 | 25013 | pFile->lastErrno = tErrno; |
| 24664 | 25014 | } |
| | @@ -24668,11 +25018,11 @@ |
| 24668 | 25018 | } |
| 24669 | 25019 | lock.l_type = F_UNLCK; |
| 24670 | 25020 | lock.l_whence = SEEK_SET; |
| 24671 | 25021 | lock.l_start = PENDING_BYTE; |
| 24672 | 25022 | lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); |
| 24673 | | - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ |
| 25023 | + if( unixFileLock(pFile, &lock)!=(-1) ){ |
| 24674 | 25024 | pInode->eFileLock = SHARED_LOCK; |
| 24675 | 25025 | }else{ |
| 24676 | 25026 | tErrno = errno; |
| 24677 | 25027 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
| 24678 | 25028 | if( IS_LOCK_ERROR(rc) ){ |
| | @@ -24692,11 +25042,11 @@ |
| 24692 | 25042 | lock.l_whence = SEEK_SET; |
| 24693 | 25043 | lock.l_start = lock.l_len = 0L; |
| 24694 | 25044 | SimulateIOErrorBenign(1); |
| 24695 | 25045 | SimulateIOError( h=(-1) ) |
| 24696 | 25046 | SimulateIOErrorBenign(0); |
| 24697 | | - if( fcntl(h, F_SETLK, &lock)!=(-1) ){ |
| 25047 | + if( unixFileLock(pFile, &lock)!=(-1) ){ |
| 24698 | 25048 | pInode->eFileLock = NO_LOCK; |
| 24699 | 25049 | }else{ |
| 24700 | 25050 | tErrno = errno; |
| 24701 | 25051 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); |
| 24702 | 25052 | if( IS_LOCK_ERROR(rc) ){ |
| | @@ -24730,11 +25080,11 @@ |
| 24730 | 25080 | ** |
| 24731 | 25081 | ** If the locking level of the file descriptor is already at or below |
| 24732 | 25082 | ** the requested locking level, this routine is a no-op. |
| 24733 | 25083 | */ |
| 24734 | 25084 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24735 | | - return _posixUnlock(id, eFileLock, 0); |
| 25085 | + return posixUnlock(id, eFileLock, 0); |
| 24736 | 25086 | } |
| 24737 | 25087 | |
| 24738 | 25088 | /* |
| 24739 | 25089 | ** This function performs the parts of the "close file" operation |
| 24740 | 25090 | ** common to all locking schemes. It closes the directory and file |
| | @@ -24780,10 +25130,12 @@ |
| 24780 | 25130 | int rc = SQLITE_OK; |
| 24781 | 25131 | if( id ){ |
| 24782 | 25132 | unixFile *pFile = (unixFile *)id; |
| 24783 | 25133 | unixUnlock(id, NO_LOCK); |
| 24784 | 25134 | unixEnterMutex(); |
| 25135 | + assert( pFile->pInode==0 || pFile->pInode->nLock>0 |
| 25136 | + || pFile->pInode->bProcessLock==0 ); |
| 24785 | 25137 | if( pFile->pInode && pFile->pInode->nLock ){ |
| 24786 | 25138 | /* If there are outstanding locks, do not actually close the file just |
| 24787 | 25139 | ** yet because that would clear those locks. Instead, add the file |
| 24788 | 25140 | ** descriptor to pInode->pUnused list. It will be automatically closed |
| 24789 | 25141 | ** when the last lock is cleared. |
| | @@ -24894,11 +25246,11 @@ |
| 24894 | 25246 | ** holds a lock on the file. No need to check further. */ |
| 24895 | 25247 | reserved = 1; |
| 24896 | 25248 | }else{ |
| 24897 | 25249 | /* The lock is held if and only if the lockfile exists */ |
| 24898 | 25250 | const char *zLockFile = (const char*)pFile->lockingContext; |
| 24899 | | - reserved = access(zLockFile, 0)==0; |
| 25251 | + reserved = osAccess(zLockFile, 0)==0; |
| 24900 | 25252 | } |
| 24901 | 25253 | OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); |
| 24902 | 25254 | *pResOut = reserved; |
| 24903 | 25255 | return rc; |
| 24904 | 25256 | } |
| | @@ -24948,11 +25300,11 @@ |
| 24948 | 25300 | #endif |
| 24949 | 25301 | return SQLITE_OK; |
| 24950 | 25302 | } |
| 24951 | 25303 | |
| 24952 | 25304 | /* grab an exclusive lock */ |
| 24953 | | - fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); |
| 25305 | + fd = robust_open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600); |
| 24954 | 25306 | if( fd<0 ){ |
| 24955 | 25307 | /* failed to open/create the file, someone else may have stolen the lock */ |
| 24956 | 25308 | int tErrno = errno; |
| 24957 | 25309 | if( EEXIST == tErrno ){ |
| 24958 | 25310 | rc = SQLITE_BUSY; |
| | @@ -25911,11 +26263,11 @@ |
| 25911 | 26263 | ** |
| 25912 | 26264 | ** If the locking level of the file descriptor is already at or below |
| 25913 | 26265 | ** the requested locking level, this routine is a no-op. |
| 25914 | 26266 | */ |
| 25915 | 26267 | static int nfsUnlock(sqlite3_file *id, int eFileLock){ |
| 25916 | | - return _posixUnlock(id, eFileLock, 1); |
| 26268 | + return posixUnlock(id, eFileLock, 1); |
| 25917 | 26269 | } |
| 25918 | 26270 | |
| 25919 | 26271 | #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ |
| 25920 | 26272 | /* |
| 25921 | 26273 | ** The code above is the NFS lock implementation. The code is specific |
| | @@ -25953,14 +26305,14 @@ |
| 25953 | 26305 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 25954 | 26306 | i64 newOffset; |
| 25955 | 26307 | #endif |
| 25956 | 26308 | TIMER_START; |
| 25957 | 26309 | #if defined(USE_PREAD) |
| 25958 | | - do{ got = pread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 26310 | + do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 25959 | 26311 | SimulateIOError( got = -1 ); |
| 25960 | 26312 | #elif defined(USE_PREAD64) |
| 25961 | | - do{ got = pread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 26313 | + do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR); |
| 25962 | 26314 | SimulateIOError( got = -1 ); |
| 25963 | 26315 | #else |
| 25964 | 26316 | newOffset = lseek(id->h, offset, SEEK_SET); |
| 25965 | 26317 | SimulateIOError( newOffset-- ); |
| 25966 | 26318 | if( newOffset!=offset ){ |
| | @@ -25969,11 +26321,11 @@ |
| 25969 | 26321 | }else{ |
| 25970 | 26322 | ((unixFile*)id)->lastErrno = 0; |
| 25971 | 26323 | } |
| 25972 | 26324 | return -1; |
| 25973 | 26325 | } |
| 25974 | | - do{ got = read(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); |
| 26326 | + do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); |
| 25975 | 26327 | #endif |
| 25976 | 26328 | TIMER_END; |
| 25977 | 26329 | if( got<0 ){ |
| 25978 | 26330 | ((unixFile*)id)->lastErrno = errno; |
| 25979 | 26331 | } |
| | @@ -26031,13 +26383,13 @@ |
| 26031 | 26383 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26032 | 26384 | i64 newOffset; |
| 26033 | 26385 | #endif |
| 26034 | 26386 | TIMER_START; |
| 26035 | 26387 | #if defined(USE_PREAD) |
| 26036 | | - do{ got = pwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 26388 | + do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 26037 | 26389 | #elif defined(USE_PREAD64) |
| 26038 | | - do{ got = pwrite64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); |
| 26390 | + do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR); |
| 26039 | 26391 | #else |
| 26040 | 26392 | newOffset = lseek(id->h, offset, SEEK_SET); |
| 26041 | 26393 | if( newOffset!=offset ){ |
| 26042 | 26394 | if( newOffset == -1 ){ |
| 26043 | 26395 | ((unixFile*)id)->lastErrno = errno; |
| | @@ -26044,11 +26396,11 @@ |
| 26044 | 26396 | }else{ |
| 26045 | 26397 | ((unixFile*)id)->lastErrno = 0; |
| 26046 | 26398 | } |
| 26047 | 26399 | return -1; |
| 26048 | 26400 | } |
| 26049 | | - do{ got = write(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); |
| 26401 | + do{ got = osWrite(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); |
| 26050 | 26402 | #endif |
| 26051 | 26403 | TIMER_END; |
| 26052 | 26404 | if( got<0 ){ |
| 26053 | 26405 | ((unixFile*)id)->lastErrno = errno; |
| 26054 | 26406 | } |
| | @@ -26212,11 +26564,11 @@ |
| 26212 | 26564 | */ |
| 26213 | 26565 | #ifdef SQLITE_NO_SYNC |
| 26214 | 26566 | rc = SQLITE_OK; |
| 26215 | 26567 | #elif HAVE_FULLFSYNC |
| 26216 | 26568 | if( fullSync ){ |
| 26217 | | - rc = fcntl(fd, F_FULLFSYNC, 0); |
| 26569 | + rc = osFcntl(fd, F_FULLFSYNC, 0); |
| 26218 | 26570 | }else{ |
| 26219 | 26571 | rc = 1; |
| 26220 | 26572 | } |
| 26221 | 26573 | /* If the FULLFSYNC failed, fall back to attempting an fsync(). |
| 26222 | 26574 | ** It shouldn't be possible for fullfsync to fail on the local |
| | @@ -26359,11 +26711,11 @@ |
| 26359 | 26711 | */ |
| 26360 | 26712 | static int unixFileSize(sqlite3_file *id, i64 *pSize){ |
| 26361 | 26713 | int rc; |
| 26362 | 26714 | struct stat buf; |
| 26363 | 26715 | assert( id ); |
| 26364 | | - rc = fstat(((unixFile*)id)->h, &buf); |
| 26716 | + rc = osFstat(((unixFile*)id)->h, &buf); |
| 26365 | 26717 | SimulateIOError( rc=1 ); |
| 26366 | 26718 | if( rc!=0 ){ |
| 26367 | 26719 | ((unixFile*)id)->lastErrno = errno; |
| 26368 | 26720 | return SQLITE_IOERR_FSTAT; |
| 26369 | 26721 | } |
| | @@ -26400,18 +26752,18 @@ |
| 26400 | 26752 | static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
| 26401 | 26753 | if( pFile->szChunk ){ |
| 26402 | 26754 | i64 nSize; /* Required file size */ |
| 26403 | 26755 | struct stat buf; /* Used to hold return values of fstat() */ |
| 26404 | 26756 | |
| 26405 | | - if( fstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 26757 | + if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 26406 | 26758 | |
| 26407 | 26759 | nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; |
| 26408 | 26760 | if( nSize>(i64)buf.st_size ){ |
| 26409 | 26761 | #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
| 26410 | 26762 | int rc; |
| 26411 | 26763 | do{ |
| 26412 | | - rc = posix_fallocate(pFile-.h, buf.st_size, nSize-buf.st_size; |
| 26764 | + rc = osFallocate(pFile->.h, buf.st_size, nSize-buf.st_size; |
| 26413 | 26765 | }while( rc<0 && errno=EINTR ); |
| 26414 | 26766 | if( rc ) return SQLITE_IOERR_WRITE; |
| 26415 | 26767 | #else |
| 26416 | 26768 | /* If the OS does not have posix_fallocate(), fake it. First use |
| 26417 | 26769 | ** ftruncate() to set the file size, then write a single byte to |
| | @@ -26608,19 +26960,21 @@ |
| 26608 | 26960 | assert( n==1 || lockType!=F_RDLCK ); |
| 26609 | 26961 | |
| 26610 | 26962 | /* Locks are within range */ |
| 26611 | 26963 | assert( n>=1 && n<SQLITE_SHM_NLOCK ); |
| 26612 | 26964 | |
| 26613 | | - /* Initialize the locking parameters */ |
| 26614 | | - memset(&f, 0, sizeof(f)); |
| 26615 | | - f.l_type = lockType; |
| 26616 | | - f.l_whence = SEEK_SET; |
| 26617 | | - f.l_start = ofst; |
| 26618 | | - f.l_len = n; |
| 26619 | | - |
| 26620 | | - rc = fcntl(pShmNode->h, F_SETLK, &f); |
| 26621 | | - rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; |
| 26965 | + if( pShmNode->h>=0 ){ |
| 26966 | + /* Initialize the locking parameters */ |
| 26967 | + memset(&f, 0, sizeof(f)); |
| 26968 | + f.l_type = lockType; |
| 26969 | + f.l_whence = SEEK_SET; |
| 26970 | + f.l_start = ofst; |
| 26971 | + f.l_len = n; |
| 26972 | + |
| 26973 | + rc = osFcntl(pShmNode->h, F_SETLK, &f); |
| 26974 | + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; |
| 26975 | + } |
| 26622 | 26976 | |
| 26623 | 26977 | /* Update the global lock state and do debug tracing */ |
| 26624 | 26978 | #ifdef SQLITE_DEBUG |
| 26625 | 26979 | { u16 mask; |
| 26626 | 26980 | OSTRACE(("SHM-LOCK ")); |
| | @@ -26671,11 +27025,15 @@ |
| 26671 | 27025 | if( p && p->nRef==0 ){ |
| 26672 | 27026 | int i; |
| 26673 | 27027 | assert( p->pInode==pFd->pInode ); |
| 26674 | 27028 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 26675 | 27029 | for(i=0; i<p->nRegion; i++){ |
| 26676 | | - munmap(p->apRegion[i], p->szRegion); |
| 27030 | + if( p->h>=0 ){ |
| 27031 | + munmap(p->apRegion[i], p->szRegion); |
| 27032 | + }else{ |
| 27033 | + sqlite3_free(p->apRegion[i]); |
| 27034 | + } |
| 26677 | 27035 | } |
| 26678 | 27036 | sqlite3_free(p->apRegion); |
| 26679 | 27037 | if( p->h>=0 ){ |
| 26680 | 27038 | robust_close(pFd, p->h, __LINE__); |
| 26681 | 27039 | p->h = -1; |
| | @@ -26711,10 +27069,16 @@ |
| 26711 | 27069 | ** "unsupported" and may go away in a future SQLite release. |
| 26712 | 27070 | ** |
| 26713 | 27071 | ** When opening a new shared-memory file, if no other instances of that |
| 26714 | 27072 | ** file are currently open, in this process or in other processes, then |
| 26715 | 27073 | ** the file must be truncated to zero length or have its header cleared. |
| 27074 | +** |
| 27075 | +** If the original database file (pDbFd) is using the "unix-excl" VFS |
| 27076 | +** that means that an exclusive lock is held on the database file and |
| 27077 | +** that no other processes are able to read or write the database. In |
| 27078 | +** that case, we do not really need shared memory. No shared memory |
| 27079 | +** file is created. The shared memory will be simulated with heap memory. |
| 26716 | 27080 | */ |
| 26717 | 27081 | static int unixOpenSharedMemory(unixFile *pDbFd){ |
| 26718 | 27082 | struct unixShm *p = 0; /* The connection to be opened */ |
| 26719 | 27083 | struct unixShmNode *pShmNode; /* The underlying mmapped file */ |
| 26720 | 27084 | int rc; /* Result code */ |
| | @@ -26740,11 +27104,11 @@ |
| 26740 | 27104 | /* Call fstat() to figure out the permissions on the database file. If |
| 26741 | 27105 | ** a new *-shm file is created, an attempt will be made to create it |
| 26742 | 27106 | ** with the same permissions. The actual permissions the file is created |
| 26743 | 27107 | ** with are subject to the current umask setting. |
| 26744 | 27108 | */ |
| 26745 | | - if( fstat(pDbFd->h, &sStat) ){ |
| 27109 | + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ |
| 26746 | 27110 | rc = SQLITE_IOERR_FSTAT; |
| 26747 | 27111 | goto shm_open_err; |
| 26748 | 27112 | } |
| 26749 | 27113 | |
| 26750 | 27114 | #ifdef SQLITE_SHM_DIRECTORY |
| | @@ -26773,29 +27137,32 @@ |
| 26773 | 27137 | if( pShmNode->mutex==0 ){ |
| 26774 | 27138 | rc = SQLITE_NOMEM; |
| 26775 | 27139 | goto shm_open_err; |
| 26776 | 27140 | } |
| 26777 | 27141 | |
| 26778 | | - pShmNode->h = open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); |
| 26779 | | - if( pShmNode->h<0 ){ |
| 26780 | | - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 26781 | | - goto shm_open_err; |
| 26782 | | - } |
| 26783 | | - |
| 26784 | | - /* Check to see if another process is holding the dead-man switch. |
| 26785 | | - ** If not, truncate the file to zero length. |
| 26786 | | - */ |
| 26787 | | - rc = SQLITE_OK; |
| 26788 | | - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ |
| 26789 | | - if( robust_ftruncate(pShmNode->h, 0) ){ |
| 26790 | | - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); |
| 26791 | | - } |
| 26792 | | - } |
| 26793 | | - if( rc==SQLITE_OK ){ |
| 26794 | | - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); |
| 26795 | | - } |
| 26796 | | - if( rc ) goto shm_open_err; |
| 27142 | + if( pInode->bProcessLock==0 ){ |
| 27143 | + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, |
| 27144 | + (sStat.st_mode & 0777)); |
| 27145 | + if( pShmNode->h<0 ){ |
| 27146 | + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 27147 | + goto shm_open_err; |
| 27148 | + } |
| 27149 | + |
| 27150 | + /* Check to see if another process is holding the dead-man switch. |
| 27151 | + ** If not, truncate the file to zero length. |
| 27152 | + */ |
| 27153 | + rc = SQLITE_OK; |
| 27154 | + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ |
| 27155 | + if( robust_ftruncate(pShmNode->h, 0) ){ |
| 27156 | + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); |
| 27157 | + } |
| 27158 | + } |
| 27159 | + if( rc==SQLITE_OK ){ |
| 27160 | + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); |
| 27161 | + } |
| 27162 | + if( rc ) goto shm_open_err; |
| 27163 | + } |
| 26797 | 27164 | } |
| 26798 | 27165 | |
| 26799 | 27166 | /* Make the new connection a child of the unixShmNode */ |
| 26800 | 27167 | p->pShmNode = pShmNode; |
| 26801 | 27168 | #ifdef SQLITE_DEBUG |
| | @@ -26865,38 +27232,44 @@ |
| 26865 | 27232 | |
| 26866 | 27233 | p = pDbFd->pShm; |
| 26867 | 27234 | pShmNode = p->pShmNode; |
| 26868 | 27235 | sqlite3_mutex_enter(pShmNode->mutex); |
| 26869 | 27236 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 27237 | + assert( pShmNode->pInode==pDbFd->pInode ); |
| 27238 | + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); |
| 27239 | + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); |
| 26870 | 27240 | |
| 26871 | 27241 | if( pShmNode->nRegion<=iRegion ){ |
| 26872 | 27242 | char **apNew; /* New apRegion[] array */ |
| 26873 | 27243 | int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ |
| 26874 | 27244 | struct stat sStat; /* Used by fstat() */ |
| 26875 | 27245 | |
| 26876 | 27246 | pShmNode->szRegion = szRegion; |
| 26877 | 27247 | |
| 26878 | | - /* The requested region is not mapped into this processes address space. |
| 26879 | | - ** Check to see if it has been allocated (i.e. if the wal-index file is |
| 26880 | | - ** large enough to contain the requested region). |
| 26881 | | - */ |
| 26882 | | - if( fstat(pShmNode->h, &sStat) ){ |
| 26883 | | - rc = SQLITE_IOERR_SHMSIZE; |
| 26884 | | - goto shmpage_out; |
| 26885 | | - } |
| 26886 | | - |
| 26887 | | - if( sStat.st_size<nByte ){ |
| 26888 | | - /* The requested memory region does not exist. If bExtend is set to |
| 26889 | | - ** false, exit early. *pp will be set to NULL and SQLITE_OK returned. |
| 26890 | | - ** |
| 26891 | | - ** Alternatively, if bExtend is true, use ftruncate() to allocate |
| 26892 | | - ** the requested memory region. |
| 26893 | | - */ |
| 26894 | | - if( !bExtend ) goto shmpage_out; |
| 26895 | | - if( robust_ftruncate(pShmNode->h, nByte) ){ |
| 26896 | | - rc = unixLogError(SQLITE_IOERR_SHMSIZE,"ftruncate",pShmNode->zFilename); |
| 26897 | | - goto shmpage_out; |
| 27248 | + if( pShmNode->h>=0 ){ |
| 27249 | + /* The requested region is not mapped into this processes address space. |
| 27250 | + ** Check to see if it has been allocated (i.e. if the wal-index file is |
| 27251 | + ** large enough to contain the requested region). |
| 27252 | + */ |
| 27253 | + if( osFstat(pShmNode->h, &sStat) ){ |
| 27254 | + rc = SQLITE_IOERR_SHMSIZE; |
| 27255 | + goto shmpage_out; |
| 27256 | + } |
| 27257 | + |
| 27258 | + if( sStat.st_size<nByte ){ |
| 27259 | + /* The requested memory region does not exist. If bExtend is set to |
| 27260 | + ** false, exit early. *pp will be set to NULL and SQLITE_OK returned. |
| 27261 | + ** |
| 27262 | + ** Alternatively, if bExtend is true, use ftruncate() to allocate |
| 27263 | + ** the requested memory region. |
| 27264 | + */ |
| 27265 | + if( !bExtend ) goto shmpage_out; |
| 27266 | + if( robust_ftruncate(pShmNode->h, nByte) ){ |
| 27267 | + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate", |
| 27268 | + pShmNode->zFilename); |
| 27269 | + goto shmpage_out; |
| 27270 | + } |
| 26898 | 27271 | } |
| 26899 | 27272 | } |
| 26900 | 27273 | |
| 26901 | 27274 | /* Map the requested memory region into this processes address space. */ |
| 26902 | 27275 | apNew = (char **)sqlite3_realloc( |
| | @@ -26906,16 +27279,26 @@ |
| 26906 | 27279 | rc = SQLITE_IOERR_NOMEM; |
| 26907 | 27280 | goto shmpage_out; |
| 26908 | 27281 | } |
| 26909 | 27282 | pShmNode->apRegion = apNew; |
| 26910 | 27283 | while(pShmNode->nRegion<=iRegion){ |
| 26911 | | - void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, |
| 26912 | | - MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 26913 | | - ); |
| 26914 | | - if( pMem==MAP_FAILED ){ |
| 26915 | | - rc = SQLITE_IOERR; |
| 26916 | | - goto shmpage_out; |
| 27284 | + void *pMem; |
| 27285 | + if( pShmNode->h>=0 ){ |
| 27286 | + pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, |
| 27287 | + MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 27288 | + ); |
| 27289 | + if( pMem==MAP_FAILED ){ |
| 27290 | + rc = SQLITE_IOERR; |
| 27291 | + goto shmpage_out; |
| 27292 | + } |
| 27293 | + }else{ |
| 27294 | + pMem = sqlite3_malloc(szRegion); |
| 27295 | + if( pMem==0 ){ |
| 27296 | + rc = SQLITE_NOMEM; |
| 27297 | + goto shmpage_out; |
| 27298 | + } |
| 27299 | + memset(pMem, 0, szRegion); |
| 26917 | 27300 | } |
| 26918 | 27301 | pShmNode->apRegion[pShmNode->nRegion] = pMem; |
| 26919 | 27302 | pShmNode->nRegion++; |
| 26920 | 27303 | } |
| 26921 | 27304 | } |
| | @@ -26958,10 +27341,12 @@ |
| 26958 | 27341 | assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) |
| 26959 | 27342 | || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) |
| 26960 | 27343 | || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) |
| 26961 | 27344 | || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); |
| 26962 | 27345 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 27346 | + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); |
| 27347 | + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); |
| 26963 | 27348 | |
| 26964 | 27349 | mask = (1<<(ofst+n)) - (1<<ofst); |
| 26965 | 27350 | assert( n>1 || mask==(1<<ofst) ); |
| 26966 | 27351 | sqlite3_mutex_enter(pShmNode->mutex); |
| 26967 | 27352 | if( flags & SQLITE_SHM_UNLOCK ){ |
| | @@ -27095,11 +27480,11 @@ |
| 27095 | 27480 | ** shared-memory file, too */ |
| 27096 | 27481 | unixEnterMutex(); |
| 27097 | 27482 | assert( pShmNode->nRef>0 ); |
| 27098 | 27483 | pShmNode->nRef--; |
| 27099 | 27484 | if( pShmNode->nRef==0 ){ |
| 27100 | | - if( deleteFlag ) unlink(pShmNode->zFilename); |
| 27485 | + if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename); |
| 27101 | 27486 | unixShmPurge(pDbFd); |
| 27102 | 27487 | } |
| 27103 | 27488 | unixLeaveMutex(); |
| 27104 | 27489 | |
| 27105 | 27490 | return SQLITE_OK; |
| | @@ -27336,11 +27721,11 @@ |
| 27336 | 27721 | */ |
| 27337 | 27722 | lockInfo.l_len = 1; |
| 27338 | 27723 | lockInfo.l_start = 0; |
| 27339 | 27724 | lockInfo.l_whence = SEEK_SET; |
| 27340 | 27725 | lockInfo.l_type = F_RDLCK; |
| 27341 | | - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { |
| 27726 | + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { |
| 27342 | 27727 | if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ |
| 27343 | 27728 | return &nfsIoMethods; |
| 27344 | 27729 | } else { |
| 27345 | 27730 | return &posixIoMethods; |
| 27346 | 27731 | } |
| | @@ -27378,11 +27763,11 @@ |
| 27378 | 27763 | */ |
| 27379 | 27764 | lockInfo.l_len = 1; |
| 27380 | 27765 | lockInfo.l_start = 0; |
| 27381 | 27766 | lockInfo.l_whence = SEEK_SET; |
| 27382 | 27767 | lockInfo.l_type = F_RDLCK; |
| 27383 | | - if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { |
| 27768 | + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { |
| 27384 | 27769 | return &posixIoMethods; |
| 27385 | 27770 | }else{ |
| 27386 | 27771 | return &semIoMethods; |
| 27387 | 27772 | } |
| 27388 | 27773 | } |
| | @@ -27412,11 +27797,12 @@ |
| 27412 | 27797 | int h, /* Open file descriptor of file being opened */ |
| 27413 | 27798 | int dirfd, /* Directory file descriptor */ |
| 27414 | 27799 | sqlite3_file *pId, /* Write to the unixFile structure here */ |
| 27415 | 27800 | const char *zFilename, /* Name of the file being opened */ |
| 27416 | 27801 | int noLock, /* Omit locking if true */ |
| 27417 | | - int isDelete /* Delete on close if true */ |
| 27802 | + int isDelete, /* Delete on close if true */ |
| 27803 | + int isReadOnly /* True if the file is opened read-only */ |
| 27418 | 27804 | ){ |
| 27419 | 27805 | const sqlite3_io_methods *pLockingStyle; |
| 27420 | 27806 | unixFile *pNew = (unixFile *)pId; |
| 27421 | 27807 | int rc = SQLITE_OK; |
| 27422 | 27808 | |
| | @@ -27439,12 +27825,19 @@ |
| 27439 | 27825 | #endif |
| 27440 | 27826 | |
| 27441 | 27827 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 27442 | 27828 | pNew->h = h; |
| 27443 | 27829 | pNew->dirfd = dirfd; |
| 27444 | | - pNew->fileFlags = 0; |
| 27445 | 27830 | pNew->zPath = zFilename; |
| 27831 | + if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ |
| 27832 | + pNew->ctrlFlags = UNIXFILE_EXCL; |
| 27833 | + }else{ |
| 27834 | + pNew->ctrlFlags = 0; |
| 27835 | + } |
| 27836 | + if( isReadOnly ){ |
| 27837 | + pNew->ctrlFlags |= UNIXFILE_RDONLY; |
| 27838 | + } |
| 27446 | 27839 | |
| 27447 | 27840 | #if OS_VXWORKS |
| 27448 | 27841 | pNew->pId = vxworksFindFileId(zFilename); |
| 27449 | 27842 | if( pNew->pId==0 ){ |
| 27450 | 27843 | noLock = 1; |
| | @@ -27601,14 +27994,14 @@ |
| 27601 | 27994 | |
| 27602 | 27995 | sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); |
| 27603 | 27996 | for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); |
| 27604 | 27997 | if( ii>0 ){ |
| 27605 | 27998 | zDirname[ii] = '\0'; |
| 27606 | | - fd = open(zDirname, O_RDONLY|O_BINARY, 0); |
| 27999 | + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); |
| 27607 | 28000 | if( fd>=0 ){ |
| 27608 | 28001 | #ifdef FD_CLOEXEC |
| 27609 | | - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
| 28002 | + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
| 27610 | 28003 | #endif |
| 27611 | 28004 | OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); |
| 27612 | 28005 | } |
| 27613 | 28006 | } |
| 27614 | 28007 | *pFd = fd; |
| | @@ -27634,13 +28027,13 @@ |
| 27634 | 28027 | |
| 27635 | 28028 | azDirs[0] = sqlite3_temp_directory; |
| 27636 | 28029 | if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
| 27637 | 28030 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 27638 | 28031 | if( zDir==0 ) continue; |
| 27639 | | - if( stat(zDir, &buf) ) continue; |
| 28032 | + if( osStat(zDir, &buf) ) continue; |
| 27640 | 28033 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 27641 | | - if( access(zDir, 07) ) continue; |
| 28034 | + if( osAccess(zDir, 07) ) continue; |
| 27642 | 28035 | break; |
| 27643 | 28036 | } |
| 27644 | 28037 | return zDir; |
| 27645 | 28038 | } |
| 27646 | 28039 | |
| | @@ -27679,11 +28072,11 @@ |
| 27679 | 28072 | sqlite3_randomness(15, &zBuf[j]); |
| 27680 | 28073 | for(i=0; i<15; i++, j++){ |
| 27681 | 28074 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 27682 | 28075 | } |
| 27683 | 28076 | zBuf[j] = 0; |
| 27684 | | - }while( access(zBuf,0)==0 ); |
| 28077 | + }while( osAccess(zBuf,0)==0 ); |
| 27685 | 28078 | return SQLITE_OK; |
| 27686 | 28079 | } |
| 27687 | 28080 | |
| 27688 | 28081 | #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) |
| 27689 | 28082 | /* |
| | @@ -27940,19 +28333,20 @@ |
| 27940 | 28333 | if( rc!=SQLITE_OK ){ |
| 27941 | 28334 | assert( !p->pUnused ); |
| 27942 | 28335 | assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); |
| 27943 | 28336 | return rc; |
| 27944 | 28337 | } |
| 27945 | | - fd = open(zName, openFlags, openMode); |
| 28338 | + fd = robust_open(zName, openFlags, openMode); |
| 27946 | 28339 | OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); |
| 27947 | 28340 | if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ |
| 27948 | 28341 | /* Failed to open the file for read/write access. Try read-only. */ |
| 27949 | 28342 | flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 27950 | 28343 | openFlags &= ~(O_RDWR|O_CREAT); |
| 27951 | 28344 | flags |= SQLITE_OPEN_READONLY; |
| 27952 | 28345 | openFlags |= O_RDONLY; |
| 27953 | | - fd = open(zName, openFlags, openMode); |
| 28346 | + isReadonly = 1; |
| 28347 | + fd = robust_open(zName, openFlags, openMode); |
| 27954 | 28348 | } |
| 27955 | 28349 | if( fd<0 ){ |
| 27956 | 28350 | rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); |
| 27957 | 28351 | goto open_finished; |
| 27958 | 28352 | } |
| | @@ -27992,11 +28386,11 @@ |
| 27992 | 28386 | goto open_finished; |
| 27993 | 28387 | } |
| 27994 | 28388 | } |
| 27995 | 28389 | |
| 27996 | 28390 | #ifdef FD_CLOEXEC |
| 27997 | | - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
| 28391 | + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
| 27998 | 28392 | #endif |
| 27999 | 28393 | |
| 28000 | 28394 | noLock = eType!=SQLITE_OPEN_MAIN_DB; |
| 28001 | 28395 | |
| 28002 | 28396 | |
| | @@ -28044,11 +28438,12 @@ |
| 28044 | 28438 | goto open_finished; |
| 28045 | 28439 | } |
| 28046 | 28440 | useProxy = !(fsInfo.f_flags&MNT_LOCAL); |
| 28047 | 28441 | } |
| 28048 | 28442 | if( useProxy ){ |
| 28049 | | - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); |
| 28443 | + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, |
| 28444 | + isDelete, isReadonly); |
| 28050 | 28445 | if( rc==SQLITE_OK ){ |
| 28051 | 28446 | rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); |
| 28052 | 28447 | if( rc!=SQLITE_OK ){ |
| 28053 | 28448 | /* Use unixClose to clean up the resources added in fillInUnixFile |
| 28054 | 28449 | ** and clear all the structure's references. Specifically, |
| | @@ -28061,11 +28456,12 @@ |
| 28061 | 28456 | goto open_finished; |
| 28062 | 28457 | } |
| 28063 | 28458 | } |
| 28064 | 28459 | #endif |
| 28065 | 28460 | |
| 28066 | | - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); |
| 28461 | + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, |
| 28462 | + isDelete, isReadonly); |
| 28067 | 28463 | open_finished: |
| 28068 | 28464 | if( rc!=SQLITE_OK ){ |
| 28069 | 28465 | sqlite3_free(p->pUnused); |
| 28070 | 28466 | } |
| 28071 | 28467 | return rc; |
| | @@ -28138,11 +28534,11 @@ |
| 28138 | 28534 | break; |
| 28139 | 28535 | |
| 28140 | 28536 | default: |
| 28141 | 28537 | assert(!"Invalid flags argument"); |
| 28142 | 28538 | } |
| 28143 | | - *pResOut = (access(zPath, amode)==0); |
| 28539 | + *pResOut = (osAccess(zPath, amode)==0); |
| 28144 | 28540 | if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ |
| 28145 | 28541 | struct stat buf; |
| 28146 | 28542 | if( 0==stat(zPath, &buf) && buf.st_size==0 ){ |
| 28147 | 28543 | *pResOut = 0; |
| 28148 | 28544 | } |
| | @@ -28180,11 +28576,11 @@ |
| 28180 | 28576 | zOut[nOut-1] = '\0'; |
| 28181 | 28577 | if( zPath[0]=='/' ){ |
| 28182 | 28578 | sqlite3_snprintf(nOut, zOut, "%s", zPath); |
| 28183 | 28579 | }else{ |
| 28184 | 28580 | int nCwd; |
| 28185 | | - if( getcwd(zOut, nOut-1)==0 ){ |
| 28581 | + if( osGetcwd(zOut, nOut-1)==0 ){ |
| 28186 | 28582 | return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); |
| 28187 | 28583 | } |
| 28188 | 28584 | nCwd = (int)strlen(zOut); |
| 28189 | 28585 | sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); |
| 28190 | 28586 | } |
| | @@ -28275,21 +28671,21 @@ |
| 28275 | 28671 | */ |
| 28276 | 28672 | memset(zBuf, 0, nBuf); |
| 28277 | 28673 | #if !defined(SQLITE_TEST) |
| 28278 | 28674 | { |
| 28279 | 28675 | int pid, fd; |
| 28280 | | - fd = open("/dev/urandom", O_RDONLY); |
| 28676 | + fd = robust_open("/dev/urandom", O_RDONLY, 0); |
| 28281 | 28677 | if( fd<0 ){ |
| 28282 | 28678 | time_t t; |
| 28283 | 28679 | time(&t); |
| 28284 | 28680 | memcpy(zBuf, &t, sizeof(t)); |
| 28285 | 28681 | pid = getpid(); |
| 28286 | 28682 | memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); |
| 28287 | 28683 | assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); |
| 28288 | 28684 | nBuf = sizeof(t) + sizeof(pid); |
| 28289 | 28685 | }else{ |
| 28290 | | - do{ nBuf = read(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); |
| 28686 | + do{ nBuf = osRead(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); |
| 28291 | 28687 | robust_close(0, fd, __LINE__); |
| 28292 | 28688 | } |
| 28293 | 28689 | } |
| 28294 | 28690 | #endif |
| 28295 | 28691 | return nBuf; |
| | @@ -28684,21 +29080,21 @@ |
| 28684 | 29080 | if( !pUnused ){ |
| 28685 | 29081 | return SQLITE_NOMEM; |
| 28686 | 29082 | } |
| 28687 | 29083 | } |
| 28688 | 29084 | if( fd<0 ){ |
| 28689 | | - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 29085 | + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 28690 | 29086 | terrno = errno; |
| 28691 | 29087 | if( fd<0 && errno==ENOENT && islockfile ){ |
| 28692 | 29088 | if( proxyCreateLockPath(path) == SQLITE_OK ){ |
| 28693 | | - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 29089 | + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 28694 | 29090 | } |
| 28695 | 29091 | } |
| 28696 | 29092 | } |
| 28697 | 29093 | if( fd<0 ){ |
| 28698 | 29094 | openFlags = O_RDONLY; |
| 28699 | | - fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 29095 | + fd = robust_open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 28700 | 29096 | terrno = errno; |
| 28701 | 29097 | } |
| 28702 | 29098 | if( fd<0 ){ |
| 28703 | 29099 | if( islockfile ){ |
| 28704 | 29100 | return SQLITE_BUSY; |
| | @@ -28723,11 +29119,11 @@ |
| 28723 | 29119 | dummyVfs.pAppData = (void*)&autolockIoFinder; |
| 28724 | 29120 | pUnused->fd = fd; |
| 28725 | 29121 | pUnused->flags = openFlags; |
| 28726 | 29122 | pNew->pUnused = pUnused; |
| 28727 | 29123 | |
| 28728 | | - rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0); |
| 29124 | + rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0); |
| 28729 | 29125 | if( rc==SQLITE_OK ){ |
| 28730 | 29126 | *ppFile = pNew; |
| 28731 | 29127 | return SQLITE_OK; |
| 28732 | 29128 | } |
| 28733 | 29129 | end_create_proxy: |
| | @@ -28808,22 +29204,23 @@ |
| 28808 | 29204 | (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ |
| 28809 | 29205 | sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); |
| 28810 | 29206 | goto end_breaklock; |
| 28811 | 29207 | } |
| 28812 | 29208 | /* read the conch content */ |
| 28813 | | - readLen = pread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); |
| 29209 | + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); |
| 28814 | 29210 | if( readLen<PROXY_PATHINDEX ){ |
| 28815 | 29211 | sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen); |
| 28816 | 29212 | goto end_breaklock; |
| 28817 | 29213 | } |
| 28818 | 29214 | /* write it out to the temporary break file */ |
| 28819 | | - fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 29215 | + fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), |
| 29216 | + SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 28820 | 29217 | if( fd<0 ){ |
| 28821 | 29218 | sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno); |
| 28822 | 29219 | goto end_breaklock; |
| 28823 | 29220 | } |
| 28824 | | - if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){ |
| 29221 | + if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){ |
| 28825 | 29222 | sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno); |
| 28826 | 29223 | goto end_breaklock; |
| 28827 | 29224 | } |
| 28828 | 29225 | if( rename(tPath, cPath) ){ |
| 28829 | 29226 | sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno); |
| | @@ -28865,11 +29262,11 @@ |
| 28865 | 29262 | * 2nd try: fail if the mod time changed or host id is different, wait |
| 28866 | 29263 | * 10 sec and try again |
| 28867 | 29264 | * 3rd try: break the lock unless the mod time has changed. |
| 28868 | 29265 | */ |
| 28869 | 29266 | struct stat buf; |
| 28870 | | - if( fstat(conchFile->h, &buf) ){ |
| 29267 | + if( osFstat(conchFile->h, &buf) ){ |
| 28871 | 29268 | pFile->lastErrno = errno; |
| 28872 | 29269 | return SQLITE_IOERR_LOCK; |
| 28873 | 29270 | } |
| 28874 | 29271 | |
| 28875 | 29272 | if( nTries==1 ){ |
| | @@ -28884,11 +29281,11 @@ |
| 28884 | 29281 | return SQLITE_BUSY; |
| 28885 | 29282 | } |
| 28886 | 29283 | |
| 28887 | 29284 | if( nTries==2 ){ |
| 28888 | 29285 | char tBuf[PROXY_MAXCONCHLEN]; |
| 28889 | | - int len = pread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); |
| 29286 | + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); |
| 28890 | 29287 | if( len<0 ){ |
| 28891 | 29288 | pFile->lastErrno = errno; |
| 28892 | 29289 | return SQLITE_IOERR_LOCK; |
| 28893 | 29290 | } |
| 28894 | 29291 | if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ |
| | @@ -29054,20 +29451,20 @@ |
| 29054 | 29451 | /* If we created a new conch file (not just updated the contents of a |
| 29055 | 29452 | ** valid conch file), try to match the permissions of the database |
| 29056 | 29453 | */ |
| 29057 | 29454 | if( rc==SQLITE_OK && createConch ){ |
| 29058 | 29455 | struct stat buf; |
| 29059 | | - int err = fstat(pFile->h, &buf); |
| 29456 | + int err = osFstat(pFile->h, &buf); |
| 29060 | 29457 | if( err==0 ){ |
| 29061 | 29458 | mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | |
| 29062 | 29459 | S_IROTH|S_IWOTH); |
| 29063 | 29460 | /* try to match the database file R/W permissions, ignore failure */ |
| 29064 | 29461 | #ifndef SQLITE_PROXY_DEBUG |
| 29065 | | - fchmod(conchFile->h, cmode); |
| 29462 | + osFchmod(conchFile->h, cmode); |
| 29066 | 29463 | #else |
| 29067 | 29464 | do{ |
| 29068 | | - rc = fchmod(conchFile->h, cmode); |
| 29465 | + rc = osFchmod(conchFile->h, cmode); |
| 29069 | 29466 | }while( rc==(-1) && errno==EINTR ); |
| 29070 | 29467 | if( rc!=0 ){ |
| 29071 | 29468 | int code = errno; |
| 29072 | 29469 | fprintf(stderr, "fchmod %o FAILED with %d %s\n", |
| 29073 | 29470 | cmode, code, strerror(code)); |
| | @@ -29089,11 +29486,11 @@ |
| 29089 | 29486 | if( rc==SQLITE_OK && pFile->openFlags ){ |
| 29090 | 29487 | if( pFile->h>=0 ){ |
| 29091 | 29488 | robust_close(pFile, pFile->h, __LINE__); |
| 29092 | 29489 | } |
| 29093 | 29490 | pFile->h = -1; |
| 29094 | | - int fd = open(pCtx->dbPath, pFile->openFlags, |
| 29491 | + int fd = robust_open(pCtx->dbPath, pFile->openFlags, |
| 29095 | 29492 | SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 29096 | 29493 | OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); |
| 29097 | 29494 | if( fd>=0 ){ |
| 29098 | 29495 | pFile->h = fd; |
| 29099 | 29496 | }else{ |
| | @@ -29315,11 +29712,11 @@ |
| 29315 | 29712 | */ |
| 29316 | 29713 | struct statfs fsInfo; |
| 29317 | 29714 | struct stat conchInfo; |
| 29318 | 29715 | int goLockless = 0; |
| 29319 | 29716 | |
| 29320 | | - if( stat(pCtx->conchFilePath, &conchInfo) == -1 ) { |
| 29717 | + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { |
| 29321 | 29718 | int err = errno; |
| 29322 | 29719 | if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ |
| 29323 | 29720 | goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; |
| 29324 | 29721 | } |
| 29325 | 29722 | } |
| | @@ -29600,11 +29997,11 @@ |
| 29600 | 29997 | ** more than that; it looks at the filesystem type that hosts the |
| 29601 | 29998 | ** database file and tries to choose an locking method appropriate for |
| 29602 | 29999 | ** that filesystem time. |
| 29603 | 30000 | */ |
| 29604 | 30001 | #define UNIXVFS(VFSNAME, FINDER) { \ |
| 29605 | | - 2, /* iVersion */ \ |
| 30002 | + 3, /* iVersion */ \ |
| 29606 | 30003 | sizeof(unixFile), /* szOsFile */ \ |
| 29607 | 30004 | MAX_PATHNAME, /* mxPathname */ \ |
| 29608 | 30005 | 0, /* pNext */ \ |
| 29609 | 30006 | VFSNAME, /* zName */ \ |
| 29610 | 30007 | (void*)&FINDER, /* pAppData */ \ |
| | @@ -29619,10 +30016,13 @@ |
| 29619 | 30016 | unixRandomness, /* xRandomness */ \ |
| 29620 | 30017 | unixSleep, /* xSleep */ \ |
| 29621 | 30018 | unixCurrentTime, /* xCurrentTime */ \ |
| 29622 | 30019 | unixGetLastError, /* xGetLastError */ \ |
| 29623 | 30020 | unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ |
| 30021 | + unixSetSystemCall, /* xSetSystemCall */ \ |
| 30022 | + unixGetSystemCall, /* xGetSystemCall */ \ |
| 30023 | + unixNextSystemCall, /* xNextSystemCall */ \ |
| 29624 | 30024 | } |
| 29625 | 30025 | |
| 29626 | 30026 | /* |
| 29627 | 30027 | ** All default VFSes for unix are contained in the following array. |
| 29628 | 30028 | ** |
| | @@ -29636,10 +30036,11 @@ |
| 29636 | 30036 | #else |
| 29637 | 30037 | UNIXVFS("unix", posixIoFinder ), |
| 29638 | 30038 | #endif |
| 29639 | 30039 | UNIXVFS("unix-none", nolockIoFinder ), |
| 29640 | 30040 | UNIXVFS("unix-dotfile", dotlockIoFinder ), |
| 30041 | + UNIXVFS("unix-excl", posixIoFinder ), |
| 29641 | 30042 | #if OS_VXWORKS |
| 29642 | 30043 | UNIXVFS("unix-namedsem", semIoFinder ), |
| 29643 | 30044 | #endif |
| 29644 | 30045 | #if SQLITE_ENABLE_LOCKING_STYLE |
| 29645 | 30046 | UNIXVFS("unix-posix", posixIoFinder ), |
| | @@ -32626,11 +33027,11 @@ |
| 32626 | 33027 | /* |
| 32627 | 33028 | ** Initialize and deinitialize the operating system interface. |
| 32628 | 33029 | */ |
| 32629 | 33030 | SQLITE_API int sqlite3_os_init(void){ |
| 32630 | 33031 | static sqlite3_vfs winVfs = { |
| 32631 | | - 2, /* iVersion */ |
| 33032 | + 3, /* iVersion */ |
| 32632 | 33033 | sizeof(winFile), /* szOsFile */ |
| 32633 | 33034 | MAX_PATH, /* mxPathname */ |
| 32634 | 33035 | 0, /* pNext */ |
| 32635 | 33036 | "win32", /* zName */ |
| 32636 | 33037 | 0, /* pAppData */ |
| | @@ -32645,10 +33046,13 @@ |
| 32645 | 33046 | winRandomness, /* xRandomness */ |
| 32646 | 33047 | winSleep, /* xSleep */ |
| 32647 | 33048 | winCurrentTime, /* xCurrentTime */ |
| 32648 | 33049 | winGetLastError, /* xGetLastError */ |
| 32649 | 33050 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 33051 | + 0, /* xSetSystemCall */ |
| 33052 | + 0, /* xGetSystemCall */ |
| 33053 | + 0, /* xNextSystemCall */ |
| 32650 | 33054 | }; |
| 32651 | 33055 | |
| 32652 | 33056 | #ifndef SQLITE_OMIT_WAL |
| 32653 | 33057 | /* get memory map allocation granularity */ |
| 32654 | 33058 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| | @@ -50782,15 +51186,13 @@ |
| 50782 | 51186 | } |
| 50783 | 51187 | if( nearby>0 ){ |
| 50784 | 51188 | u32 i; |
| 50785 | 51189 | int dist; |
| 50786 | 51190 | closest = 0; |
| 50787 | | - dist = get4byte(&aData[8]) - nearby; |
| 50788 | | - if( dist<0 ) dist = -dist; |
| 51191 | + dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); |
| 50789 | 51192 | for(i=1; i<k; i++){ |
| 50790 | | - int d2 = get4byte(&aData[8+i*4]) - nearby; |
| 50791 | | - if( d2<0 ) d2 = -d2; |
| 51193 | + int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby); |
| 50792 | 51194 | if( d2<dist ){ |
| 50793 | 51195 | closest = i; |
| 50794 | 51196 | dist = d2; |
| 50795 | 51197 | } |
| 50796 | 51198 | } |
| | @@ -55777,13 +56179,18 @@ |
| 55777 | 56179 | } |
| 55778 | 56180 | }else if( op==TK_UMINUS ) { |
| 55779 | 56181 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 55780 | 56182 | if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ |
| 55781 | 56183 | sqlite3VdbeMemNumerify(pVal); |
| 55782 | | - pVal->u.i = -1 * pVal->u.i; |
| 55783 | | - /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ |
| 55784 | | - pVal->r = (double)-1 * pVal->r; |
| 56184 | + if( pVal->u.i==SMALLEST_INT64 ){ |
| 56185 | + pVal->flags &= MEM_Int; |
| 56186 | + pVal->flags |= MEM_Real; |
| 56187 | + pVal->r = (double)LARGEST_INT64; |
| 56188 | + }else{ |
| 56189 | + pVal->u.i = -pVal->u.i; |
| 56190 | + } |
| 56191 | + pVal->r = -pVal->r; |
| 55785 | 56192 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 55786 | 56193 | } |
| 55787 | 56194 | }else if( op==TK_NULL ){ |
| 55788 | 56195 | pVal = sqlite3ValueNew(db); |
| 55789 | 56196 | if( pVal==0 ) goto no_mem; |
| | @@ -56805,12 +57212,12 @@ |
| 56805 | 57212 | ** will be used so that it can acquire mutexes on them all in sorted |
| 56806 | 57213 | ** order (via sqlite3VdbeMutexArrayEnter(). Mutexes are acquired |
| 56807 | 57214 | ** in order (and released in reverse order) to avoid deadlocks. |
| 56808 | 57215 | */ |
| 56809 | 57216 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ |
| 56810 | | - int mask; |
| 56811 | | - assert( i>=0 && i<p->db->nDb && i<sizeof(u32)*8 ); |
| 57217 | + tAttachMask mask; |
| 57218 | + assert( i>=0 && i<p->db->nDb && i<sizeof(tAttachMask)*8 ); |
| 56812 | 57219 | assert( i<(int)sizeof(p->btreeMask)*8 ); |
| 56813 | 57220 | mask = ((u32)1)<<i; |
| 56814 | 57221 | if( (p->btreeMask & mask)==0 ){ |
| 56815 | 57222 | p->btreeMask |= mask; |
| 56816 | 57223 | sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt); |
| | @@ -61309,10 +61716,11 @@ |
| 61309 | 61716 | struct OP_SetCookie_stack_vars { |
| 61310 | 61717 | Db *pDb; |
| 61311 | 61718 | } au; |
| 61312 | 61719 | struct OP_VerifyCookie_stack_vars { |
| 61313 | 61720 | int iMeta; |
| 61721 | + int iGen; |
| 61314 | 61722 | Btree *pBt; |
| 61315 | 61723 | } av; |
| 61316 | 61724 | struct OP_OpenWrite_stack_vars { |
| 61317 | 61725 | int nField; |
| 61318 | 61726 | KeyInfo *pKeyInfo; |
| | @@ -63931,14 +64339,16 @@ |
| 63931 | 64339 | p->expired = 0; |
| 63932 | 64340 | } |
| 63933 | 64341 | break; |
| 63934 | 64342 | } |
| 63935 | 64343 | |
| 63936 | | -/* Opcode: VerifyCookie P1 P2 * |
| 64344 | +/* Opcode: VerifyCookie P1 P2 P3 * * |
| 63937 | 64345 | ** |
| 63938 | 64346 | ** Check the value of global database parameter number 0 (the |
| 63939 | | -** schema version) and make sure it is equal to P2. |
| 64347 | +** schema version) and make sure it is equal to P2 and that the |
| 64348 | +** generation counter on the local schema parse equals P3. |
| 64349 | +** |
| 63940 | 64350 | ** P1 is the database number which is 0 for the main database file |
| 63941 | 64351 | ** and 1 for the file holding temporary tables and some higher number |
| 63942 | 64352 | ** for auxiliary databases. |
| 63943 | 64353 | ** |
| 63944 | 64354 | ** The cookie changes its value whenever the database schema changes. |
| | @@ -63950,21 +64360,24 @@ |
| 63950 | 64360 | ** invoked. |
| 63951 | 64361 | */ |
| 63952 | 64362 | case OP_VerifyCookie: { |
| 63953 | 64363 | #if 0 /* local variables moved into u.av */ |
| 63954 | 64364 | int iMeta; |
| 64365 | + int iGen; |
| 63955 | 64366 | Btree *pBt; |
| 63956 | 64367 | #endif /* local variables moved into u.av */ |
| 64368 | + |
| 63957 | 64369 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 63958 | 64370 | assert( (p->btreeMask & (1<<pOp->p1))!=0 ); |
| 63959 | 64371 | u.av.pBt = db->aDb[pOp->p1].pBt; |
| 63960 | 64372 | if( u.av.pBt ){ |
| 63961 | 64373 | sqlite3BtreeGetMeta(u.av.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.av.iMeta); |
| 64374 | + u.av.iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 63962 | 64375 | }else{ |
| 63963 | 64376 | u.av.iMeta = 0; |
| 63964 | 64377 | } |
| 63965 | | - if( u.av.iMeta!=pOp->p2 ){ |
| 64378 | + if( u.av.iMeta!=pOp->p2 || u.av.iGen!=pOp->p3 ){ |
| 63966 | 64379 | sqlite3DbFree(db, p->zErrMsg); |
| 63967 | 64380 | p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); |
| 63968 | 64381 | /* If the schema-cookie from the database file matches the cookie |
| 63969 | 64382 | ** stored with the in-memory representation of the schema, do |
| 63970 | 64383 | ** not reload the schema from the database file. |
| | @@ -65694,18 +66107,14 @@ |
| 65694 | 66107 | rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); |
| 65695 | 66108 | pOut->u.i = u.bt.pgno; |
| 65696 | 66109 | break; |
| 65697 | 66110 | } |
| 65698 | 66111 | |
| 65699 | | -/* Opcode: ParseSchema P1 P2 * P4 * |
| 66112 | +/* Opcode: ParseSchema P1 * * P4 * |
| 65700 | 66113 | ** |
| 65701 | 66114 | ** Read and parse all entries from the SQLITE_MASTER table of database P1 |
| 65702 | | -** that match the WHERE clause P4. P2 is the "force" flag. Always do |
| 65703 | | -** the parsing if P2 is true. If P2 is false, then this routine is a |
| 65704 | | -** no-op if the schema is not currently loaded. In other words, if P2 |
| 65705 | | -** is false, the SQLITE_MASTER table is only parsed if the rest of the |
| 65706 | | -** schema is already loaded into the symbol table. |
| 66115 | +** that match the WHERE clause P4. |
| 65707 | 66116 | ** |
| 65708 | 66117 | ** This opcode invokes the parser to create a new virtual machine, |
| 65709 | 66118 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 65710 | 66119 | */ |
| 65711 | 66120 | case OP_ParseSchema: { |
| | @@ -65717,18 +66126,11 @@ |
| 65717 | 66126 | #endif /* local variables moved into u.bu */ |
| 65718 | 66127 | |
| 65719 | 66128 | u.bu.iDb = pOp->p1; |
| 65720 | 66129 | assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb ); |
| 65721 | 66130 | |
| 65722 | | - /* If pOp->p2 is 0, then this opcode is being executed to read a |
| 65723 | | - ** single row, for example the row corresponding to a new index |
| 65724 | | - ** created by this VDBE, from the sqlite_master table. It only |
| 65725 | | - ** does this if the corresponding in-memory schema is currently |
| 65726 | | - ** loaded. Otherwise, the new index definition can be loaded along |
| 65727 | | - ** with the rest of the schema when it is required. |
| 65728 | | - ** |
| 65729 | | - ** Although the mutex on the BtShared object that corresponds to |
| 66131 | + /* Although the mutex on the BtShared object that corresponds to |
| 65730 | 66132 | ** database u.bu.iDb (the database containing the sqlite_master table |
| 65731 | 66133 | ** read by this instruction) is currently held, it is necessary to |
| 65732 | 66134 | ** obtain the mutexes on all attached databases before checking if |
| 65733 | 66135 | ** the schema of u.bu.iDb is loaded. This is because, at the start of |
| 65734 | 66136 | ** the sqlite3_exec() call below, SQLite will invoke |
| | @@ -65740,11 +66142,11 @@ |
| 65740 | 66142 | ** can result in a "no such table: sqlite_master" or "malformed |
| 65741 | 66143 | ** database schema" error being returned to the user. |
| 65742 | 66144 | */ |
| 65743 | 66145 | assert( sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) ); |
| 65744 | 66146 | sqlite3BtreeEnterAll(db); |
| 65745 | | - if( pOp->p2 || DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ){ |
| 66147 | + if( ALWAYS(DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded)) ){ |
| 65746 | 66148 | u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb); |
| 65747 | 66149 | u.bu.initData.db = db; |
| 65748 | 66150 | u.bu.initData.iDb = pOp->p1; |
| 65749 | 66151 | u.bu.initData.pzErrMsg = &p->zErrMsg; |
| 65750 | 66152 | u.bu.zSql = sqlite3MPrintf(db, |
| | @@ -67395,10 +67797,11 @@ |
| 67395 | 67797 | sqlite3VdbeChangeP2(v, 0, flags); |
| 67396 | 67798 | |
| 67397 | 67799 | /* Configure the OP_VerifyCookie */ |
| 67398 | 67800 | sqlite3VdbeChangeP1(v, 1, iDb); |
| 67399 | 67801 | sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); |
| 67802 | + sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); |
| 67400 | 67803 | |
| 67401 | 67804 | /* Make sure a mutex is held on the table to be accessed */ |
| 67402 | 67805 | sqlite3VdbeUsesBtree(v, iDb); |
| 67403 | 67806 | |
| 67404 | 67807 | /* Configure the OP_TableLock instruction */ |
| | @@ -69826,10 +70229,11 @@ |
| 69826 | 70229 | |
| 69827 | 70230 | if( pToken ){ |
| 69828 | 70231 | if( op!=TK_INTEGER || pToken->z==0 |
| 69829 | 70232 | || sqlite3GetInt32(pToken->z, &iValue)==0 ){ |
| 69830 | 70233 | nExtra = pToken->n+1; |
| 70234 | + assert( iValue>=0 ); |
| 69831 | 70235 | } |
| 69832 | 70236 | } |
| 69833 | 70237 | pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra); |
| 69834 | 70238 | if( pNew ){ |
| 69835 | 70239 | pNew->op = (u8)op; |
| | @@ -70051,10 +70455,12 @@ |
| 70051 | 70455 | /* |
| 70052 | 70456 | ** Recursively delete an expression tree. |
| 70053 | 70457 | */ |
| 70054 | 70458 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| 70055 | 70459 | if( p==0 ) return; |
| 70460 | + /* Sanity check: Assert that the IntValue is non-negative if it exists */ |
| 70461 | + assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); |
| 70056 | 70462 | if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ |
| 70057 | 70463 | sqlite3ExprDelete(db, p->pLeft); |
| 70058 | 70464 | sqlite3ExprDelete(db, p->pRight); |
| 70059 | 70465 | if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){ |
| 70060 | 70466 | sqlite3DbFree(db, p->u.zToken); |
| | @@ -70660,17 +71066,10 @@ |
| 70660 | 71066 | } |
| 70661 | 71067 | break; |
| 70662 | 71068 | } |
| 70663 | 71069 | default: break; |
| 70664 | 71070 | } |
| 70665 | | - if( rc ){ |
| 70666 | | - assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly) |
| 70667 | | - || (p->flags2 & EP2_MallocedToken)==0 ); |
| 70668 | | - p->op = TK_INTEGER; |
| 70669 | | - p->flags |= EP_IntValue; |
| 70670 | | - p->u.iValue = *pValue; |
| 70671 | | - } |
| 70672 | 71071 | return rc; |
| 70673 | 71072 | } |
| 70674 | 71073 | |
| 70675 | 71074 | /* |
| 70676 | 71075 | ** Return FALSE if there is no chance that the expression can be NULL. |
| | @@ -71391,10 +71790,11 @@ |
| 71391 | 71790 | */ |
| 71392 | 71791 | static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ |
| 71393 | 71792 | Vdbe *v = pParse->pVdbe; |
| 71394 | 71793 | if( pExpr->flags & EP_IntValue ){ |
| 71395 | 71794 | int i = pExpr->u.iValue; |
| 71795 | + assert( i>=0 ); |
| 71396 | 71796 | if( negFlag ) i = -i; |
| 71397 | 71797 | sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); |
| 71398 | 71798 | }else{ |
| 71399 | 71799 | int c; |
| 71400 | 71800 | i64 value; |
| | @@ -75655,19 +76055,21 @@ |
| 75655 | 76055 | ** set for each database that is used. Generate code to start a |
| 75656 | 76056 | ** transaction on each used database and to verify the schema cookie |
| 75657 | 76057 | ** on each used database. |
| 75658 | 76058 | */ |
| 75659 | 76059 | if( pParse->cookieGoto>0 ){ |
| 75660 | | - u32 mask; |
| 76060 | + tAttachMask mask; |
| 75661 | 76061 | int iDb; |
| 75662 | 76062 | sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); |
| 75663 | 76063 | for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ |
| 75664 | 76064 | if( (mask & pParse->cookieMask)==0 ) continue; |
| 75665 | 76065 | sqlite3VdbeUsesBtree(v, iDb); |
| 75666 | 76066 | sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); |
| 75667 | 76067 | if( db->init.busy==0 ){ |
| 75668 | | - sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); |
| 76068 | + sqlite3VdbeAddOp3(v, OP_VerifyCookie, |
| 76069 | + iDb, pParse->cookieValue[iDb], |
| 76070 | + db->aDb[iDb].pSchema->iGeneration); |
| 75669 | 76071 | } |
| 75670 | 76072 | } |
| 75671 | 76073 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 75672 | 76074 | { |
| 75673 | 76075 | int i; |
| | @@ -75873,11 +76275,11 @@ |
| 75873 | 76275 | int len; |
| 75874 | 76276 | Hash *pHash = &db->aDb[iDb].pSchema->idxHash; |
| 75875 | 76277 | |
| 75876 | 76278 | len = sqlite3Strlen30(zIdxName); |
| 75877 | 76279 | pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0); |
| 75878 | | - if( pIndex ){ |
| 76280 | + if( ALWAYS(pIndex) ){ |
| 75879 | 76281 | if( pIndex->pTable->pIndex==pIndex ){ |
| 75880 | 76282 | pIndex->pTable->pIndex = pIndex->pNext; |
| 75881 | 76283 | }else{ |
| 75882 | 76284 | Index *p; |
| 75883 | 76285 | /* Justification of ALWAYS(); The index must be on the list of |
| | @@ -78949,16 +79351,16 @@ |
| 78949 | 79351 | if( v==0 ) return; /* This only happens if there was a prior error */ |
| 78950 | 79352 | pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; |
| 78951 | 79353 | } |
| 78952 | 79354 | if( iDb>=0 ){ |
| 78953 | 79355 | sqlite3 *db = pToplevel->db; |
| 78954 | | - int mask; |
| 79356 | + tAttachMask mask; |
| 78955 | 79357 | |
| 78956 | 79358 | assert( iDb<db->nDb ); |
| 78957 | 79359 | assert( db->aDb[iDb].pBt!=0 || iDb==1 ); |
| 78958 | 79360 | assert( iDb<SQLITE_MAX_ATTACHED+2 ); |
| 78959 | | - mask = 1<<iDb; |
| 79361 | + mask = ((tAttachMask)1)<<iDb; |
| 78960 | 79362 | if( (pToplevel->cookieMask & mask)==0 ){ |
| 78961 | 79363 | pToplevel->cookieMask |= mask; |
| 78962 | 79364 | pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; |
| 78963 | 79365 | if( !OMIT_TEMPDB && iDb==1 ){ |
| 78964 | 79366 | sqlite3OpenTempDatabase(pToplevel); |
| | @@ -78981,11 +79383,11 @@ |
| 78981 | 79383 | ** necessary to undo a write and the checkpoint should not be set. |
| 78982 | 79384 | */ |
| 78983 | 79385 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ |
| 78984 | 79386 | Parse *pToplevel = sqlite3ParseToplevel(pParse); |
| 78985 | 79387 | sqlite3CodeVerifySchema(pParse, iDb); |
| 78986 | | - pToplevel->writeMask |= 1<<iDb; |
| 79388 | + pToplevel->writeMask |= ((tAttachMask)1)<<iDb; |
| 78987 | 79389 | pToplevel->isMultiWrite |= setStatement; |
| 78988 | 79390 | } |
| 78989 | 79391 | |
| 78990 | 79392 | /* |
| 78991 | 79393 | ** Indicate that the statement currently under construction might write |
| | @@ -79626,11 +80028,14 @@ |
| 79626 | 80028 | sqlite3DeleteTable(0, pTab); |
| 79627 | 80029 | } |
| 79628 | 80030 | sqlite3HashClear(&temp1); |
| 79629 | 80031 | sqlite3HashClear(&pSchema->fkeyHash); |
| 79630 | 80032 | pSchema->pSeqTab = 0; |
| 79631 | | - pSchema->flags &= ~DB_SchemaLoaded; |
| 80033 | + if( pSchema->flags & DB_SchemaLoaded ){ |
| 80034 | + pSchema->iGeneration++; |
| 80035 | + pSchema->flags &= ~DB_SchemaLoaded; |
| 80036 | + } |
| 79632 | 80037 | } |
| 79633 | 80038 | |
| 79634 | 80039 | /* |
| 79635 | 80040 | ** Find and return the schema associated with a BTree. Create |
| 79636 | 80041 | ** a new one if necessary. |
| | @@ -84381,12 +84786,13 @@ |
| 84381 | 84786 | ** index and making sure that duplicate entries do not already exist. |
| 84382 | 84787 | ** Add the new records to the indices as we go. |
| 84383 | 84788 | */ |
| 84384 | 84789 | for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ |
| 84385 | 84790 | int regIdx; |
| 84791 | +#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT |
| 84386 | 84792 | int regR; |
| 84387 | | - |
| 84793 | +#endif |
| 84388 | 84794 | if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */ |
| 84389 | 84795 | |
| 84390 | 84796 | /* Create a key for accessing the index entry */ |
| 84391 | 84797 | regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1); |
| 84392 | 84798 | for(i=0; i<pIdx->nColumn; i++){ |
| | @@ -84399,10 +84805,15 @@ |
| 84399 | 84805 | } |
| 84400 | 84806 | sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); |
| 84401 | 84807 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); |
| 84402 | 84808 | sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); |
| 84403 | 84809 | sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); |
| 84810 | + |
| 84811 | +#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT |
| 84812 | + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); |
| 84813 | + continue; /* Treat pIdx as if it is not a UNIQUE index */ |
| 84814 | +#else |
| 84404 | 84815 | |
| 84405 | 84816 | /* Find out what action to take in case there is an indexing conflict */ |
| 84406 | 84817 | onError = pIdx->onError; |
| 84407 | 84818 | if( onError==OE_None ){ |
| 84408 | 84819 | sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1); |
| | @@ -84473,10 +84884,11 @@ |
| 84473 | 84884 | break; |
| 84474 | 84885 | } |
| 84475 | 84886 | } |
| 84476 | 84887 | sqlite3VdbeJumpHere(v, j3); |
| 84477 | 84888 | sqlite3ReleaseTempReg(pParse, regR); |
| 84889 | +#endif |
| 84478 | 84890 | } |
| 84479 | 84891 | |
| 84480 | 84892 | if( pbMayReplace ){ |
| 84481 | 84893 | *pbMayReplace = seenReplace; |
| 84482 | 84894 | } |
| | @@ -86501,12 +86913,11 @@ |
| 86501 | 86913 | addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); |
| 86502 | 86914 | sqlite3VdbeChangeP1(v, addr, iDb); |
| 86503 | 86915 | sqlite3VdbeChangeP1(v, addr+1, iDb); |
| 86504 | 86916 | sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); |
| 86505 | 86917 | }else{ |
| 86506 | | - int size = sqlite3Atoi(zRight); |
| 86507 | | - if( size<0 ) size = -size; |
| 86918 | + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); |
| 86508 | 86919 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 86509 | 86920 | sqlite3VdbeAddOp2(v, OP_Integer, size, 1); |
| 86510 | 86921 | sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); |
| 86511 | 86922 | pDb->pSchema->cache_size = size; |
| 86512 | 86923 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| | @@ -86811,12 +87222,11 @@ |
| 86811 | 87222 | if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ |
| 86812 | 87223 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 86813 | 87224 | if( !zRight ){ |
| 86814 | 87225 | returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); |
| 86815 | 87226 | }else{ |
| 86816 | | - int size = sqlite3Atoi(zRight); |
| 86817 | | - if( size<0 ) size = -size; |
| 87227 | + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); |
| 86818 | 87228 | pDb->pSchema->cache_size = size; |
| 86819 | 87229 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 86820 | 87230 | } |
| 86821 | 87231 | }else |
| 86822 | 87232 | |
| | @@ -87920,13 +88330,12 @@ |
| 87920 | 88330 | DbSetProperty(db, iDb, DB_Empty); |
| 87921 | 88331 | } |
| 87922 | 88332 | pDb->pSchema->enc = ENC(db); |
| 87923 | 88333 | |
| 87924 | 88334 | if( pDb->pSchema->cache_size==0 ){ |
| 87925 | | - size = meta[BTREE_DEFAULT_CACHE_SIZE-1]; |
| 88335 | + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); |
| 87926 | 88336 | if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } |
| 87927 | | - if( size<0 ) size = -size; |
| 87928 | 88337 | pDb->pSchema->cache_size = size; |
| 87929 | 88338 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 87930 | 88339 | } |
| 87931 | 88340 | |
| 87932 | 88341 | /* |
| | @@ -93787,12 +94196,16 @@ |
| 93787 | 94196 | int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ |
| 93788 | 94197 | ExprList *pChanges, /* Columns that change in an UPDATE statement */ |
| 93789 | 94198 | int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ |
| 93790 | 94199 | ){ |
| 93791 | 94200 | int mask = 0; |
| 93792 | | - Trigger *pList = sqlite3TriggerList(pParse, pTab); |
| 94201 | + Trigger *pList = 0; |
| 93793 | 94202 | Trigger *p; |
| 94203 | + |
| 94204 | + if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ |
| 94205 | + pList = sqlite3TriggerList(pParse, pTab); |
| 94206 | + } |
| 93794 | 94207 | assert( pList==0 || IsVirtual(pTab)==0 ); |
| 93795 | 94208 | for(p=pList; p; p=p->pNext){ |
| 93796 | 94209 | if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ |
| 93797 | 94210 | mask |= p->tr_tm; |
| 93798 | 94211 | } |
| | @@ -95642,11 +96055,11 @@ |
| 95642 | 96055 | v = sqlite3GetVdbe(pParse); |
| 95643 | 96056 | sqlite3ChangeCookie(pParse, iDb); |
| 95644 | 96057 | |
| 95645 | 96058 | sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); |
| 95646 | 96059 | zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); |
| 95647 | | - sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 1, 0, zWhere, P4_DYNAMIC); |
| 96060 | + sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); |
| 95648 | 96061 | sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, |
| 95649 | 96062 | pTab->zName, sqlite3Strlen30(pTab->zName) + 1); |
| 95650 | 96063 | } |
| 95651 | 96064 | |
| 95652 | 96065 | /* If we are rereading the sqlite_master table create the in-memory |
| | @@ -98732,11 +99145,12 @@ |
| 98732 | 99145 | /* |
| 98733 | 99146 | ** Estimate the number of rows that will be returned based on |
| 98734 | 99147 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 98735 | 99148 | ** the histogram data. This only works when x is the left-most |
| 98736 | 99149 | ** column of an index and sqlite_stat2 histogram data is available |
| 98737 | | -** for that index. |
| 99150 | +** for that index. When pExpr==NULL that means the constraint is |
| 99151 | +** "x IS NULL" instead of "x=VALUE". |
| 98738 | 99152 | ** |
| 98739 | 99153 | ** Write the estimated row count into *pnRow and return SQLITE_OK. |
| 98740 | 99154 | ** If unable to make an estimate, leave *pnRow unchanged and return |
| 98741 | 99155 | ** non-zero. |
| 98742 | 99156 | ** |
| | @@ -98757,12 +99171,16 @@ |
| 98757 | 99171 | int rc; /* Subfunction return code */ |
| 98758 | 99172 | double nRowEst; /* New estimate of the number of rows */ |
| 98759 | 99173 | |
| 98760 | 99174 | assert( p->aSample!=0 ); |
| 98761 | 99175 | aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 98762 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRhs); |
| 98763 | | - if( rc ) goto whereEqualScanEst_cancel; |
| 99176 | + if( pExpr ){ |
| 99177 | + rc = valueFromExpr(pParse, pExpr, aff, &pRhs); |
| 99178 | + if( rc ) goto whereEqualScanEst_cancel; |
| 99179 | + }else{ |
| 99180 | + pRhs = sqlite3ValueNew(pParse->db); |
| 99181 | + } |
| 98764 | 99182 | if( pRhs==0 ) return SQLITE_NOTFOUND; |
| 98765 | 99183 | rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); |
| 98766 | 99184 | if( rc ) goto whereEqualScanEst_cancel; |
| 98767 | 99185 | rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper); |
| 98768 | 99186 | if( rc ) goto whereEqualScanEst_cancel; |
| | @@ -99147,11 +99565,13 @@ |
| 99147 | 99565 | ** data is available for column x, then it might be possible |
| 99148 | 99566 | ** to get a better estimate on the number of rows based on |
| 99149 | 99567 | ** VALUE and how common that value is according to the histogram. |
| 99150 | 99568 | */ |
| 99151 | 99569 | if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 ){ |
| 99152 | | - if( pFirstTerm->eOperator==WO_EQ ){ |
| 99570 | + if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ |
| 99571 | + testcase( pFirstTerm->eOperator==WO_EQ ); |
| 99572 | + testcase( pFirstTerm->pOperator==WO_ISNULL ); |
| 99153 | 99573 | whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); |
| 99154 | 99574 | }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ |
| 99155 | 99575 | whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); |
| 99156 | 99576 | } |
| 99157 | 99577 | } |
| | @@ -100213,11 +100633,17 @@ |
| 100213 | 100633 | } |
| 100214 | 100634 | |
| 100215 | 100635 | /* Record the instruction used to terminate the loop. Disable |
| 100216 | 100636 | ** WHERE clause terms made redundant by the index range scan. |
| 100217 | 100637 | */ |
| 100218 | | - pLevel->op = bRev ? OP_Prev : OP_Next; |
| 100638 | + if( pLevel->plan.wsFlags & WHERE_UNIQUE ){ |
| 100639 | + pLevel->op = OP_Noop; |
| 100640 | + }else if( bRev ){ |
| 100641 | + pLevel->op = OP_Prev; |
| 100642 | + }else{ |
| 100643 | + pLevel->op = OP_Next; |
| 100644 | + } |
| 100219 | 100645 | pLevel->p1 = iIdxCur; |
| 100220 | 100646 | }else |
| 100221 | 100647 | |
| 100222 | 100648 | #ifndef SQLITE_OMIT_OR_OPTIMIZATION |
| 100223 | 100649 | if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){ |
| | @@ -106160,10 +106586,17 @@ |
| 106160 | 106586 | case SQLITE_CONFIG_HEAP: { |
| 106161 | 106587 | /* Designate a buffer for heap memory space */ |
| 106162 | 106588 | sqlite3GlobalConfig.pHeap = va_arg(ap, void*); |
| 106163 | 106589 | sqlite3GlobalConfig.nHeap = va_arg(ap, int); |
| 106164 | 106590 | sqlite3GlobalConfig.mnReq = va_arg(ap, int); |
| 106591 | + |
| 106592 | + if( sqlite3GlobalConfig.mnReq<1 ){ |
| 106593 | + sqlite3GlobalConfig.mnReq = 1; |
| 106594 | + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ |
| 106595 | + /* cap min request size at 2^12 */ |
| 106596 | + sqlite3GlobalConfig.mnReq = (1<<12); |
| 106597 | + } |
| 106165 | 106598 | |
| 106166 | 106599 | if( sqlite3GlobalConfig.pHeap==0 ){ |
| 106167 | 106600 | /* If the heap pointer is NULL, then restore the malloc implementation |
| 106168 | 106601 | ** back to NULL pointers too. This will cause the malloc to go |
| 106169 | 106602 | ** back to its default implementation when sqlite3_initialize() is |
| | @@ -106301,11 +106734,39 @@ |
| 106301 | 106734 | int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ |
| 106302 | 106735 | rc = setupLookaside(db, pBuf, sz, cnt); |
| 106303 | 106736 | break; |
| 106304 | 106737 | } |
| 106305 | 106738 | default: { |
| 106739 | + static const struct { |
| 106740 | + int op; /* The opcode */ |
| 106741 | + u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ |
| 106742 | + } aFlagOp[] = { |
| 106743 | + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, |
| 106744 | + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, |
| 106745 | + }; |
| 106746 | + unsigned int i; |
| 106306 | 106747 | rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ |
| 106748 | + for(i=0; i<ArraySize(aFlagOp); i++){ |
| 106749 | + if( aFlagOp[i].op==op ){ |
| 106750 | + int onoff = va_arg(ap, int); |
| 106751 | + int *pRes = va_arg(ap, int*); |
| 106752 | + int oldFlags = db->flags; |
| 106753 | + if( onoff>0 ){ |
| 106754 | + db->flags |= aFlagOp[i].mask; |
| 106755 | + }else if( onoff==0 ){ |
| 106756 | + db->flags &= ~aFlagOp[i].mask; |
| 106757 | + } |
| 106758 | + if( oldFlags!=db->flags ){ |
| 106759 | + sqlite3ExpirePreparedStatements(db); |
| 106760 | + } |
| 106761 | + if( pRes ){ |
| 106762 | + *pRes = (db->flags & aFlagOp[i].mask)!=0; |
| 106763 | + } |
| 106764 | + rc = SQLITE_OK; |
| 106765 | + break; |
| 106766 | + } |
| 106767 | + } |
| 106307 | 106768 | break; |
| 106308 | 106769 | } |
| 106309 | 106770 | } |
| 106310 | 106771 | va_end(ap); |
| 106311 | 106772 | return rc; |
| | @@ -107474,12 +107935,12 @@ |
| 107474 | 107935 | # error SQLITE_MAX_VDBE_OP must be at least 40 |
| 107475 | 107936 | #endif |
| 107476 | 107937 | #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 |
| 107477 | 107938 | # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 |
| 107478 | 107939 | #endif |
| 107479 | | -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>30 |
| 107480 | | -# error SQLITE_MAX_ATTACHED must be between 0 and 30 |
| 107940 | +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 |
| 107941 | +# error SQLITE_MAX_ATTACHED must be between 0 and 62 |
| 107481 | 107942 | #endif |
| 107482 | 107943 | #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 |
| 107483 | 107944 | # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 |
| 107484 | 107945 | #endif |
| 107485 | 107946 | #if SQLITE_MAX_COLUMN>32767 |
| | @@ -107634,11 +108095,11 @@ |
| 107634 | 108095 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); |
| 107635 | 108096 | memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); |
| 107636 | 108097 | db->autoCommit = 1; |
| 107637 | 108098 | db->nextAutovac = -1; |
| 107638 | 108099 | db->nextPagesize = 0; |
| 107639 | | - db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex |
| 108100 | + db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger |
| 107640 | 108101 | #if SQLITE_DEFAULT_FILE_FORMAT<4 |
| 107641 | 108102 | | SQLITE_LegacyFileFmt |
| 107642 | 108103 | #endif |
| 107643 | 108104 | #ifdef SQLITE_ENABLE_LOAD_EXTENSION |
| 107644 | 108105 | | SQLITE_LoadExtension |
| | @@ -119847,17 +120308,17 @@ |
| 119847 | 120308 | Fts3Expr *pExpr, /* Phrase expression node */ |
| 119848 | 120309 | int iPhrase, /* Phrase number */ |
| 119849 | 120310 | void *pCtx /* Pointer to MatchInfo structure */ |
| 119850 | 120311 | ){ |
| 119851 | 120312 | MatchInfo *p = (MatchInfo *)pCtx; |
| 120313 | + int iStart = iPhrase * p->nCol * 3; |
| 120314 | + int i; |
| 120315 | + |
| 120316 | + for(i=0; i<p->nCol; i++) p->aMatchinfo[iStart+i*3] = 0; |
| 119852 | 120317 | |
| 119853 | 120318 | if( pExpr->aDoclist ){ |
| 119854 | 120319 | char *pCsr; |
| 119855 | | - int iStart = iPhrase * p->nCol * 3; |
| 119856 | | - int i; |
| 119857 | | - |
| 119858 | | - for(i=0; i<p->nCol; i++) p->aMatchinfo[iStart+i*3] = 0; |
| 119859 | 120320 | |
| 119860 | 120321 | pCsr = sqlite3Fts3FindPositions(pExpr, p->pCursor->iPrevId, -1); |
| 119861 | 120322 | if( pCsr ){ |
| 119862 | 120323 | fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 0); |
| 119863 | 120324 | } |
| | @@ -121944,19 +122405,19 @@ |
| 121944 | 122405 | ** to which the constraint applies. The leftmost coordinate column |
| 121945 | 122406 | ** is 'a', the second from the left 'b' etc. |
| 121946 | 122407 | */ |
| 121947 | 122408 | static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 121948 | 122409 | int rc = SQLITE_OK; |
| 121949 | | - int ii, cCol; |
| 122410 | + int ii; |
| 121950 | 122411 | |
| 121951 | 122412 | int iIdx = 0; |
| 121952 | 122413 | char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; |
| 121953 | 122414 | memset(zIdxStr, 0, sizeof(zIdxStr)); |
| 121954 | 122415 | UNUSED_PARAMETER(tab); |
| 121955 | 122416 | |
| 121956 | 122417 | assert( pIdxInfo->idxStr==0 ); |
| 121957 | | - for(ii=0; ii<pIdxInfo->nConstraint; ii++){ |
| 122418 | + for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(sizeof(zIdxStr)-1); ii++){ |
| 121958 | 122419 | struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; |
| 121959 | 122420 | |
| 121960 | 122421 | if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
| 121961 | 122422 | /* We have an equality constraint on the rowid. Use strategy 1. */ |
| 121962 | 122423 | int jj; |
| | @@ -121976,13 +122437,11 @@ |
| 121976 | 122437 | pIdxInfo->estimatedCost = 10.0; |
| 121977 | 122438 | return SQLITE_OK; |
| 121978 | 122439 | } |
| 121979 | 122440 | |
| 121980 | 122441 | if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ |
| 121981 | | - int j, opmsk; |
| 121982 | | - static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; |
| 121983 | | - u8 op = 0; |
| 122442 | + u8 op; |
| 121984 | 122443 | switch( p->op ){ |
| 121985 | 122444 | case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; |
| 121986 | 122445 | case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; |
| 121987 | 122446 | case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; |
| 121988 | 122447 | case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; |
| | @@ -121990,41 +122449,14 @@ |
| 121990 | 122449 | default: |
| 121991 | 122450 | assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); |
| 121992 | 122451 | op = RTREE_MATCH; |
| 121993 | 122452 | break; |
| 121994 | 122453 | } |
| 121995 | | - assert( op!=0 ); |
| 121996 | | - |
| 121997 | | - /* Make sure this particular constraint has not been used before. |
| 121998 | | - ** If it has been used before, ignore it. |
| 121999 | | - ** |
| 122000 | | - ** A <= or < can be used if there is a prior >= or >. |
| 122001 | | - ** A >= or > can be used if there is a prior < or <=. |
| 122002 | | - ** A <= or < is disqualified if there is a prior <=, <, or ==. |
| 122003 | | - ** A >= or > is disqualified if there is a prior >=, >, or ==. |
| 122004 | | - ** A == is disqualifed if there is any prior constraint. |
| 122005 | | - */ |
| 122006 | | - assert( compatible[RTREE_EQ & 7]==0 ); |
| 122007 | | - assert( compatible[RTREE_LT & 7]==1 ); |
| 122008 | | - assert( compatible[RTREE_LE & 7]==1 ); |
| 122009 | | - assert( compatible[RTREE_GT & 7]==2 ); |
| 122010 | | - assert( compatible[RTREE_GE & 7]==2 ); |
| 122011 | | - cCol = p->iColumn - 1 + 'a'; |
| 122012 | | - opmsk = compatible[op & 7]; |
| 122013 | | - for(j=0; j<iIdx; j+=2){ |
| 122014 | | - if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ |
| 122015 | | - op = 0; |
| 122016 | | - break; |
| 122017 | | - } |
| 122018 | | - } |
| 122019 | | - if( op ){ |
| 122020 | | - assert( iIdx<sizeof(zIdxStr)-1 ); |
| 122021 | | - zIdxStr[iIdx++] = op; |
| 122022 | | - zIdxStr[iIdx++] = cCol; |
| 122023 | | - pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 122024 | | - pIdxInfo->aConstraintUsage[ii].omit = 1; |
| 122025 | | - } |
| 122454 | + zIdxStr[iIdx++] = op; |
| 122455 | + zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; |
| 122456 | + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 122457 | + pIdxInfo->aConstraintUsage[ii].omit = 1; |
| 122026 | 122458 | } |
| 122027 | 122459 | } |
| 122028 | 122460 | |
| 122029 | 122461 | pIdxInfo->idxNum = 2; |
| 122030 | 122462 | pIdxInfo->needToFreeIdxStr = 1; |
| 122031 | 122463 | |