Fossil SCM
Merge trunk
Commit
db4e4b46c39b2983a0c279ef41c5800b57e2654ee7ed0730c9441b82e0514cdd
Parent
084f17dcd627884…
16 files changed
+11
-2
+176
-198
+176
-198
+3
-3
+1
-1
+2
-2
+2
-2
+1
-6
+11
-3
+1
-1
+1
-1
+5
-3
+41
-5
+2
-1
+1
-1
+1
-1
+11
-2
| --- extsrc/shell.c | ||
| +++ extsrc/shell.c | ||
| @@ -1266,16 +1266,25 @@ | ||
| 1266 | 1266 | return 0x3fffffff & (int)(z2 - z); |
| 1267 | 1267 | } |
| 1268 | 1268 | |
| 1269 | 1269 | /* |
| 1270 | 1270 | ** Return the length of a string in characters. Multibyte UTF8 characters |
| 1271 | -** count as a single character. | |
| 1271 | +** count as a single character for single-width characters, or as two | |
| 1272 | +** characters for double-width characters. | |
| 1272 | 1273 | */ |
| 1273 | 1274 | static int strlenChar(const char *z){ |
| 1274 | 1275 | int n = 0; |
| 1275 | 1276 | while( *z ){ |
| 1276 | - if( (0xc0&*(z++))!=0x80 ) n++; | |
| 1277 | + if( (0x80&z[0])==0 ){ | |
| 1278 | + n++; | |
| 1279 | + z++; | |
| 1280 | + }else{ | |
| 1281 | + int u = 0; | |
| 1282 | + int len = decodeUtf8((const u8*)z, &u); | |
| 1283 | + z += len; | |
| 1284 | + n += cli_wcwidth(u); | |
| 1285 | + } | |
| 1277 | 1286 | } |
| 1278 | 1287 | return n; |
| 1279 | 1288 | } |
| 1280 | 1289 | |
| 1281 | 1290 | /* |
| 1282 | 1291 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -1266,16 +1266,25 @@ | |
| 1266 | return 0x3fffffff & (int)(z2 - z); |
| 1267 | } |
| 1268 | |
| 1269 | /* |
| 1270 | ** Return the length of a string in characters. Multibyte UTF8 characters |
| 1271 | ** count as a single character. |
| 1272 | */ |
| 1273 | static int strlenChar(const char *z){ |
| 1274 | int n = 0; |
| 1275 | while( *z ){ |
| 1276 | if( (0xc0&*(z++))!=0x80 ) n++; |
| 1277 | } |
| 1278 | return n; |
| 1279 | } |
| 1280 | |
| 1281 | /* |
| 1282 |
| --- extsrc/shell.c | |
| +++ extsrc/shell.c | |
| @@ -1266,16 +1266,25 @@ | |
| 1266 | return 0x3fffffff & (int)(z2 - z); |
| 1267 | } |
| 1268 | |
| 1269 | /* |
| 1270 | ** Return the length of a string in characters. Multibyte UTF8 characters |
| 1271 | ** count as a single character for single-width characters, or as two |
| 1272 | ** characters for double-width characters. |
| 1273 | */ |
| 1274 | static int strlenChar(const char *z){ |
| 1275 | int n = 0; |
| 1276 | while( *z ){ |
| 1277 | if( (0x80&z[0])==0 ){ |
| 1278 | n++; |
| 1279 | z++; |
| 1280 | }else{ |
| 1281 | int u = 0; |
| 1282 | int len = decodeUtf8((const u8*)z, &u); |
| 1283 | z += len; |
| 1284 | n += cli_wcwidth(u); |
| 1285 | } |
| 1286 | } |
| 1287 | return n; |
| 1288 | } |
| 1289 | |
| 1290 | /* |
| 1291 |
+176
-198
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | -** version 3.50.0. By combining all the individual C code files into this | |
| 3 | +** version 3.51.0. By combining all the individual C code files into this | |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** 336ceeccc6f85bd78f4a26648af7edf9056d with changes in files: | |
| 21 | +** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: | |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | ||
| 463 | 463 | ** |
| 464 | 464 | ** See also: [sqlite3_libversion()], |
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | -#define SQLITE_VERSION "3.50.0" | |
| 469 | -#define SQLITE_VERSION_NUMBER 3050000 | |
| 470 | -#define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" | |
| 468 | +#define SQLITE_VERSION "3.51.0" | |
| 469 | +#define SQLITE_VERSION_NUMBER 3051000 | |
| 470 | +#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| @@ -15174,11 +15174,11 @@ | ||
| 15174 | 15174 | /* |
| 15175 | 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | 15176 | ** ourselves. |
| 15177 | 15177 | */ |
| 15178 | 15178 | #ifndef offsetof |
| 15179 | -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 15179 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 15180 | 15180 | #endif |
| 15181 | 15181 | |
| 15182 | 15182 | /* |
| 15183 | 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | ||
| 17401 | 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | 17402 | #endif |
| 17403 | 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | 17405 | |
| 17406 | -SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); | |
| 17406 | +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); | |
| 17407 | 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | 17410 | |
| 17411 | 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | ||
| 18701 | 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | +#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ | |
| 18706 | 18707 | |
| 18707 | 18708 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18708 | 18709 | |
| 18709 | 18710 | /* |
| 18710 | 18711 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | ||
| 19016 | 19017 | /* |
| 19017 | 19018 | ** An instance of the following structure is passed as the first |
| 19018 | 19019 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19019 | 19020 | ** comparison of the two index keys. |
| 19020 | 19021 | ** |
| 19021 | -** Note that aSortOrder[] and aColl[] have nField+1 slots. There | |
| 19022 | -** are nField slots for the columns of an index then one extra slot | |
| 19023 | -** for the rowid at the end. | |
| 19022 | +** The aSortOrder[] and aColl[] arrays have nAllField slots each. There | |
| 19023 | +** are nKeyField slots for the columns of an index then extra slots | |
| 19024 | +** for the rowid or key at the end. The aSortOrder array is located after | |
| 19025 | +** the aColl[] array. | |
| 19026 | +** | |
| 19027 | +** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL | |
| 19028 | +** to indicate that this object is for use by a preupdate hook. When aSortFlags | |
| 19029 | +** is NULL, then nAllField is uninitialized and no space is allocated for | |
| 19030 | +** aColl[], so those fields may not be used. | |
| 19024 | 19031 | */ |
| 19025 | 19032 | struct KeyInfo { |
| 19026 | 19033 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19027 | 19034 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19028 | 19035 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | ||
| 19030 | 19037 | sqlite3 *db; /* The database connection */ |
| 19031 | 19038 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19032 | 19039 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19033 | 19040 | }; |
| 19034 | 19041 | |
| 19035 | -/* The size (in bytes) of a KeyInfo object with up to N fields */ | |
| 19042 | +/* The size (in bytes) of a KeyInfo object with up to N fields. This includes | |
| 19043 | +** the main body of the KeyInfo object and the aColl[] array of N elements, | |
| 19044 | +** but does not count the memory used to hold aSortFlags[]. */ | |
| 19036 | 19045 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19046 | + | |
| 19047 | +/* The size of a bare KeyInfo with no aColl[] entries */ | |
| 19048 | +#if FLEXARRAY+1 > 1 | |
| 19049 | +# define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) | |
| 19050 | +#else | |
| 19051 | +# define SZ_KEYINFO_0 sizeof(KeyInfo) | |
| 19052 | +#endif | |
| 19037 | 19053 | |
| 19038 | 19054 | /* |
| 19039 | 19055 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19040 | 19056 | */ |
| 19041 | 19057 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | ||
| 19051 | 19067 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19052 | 19068 | ** OP_Column opcode. |
| 19053 | 19069 | ** |
| 19054 | 19070 | ** An instance of this object serves as a "key" for doing a search on |
| 19055 | 19071 | ** an index b+tree. The goal of the search is to find the entry that |
| 19056 | -** is closed to the key described by this object. This object might hold | |
| 19057 | -** just a prefix of the key. The number of fields is given by | |
| 19058 | -** pKeyInfo->nField. | |
| 19072 | +** is closest to the key described by this object. This object might hold | |
| 19073 | +** just a prefix of the key. The number of fields is given by nField. | |
| 19059 | 19074 | ** |
| 19060 | 19075 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19061 | 19076 | ** or greater than a key in the btree, respectively. These are normally |
| 19062 | 19077 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19063 | 19078 | ** is in DESC order. |
| 19064 | 19079 | ** |
| 19065 | 19080 | ** The key comparison functions actually return default_rc when they find |
| 19066 | 19081 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19067 | 19082 | ** multiple entries in the b-tree with the same key (when only looking |
| 19068 | -** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to | |
| 19083 | +** at the first nField elements) then default_rc can be set to -1 to | |
| 19069 | 19084 | ** cause the search to find the last match, or +1 to cause the search to |
| 19070 | 19085 | ** find the first match. |
| 19071 | 19086 | ** |
| 19072 | 19087 | ** The key comparison functions will set eqSeen to true if they ever |
| 19073 | 19088 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | ||
| 19075 | 19090 | ** before the first match or immediately after the last match. The |
| 19076 | 19091 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19077 | 19092 | ** b-tree. |
| 19078 | 19093 | */ |
| 19079 | 19094 | struct UnpackedRecord { |
| 19080 | - KeyInfo *pKeyInfo; /* Collation and sort-order information */ | |
| 19081 | - Mem *aMem; /* Values */ | |
| 19095 | + KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ | |
| 19096 | + Mem *aMem; /* Values for columns of the index */ | |
| 19082 | 19097 | union { |
| 19083 | 19098 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19084 | 19099 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19085 | 19100 | } u; |
| 19086 | 19101 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | ||
| 24132 | 24147 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24133 | 24148 | Mem *aNew; /* Array of new.* values */ |
| 24134 | 24149 | Table *pTab; /* Schema object being updated */ |
| 24135 | 24150 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24136 | 24151 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24137 | - u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ | |
| 24152 | + u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ | |
| 24138 | 24153 | }; |
| 24139 | 24154 | |
| 24140 | 24155 | /* |
| 24141 | 24156 | ** An instance of this object is used to pass an vector of values into |
| 24142 | 24157 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | ||
| 35013 | 35028 | } |
| 35014 | 35029 | |
| 35015 | 35030 | /* |
| 35016 | 35031 | ** Write a single UTF8 character whose value is v into the |
| 35017 | 35032 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35018 | -** least for bytes. Return the number of bytes needed | |
| 35033 | +** least four bytes. Return the number of bytes needed | |
| 35019 | 35034 | ** to encode the new character. |
| 35020 | 35035 | */ |
| 35021 | 35036 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35022 | 35037 | if( v<0x00080 ){ |
| 35023 | 35038 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | ||
| 43872 | 43887 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43873 | 43888 | |
| 43874 | 43889 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43875 | 43890 | ** in the following list than the lock being obtained are already held: |
| 43876 | 43891 | ** |
| 43877 | - ** 1. Checkpointer lock (ofst==1). | |
| 43878 | - ** 2. Write lock (ofst==0). | |
| 43879 | - ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 43892 | + ** 1. Recovery lock (ofst==2). | |
| 43893 | + ** 2. Checkpointer lock (ofst==1). | |
| 43894 | + ** 3. Write lock (ofst==0). | |
| 43895 | + ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 43880 | 43896 | ** |
| 43881 | 43897 | ** In other words, if this is a blocking lock, none of the locks that |
| 43882 | 43898 | ** occur later in the above list than the lock being obtained may be |
| 43883 | 43899 | ** held. |
| 43884 | - ** | |
| 43885 | - ** It is not permitted to block on the RECOVER lock. | |
| 43886 | 43900 | */ |
| 43887 | 43901 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43888 | 43902 | { |
| 43889 | 43903 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43890 | 43904 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43891 | - (ofst!=2) /* not RECOVER */ | |
| 43905 | + (ofst!=2 || lockMask==0) | |
| 43892 | 43906 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43893 | 43907 | && (ofst!=0 || lockMask<3) |
| 43894 | 43908 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43895 | 43909 | )); |
| 43896 | 43910 | } |
| @@ -49851,11 +49865,15 @@ | ||
| 49851 | 49865 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49852 | 49866 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49853 | 49867 | if( res==WAIT_OBJECT_0 ){ |
| 49854 | 49868 | ret = TRUE; |
| 49855 | 49869 | }else if( res==WAIT_TIMEOUT ){ |
| 49870 | +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 | |
| 49856 | 49871 | rc = SQLITE_BUSY_TIMEOUT; |
| 49872 | +#else | |
| 49873 | + rc = SQLITE_BUSY; | |
| 49874 | +#endif | |
| 49857 | 49875 | }else{ |
| 49858 | 49876 | /* Some other error has occurred */ |
| 49859 | 49877 | rc = SQLITE_IOERR_LOCK; |
| 49860 | 49878 | } |
| 49861 | 49879 | |
| @@ -51337,17 +51355,17 @@ | ||
| 51337 | 51355 | int nChar; |
| 51338 | 51356 | LPWSTR zWideFilename; |
| 51339 | 51357 | |
| 51340 | 51358 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51341 | 51359 | && winIsDirSep(zFilename[2])) ){ |
| 51342 | - int nByte; | |
| 51360 | + i64 nByte; | |
| 51343 | 51361 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51344 | 51362 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51345 | - nByte = (int)osCygwin_conv_path(convertflag, | |
| 51363 | + nByte = (i64)osCygwin_conv_path(convertflag, | |
| 51346 | 51364 | zFilename, 0, 0); |
| 51347 | 51365 | if( nByte>0 ){ |
| 51348 | - zConverted = sqlite3MallocZero(nByte+12); | |
| 51366 | + zConverted = sqlite3MallocZero(12+(u64)nByte); | |
| 51349 | 51367 | if ( zConverted==0 ){ |
| 51350 | 51368 | return zConverted; |
| 51351 | 51369 | } |
| 51352 | 51370 | zWideFilename = zConverted; |
| 51353 | 51371 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | ||
| 51662 | 51680 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51663 | 51681 | |
| 51664 | 51682 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51665 | 51683 | ** in the following list than the lock being obtained are already held: |
| 51666 | 51684 | ** |
| 51667 | - ** 1. Checkpointer lock (ofst==1). | |
| 51668 | - ** 2. Write lock (ofst==0). | |
| 51669 | - ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 51685 | + ** 1. Recovery lock (ofst==2). | |
| 51686 | + ** 2. Checkpointer lock (ofst==1). | |
| 51687 | + ** 3. Write lock (ofst==0). | |
| 51688 | + ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 51670 | 51689 | ** |
| 51671 | 51690 | ** In other words, if this is a blocking lock, none of the locks that |
| 51672 | 51691 | ** occur later in the above list than the lock being obtained may be |
| 51673 | 51692 | ** held. |
| 51674 | - ** | |
| 51675 | - ** It is not permitted to block on the RECOVER lock. | |
| 51676 | 51693 | */ |
| 51677 | 51694 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51678 | 51695 | { |
| 51679 | 51696 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51680 | 51697 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51681 | - (ofst!=2) /* not RECOVER */ | |
| 51698 | + (ofst!=2 || lockMask==0) | |
| 51682 | 51699 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51683 | 51700 | && (ofst!=0 || lockMask<3) |
| 51684 | 51701 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51685 | 51702 | )); |
| 51686 | 51703 | } |
| @@ -52226,31 +52243,10 @@ | ||
| 52226 | 52243 | ** |
| 52227 | 52244 | ** This division contains the implementation of methods on the |
| 52228 | 52245 | ** sqlite3_vfs object. |
| 52229 | 52246 | */ |
| 52230 | 52247 | |
| 52231 | -#if 0 /* No longer necessary */ | |
| 52232 | -/* | |
| 52233 | -** Convert a filename from whatever the underlying operating system | |
| 52234 | -** supports for filenames into UTF-8. Space to hold the result is | |
| 52235 | -** obtained from malloc and must be freed by the calling function. | |
| 52236 | -*/ | |
| 52237 | -static char *winConvertToUtf8Filename(const void *zFilename){ | |
| 52238 | - char *zConverted = 0; | |
| 52239 | - if( osIsNT() ){ | |
| 52240 | - zConverted = winUnicodeToUtf8(zFilename); | |
| 52241 | - } | |
| 52242 | -#ifdef SQLITE_WIN32_HAS_ANSI | |
| 52243 | - else{ | |
| 52244 | - zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); | |
| 52245 | - } | |
| 52246 | -#endif | |
| 52247 | - /* caller will handle out of memory */ | |
| 52248 | - return zConverted; | |
| 52249 | -} | |
| 52250 | -#endif | |
| 52251 | - | |
| 52252 | 52248 | /* |
| 52253 | 52249 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52254 | 52250 | ** ends with a directory separator character or one was successfully |
| 52255 | 52251 | ** added to it. |
| 52256 | 52252 | */ |
| @@ -52386,46 +52382,10 @@ | ||
| 52386 | 52382 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52387 | 52383 | sqlite3_free(zConverted); |
| 52388 | 52384 | break; |
| 52389 | 52385 | } |
| 52390 | 52386 | sqlite3_free(zConverted); |
| 52391 | -#if 0 /* No longer necessary */ | |
| 52392 | - }else{ | |
| 52393 | - zConverted = sqlite3MallocZero( nMax+1 ); | |
| 52394 | - if( !zConverted ){ | |
| 52395 | - sqlite3_free(zBuf); | |
| 52396 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 52397 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 52398 | - } | |
| 52399 | - if( osCygwin_conv_path( | |
| 52400 | - CCP_POSIX_TO_WIN_W, zDir, | |
| 52401 | - zConverted, nMax+1)<0 ){ | |
| 52402 | - sqlite3_free(zConverted); | |
| 52403 | - sqlite3_free(zBuf); | |
| 52404 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); | |
| 52405 | - return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, | |
| 52406 | - "winGetTempname2", zDir); | |
| 52407 | - } | |
| 52408 | - if( winIsDir(zConverted) ){ | |
| 52409 | - /* At this point, we know the candidate directory exists and should | |
| 52410 | - ** be used. However, we may need to convert the string containing | |
| 52411 | - ** its name into UTF-8 (i.e. if it is UTF-16 right now). | |
| 52412 | - */ | |
| 52413 | - char *zUtf8 = winConvertToUtf8Filename(zConverted); | |
| 52414 | - if( !zUtf8 ){ | |
| 52415 | - sqlite3_free(zConverted); | |
| 52416 | - sqlite3_free(zBuf); | |
| 52417 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 52418 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 52419 | - } | |
| 52420 | - sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); | |
| 52421 | - sqlite3_free(zUtf8); | |
| 52422 | - sqlite3_free(zConverted); | |
| 52423 | - break; | |
| 52424 | - } | |
| 52425 | - sqlite3_free(zConverted); | |
| 52426 | -#endif /* No longer necessary */ | |
| 52427 | 52387 | } |
| 52428 | 52388 | } |
| 52429 | 52389 | } |
| 52430 | 52390 | #endif |
| 52431 | 52391 | |
| @@ -53320,38 +53280,10 @@ | ||
| 53320 | 53280 | winSimplifyName(zFull); |
| 53321 | 53281 | return rc; |
| 53322 | 53282 | } |
| 53323 | 53283 | } |
| 53324 | 53284 | #endif /* __CYGWIN__ */ |
| 53325 | -#if 0 /* This doesn't work correctly at all! See: | |
| 53326 | - <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> | |
| 53327 | -*/ | |
| 53328 | - SimulateIOError( return SQLITE_ERROR ); | |
| 53329 | - UNUSED_PARAMETER(nFull); | |
| 53330 | - assert( nFull>=pVfs->mxPathname ); | |
| 53331 | - char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); | |
| 53332 | - if( !zOut ){ | |
| 53333 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 53334 | - } | |
| 53335 | - if( osCygwin_conv_path( | |
| 53336 | - CCP_POSIX_TO_WIN_W, | |
| 53337 | - zRelative, zOut, pVfs->mxPathname+1)<0 ){ | |
| 53338 | - sqlite3_free(zOut); | |
| 53339 | - return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, | |
| 53340 | - "winFullPathname2", zRelative); | |
| 53341 | - }else{ | |
| 53342 | - char *zUtf8 = winConvertToUtf8Filename(zOut); | |
| 53343 | - if( !zUtf8 ){ | |
| 53344 | - sqlite3_free(zOut); | |
| 53345 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 53346 | - } | |
| 53347 | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); | |
| 53348 | - sqlite3_free(zUtf8); | |
| 53349 | - sqlite3_free(zOut); | |
| 53350 | - } | |
| 53351 | - return SQLITE_OK; | |
| 53352 | -#endif | |
| 53353 | 53285 | |
| 53354 | 53286 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53355 | 53287 | SimulateIOError( return SQLITE_ERROR ); |
| 53356 | 53288 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53357 | 53289 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | ||
| 53493 | 53425 | ** Interfaces for opening a shared library, finding entry points |
| 53494 | 53426 | ** within the shared library, and closing the shared library. |
| 53495 | 53427 | */ |
| 53496 | 53428 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53497 | 53429 | HANDLE h; |
| 53498 | -#if 0 /* This doesn't work correctly at all! See: | |
| 53499 | - <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> | |
| 53500 | -*/ | |
| 53501 | - int nFull = pVfs->mxPathname+1; | |
| 53502 | - char *zFull = sqlite3MallocZero( nFull ); | |
| 53503 | - void *zConverted = 0; | |
| 53504 | - if( zFull==0 ){ | |
| 53505 | - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); | |
| 53506 | - return 0; | |
| 53507 | - } | |
| 53508 | - if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ | |
| 53509 | - sqlite3_free(zFull); | |
| 53510 | - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); | |
| 53511 | - return 0; | |
| 53512 | - } | |
| 53513 | - zConverted = winConvertFromUtf8Filename(zFull); | |
| 53514 | - sqlite3_free(zFull); | |
| 53515 | -#else | |
| 53516 | 53430 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53517 | 53431 | UNUSED_PARAMETER(pVfs); |
| 53518 | -#endif | |
| 53519 | 53432 | if( zConverted==0 ){ |
| 53520 | 53433 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53521 | 53434 | return 0; |
| 53522 | 53435 | } |
| 53523 | 53436 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | ||
| 58855 | 58768 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58856 | 58769 | PCache *pPCache; /* Pointer to page cache object */ |
| 58857 | 58770 | #ifndef SQLITE_OMIT_WAL |
| 58858 | 58771 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58859 | 58772 | char *zWal; /* File name for write-ahead log */ |
| 58773 | +#endif | |
| 58774 | +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT | |
| 58775 | + sqlite3 *dbWal; | |
| 58860 | 58776 | #endif |
| 58861 | 58777 | }; |
| 58862 | 58778 | |
| 58863 | 58779 | /* |
| 58864 | 58780 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | ||
| 65737 | 65653 | if( rc==SQLITE_OK ){ |
| 65738 | 65654 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65739 | 65655 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65740 | 65656 | pPager->journalSizeLimit, &pPager->pWal |
| 65741 | 65657 | ); |
| 65658 | +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT | |
| 65659 | + if( rc==SQLITE_OK ){ | |
| 65660 | + sqlite3WalDb(pPager->pWal, pPager->dbWal); | |
| 65661 | + } | |
| 65662 | +#endif | |
| 65742 | 65663 | } |
| 65743 | 65664 | pagerFixMaplimit(pPager); |
| 65744 | 65665 | |
| 65745 | 65666 | return rc; |
| 65746 | 65667 | } |
| @@ -65856,10 +65777,11 @@ | ||
| 65856 | 65777 | /* |
| 65857 | 65778 | ** Set the database handle used by the wal layer to determine if |
| 65858 | 65779 | ** blocking locks are required. |
| 65859 | 65780 | */ |
| 65860 | 65781 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65782 | + pPager->dbWal = db; | |
| 65861 | 65783 | if( pagerUseWal(pPager) ){ |
| 65862 | 65784 | sqlite3WalDb(pPager->pWal, db); |
| 65863 | 65785 | } |
| 65864 | 65786 | } |
| 65865 | 65787 | #endif |
| @@ -69029,11 +68951,10 @@ | ||
| 69029 | 68951 | assert( rc==SQLITE_OK ); |
| 69030 | 68952 | if( pWal->bShmUnreliable==0 ){ |
| 69031 | 68953 | rc = walIndexReadHdr(pWal, pChanged); |
| 69032 | 68954 | } |
| 69033 | 68955 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 69034 | - walDisableBlocking(pWal); | |
| 69035 | 68956 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 69036 | 68957 | rc = SQLITE_BUSY; |
| 69037 | 68958 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 69038 | 68959 | } |
| 69039 | 68960 | #endif |
| @@ -69044,10 +68965,11 @@ | ||
| 69044 | 68965 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 69045 | 68966 | ** would be technically correct. But the race is benign since with |
| 69046 | 68967 | ** WAL_RETRY this routine will be called again and will probably be |
| 69047 | 68968 | ** right on the second iteration. |
| 69048 | 68969 | */ |
| 68970 | + (void)walEnableBlocking(pWal); | |
| 69049 | 68971 | if( pWal->apWiData[0]==0 ){ |
| 69050 | 68972 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 69051 | 68973 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 69052 | 68974 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 69053 | 68975 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | ||
| 69060 | 68982 | rc = WAL_RETRY; |
| 69061 | 68983 | }else if( rc==SQLITE_BUSY ){ |
| 69062 | 68984 | rc = SQLITE_BUSY_RECOVERY; |
| 69063 | 68985 | } |
| 69064 | 68986 | } |
| 68987 | + walDisableBlocking(pWal); | |
| 69065 | 68988 | if( rc!=SQLITE_OK ){ |
| 69066 | 68989 | return rc; |
| 69067 | 68990 | } |
| 69068 | 68991 | else if( pWal->bShmUnreliable ){ |
| 69069 | 68992 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | ||
| 72509 | 72432 | if( pKey ){ |
| 72510 | 72433 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72511 | 72434 | assert( nKey==(i64)(int)nKey ); |
| 72512 | 72435 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72513 | 72436 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72514 | - sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); | |
| 72437 | + sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); | |
| 72515 | 72438 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72516 | 72439 | rc = SQLITE_CORRUPT_BKPT; |
| 72517 | 72440 | }else{ |
| 72518 | 72441 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72519 | 72442 | } |
| @@ -74493,10 +74416,11 @@ | ||
| 74493 | 74416 | removed = 1; |
| 74494 | 74417 | } |
| 74495 | 74418 | sqlite3_mutex_leave(pMainMtx); |
| 74496 | 74419 | return removed; |
| 74497 | 74420 | #else |
| 74421 | + UNUSED_PARAMETER( pBt ); | |
| 74498 | 74422 | return 1; |
| 74499 | 74423 | #endif |
| 74500 | 74424 | } |
| 74501 | 74425 | |
| 74502 | 74426 | /* |
| @@ -75334,10 +75258,17 @@ | ||
| 75334 | 75258 | |
| 75335 | 75259 | if( rc!=SQLITE_OK ){ |
| 75336 | 75260 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75337 | 75261 | unlockBtreeIfUnused(pBt); |
| 75338 | 75262 | } |
| 75263 | +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) | |
| 75264 | + if( rc==SQLITE_BUSY_TIMEOUT ){ | |
| 75265 | + /* If a blocking lock timed out, break out of the loop here so that | |
| 75266 | + ** the busy-handler is not invoked. */ | |
| 75267 | + break; | |
| 75268 | + } | |
| 75269 | +#endif | |
| 75339 | 75270 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75340 | 75271 | btreeInvokeBusyHandler(pBt) ); |
| 75341 | 75272 | sqlite3PagerWalDb(pPager, 0); |
| 75342 | 75273 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75343 | 75274 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | ||
| 82954 | 82885 | ** btree as the argument handle holds an exclusive lock on the |
| 82955 | 82886 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82956 | 82887 | */ |
| 82957 | 82888 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82958 | 82889 | int rc; |
| 82890 | + UNUSED_PARAMETER(p); /* only used in DEBUG builds */ | |
| 82959 | 82891 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82960 | 82892 | sqlite3BtreeEnter(p); |
| 82961 | 82893 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82962 | 82894 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82963 | 82895 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | ||
| 90174 | 90106 | } |
| 90175 | 90107 | } |
| 90176 | 90108 | return; |
| 90177 | 90109 | } |
| 90178 | 90110 | /* |
| 90179 | -** This routine is used to allocate sufficient space for an UnpackedRecord | |
| 90180 | -** structure large enough to be used with sqlite3VdbeRecordUnpack() if | |
| 90181 | -** the first argument is a pointer to KeyInfo structure pKeyInfo. | |
| 90182 | -** | |
| 90183 | -** The space is either allocated using sqlite3DbMallocRaw() or from within | |
| 90184 | -** the unaligned buffer passed via the second and third arguments (presumably | |
| 90185 | -** stack space). If the former, then *ppFree is set to a pointer that should | |
| 90186 | -** be eventually freed by the caller using sqlite3DbFree(). Or, if the | |
| 90187 | -** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL | |
| 90188 | -** before returning. | |
| 90189 | -** | |
| 90190 | -** If an OOM error occurs, NULL is returned. | |
| 90111 | +** Allocate sufficient space for an UnpackedRecord structure large enough | |
| 90112 | +** to hold a decoded index record for pKeyInfo. | |
| 90113 | +** | |
| 90114 | +** The space is allocated using sqlite3DbMallocRaw(). If an OOM error | |
| 90115 | +** occurs, NULL is returned. | |
| 90191 | 90116 | */ |
| 90192 | 90117 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90193 | 90118 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90194 | 90119 | ){ |
| 90195 | 90120 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90196 | - int nByte; /* Number of bytes required for *p */ | |
| 90121 | + u64 nByte; /* Number of bytes required for *p */ | |
| 90197 | 90122 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90198 | 90123 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90199 | 90124 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90200 | 90125 | if( !p ) return 0; |
| 90201 | 90126 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90202 | - assert( pKeyInfo->aSortFlags!=0 ); | |
| 90203 | 90127 | p->pKeyInfo = pKeyInfo; |
| 90204 | 90128 | p->nField = pKeyInfo->nKeyField + 1; |
| 90205 | 90129 | return p; |
| 90206 | 90130 | } |
| 90207 | 90131 | |
| @@ -90209,11 +90133,10 @@ | ||
| 90209 | 90133 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90210 | 90134 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90211 | 90135 | ** contents of the decoded record. |
| 90212 | 90136 | */ |
| 90213 | 90137 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90214 | - KeyInfo *pKeyInfo, /* Information about the record format */ | |
| 90215 | 90138 | int nKey, /* Size of the binary record */ |
| 90216 | 90139 | const void *pKey, /* The binary record */ |
| 90217 | 90140 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90218 | 90141 | ){ |
| 90219 | 90142 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | ||
| 90220 | 90143 | u32 d; |
| 90221 | 90144 | u32 idx; /* Offset in aKey[] to read from */ |
| 90222 | 90145 | u16 u; /* Unsigned loop counter */ |
| 90223 | 90146 | u32 szHdr; |
| 90224 | 90147 | Mem *pMem = p->aMem; |
| 90148 | + KeyInfo *pKeyInfo = p->pKeyInfo; | |
| 90225 | 90149 | |
| 90226 | 90150 | p->default_rc = 0; |
| 90227 | 90151 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90228 | 90152 | idx = getVarint32(aKey, szHdr); |
| 90229 | 90153 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | ||
| 90247 | 90171 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90248 | 90172 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90249 | 90173 | ** warnings from MSAN. */ |
| 90250 | 90174 | sqlite3VdbeMemSetNull(pMem-1); |
| 90251 | 90175 | } |
| 90176 | + testcase( u == pKeyInfo->nKeyField + 1 ); | |
| 90177 | + testcase( u < pKeyInfo->nKeyField + 1 ); | |
| 90252 | 90178 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90253 | 90179 | p->nField = u; |
| 90254 | 90180 | } |
| 90255 | 90181 | |
| 90256 | 90182 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | ||
| 91106 | 91032 | ** is an integer. |
| 91107 | 91033 | ** |
| 91108 | 91034 | ** The easiest way to enforce this limit is to consider only records with |
| 91109 | 91035 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91110 | 91036 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91037 | + assert( p->pKeyInfo->aSortFlags!=0 ); | |
| 91111 | 91038 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91112 | 91039 | int flags = p->aMem[0].flags; |
| 91113 | 91040 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91114 | 91041 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91115 | 91042 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | ||
| 91464 | 91391 | ){ |
| 91465 | 91392 | sqlite3 *db = v->db; |
| 91466 | 91393 | i64 iKey2; |
| 91467 | 91394 | PreUpdate preupdate; |
| 91468 | 91395 | const char *zTbl = pTab->zName; |
| 91469 | - static const u8 fakeSortOrder = 0; | |
| 91470 | 91396 | #ifdef SQLITE_DEBUG |
| 91471 | 91397 | int nRealCol; |
| 91472 | 91398 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91473 | 91399 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91474 | 91400 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | ||
| 91503 | 91429 | preupdate.iNewReg = iReg; |
| 91504 | 91430 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91505 | 91431 | preupdate.pKeyinfo->db = db; |
| 91506 | 91432 | preupdate.pKeyinfo->enc = ENC(db); |
| 91507 | 91433 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91508 | - preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; | |
| 91434 | + preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ | |
| 91509 | 91435 | preupdate.iKey1 = iKey1; |
| 91510 | 91436 | preupdate.iKey2 = iKey2; |
| 91511 | 91437 | preupdate.pTab = pTab; |
| 91512 | 91438 | preupdate.iBlobWrite = iBlobWrite; |
| 91513 | 91439 | |
| @@ -93700,11 +93626,11 @@ | ||
| 93700 | 93626 | UnpackedRecord *pRet; /* Return value */ |
| 93701 | 93627 | |
| 93702 | 93628 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93703 | 93629 | if( pRet ){ |
| 93704 | 93630 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93705 | - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); | |
| 93631 | + sqlite3VdbeRecordUnpack(nKey, pKey, pRet); | |
| 93706 | 93632 | } |
| 93707 | 93633 | return pRet; |
| 93708 | 93634 | } |
| 93709 | 93635 | |
| 93710 | 93636 | /* |
| @@ -96893,10 +96819,11 @@ | ||
| 96893 | 96819 | } |
| 96894 | 96820 | n = pOp->p3; |
| 96895 | 96821 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96896 | 96822 | assert( n>0 ); |
| 96897 | 96823 | assert( pKeyInfo!=0 ); |
| 96824 | + assert( pKeyInfo->aSortFlags!=0 ); | |
| 96898 | 96825 | p1 = pOp->p1; |
| 96899 | 96826 | p2 = pOp->p2; |
| 96900 | 96827 | #ifdef SQLITE_DEBUG |
| 96901 | 96828 | if( aPermute ){ |
| 96902 | 96829 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | ||
| 99766 | 99693 | rc = ExpandBlob(r.aMem); |
| 99767 | 99694 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99768 | 99695 | if( rc ) goto no_mem; |
| 99769 | 99696 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99770 | 99697 | if( pIdxKey==0 ) goto no_mem; |
| 99771 | - sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); | |
| 99698 | + sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); | |
| 99772 | 99699 | pIdxKey->default_rc = 0; |
| 99773 | 99700 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99774 | 99701 | sqlite3DbFreeNN(db, pIdxKey); |
| 99775 | 99702 | } |
| 99776 | 99703 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | ||
| 104942 | 104869 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104943 | 104870 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104944 | 104871 | ){ |
| 104945 | 104872 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104946 | 104873 | if( *pbKey2Cached==0 ){ |
| 104947 | - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); | |
| 104874 | + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); | |
| 104948 | 104875 | *pbKey2Cached = 1; |
| 104949 | 104876 | } |
| 104950 | 104877 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104951 | 104878 | } |
| 104952 | 104879 | |
| @@ -104969,11 +104896,11 @@ | ||
| 104969 | 104896 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104970 | 104897 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104971 | 104898 | ){ |
| 104972 | 104899 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104973 | 104900 | if( !*pbKey2Cached ){ |
| 104974 | - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); | |
| 104901 | + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); | |
| 104975 | 104902 | *pbKey2Cached = 1; |
| 104976 | 104903 | } |
| 104977 | 104904 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104978 | 104905 | } |
| 104979 | 104906 | |
| @@ -105009,10 +104936,11 @@ | ||
| 105009 | 104936 | res = vdbeSorterCompareTail( |
| 105010 | 104937 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105011 | 104938 | ); |
| 105012 | 104939 | } |
| 105013 | 104940 | }else{ |
| 104941 | + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); | |
| 105014 | 104942 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 105015 | 104943 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 105016 | 104944 | res = res * -1; |
| 105017 | 104945 | } |
| 105018 | 104946 | } |
| @@ -105072,10 +105000,11 @@ | ||
| 105072 | 105000 | }else{ |
| 105073 | 105001 | if( *v2 & 0x80 ) res = +1; |
| 105074 | 105002 | } |
| 105075 | 105003 | } |
| 105076 | 105004 | |
| 105005 | + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); | |
| 105077 | 105006 | if( res==0 ){ |
| 105078 | 105007 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105079 | 105008 | res = vdbeSorterCompareTail( |
| 105080 | 105009 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105081 | 105010 | ); |
| @@ -105145,11 +105074,12 @@ | ||
| 105145 | 105074 | assert( pCsr->pKeyInfo ); |
| 105146 | 105075 | assert( !pCsr->isEphemeral ); |
| 105147 | 105076 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105148 | 105077 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105149 | 105078 | < 0x7fffffff ); |
| 105150 | - szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); | |
| 105079 | + assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); | |
| 105080 | + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); | |
| 105151 | 105081 | sz = SZ_VDBESORTER(nWorker+1); |
| 105152 | 105082 | |
| 105153 | 105083 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105154 | 105084 | pCsr->uc.pSorter = pSorter; |
| 105155 | 105085 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | ||
| 105159 | 105089 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105160 | 105090 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105161 | 105091 | pKeyInfo->db = 0; |
| 105162 | 105092 | if( nField && nWorker==0 ){ |
| 105163 | 105093 | pKeyInfo->nKeyField = nField; |
| 105094 | + assert( nField<=pCsr->pKeyInfo->nAllField ); | |
| 105164 | 105095 | } |
| 105096 | + /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, | |
| 105097 | + ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives | |
| 105098 | + ** longer that pSorter. */ | |
| 105099 | + assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); | |
| 105165 | 105100 | sqlite3BtreeEnter(pBt); |
| 105166 | 105101 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105167 | 105102 | sqlite3BtreeLeave(pBt); |
| 105168 | 105103 | pSorter->nTask = nWorker + 1; |
| 105169 | 105104 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | ||
| 106939 | 106874 | r2->nField = nKeyCol; |
| 106940 | 106875 | } |
| 106941 | 106876 | assert( r2->nField==nKeyCol ); |
| 106942 | 106877 | |
| 106943 | 106878 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106944 | - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); | |
| 106879 | + sqlite3VdbeRecordUnpack(nKey, pKey, r2); | |
| 106945 | 106880 | for(i=0; i<nKeyCol; i++){ |
| 106946 | 106881 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106947 | 106882 | *pRes = -1; |
| 106948 | 106883 | return SQLITE_OK; |
| 106949 | 106884 | } |
| @@ -110495,11 +110430,13 @@ | ||
| 110495 | 110430 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110496 | 110431 | return sqlite3ExprAffinity( |
| 110497 | 110432 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110498 | 110433 | ); |
| 110499 | 110434 | } |
| 110500 | - if( op==TK_VECTOR ){ | |
| 110435 | + if( op==TK_VECTOR | |
| 110436 | + || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) | |
| 110437 | + ){ | |
| 110501 | 110438 | assert( ExprUseXList(pExpr) ); |
| 110502 | 110439 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110503 | 110440 | } |
| 110504 | 110441 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110505 | 110442 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | ||
| 110688 | 110625 | } |
| 110689 | 110626 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110690 | 110627 | p = p->pLeft; |
| 110691 | 110628 | continue; |
| 110692 | 110629 | } |
| 110693 | - if( op==TK_VECTOR ){ | |
| 110630 | + if( op==TK_VECTOR | |
| 110631 | + || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) | |
| 110632 | + ){ | |
| 110694 | 110633 | assert( ExprUseXList(p) ); |
| 110695 | 110634 | p = p->x.pList->a[0].pExpr; |
| 110696 | 110635 | continue; |
| 110697 | 110636 | } |
| 110698 | 110637 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | ||
| 119025 | 118964 | }else{ |
| 119026 | 118965 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 119027 | 118966 | } |
| 119028 | 118967 | |
| 119029 | 118968 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 119030 | - zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); | |
| 118969 | + zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); | |
| 119031 | 118970 | }else{ |
| 119032 | 118971 | assert( nSql>0 ); |
| 119033 | - zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); | |
| 118972 | + zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); | |
| 119034 | 118973 | if( zOut ){ |
| 119035 | 118974 | zBuf1 = &zOut[nSql*2+1]; |
| 119036 | 118975 | zBuf2 = &zOut[nSql*4+2]; |
| 119037 | 118976 | } |
| 119038 | 118977 | } |
| @@ -138772,10 +138711,12 @@ | ||
| 138772 | 138711 | /* Version 3.43.0 and later */ |
| 138773 | 138712 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138774 | 138713 | /* Version 3.44.0 and later */ |
| 138775 | 138714 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138776 | 138715 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138716 | + /* Version 3.50.0 and later */ | |
| 138717 | + int (*setlk_timeout)(sqlite3*,int,int); | |
| 138777 | 138718 | }; |
| 138778 | 138719 | |
| 138779 | 138720 | /* |
| 138780 | 138721 | ** This is the function signature used for all extension entry points. It |
| 138781 | 138722 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | ||
| 139105 | 139046 | /* Version 3.43.0 and later */ |
| 139106 | 139047 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139107 | 139048 | /* Version 3.44.0 and later */ |
| 139108 | 139049 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139109 | 139050 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139051 | +/* Version 3.50.0 and later */ | |
| 139052 | +#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout | |
| 139110 | 139053 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139111 | 139054 | |
| 139112 | 139055 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139113 | 139056 | /* This case when the file really is being compiled as a loadable |
| 139114 | 139057 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | ||
| 139626 | 139569 | sqlite3_is_interrupted, |
| 139627 | 139570 | /* Version 3.43.0 and later */ |
| 139628 | 139571 | sqlite3_stmt_explain, |
| 139629 | 139572 | /* Version 3.44.0 and later */ |
| 139630 | 139573 | sqlite3_get_clientdata, |
| 139631 | - sqlite3_set_clientdata | |
| 139574 | + sqlite3_set_clientdata, | |
| 139575 | + /* Version 3.50.0 and later */ | |
| 139576 | + sqlite3_setlk_timeout | |
| 139632 | 139577 | }; |
| 139633 | 139578 | |
| 139634 | 139579 | /* True if x is the directory separator character |
| 139635 | 139580 | */ |
| 139636 | 139581 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | ||
| 145464 | 145409 | "not present in both tables", zName); |
| 145465 | 145410 | return 1; |
| 145466 | 145411 | } |
| 145467 | 145412 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145468 | 145413 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145469 | - if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ | |
| 145414 | + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ | |
| 145470 | 145415 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145471 | 145416 | ** JOINs. If only a single table on the left side of this join |
| 145472 | 145417 | ** contains the zName column, then this branch is a no-op. |
| 145473 | 145418 | ** But if there are two or more tables on the left side |
| 145474 | 145419 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | ||
| 145480 | 145425 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145481 | 145426 | ** adding a new error so as to not break legacy applications. |
| 145482 | 145427 | */ |
| 145483 | 145428 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145484 | 145429 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145430 | + assert( pE1!=0 ); | |
| 145431 | + ExprSetProperty(pE1, EP_CanBeNull); | |
| 145485 | 145432 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145486 | 145433 | pRight->fg.isSynthUsing)!=0 ){ |
| 145487 | 145434 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145488 | 145435 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145489 | 145436 | ){ |
| @@ -145496,11 +145443,17 @@ | ||
| 145496 | 145443 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145497 | 145444 | } |
| 145498 | 145445 | if( pFuncArgs ){ |
| 145499 | 145446 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145500 | 145447 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145448 | + if( pE1 ){ | |
| 145449 | + pE1->affExpr = SQLITE_AFF_DEFER; | |
| 145450 | + } | |
| 145501 | 145451 | } |
| 145452 | + }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ | |
| 145453 | + assert( pE1!=0 ); | |
| 145454 | + ExprSetProperty(pE1, EP_CanBeNull); | |
| 145502 | 145455 | } |
| 145503 | 145456 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145504 | 145457 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145505 | 145458 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145506 | 145459 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | ||
| 146973 | 146926 | #else |
| 146974 | 146927 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146975 | 146928 | #endif |
| 146976 | 146929 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146977 | 146930 | } |
| 146931 | +#else | |
| 146932 | + UNUSED_PARAMETER(pParse); | |
| 146933 | + UNUSED_PARAMETER(pTabList); | |
| 146934 | + UNUSED_PARAMETER(pEList); | |
| 146978 | 146935 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146979 | 146936 | } |
| 146980 | 146937 | |
| 146981 | 146938 | |
| 146982 | 146939 | /* |
| @@ -149104,13 +149061,13 @@ | ||
| 149104 | 149061 | ** other than the one FROM-clause subquery that is a candidate |
| 149105 | 149062 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149106 | 149063 | ** from 2015-02-09.) |
| 149107 | 149064 | ** |
| 149108 | 149065 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149109 | -** (3a) the subquery may not be a join and | |
| 149110 | -** (3b) the FROM clause of the subquery may not contain a virtual | |
| 149111 | -** table and | |
| 149066 | +** (3a) the subquery may not be a join | |
| 149067 | +** (**) Was (3b): "the FROM clause of the subquery may not contain | |
| 149068 | +** a virtual table" | |
| 149112 | 149069 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149113 | 149070 | ** is now managed correctly |
| 149114 | 149071 | ** (3d) the outer query may not be DISTINCT. |
| 149115 | 149072 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149116 | 149073 | ** |
| @@ -149322,11 +149279,11 @@ | ||
| 149322 | 149279 | ** |
| 149323 | 149280 | ** See also tickets #306, #350, and #3300. |
| 149324 | 149281 | */ |
| 149325 | 149282 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149326 | 149283 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149327 | - || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ | |
| 149284 | + /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ | |
| 149328 | 149285 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149329 | 149286 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149330 | 149287 | ){ |
| 149331 | 149288 | return 0; |
| 149332 | 149289 | } |
| @@ -153366,10 +153323,14 @@ | ||
| 153366 | 153323 | } |
| 153367 | 153324 | |
| 153368 | 153325 | if( iOrderByCol ){ |
| 153369 | 153326 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153370 | 153327 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153328 | + while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ | |
| 153329 | + pX = pBase->pLeft; | |
| 153330 | + pBase = sqlite3ExprSkipCollateAndLikely(pX); | |
| 153331 | + } | |
| 153371 | 153332 | if( ALWAYS(pBase!=0) |
| 153372 | 153333 | && pBase->op!=TK_AGG_COLUMN |
| 153373 | 153334 | && pBase->op!=TK_REGISTER |
| 153374 | 153335 | ){ |
| 153375 | 153336 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | ||
| 157343 | 157304 | saved_flags = db->flags; |
| 157344 | 157305 | saved_mDbFlags = db->mDbFlags; |
| 157345 | 157306 | saved_nChange = db->nChange; |
| 157346 | 157307 | saved_nTotalChange = db->nTotalChange; |
| 157347 | 157308 | saved_mTrace = db->mTrace; |
| 157348 | - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; | |
| 157309 | + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments | |
| 157310 | + | SQLITE_AttachCreate | SQLITE_AttachWrite; | |
| 157349 | 157311 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157350 | 157312 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157351 | 157313 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157352 | 157314 | db->mTrace = 0; |
| 157353 | 157315 | |
| @@ -161818,16 +161780,17 @@ | ||
| 161818 | 161780 | } |
| 161819 | 161781 | |
| 161820 | 161782 | if( pLevel->iLeftJoin==0 ){ |
| 161821 | 161783 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161822 | 161784 | ** terms from the query that must be true due to the WHERE clause of |
| 161823 | - ** the partial index. | |
| 161785 | + ** the partial index. This optimization does not work on an outer join, | |
| 161786 | + ** as shown by: | |
| 161824 | 161787 | ** |
| 161825 | - ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work | |
| 161826 | - ** for a LEFT JOIN. | |
| 161788 | + ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) | |
| 161789 | + ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) | |
| 161827 | 161790 | */ |
| 161828 | - if( pIdx->pPartIdxWhere ){ | |
| 161791 | + if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ | |
| 161829 | 161792 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161830 | 161793 | } |
| 161831 | 161794 | }else{ |
| 161832 | 161795 | testcase( pIdx->pPartIdxWhere ); |
| 161833 | 161796 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | ||
| 168080 | 168043 | Expr *pExpr; |
| 168081 | 168044 | pExpr = pTerm->pExpr; |
| 168082 | 168045 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168083 | 168046 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168084 | 168047 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168048 | + && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) | |
| 168085 | 168049 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168086 | 168050 | ){ |
| 168087 | 168051 | return 1; |
| 168088 | 168052 | } |
| 168089 | 168053 | } |
| @@ -188883,11 +188847,11 @@ | ||
| 188883 | 188847 | |
| 188884 | 188848 | /* |
| 188885 | 188849 | ** Macros needed to provide flexible arrays in a portable way |
| 188886 | 188850 | */ |
| 188887 | 188851 | #ifndef offsetof |
| 188888 | -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 188852 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 188889 | 188853 | #endif |
| 188890 | 188854 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188891 | 188855 | # define FLEXARRAY |
| 188892 | 188856 | #else |
| 188893 | 188857 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | ||
| 209116 | 209080 | nExtra = 0; |
| 209117 | 209081 | }else if( szType==12 ){ |
| 209118 | 209082 | nExtra = 1; |
| 209119 | 209083 | }else if( szType==13 ){ |
| 209120 | 209084 | nExtra = 2; |
| 209121 | - }else{ | |
| 209085 | + }else if( szType==14 ){ | |
| 209122 | 209086 | nExtra = 4; |
| 209087 | + }else{ | |
| 209088 | + nExtra = 8; | |
| 209123 | 209089 | } |
| 209124 | 209090 | if( szPayload<=11 ){ |
| 209125 | 209091 | nNeeded = 0; |
| 209126 | 209092 | }else if( szPayload<=0xff ){ |
| 209127 | 209093 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | ||
| 212681 | 212647 | const char *z; |
| 212682 | 212648 | u32 n; |
| 212683 | 212649 | UNUSED_PARAMETER(argc); |
| 212684 | 212650 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212685 | 212651 | if( pStr ){ |
| 212652 | + z = (const char*)sqlite3_value_text(argv[0]); | |
| 212653 | + n = sqlite3Strlen30(z); | |
| 212686 | 212654 | if( pStr->zBuf==0 ){ |
| 212687 | 212655 | jsonStringInit(pStr, ctx); |
| 212688 | 212656 | jsonAppendChar(pStr, '{'); |
| 212689 | - }else if( pStr->nUsed>1 ){ | |
| 212657 | + }else if( pStr->nUsed>1 && z!=0 ){ | |
| 212690 | 212658 | jsonAppendChar(pStr, ','); |
| 212691 | 212659 | } |
| 212692 | 212660 | pStr->pCtx = ctx; |
| 212693 | - z = (const char*)sqlite3_value_text(argv[0]); | |
| 212694 | - n = sqlite3Strlen30(z); | |
| 212695 | - jsonAppendString(pStr, z, n); | |
| 212696 | - jsonAppendChar(pStr, ':'); | |
| 212697 | - jsonAppendSqlValue(pStr, argv[1]); | |
| 212661 | + if( z!=0 ){ | |
| 212662 | + jsonAppendString(pStr, z, n); | |
| 212663 | + jsonAppendChar(pStr, ':'); | |
| 212664 | + jsonAppendSqlValue(pStr, argv[1]); | |
| 212665 | + } | |
| 212698 | 212666 | } |
| 212699 | 212667 | } |
| 212700 | 212668 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212701 | 212669 | JsonString *pStr; |
| 212702 | 212670 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | ||
| 213500 | 213468 | #else |
| 213501 | 213469 | /* #include "sqlite3.h" */ |
| 213502 | 213470 | #endif |
| 213503 | 213471 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213504 | 213472 | |
| 213473 | +/* #include <stddef.h> */ | |
| 213474 | + | |
| 213505 | 213475 | /* |
| 213506 | 213476 | ** If building separately, we will need some setup that is normally |
| 213507 | 213477 | ** found in sqliteInt.h |
| 213508 | 213478 | */ |
| 213509 | 213479 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | ||
| 213531 | 213501 | #else |
| 213532 | 213502 | # define ALWAYS(X) (X) |
| 213533 | 213503 | # define NEVER(X) (X) |
| 213534 | 213504 | #endif |
| 213535 | 213505 | #ifndef offsetof |
| 213536 | -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 213506 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 213537 | 213507 | #endif |
| 213538 | 213508 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213539 | 213509 | # define FLEXARRAY |
| 213540 | 213510 | #else |
| 213541 | 213511 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | ||
| 227848 | 227818 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227849 | 227819 | int rc; |
| 227850 | 227820 | sqlite3 *db = pTab->db; |
| 227851 | 227821 | Btree *pBt; |
| 227852 | 227822 | |
| 227853 | - (void)idxStr; | |
| 227823 | + UNUSED_PARAMETER(idxStr); | |
| 227824 | + UNUSED_PARAMETER(argc); | |
| 227854 | 227825 | |
| 227855 | 227826 | /* Default setting is no rows of result */ |
| 227856 | 227827 | pCsr->pgno = 1; |
| 227857 | 227828 | pCsr->mxPgno = 0; |
| 227858 | 227829 | |
| @@ -231510,18 +231481,19 @@ | ||
| 231510 | 231481 | /* |
| 231511 | 231482 | ** If the SessionInput object passed as the only argument is a streaming |
| 231512 | 231483 | ** object and the buffer is full, discard some data to free up space. |
| 231513 | 231484 | */ |
| 231514 | 231485 | static void sessionDiscardData(SessionInput *pIn){ |
| 231515 | - if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ | |
| 231516 | - int nMove = pIn->buf.nBuf - pIn->iNext; | |
| 231486 | + if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ | |
| 231487 | + int nMove = pIn->buf.nBuf - pIn->iCurrent; | |
| 231517 | 231488 | assert( nMove>=0 ); |
| 231518 | 231489 | if( nMove>0 ){ |
| 231519 | - memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); | |
| 231490 | + memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); | |
| 231520 | 231491 | } |
| 231521 | - pIn->buf.nBuf -= pIn->iNext; | |
| 231522 | - pIn->iNext = 0; | |
| 231492 | + pIn->buf.nBuf -= pIn->iCurrent; | |
| 231493 | + pIn->iNext -= pIn->iCurrent; | |
| 231494 | + pIn->iCurrent = 0; | |
| 231523 | 231495 | pIn->nData = pIn->buf.nBuf; |
| 231524 | 231496 | } |
| 231525 | 231497 | } |
| 231526 | 231498 | |
| 231527 | 231499 | /* |
| @@ -231871,12 +231843,12 @@ | ||
| 231871 | 231843 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231872 | 231844 | ** it, or for the two single byte values otherwise. */ |
| 231873 | 231845 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231874 | 231846 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231875 | 231847 | |
| 231876 | - sessionDiscardData(&p->in); | |
| 231877 | 231848 | p->in.iCurrent = p->in.iNext; |
| 231849 | + sessionDiscardData(&p->in); | |
| 231878 | 231850 | |
| 231879 | 231851 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231880 | 231852 | if( p->in.iNext>=p->in.nData ){ |
| 231881 | 231853 | return SQLITE_DONE; |
| 231882 | 231854 | } |
| @@ -234231,18 +234203,23 @@ | ||
| 234231 | 234203 | */ |
| 234232 | 234204 | SQLITE_API int sqlite3changegroup_add_change( |
| 234233 | 234205 | sqlite3_changegroup *pGrp, |
| 234234 | 234206 | sqlite3_changeset_iter *pIter |
| 234235 | 234207 | ){ |
| 234208 | + int rc = SQLITE_OK; | |
| 234209 | + | |
| 234236 | 234210 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234237 | 234211 | || pIter->rc!=SQLITE_OK |
| 234238 | 234212 | || pIter->bInvert |
| 234239 | 234213 | ){ |
| 234240 | 234214 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234241 | - return SQLITE_ERROR; | |
| 234215 | + rc = SQLITE_ERROR; | |
| 234216 | + }else{ | |
| 234217 | + pIter->in.bNoDiscard = 1; | |
| 234218 | + rc = sessionOneChangeToHash(pGrp, pIter, 0); | |
| 234242 | 234219 | } |
| 234243 | - return sessionOneChangeToHash(pGrp, pIter, 0); | |
| 234220 | + return rc; | |
| 234244 | 234221 | } |
| 234245 | 234222 | |
| 234246 | 234223 | /* |
| 234247 | 234224 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234248 | 234225 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | ||
| 235536 | 235513 | /* #include "sqlite3ext.h" */ |
| 235537 | 235514 | SQLITE_EXTENSION_INIT1 |
| 235538 | 235515 | |
| 235539 | 235516 | /* #include <string.h> */ |
| 235540 | 235517 | /* #include <assert.h> */ |
| 235518 | +/* #include <stddef.h> */ | |
| 235541 | 235519 | |
| 235542 | 235520 | #ifndef SQLITE_AMALGAMATION |
| 235543 | 235521 | |
| 235544 | 235522 | typedef unsigned char u8; |
| 235545 | 235523 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | ||
| 235595 | 235573 | |
| 235596 | 235574 | /* |
| 235597 | 235575 | ** Macros needed to provide flexible arrays in a portable way |
| 235598 | 235576 | */ |
| 235599 | 235577 | #ifndef offsetof |
| 235600 | -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 235578 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 235601 | 235579 | #endif |
| 235602 | 235580 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235603 | 235581 | # define FLEXARRAY |
| 235604 | 235582 | #else |
| 235605 | 235583 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | ||
| 257279 | 257257 | int nArg, /* Number of args */ |
| 257280 | 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257281 | 257259 | ){ |
| 257282 | 257260 | assert( nArg==0 ); |
| 257283 | 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257284 | - sqlite3_result_text(pCtx, "fts5: 2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349", -1, SQLITE_TRANSIENT); | |
| 257262 | + sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); | |
| 257285 | 257263 | } |
| 257286 | 257264 | |
| 257287 | 257265 | /* |
| 257288 | 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257289 | 257267 | ** |
| 257290 | 257268 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.50.0. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** 336ceeccc6f85bd78f4a26648af7edf9056d with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | |
| 463 | ** |
| 464 | ** See also: [sqlite3_libversion()], |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.50.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3050000 |
| 470 | #define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -15174,11 +15174,11 @@ | |
| 15174 | /* |
| 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | ** ourselves. |
| 15177 | */ |
| 15178 | #ifndef offsetof |
| 15179 | #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 15180 | #endif |
| 15181 | |
| 15182 | /* |
| 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | |
| 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | #endif |
| 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | |
| 17406 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | |
| 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | |
| 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | |
| 18707 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18708 | |
| 18709 | /* |
| 18710 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | |
| 19016 | /* |
| 19017 | ** An instance of the following structure is passed as the first |
| 19018 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19019 | ** comparison of the two index keys. |
| 19020 | ** |
| 19021 | ** Note that aSortOrder[] and aColl[] have nField+1 slots. There |
| 19022 | ** are nField slots for the columns of an index then one extra slot |
| 19023 | ** for the rowid at the end. |
| 19024 | */ |
| 19025 | struct KeyInfo { |
| 19026 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19027 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19028 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | |
| 19030 | sqlite3 *db; /* The database connection */ |
| 19031 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19032 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19033 | }; |
| 19034 | |
| 19035 | /* The size (in bytes) of a KeyInfo object with up to N fields */ |
| 19036 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19037 | |
| 19038 | /* |
| 19039 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19040 | */ |
| 19041 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | |
| 19051 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19052 | ** OP_Column opcode. |
| 19053 | ** |
| 19054 | ** An instance of this object serves as a "key" for doing a search on |
| 19055 | ** an index b+tree. The goal of the search is to find the entry that |
| 19056 | ** is closed to the key described by this object. This object might hold |
| 19057 | ** just a prefix of the key. The number of fields is given by |
| 19058 | ** pKeyInfo->nField. |
| 19059 | ** |
| 19060 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19061 | ** or greater than a key in the btree, respectively. These are normally |
| 19062 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19063 | ** is in DESC order. |
| 19064 | ** |
| 19065 | ** The key comparison functions actually return default_rc when they find |
| 19066 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19067 | ** multiple entries in the b-tree with the same key (when only looking |
| 19068 | ** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to |
| 19069 | ** cause the search to find the last match, or +1 to cause the search to |
| 19070 | ** find the first match. |
| 19071 | ** |
| 19072 | ** The key comparison functions will set eqSeen to true if they ever |
| 19073 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | |
| 19075 | ** before the first match or immediately after the last match. The |
| 19076 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19077 | ** b-tree. |
| 19078 | */ |
| 19079 | struct UnpackedRecord { |
| 19080 | KeyInfo *pKeyInfo; /* Collation and sort-order information */ |
| 19081 | Mem *aMem; /* Values */ |
| 19082 | union { |
| 19083 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19084 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19085 | } u; |
| 19086 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | |
| 24132 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24133 | Mem *aNew; /* Array of new.* values */ |
| 24134 | Table *pTab; /* Schema object being updated */ |
| 24135 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24136 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24137 | u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ |
| 24138 | }; |
| 24139 | |
| 24140 | /* |
| 24141 | ** An instance of this object is used to pass an vector of values into |
| 24142 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | |
| 35013 | } |
| 35014 | |
| 35015 | /* |
| 35016 | ** Write a single UTF8 character whose value is v into the |
| 35017 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35018 | ** least for bytes. Return the number of bytes needed |
| 35019 | ** to encode the new character. |
| 35020 | */ |
| 35021 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35022 | if( v<0x00080 ){ |
| 35023 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | |
| 43872 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43873 | |
| 43874 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43875 | ** in the following list than the lock being obtained are already held: |
| 43876 | ** |
| 43877 | ** 1. Checkpointer lock (ofst==1). |
| 43878 | ** 2. Write lock (ofst==0). |
| 43879 | ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 43880 | ** |
| 43881 | ** In other words, if this is a blocking lock, none of the locks that |
| 43882 | ** occur later in the above list than the lock being obtained may be |
| 43883 | ** held. |
| 43884 | ** |
| 43885 | ** It is not permitted to block on the RECOVER lock. |
| 43886 | */ |
| 43887 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43888 | { |
| 43889 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43890 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43891 | (ofst!=2) /* not RECOVER */ |
| 43892 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43893 | && (ofst!=0 || lockMask<3) |
| 43894 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43895 | )); |
| 43896 | } |
| @@ -49851,11 +49865,15 @@ | |
| 49851 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49852 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49853 | if( res==WAIT_OBJECT_0 ){ |
| 49854 | ret = TRUE; |
| 49855 | }else if( res==WAIT_TIMEOUT ){ |
| 49856 | rc = SQLITE_BUSY_TIMEOUT; |
| 49857 | }else{ |
| 49858 | /* Some other error has occurred */ |
| 49859 | rc = SQLITE_IOERR_LOCK; |
| 49860 | } |
| 49861 | |
| @@ -51337,17 +51355,17 @@ | |
| 51337 | int nChar; |
| 51338 | LPWSTR zWideFilename; |
| 51339 | |
| 51340 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51341 | && winIsDirSep(zFilename[2])) ){ |
| 51342 | int nByte; |
| 51343 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51344 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51345 | nByte = (int)osCygwin_conv_path(convertflag, |
| 51346 | zFilename, 0, 0); |
| 51347 | if( nByte>0 ){ |
| 51348 | zConverted = sqlite3MallocZero(nByte+12); |
| 51349 | if ( zConverted==0 ){ |
| 51350 | return zConverted; |
| 51351 | } |
| 51352 | zWideFilename = zConverted; |
| 51353 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | |
| 51662 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51663 | |
| 51664 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51665 | ** in the following list than the lock being obtained are already held: |
| 51666 | ** |
| 51667 | ** 1. Checkpointer lock (ofst==1). |
| 51668 | ** 2. Write lock (ofst==0). |
| 51669 | ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 51670 | ** |
| 51671 | ** In other words, if this is a blocking lock, none of the locks that |
| 51672 | ** occur later in the above list than the lock being obtained may be |
| 51673 | ** held. |
| 51674 | ** |
| 51675 | ** It is not permitted to block on the RECOVER lock. |
| 51676 | */ |
| 51677 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51678 | { |
| 51679 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51680 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51681 | (ofst!=2) /* not RECOVER */ |
| 51682 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51683 | && (ofst!=0 || lockMask<3) |
| 51684 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51685 | )); |
| 51686 | } |
| @@ -52226,31 +52243,10 @@ | |
| 52226 | ** |
| 52227 | ** This division contains the implementation of methods on the |
| 52228 | ** sqlite3_vfs object. |
| 52229 | */ |
| 52230 | |
| 52231 | #if 0 /* No longer necessary */ |
| 52232 | /* |
| 52233 | ** Convert a filename from whatever the underlying operating system |
| 52234 | ** supports for filenames into UTF-8. Space to hold the result is |
| 52235 | ** obtained from malloc and must be freed by the calling function. |
| 52236 | */ |
| 52237 | static char *winConvertToUtf8Filename(const void *zFilename){ |
| 52238 | char *zConverted = 0; |
| 52239 | if( osIsNT() ){ |
| 52240 | zConverted = winUnicodeToUtf8(zFilename); |
| 52241 | } |
| 52242 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 52243 | else{ |
| 52244 | zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); |
| 52245 | } |
| 52246 | #endif |
| 52247 | /* caller will handle out of memory */ |
| 52248 | return zConverted; |
| 52249 | } |
| 52250 | #endif |
| 52251 | |
| 52252 | /* |
| 52253 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52254 | ** ends with a directory separator character or one was successfully |
| 52255 | ** added to it. |
| 52256 | */ |
| @@ -52386,46 +52382,10 @@ | |
| 52386 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52387 | sqlite3_free(zConverted); |
| 52388 | break; |
| 52389 | } |
| 52390 | sqlite3_free(zConverted); |
| 52391 | #if 0 /* No longer necessary */ |
| 52392 | }else{ |
| 52393 | zConverted = sqlite3MallocZero( nMax+1 ); |
| 52394 | if( !zConverted ){ |
| 52395 | sqlite3_free(zBuf); |
| 52396 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 52397 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52398 | } |
| 52399 | if( osCygwin_conv_path( |
| 52400 | CCP_POSIX_TO_WIN_W, zDir, |
| 52401 | zConverted, nMax+1)<0 ){ |
| 52402 | sqlite3_free(zConverted); |
| 52403 | sqlite3_free(zBuf); |
| 52404 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); |
| 52405 | return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, |
| 52406 | "winGetTempname2", zDir); |
| 52407 | } |
| 52408 | if( winIsDir(zConverted) ){ |
| 52409 | /* At this point, we know the candidate directory exists and should |
| 52410 | ** be used. However, we may need to convert the string containing |
| 52411 | ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 52412 | */ |
| 52413 | char *zUtf8 = winConvertToUtf8Filename(zConverted); |
| 52414 | if( !zUtf8 ){ |
| 52415 | sqlite3_free(zConverted); |
| 52416 | sqlite3_free(zBuf); |
| 52417 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 52418 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52419 | } |
| 52420 | sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 52421 | sqlite3_free(zUtf8); |
| 52422 | sqlite3_free(zConverted); |
| 52423 | break; |
| 52424 | } |
| 52425 | sqlite3_free(zConverted); |
| 52426 | #endif /* No longer necessary */ |
| 52427 | } |
| 52428 | } |
| 52429 | } |
| 52430 | #endif |
| 52431 | |
| @@ -53320,38 +53280,10 @@ | |
| 53320 | winSimplifyName(zFull); |
| 53321 | return rc; |
| 53322 | } |
| 53323 | } |
| 53324 | #endif /* __CYGWIN__ */ |
| 53325 | #if 0 /* This doesn't work correctly at all! See: |
| 53326 | <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> |
| 53327 | */ |
| 53328 | SimulateIOError( return SQLITE_ERROR ); |
| 53329 | UNUSED_PARAMETER(nFull); |
| 53330 | assert( nFull>=pVfs->mxPathname ); |
| 53331 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 53332 | if( !zOut ){ |
| 53333 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53334 | } |
| 53335 | if( osCygwin_conv_path( |
| 53336 | CCP_POSIX_TO_WIN_W, |
| 53337 | zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 53338 | sqlite3_free(zOut); |
| 53339 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 53340 | "winFullPathname2", zRelative); |
| 53341 | }else{ |
| 53342 | char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 53343 | if( !zUtf8 ){ |
| 53344 | sqlite3_free(zOut); |
| 53345 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53346 | } |
| 53347 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); |
| 53348 | sqlite3_free(zUtf8); |
| 53349 | sqlite3_free(zOut); |
| 53350 | } |
| 53351 | return SQLITE_OK; |
| 53352 | #endif |
| 53353 | |
| 53354 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53355 | SimulateIOError( return SQLITE_ERROR ); |
| 53356 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53357 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | |
| 53493 | ** Interfaces for opening a shared library, finding entry points |
| 53494 | ** within the shared library, and closing the shared library. |
| 53495 | */ |
| 53496 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53497 | HANDLE h; |
| 53498 | #if 0 /* This doesn't work correctly at all! See: |
| 53499 | <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> |
| 53500 | */ |
| 53501 | int nFull = pVfs->mxPathname+1; |
| 53502 | char *zFull = sqlite3MallocZero( nFull ); |
| 53503 | void *zConverted = 0; |
| 53504 | if( zFull==0 ){ |
| 53505 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53506 | return 0; |
| 53507 | } |
| 53508 | if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ |
| 53509 | sqlite3_free(zFull); |
| 53510 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53511 | return 0; |
| 53512 | } |
| 53513 | zConverted = winConvertFromUtf8Filename(zFull); |
| 53514 | sqlite3_free(zFull); |
| 53515 | #else |
| 53516 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53517 | UNUSED_PARAMETER(pVfs); |
| 53518 | #endif |
| 53519 | if( zConverted==0 ){ |
| 53520 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53521 | return 0; |
| 53522 | } |
| 53523 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | |
| 58855 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58856 | PCache *pPCache; /* Pointer to page cache object */ |
| 58857 | #ifndef SQLITE_OMIT_WAL |
| 58858 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58859 | char *zWal; /* File name for write-ahead log */ |
| 58860 | #endif |
| 58861 | }; |
| 58862 | |
| 58863 | /* |
| 58864 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | |
| 65737 | if( rc==SQLITE_OK ){ |
| 65738 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65739 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65740 | pPager->journalSizeLimit, &pPager->pWal |
| 65741 | ); |
| 65742 | } |
| 65743 | pagerFixMaplimit(pPager); |
| 65744 | |
| 65745 | return rc; |
| 65746 | } |
| @@ -65856,10 +65777,11 @@ | |
| 65856 | /* |
| 65857 | ** Set the database handle used by the wal layer to determine if |
| 65858 | ** blocking locks are required. |
| 65859 | */ |
| 65860 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65861 | if( pagerUseWal(pPager) ){ |
| 65862 | sqlite3WalDb(pPager->pWal, db); |
| 65863 | } |
| 65864 | } |
| 65865 | #endif |
| @@ -69029,11 +68951,10 @@ | |
| 69029 | assert( rc==SQLITE_OK ); |
| 69030 | if( pWal->bShmUnreliable==0 ){ |
| 69031 | rc = walIndexReadHdr(pWal, pChanged); |
| 69032 | } |
| 69033 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 69034 | walDisableBlocking(pWal); |
| 69035 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 69036 | rc = SQLITE_BUSY; |
| 69037 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 69038 | } |
| 69039 | #endif |
| @@ -69044,10 +68965,11 @@ | |
| 69044 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 69045 | ** would be technically correct. But the race is benign since with |
| 69046 | ** WAL_RETRY this routine will be called again and will probably be |
| 69047 | ** right on the second iteration. |
| 69048 | */ |
| 69049 | if( pWal->apWiData[0]==0 ){ |
| 69050 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 69051 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 69052 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 69053 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | |
| 69060 | rc = WAL_RETRY; |
| 69061 | }else if( rc==SQLITE_BUSY ){ |
| 69062 | rc = SQLITE_BUSY_RECOVERY; |
| 69063 | } |
| 69064 | } |
| 69065 | if( rc!=SQLITE_OK ){ |
| 69066 | return rc; |
| 69067 | } |
| 69068 | else if( pWal->bShmUnreliable ){ |
| 69069 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | |
| 72509 | if( pKey ){ |
| 72510 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72511 | assert( nKey==(i64)(int)nKey ); |
| 72512 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72513 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72514 | sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); |
| 72515 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72516 | rc = SQLITE_CORRUPT_BKPT; |
| 72517 | }else{ |
| 72518 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72519 | } |
| @@ -74493,10 +74416,11 @@ | |
| 74493 | removed = 1; |
| 74494 | } |
| 74495 | sqlite3_mutex_leave(pMainMtx); |
| 74496 | return removed; |
| 74497 | #else |
| 74498 | return 1; |
| 74499 | #endif |
| 74500 | } |
| 74501 | |
| 74502 | /* |
| @@ -75334,10 +75258,17 @@ | |
| 75334 | |
| 75335 | if( rc!=SQLITE_OK ){ |
| 75336 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75337 | unlockBtreeIfUnused(pBt); |
| 75338 | } |
| 75339 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75340 | btreeInvokeBusyHandler(pBt) ); |
| 75341 | sqlite3PagerWalDb(pPager, 0); |
| 75342 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75343 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | |
| 82954 | ** btree as the argument handle holds an exclusive lock on the |
| 82955 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82956 | */ |
| 82957 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82958 | int rc; |
| 82959 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82960 | sqlite3BtreeEnter(p); |
| 82961 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82962 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82963 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | |
| 90174 | } |
| 90175 | } |
| 90176 | return; |
| 90177 | } |
| 90178 | /* |
| 90179 | ** This routine is used to allocate sufficient space for an UnpackedRecord |
| 90180 | ** structure large enough to be used with sqlite3VdbeRecordUnpack() if |
| 90181 | ** the first argument is a pointer to KeyInfo structure pKeyInfo. |
| 90182 | ** |
| 90183 | ** The space is either allocated using sqlite3DbMallocRaw() or from within |
| 90184 | ** the unaligned buffer passed via the second and third arguments (presumably |
| 90185 | ** stack space). If the former, then *ppFree is set to a pointer that should |
| 90186 | ** be eventually freed by the caller using sqlite3DbFree(). Or, if the |
| 90187 | ** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL |
| 90188 | ** before returning. |
| 90189 | ** |
| 90190 | ** If an OOM error occurs, NULL is returned. |
| 90191 | */ |
| 90192 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90193 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90194 | ){ |
| 90195 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90196 | int nByte; /* Number of bytes required for *p */ |
| 90197 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90198 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90199 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90200 | if( !p ) return 0; |
| 90201 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90202 | assert( pKeyInfo->aSortFlags!=0 ); |
| 90203 | p->pKeyInfo = pKeyInfo; |
| 90204 | p->nField = pKeyInfo->nKeyField + 1; |
| 90205 | return p; |
| 90206 | } |
| 90207 | |
| @@ -90209,11 +90133,10 @@ | |
| 90209 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90210 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90211 | ** contents of the decoded record. |
| 90212 | */ |
| 90213 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90214 | KeyInfo *pKeyInfo, /* Information about the record format */ |
| 90215 | int nKey, /* Size of the binary record */ |
| 90216 | const void *pKey, /* The binary record */ |
| 90217 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90218 | ){ |
| 90219 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | |
| 90220 | u32 d; |
| 90221 | u32 idx; /* Offset in aKey[] to read from */ |
| 90222 | u16 u; /* Unsigned loop counter */ |
| 90223 | u32 szHdr; |
| 90224 | Mem *pMem = p->aMem; |
| 90225 | |
| 90226 | p->default_rc = 0; |
| 90227 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90228 | idx = getVarint32(aKey, szHdr); |
| 90229 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | |
| 90247 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90248 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90249 | ** warnings from MSAN. */ |
| 90250 | sqlite3VdbeMemSetNull(pMem-1); |
| 90251 | } |
| 90252 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90253 | p->nField = u; |
| 90254 | } |
| 90255 | |
| 90256 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | |
| 91106 | ** is an integer. |
| 91107 | ** |
| 91108 | ** The easiest way to enforce this limit is to consider only records with |
| 91109 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91110 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91111 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91112 | int flags = p->aMem[0].flags; |
| 91113 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91114 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91115 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | |
| 91464 | ){ |
| 91465 | sqlite3 *db = v->db; |
| 91466 | i64 iKey2; |
| 91467 | PreUpdate preupdate; |
| 91468 | const char *zTbl = pTab->zName; |
| 91469 | static const u8 fakeSortOrder = 0; |
| 91470 | #ifdef SQLITE_DEBUG |
| 91471 | int nRealCol; |
| 91472 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91473 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91474 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | |
| 91503 | preupdate.iNewReg = iReg; |
| 91504 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91505 | preupdate.pKeyinfo->db = db; |
| 91506 | preupdate.pKeyinfo->enc = ENC(db); |
| 91507 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91508 | preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; |
| 91509 | preupdate.iKey1 = iKey1; |
| 91510 | preupdate.iKey2 = iKey2; |
| 91511 | preupdate.pTab = pTab; |
| 91512 | preupdate.iBlobWrite = iBlobWrite; |
| 91513 | |
| @@ -93700,11 +93626,11 @@ | |
| 93700 | UnpackedRecord *pRet; /* Return value */ |
| 93701 | |
| 93702 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93703 | if( pRet ){ |
| 93704 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93705 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); |
| 93706 | } |
| 93707 | return pRet; |
| 93708 | } |
| 93709 | |
| 93710 | /* |
| @@ -96893,10 +96819,11 @@ | |
| 96893 | } |
| 96894 | n = pOp->p3; |
| 96895 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96896 | assert( n>0 ); |
| 96897 | assert( pKeyInfo!=0 ); |
| 96898 | p1 = pOp->p1; |
| 96899 | p2 = pOp->p2; |
| 96900 | #ifdef SQLITE_DEBUG |
| 96901 | if( aPermute ){ |
| 96902 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | |
| 99766 | rc = ExpandBlob(r.aMem); |
| 99767 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99768 | if( rc ) goto no_mem; |
| 99769 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99770 | if( pIdxKey==0 ) goto no_mem; |
| 99771 | sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); |
| 99772 | pIdxKey->default_rc = 0; |
| 99773 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99774 | sqlite3DbFreeNN(db, pIdxKey); |
| 99775 | } |
| 99776 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | |
| 104942 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104943 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104944 | ){ |
| 104945 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104946 | if( *pbKey2Cached==0 ){ |
| 104947 | sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); |
| 104948 | *pbKey2Cached = 1; |
| 104949 | } |
| 104950 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104951 | } |
| 104952 | |
| @@ -104969,11 +104896,11 @@ | |
| 104969 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104970 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104971 | ){ |
| 104972 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104973 | if( !*pbKey2Cached ){ |
| 104974 | sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); |
| 104975 | *pbKey2Cached = 1; |
| 104976 | } |
| 104977 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104978 | } |
| 104979 | |
| @@ -105009,10 +104936,11 @@ | |
| 105009 | res = vdbeSorterCompareTail( |
| 105010 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105011 | ); |
| 105012 | } |
| 105013 | }else{ |
| 105014 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 105015 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 105016 | res = res * -1; |
| 105017 | } |
| 105018 | } |
| @@ -105072,10 +105000,11 @@ | |
| 105072 | }else{ |
| 105073 | if( *v2 & 0x80 ) res = +1; |
| 105074 | } |
| 105075 | } |
| 105076 | |
| 105077 | if( res==0 ){ |
| 105078 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105079 | res = vdbeSorterCompareTail( |
| 105080 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105081 | ); |
| @@ -105145,11 +105074,12 @@ | |
| 105145 | assert( pCsr->pKeyInfo ); |
| 105146 | assert( !pCsr->isEphemeral ); |
| 105147 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105148 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105149 | < 0x7fffffff ); |
| 105150 | szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); |
| 105151 | sz = SZ_VDBESORTER(nWorker+1); |
| 105152 | |
| 105153 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105154 | pCsr->uc.pSorter = pSorter; |
| 105155 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | |
| 105159 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105160 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105161 | pKeyInfo->db = 0; |
| 105162 | if( nField && nWorker==0 ){ |
| 105163 | pKeyInfo->nKeyField = nField; |
| 105164 | } |
| 105165 | sqlite3BtreeEnter(pBt); |
| 105166 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105167 | sqlite3BtreeLeave(pBt); |
| 105168 | pSorter->nTask = nWorker + 1; |
| 105169 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | |
| 106939 | r2->nField = nKeyCol; |
| 106940 | } |
| 106941 | assert( r2->nField==nKeyCol ); |
| 106942 | |
| 106943 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106944 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); |
| 106945 | for(i=0; i<nKeyCol; i++){ |
| 106946 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106947 | *pRes = -1; |
| 106948 | return SQLITE_OK; |
| 106949 | } |
| @@ -110495,11 +110430,13 @@ | |
| 110495 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110496 | return sqlite3ExprAffinity( |
| 110497 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110498 | ); |
| 110499 | } |
| 110500 | if( op==TK_VECTOR ){ |
| 110501 | assert( ExprUseXList(pExpr) ); |
| 110502 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110503 | } |
| 110504 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110505 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | |
| 110688 | } |
| 110689 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110690 | p = p->pLeft; |
| 110691 | continue; |
| 110692 | } |
| 110693 | if( op==TK_VECTOR ){ |
| 110694 | assert( ExprUseXList(p) ); |
| 110695 | p = p->x.pList->a[0].pExpr; |
| 110696 | continue; |
| 110697 | } |
| 110698 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | |
| 119025 | }else{ |
| 119026 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 119027 | } |
| 119028 | |
| 119029 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 119030 | zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); |
| 119031 | }else{ |
| 119032 | assert( nSql>0 ); |
| 119033 | zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); |
| 119034 | if( zOut ){ |
| 119035 | zBuf1 = &zOut[nSql*2+1]; |
| 119036 | zBuf2 = &zOut[nSql*4+2]; |
| 119037 | } |
| 119038 | } |
| @@ -138772,10 +138711,12 @@ | |
| 138772 | /* Version 3.43.0 and later */ |
| 138773 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138774 | /* Version 3.44.0 and later */ |
| 138775 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138776 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138777 | }; |
| 138778 | |
| 138779 | /* |
| 138780 | ** This is the function signature used for all extension entry points. It |
| 138781 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | |
| 139105 | /* Version 3.43.0 and later */ |
| 139106 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139107 | /* Version 3.44.0 and later */ |
| 139108 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139109 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139110 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139111 | |
| 139112 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139113 | /* This case when the file really is being compiled as a loadable |
| 139114 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | |
| 139626 | sqlite3_is_interrupted, |
| 139627 | /* Version 3.43.0 and later */ |
| 139628 | sqlite3_stmt_explain, |
| 139629 | /* Version 3.44.0 and later */ |
| 139630 | sqlite3_get_clientdata, |
| 139631 | sqlite3_set_clientdata |
| 139632 | }; |
| 139633 | |
| 139634 | /* True if x is the directory separator character |
| 139635 | */ |
| 139636 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | |
| 145464 | "not present in both tables", zName); |
| 145465 | return 1; |
| 145466 | } |
| 145467 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145468 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145469 | if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ |
| 145470 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145471 | ** JOINs. If only a single table on the left side of this join |
| 145472 | ** contains the zName column, then this branch is a no-op. |
| 145473 | ** But if there are two or more tables on the left side |
| 145474 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | |
| 145480 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145481 | ** adding a new error so as to not break legacy applications. |
| 145482 | */ |
| 145483 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145484 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145485 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145486 | pRight->fg.isSynthUsing)!=0 ){ |
| 145487 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145488 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145489 | ){ |
| @@ -145496,11 +145443,17 @@ | |
| 145496 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145497 | } |
| 145498 | if( pFuncArgs ){ |
| 145499 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145500 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145501 | } |
| 145502 | } |
| 145503 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145504 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145505 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145506 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | |
| 146973 | #else |
| 146974 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146975 | #endif |
| 146976 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146977 | } |
| 146978 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146979 | } |
| 146980 | |
| 146981 | |
| 146982 | /* |
| @@ -149104,13 +149061,13 @@ | |
| 149104 | ** other than the one FROM-clause subquery that is a candidate |
| 149105 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149106 | ** from 2015-02-09.) |
| 149107 | ** |
| 149108 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149109 | ** (3a) the subquery may not be a join and |
| 149110 | ** (3b) the FROM clause of the subquery may not contain a virtual |
| 149111 | ** table and |
| 149112 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149113 | ** is now managed correctly |
| 149114 | ** (3d) the outer query may not be DISTINCT. |
| 149115 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149116 | ** |
| @@ -149322,11 +149279,11 @@ | |
| 149322 | ** |
| 149323 | ** See also tickets #306, #350, and #3300. |
| 149324 | */ |
| 149325 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149326 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149327 | || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ |
| 149328 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149329 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149330 | ){ |
| 149331 | return 0; |
| 149332 | } |
| @@ -153366,10 +153323,14 @@ | |
| 153366 | } |
| 153367 | |
| 153368 | if( iOrderByCol ){ |
| 153369 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153370 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153371 | if( ALWAYS(pBase!=0) |
| 153372 | && pBase->op!=TK_AGG_COLUMN |
| 153373 | && pBase->op!=TK_REGISTER |
| 153374 | ){ |
| 153375 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | |
| 157343 | saved_flags = db->flags; |
| 157344 | saved_mDbFlags = db->mDbFlags; |
| 157345 | saved_nChange = db->nChange; |
| 157346 | saved_nTotalChange = db->nTotalChange; |
| 157347 | saved_mTrace = db->mTrace; |
| 157348 | db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; |
| 157349 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157350 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157351 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157352 | db->mTrace = 0; |
| 157353 | |
| @@ -161818,16 +161780,17 @@ | |
| 161818 | } |
| 161819 | |
| 161820 | if( pLevel->iLeftJoin==0 ){ |
| 161821 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161822 | ** terms from the query that must be true due to the WHERE clause of |
| 161823 | ** the partial index. |
| 161824 | ** |
| 161825 | ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work |
| 161826 | ** for a LEFT JOIN. |
| 161827 | */ |
| 161828 | if( pIdx->pPartIdxWhere ){ |
| 161829 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161830 | } |
| 161831 | }else{ |
| 161832 | testcase( pIdx->pPartIdxWhere ); |
| 161833 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | |
| 168080 | Expr *pExpr; |
| 168081 | pExpr = pTerm->pExpr; |
| 168082 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168083 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168084 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168085 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168086 | ){ |
| 168087 | return 1; |
| 168088 | } |
| 168089 | } |
| @@ -188883,11 +188847,11 @@ | |
| 188883 | |
| 188884 | /* |
| 188885 | ** Macros needed to provide flexible arrays in a portable way |
| 188886 | */ |
| 188887 | #ifndef offsetof |
| 188888 | # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 188889 | #endif |
| 188890 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188891 | # define FLEXARRAY |
| 188892 | #else |
| 188893 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | |
| 209116 | nExtra = 0; |
| 209117 | }else if( szType==12 ){ |
| 209118 | nExtra = 1; |
| 209119 | }else if( szType==13 ){ |
| 209120 | nExtra = 2; |
| 209121 | }else{ |
| 209122 | nExtra = 4; |
| 209123 | } |
| 209124 | if( szPayload<=11 ){ |
| 209125 | nNeeded = 0; |
| 209126 | }else if( szPayload<=0xff ){ |
| 209127 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | |
| 212681 | const char *z; |
| 212682 | u32 n; |
| 212683 | UNUSED_PARAMETER(argc); |
| 212684 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212685 | if( pStr ){ |
| 212686 | if( pStr->zBuf==0 ){ |
| 212687 | jsonStringInit(pStr, ctx); |
| 212688 | jsonAppendChar(pStr, '{'); |
| 212689 | }else if( pStr->nUsed>1 ){ |
| 212690 | jsonAppendChar(pStr, ','); |
| 212691 | } |
| 212692 | pStr->pCtx = ctx; |
| 212693 | z = (const char*)sqlite3_value_text(argv[0]); |
| 212694 | n = sqlite3Strlen30(z); |
| 212695 | jsonAppendString(pStr, z, n); |
| 212696 | jsonAppendChar(pStr, ':'); |
| 212697 | jsonAppendSqlValue(pStr, argv[1]); |
| 212698 | } |
| 212699 | } |
| 212700 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212701 | JsonString *pStr; |
| 212702 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | |
| 213500 | #else |
| 213501 | /* #include "sqlite3.h" */ |
| 213502 | #endif |
| 213503 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213504 | |
| 213505 | /* |
| 213506 | ** If building separately, we will need some setup that is normally |
| 213507 | ** found in sqliteInt.h |
| 213508 | */ |
| 213509 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | |
| 213531 | #else |
| 213532 | # define ALWAYS(X) (X) |
| 213533 | # define NEVER(X) (X) |
| 213534 | #endif |
| 213535 | #ifndef offsetof |
| 213536 | #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 213537 | #endif |
| 213538 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213539 | # define FLEXARRAY |
| 213540 | #else |
| 213541 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | |
| 227848 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227849 | int rc; |
| 227850 | sqlite3 *db = pTab->db; |
| 227851 | Btree *pBt; |
| 227852 | |
| 227853 | (void)idxStr; |
| 227854 | |
| 227855 | /* Default setting is no rows of result */ |
| 227856 | pCsr->pgno = 1; |
| 227857 | pCsr->mxPgno = 0; |
| 227858 | |
| @@ -231510,18 +231481,19 @@ | |
| 231510 | /* |
| 231511 | ** If the SessionInput object passed as the only argument is a streaming |
| 231512 | ** object and the buffer is full, discard some data to free up space. |
| 231513 | */ |
| 231514 | static void sessionDiscardData(SessionInput *pIn){ |
| 231515 | if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ |
| 231516 | int nMove = pIn->buf.nBuf - pIn->iNext; |
| 231517 | assert( nMove>=0 ); |
| 231518 | if( nMove>0 ){ |
| 231519 | memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); |
| 231520 | } |
| 231521 | pIn->buf.nBuf -= pIn->iNext; |
| 231522 | pIn->iNext = 0; |
| 231523 | pIn->nData = pIn->buf.nBuf; |
| 231524 | } |
| 231525 | } |
| 231526 | |
| 231527 | /* |
| @@ -231871,12 +231843,12 @@ | |
| 231871 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231872 | ** it, or for the two single byte values otherwise. */ |
| 231873 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231874 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231875 | |
| 231876 | sessionDiscardData(&p->in); |
| 231877 | p->in.iCurrent = p->in.iNext; |
| 231878 | |
| 231879 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231880 | if( p->in.iNext>=p->in.nData ){ |
| 231881 | return SQLITE_DONE; |
| 231882 | } |
| @@ -234231,18 +234203,23 @@ | |
| 234231 | */ |
| 234232 | SQLITE_API int sqlite3changegroup_add_change( |
| 234233 | sqlite3_changegroup *pGrp, |
| 234234 | sqlite3_changeset_iter *pIter |
| 234235 | ){ |
| 234236 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234237 | || pIter->rc!=SQLITE_OK |
| 234238 | || pIter->bInvert |
| 234239 | ){ |
| 234240 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234241 | return SQLITE_ERROR; |
| 234242 | } |
| 234243 | return sessionOneChangeToHash(pGrp, pIter, 0); |
| 234244 | } |
| 234245 | |
| 234246 | /* |
| 234247 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234248 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | |
| 235536 | /* #include "sqlite3ext.h" */ |
| 235537 | SQLITE_EXTENSION_INIT1 |
| 235538 | |
| 235539 | /* #include <string.h> */ |
| 235540 | /* #include <assert.h> */ |
| 235541 | |
| 235542 | #ifndef SQLITE_AMALGAMATION |
| 235543 | |
| 235544 | typedef unsigned char u8; |
| 235545 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | |
| 235595 | |
| 235596 | /* |
| 235597 | ** Macros needed to provide flexible arrays in a portable way |
| 235598 | */ |
| 235599 | #ifndef offsetof |
| 235600 | # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 235601 | #endif |
| 235602 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235603 | # define FLEXARRAY |
| 235604 | #else |
| 235605 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | |
| 257279 | int nArg, /* Number of args */ |
| 257280 | sqlite3_value **apUnused /* Function arguments */ |
| 257281 | ){ |
| 257282 | assert( nArg==0 ); |
| 257283 | UNUSED_PARAM2(nArg, apUnused); |
| 257284 | sqlite3_result_text(pCtx, "fts5: 2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349", -1, SQLITE_TRANSIENT); |
| 257285 | } |
| 257286 | |
| 257287 | /* |
| 257288 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257289 | ** |
| 257290 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.51.0. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | |
| 463 | ** |
| 464 | ** See also: [sqlite3_libversion()], |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -15174,11 +15174,11 @@ | |
| 15174 | /* |
| 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | ** ourselves. |
| 15177 | */ |
| 15178 | #ifndef offsetof |
| 15179 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 15180 | #endif |
| 15181 | |
| 15182 | /* |
| 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | |
| 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | #endif |
| 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | |
| 17406 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); |
| 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | |
| 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | |
| 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | #define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ |
| 18707 | |
| 18708 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18709 | |
| 18710 | /* |
| 18711 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | |
| 19017 | /* |
| 19018 | ** An instance of the following structure is passed as the first |
| 19019 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19020 | ** comparison of the two index keys. |
| 19021 | ** |
| 19022 | ** The aSortOrder[] and aColl[] arrays have nAllField slots each. There |
| 19023 | ** are nKeyField slots for the columns of an index then extra slots |
| 19024 | ** for the rowid or key at the end. The aSortOrder array is located after |
| 19025 | ** the aColl[] array. |
| 19026 | ** |
| 19027 | ** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL |
| 19028 | ** to indicate that this object is for use by a preupdate hook. When aSortFlags |
| 19029 | ** is NULL, then nAllField is uninitialized and no space is allocated for |
| 19030 | ** aColl[], so those fields may not be used. |
| 19031 | */ |
| 19032 | struct KeyInfo { |
| 19033 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19034 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19035 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | |
| 19037 | sqlite3 *db; /* The database connection */ |
| 19038 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19039 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19040 | }; |
| 19041 | |
| 19042 | /* The size (in bytes) of a KeyInfo object with up to N fields. This includes |
| 19043 | ** the main body of the KeyInfo object and the aColl[] array of N elements, |
| 19044 | ** but does not count the memory used to hold aSortFlags[]. */ |
| 19045 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19046 | |
| 19047 | /* The size of a bare KeyInfo with no aColl[] entries */ |
| 19048 | #if FLEXARRAY+1 > 1 |
| 19049 | # define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) |
| 19050 | #else |
| 19051 | # define SZ_KEYINFO_0 sizeof(KeyInfo) |
| 19052 | #endif |
| 19053 | |
| 19054 | /* |
| 19055 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19056 | */ |
| 19057 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | |
| 19067 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19068 | ** OP_Column opcode. |
| 19069 | ** |
| 19070 | ** An instance of this object serves as a "key" for doing a search on |
| 19071 | ** an index b+tree. The goal of the search is to find the entry that |
| 19072 | ** is closest to the key described by this object. This object might hold |
| 19073 | ** just a prefix of the key. The number of fields is given by nField. |
| 19074 | ** |
| 19075 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19076 | ** or greater than a key in the btree, respectively. These are normally |
| 19077 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19078 | ** is in DESC order. |
| 19079 | ** |
| 19080 | ** The key comparison functions actually return default_rc when they find |
| 19081 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19082 | ** multiple entries in the b-tree with the same key (when only looking |
| 19083 | ** at the first nField elements) then default_rc can be set to -1 to |
| 19084 | ** cause the search to find the last match, or +1 to cause the search to |
| 19085 | ** find the first match. |
| 19086 | ** |
| 19087 | ** The key comparison functions will set eqSeen to true if they ever |
| 19088 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | |
| 19090 | ** before the first match or immediately after the last match. The |
| 19091 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19092 | ** b-tree. |
| 19093 | */ |
| 19094 | struct UnpackedRecord { |
| 19095 | KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ |
| 19096 | Mem *aMem; /* Values for columns of the index */ |
| 19097 | union { |
| 19098 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19099 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19100 | } u; |
| 19101 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | |
| 24147 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24148 | Mem *aNew; /* Array of new.* values */ |
| 24149 | Table *pTab; /* Schema object being updated */ |
| 24150 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24151 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24152 | u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ |
| 24153 | }; |
| 24154 | |
| 24155 | /* |
| 24156 | ** An instance of this object is used to pass an vector of values into |
| 24157 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | |
| 35028 | } |
| 35029 | |
| 35030 | /* |
| 35031 | ** Write a single UTF8 character whose value is v into the |
| 35032 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35033 | ** least four bytes. Return the number of bytes needed |
| 35034 | ** to encode the new character. |
| 35035 | */ |
| 35036 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35037 | if( v<0x00080 ){ |
| 35038 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | |
| 43887 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43888 | |
| 43889 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43890 | ** in the following list than the lock being obtained are already held: |
| 43891 | ** |
| 43892 | ** 1. Recovery lock (ofst==2). |
| 43893 | ** 2. Checkpointer lock (ofst==1). |
| 43894 | ** 3. Write lock (ofst==0). |
| 43895 | ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 43896 | ** |
| 43897 | ** In other words, if this is a blocking lock, none of the locks that |
| 43898 | ** occur later in the above list than the lock being obtained may be |
| 43899 | ** held. |
| 43900 | */ |
| 43901 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43902 | { |
| 43903 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43904 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43905 | (ofst!=2 || lockMask==0) |
| 43906 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43907 | && (ofst!=0 || lockMask<3) |
| 43908 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43909 | )); |
| 43910 | } |
| @@ -49851,11 +49865,15 @@ | |
| 49865 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49866 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49867 | if( res==WAIT_OBJECT_0 ){ |
| 49868 | ret = TRUE; |
| 49869 | }else if( res==WAIT_TIMEOUT ){ |
| 49870 | #if SQLITE_ENABLE_SETLK_TIMEOUT==1 |
| 49871 | rc = SQLITE_BUSY_TIMEOUT; |
| 49872 | #else |
| 49873 | rc = SQLITE_BUSY; |
| 49874 | #endif |
| 49875 | }else{ |
| 49876 | /* Some other error has occurred */ |
| 49877 | rc = SQLITE_IOERR_LOCK; |
| 49878 | } |
| 49879 | |
| @@ -51337,17 +51355,17 @@ | |
| 51355 | int nChar; |
| 51356 | LPWSTR zWideFilename; |
| 51357 | |
| 51358 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51359 | && winIsDirSep(zFilename[2])) ){ |
| 51360 | i64 nByte; |
| 51361 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51362 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51363 | nByte = (i64)osCygwin_conv_path(convertflag, |
| 51364 | zFilename, 0, 0); |
| 51365 | if( nByte>0 ){ |
| 51366 | zConverted = sqlite3MallocZero(12+(u64)nByte); |
| 51367 | if ( zConverted==0 ){ |
| 51368 | return zConverted; |
| 51369 | } |
| 51370 | zWideFilename = zConverted; |
| 51371 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | |
| 51680 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51681 | |
| 51682 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51683 | ** in the following list than the lock being obtained are already held: |
| 51684 | ** |
| 51685 | ** 1. Recovery lock (ofst==2). |
| 51686 | ** 2. Checkpointer lock (ofst==1). |
| 51687 | ** 3. Write lock (ofst==0). |
| 51688 | ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 51689 | ** |
| 51690 | ** In other words, if this is a blocking lock, none of the locks that |
| 51691 | ** occur later in the above list than the lock being obtained may be |
| 51692 | ** held. |
| 51693 | */ |
| 51694 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51695 | { |
| 51696 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51697 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51698 | (ofst!=2 || lockMask==0) |
| 51699 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51700 | && (ofst!=0 || lockMask<3) |
| 51701 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51702 | )); |
| 51703 | } |
| @@ -52226,31 +52243,10 @@ | |
| 52243 | ** |
| 52244 | ** This division contains the implementation of methods on the |
| 52245 | ** sqlite3_vfs object. |
| 52246 | */ |
| 52247 | |
| 52248 | /* |
| 52249 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52250 | ** ends with a directory separator character or one was successfully |
| 52251 | ** added to it. |
| 52252 | */ |
| @@ -52386,46 +52382,10 @@ | |
| 52382 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52383 | sqlite3_free(zConverted); |
| 52384 | break; |
| 52385 | } |
| 52386 | sqlite3_free(zConverted); |
| 52387 | } |
| 52388 | } |
| 52389 | } |
| 52390 | #endif |
| 52391 | |
| @@ -53320,38 +53280,10 @@ | |
| 53280 | winSimplifyName(zFull); |
| 53281 | return rc; |
| 53282 | } |
| 53283 | } |
| 53284 | #endif /* __CYGWIN__ */ |
| 53285 | |
| 53286 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53287 | SimulateIOError( return SQLITE_ERROR ); |
| 53288 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53289 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | |
| 53425 | ** Interfaces for opening a shared library, finding entry points |
| 53426 | ** within the shared library, and closing the shared library. |
| 53427 | */ |
| 53428 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53429 | HANDLE h; |
| 53430 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53431 | UNUSED_PARAMETER(pVfs); |
| 53432 | if( zConverted==0 ){ |
| 53433 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53434 | return 0; |
| 53435 | } |
| 53436 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | |
| 58768 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58769 | PCache *pPCache; /* Pointer to page cache object */ |
| 58770 | #ifndef SQLITE_OMIT_WAL |
| 58771 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58772 | char *zWal; /* File name for write-ahead log */ |
| 58773 | #endif |
| 58774 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 58775 | sqlite3 *dbWal; |
| 58776 | #endif |
| 58777 | }; |
| 58778 | |
| 58779 | /* |
| 58780 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | |
| 65653 | if( rc==SQLITE_OK ){ |
| 65654 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65655 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65656 | pPager->journalSizeLimit, &pPager->pWal |
| 65657 | ); |
| 65658 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 65659 | if( rc==SQLITE_OK ){ |
| 65660 | sqlite3WalDb(pPager->pWal, pPager->dbWal); |
| 65661 | } |
| 65662 | #endif |
| 65663 | } |
| 65664 | pagerFixMaplimit(pPager); |
| 65665 | |
| 65666 | return rc; |
| 65667 | } |
| @@ -65856,10 +65777,11 @@ | |
| 65777 | /* |
| 65778 | ** Set the database handle used by the wal layer to determine if |
| 65779 | ** blocking locks are required. |
| 65780 | */ |
| 65781 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65782 | pPager->dbWal = db; |
| 65783 | if( pagerUseWal(pPager) ){ |
| 65784 | sqlite3WalDb(pPager->pWal, db); |
| 65785 | } |
| 65786 | } |
| 65787 | #endif |
| @@ -69029,11 +68951,10 @@ | |
| 68951 | assert( rc==SQLITE_OK ); |
| 68952 | if( pWal->bShmUnreliable==0 ){ |
| 68953 | rc = walIndexReadHdr(pWal, pChanged); |
| 68954 | } |
| 68955 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 68956 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 68957 | rc = SQLITE_BUSY; |
| 68958 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 68959 | } |
| 68960 | #endif |
| @@ -69044,10 +68965,11 @@ | |
| 68965 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 68966 | ** would be technically correct. But the race is benign since with |
| 68967 | ** WAL_RETRY this routine will be called again and will probably be |
| 68968 | ** right on the second iteration. |
| 68969 | */ |
| 68970 | (void)walEnableBlocking(pWal); |
| 68971 | if( pWal->apWiData[0]==0 ){ |
| 68972 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 68973 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 68974 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 68975 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | |
| 68982 | rc = WAL_RETRY; |
| 68983 | }else if( rc==SQLITE_BUSY ){ |
| 68984 | rc = SQLITE_BUSY_RECOVERY; |
| 68985 | } |
| 68986 | } |
| 68987 | walDisableBlocking(pWal); |
| 68988 | if( rc!=SQLITE_OK ){ |
| 68989 | return rc; |
| 68990 | } |
| 68991 | else if( pWal->bShmUnreliable ){ |
| 68992 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | |
| 72432 | if( pKey ){ |
| 72433 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72434 | assert( nKey==(i64)(int)nKey ); |
| 72435 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72436 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72437 | sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); |
| 72438 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72439 | rc = SQLITE_CORRUPT_BKPT; |
| 72440 | }else{ |
| 72441 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72442 | } |
| @@ -74493,10 +74416,11 @@ | |
| 74416 | removed = 1; |
| 74417 | } |
| 74418 | sqlite3_mutex_leave(pMainMtx); |
| 74419 | return removed; |
| 74420 | #else |
| 74421 | UNUSED_PARAMETER( pBt ); |
| 74422 | return 1; |
| 74423 | #endif |
| 74424 | } |
| 74425 | |
| 74426 | /* |
| @@ -75334,10 +75258,17 @@ | |
| 75258 | |
| 75259 | if( rc!=SQLITE_OK ){ |
| 75260 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75261 | unlockBtreeIfUnused(pBt); |
| 75262 | } |
| 75263 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 75264 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 75265 | /* If a blocking lock timed out, break out of the loop here so that |
| 75266 | ** the busy-handler is not invoked. */ |
| 75267 | break; |
| 75268 | } |
| 75269 | #endif |
| 75270 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75271 | btreeInvokeBusyHandler(pBt) ); |
| 75272 | sqlite3PagerWalDb(pPager, 0); |
| 75273 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75274 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | |
| 82885 | ** btree as the argument handle holds an exclusive lock on the |
| 82886 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82887 | */ |
| 82888 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82889 | int rc; |
| 82890 | UNUSED_PARAMETER(p); /* only used in DEBUG builds */ |
| 82891 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82892 | sqlite3BtreeEnter(p); |
| 82893 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82894 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82895 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | |
| 90106 | } |
| 90107 | } |
| 90108 | return; |
| 90109 | } |
| 90110 | /* |
| 90111 | ** Allocate sufficient space for an UnpackedRecord structure large enough |
| 90112 | ** to hold a decoded index record for pKeyInfo. |
| 90113 | ** |
| 90114 | ** The space is allocated using sqlite3DbMallocRaw(). If an OOM error |
| 90115 | ** occurs, NULL is returned. |
| 90116 | */ |
| 90117 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90118 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90119 | ){ |
| 90120 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90121 | u64 nByte; /* Number of bytes required for *p */ |
| 90122 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90123 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90124 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90125 | if( !p ) return 0; |
| 90126 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90127 | p->pKeyInfo = pKeyInfo; |
| 90128 | p->nField = pKeyInfo->nKeyField + 1; |
| 90129 | return p; |
| 90130 | } |
| 90131 | |
| @@ -90209,11 +90133,10 @@ | |
| 90133 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90134 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90135 | ** contents of the decoded record. |
| 90136 | */ |
| 90137 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90138 | int nKey, /* Size of the binary record */ |
| 90139 | const void *pKey, /* The binary record */ |
| 90140 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90141 | ){ |
| 90142 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | |
| 90143 | u32 d; |
| 90144 | u32 idx; /* Offset in aKey[] to read from */ |
| 90145 | u16 u; /* Unsigned loop counter */ |
| 90146 | u32 szHdr; |
| 90147 | Mem *pMem = p->aMem; |
| 90148 | KeyInfo *pKeyInfo = p->pKeyInfo; |
| 90149 | |
| 90150 | p->default_rc = 0; |
| 90151 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90152 | idx = getVarint32(aKey, szHdr); |
| 90153 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | |
| 90171 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90172 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90173 | ** warnings from MSAN. */ |
| 90174 | sqlite3VdbeMemSetNull(pMem-1); |
| 90175 | } |
| 90176 | testcase( u == pKeyInfo->nKeyField + 1 ); |
| 90177 | testcase( u < pKeyInfo->nKeyField + 1 ); |
| 90178 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90179 | p->nField = u; |
| 90180 | } |
| 90181 | |
| 90182 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | |
| 91032 | ** is an integer. |
| 91033 | ** |
| 91034 | ** The easiest way to enforce this limit is to consider only records with |
| 91035 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91036 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91037 | assert( p->pKeyInfo->aSortFlags!=0 ); |
| 91038 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91039 | int flags = p->aMem[0].flags; |
| 91040 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91041 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91042 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | |
| 91391 | ){ |
| 91392 | sqlite3 *db = v->db; |
| 91393 | i64 iKey2; |
| 91394 | PreUpdate preupdate; |
| 91395 | const char *zTbl = pTab->zName; |
| 91396 | #ifdef SQLITE_DEBUG |
| 91397 | int nRealCol; |
| 91398 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91399 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91400 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | |
| 91429 | preupdate.iNewReg = iReg; |
| 91430 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91431 | preupdate.pKeyinfo->db = db; |
| 91432 | preupdate.pKeyinfo->enc = ENC(db); |
| 91433 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91434 | preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ |
| 91435 | preupdate.iKey1 = iKey1; |
| 91436 | preupdate.iKey2 = iKey2; |
| 91437 | preupdate.pTab = pTab; |
| 91438 | preupdate.iBlobWrite = iBlobWrite; |
| 91439 | |
| @@ -93700,11 +93626,11 @@ | |
| 93626 | UnpackedRecord *pRet; /* Return value */ |
| 93627 | |
| 93628 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93629 | if( pRet ){ |
| 93630 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93631 | sqlite3VdbeRecordUnpack(nKey, pKey, pRet); |
| 93632 | } |
| 93633 | return pRet; |
| 93634 | } |
| 93635 | |
| 93636 | /* |
| @@ -96893,10 +96819,11 @@ | |
| 96819 | } |
| 96820 | n = pOp->p3; |
| 96821 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96822 | assert( n>0 ); |
| 96823 | assert( pKeyInfo!=0 ); |
| 96824 | assert( pKeyInfo->aSortFlags!=0 ); |
| 96825 | p1 = pOp->p1; |
| 96826 | p2 = pOp->p2; |
| 96827 | #ifdef SQLITE_DEBUG |
| 96828 | if( aPermute ){ |
| 96829 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | |
| 99693 | rc = ExpandBlob(r.aMem); |
| 99694 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99695 | if( rc ) goto no_mem; |
| 99696 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99697 | if( pIdxKey==0 ) goto no_mem; |
| 99698 | sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); |
| 99699 | pIdxKey->default_rc = 0; |
| 99700 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99701 | sqlite3DbFreeNN(db, pIdxKey); |
| 99702 | } |
| 99703 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | |
| 104869 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104870 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104871 | ){ |
| 104872 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104873 | if( *pbKey2Cached==0 ){ |
| 104874 | sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); |
| 104875 | *pbKey2Cached = 1; |
| 104876 | } |
| 104877 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104878 | } |
| 104879 | |
| @@ -104969,11 +104896,11 @@ | |
| 104896 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104897 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104898 | ){ |
| 104899 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104900 | if( !*pbKey2Cached ){ |
| 104901 | sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); |
| 104902 | *pbKey2Cached = 1; |
| 104903 | } |
| 104904 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104905 | } |
| 104906 | |
| @@ -105009,10 +104936,11 @@ | |
| 104936 | res = vdbeSorterCompareTail( |
| 104937 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 104938 | ); |
| 104939 | } |
| 104940 | }else{ |
| 104941 | assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); |
| 104942 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 104943 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 104944 | res = res * -1; |
| 104945 | } |
| 104946 | } |
| @@ -105072,10 +105000,11 @@ | |
| 105000 | }else{ |
| 105001 | if( *v2 & 0x80 ) res = +1; |
| 105002 | } |
| 105003 | } |
| 105004 | |
| 105005 | assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); |
| 105006 | if( res==0 ){ |
| 105007 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105008 | res = vdbeSorterCompareTail( |
| 105009 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105010 | ); |
| @@ -105145,11 +105074,12 @@ | |
| 105074 | assert( pCsr->pKeyInfo ); |
| 105075 | assert( !pCsr->isEphemeral ); |
| 105076 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105077 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105078 | < 0x7fffffff ); |
| 105079 | assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); |
| 105080 | szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); |
| 105081 | sz = SZ_VDBESORTER(nWorker+1); |
| 105082 | |
| 105083 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105084 | pCsr->uc.pSorter = pSorter; |
| 105085 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | |
| 105089 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105090 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105091 | pKeyInfo->db = 0; |
| 105092 | if( nField && nWorker==0 ){ |
| 105093 | pKeyInfo->nKeyField = nField; |
| 105094 | assert( nField<=pCsr->pKeyInfo->nAllField ); |
| 105095 | } |
| 105096 | /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, |
| 105097 | ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives |
| 105098 | ** longer that pSorter. */ |
| 105099 | assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); |
| 105100 | sqlite3BtreeEnter(pBt); |
| 105101 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105102 | sqlite3BtreeLeave(pBt); |
| 105103 | pSorter->nTask = nWorker + 1; |
| 105104 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | |
| 106874 | r2->nField = nKeyCol; |
| 106875 | } |
| 106876 | assert( r2->nField==nKeyCol ); |
| 106877 | |
| 106878 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106879 | sqlite3VdbeRecordUnpack(nKey, pKey, r2); |
| 106880 | for(i=0; i<nKeyCol; i++){ |
| 106881 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106882 | *pRes = -1; |
| 106883 | return SQLITE_OK; |
| 106884 | } |
| @@ -110495,11 +110430,13 @@ | |
| 110430 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110431 | return sqlite3ExprAffinity( |
| 110432 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110433 | ); |
| 110434 | } |
| 110435 | if( op==TK_VECTOR |
| 110436 | || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) |
| 110437 | ){ |
| 110438 | assert( ExprUseXList(pExpr) ); |
| 110439 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110440 | } |
| 110441 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110442 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | |
| 110625 | } |
| 110626 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110627 | p = p->pLeft; |
| 110628 | continue; |
| 110629 | } |
| 110630 | if( op==TK_VECTOR |
| 110631 | || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) |
| 110632 | ){ |
| 110633 | assert( ExprUseXList(p) ); |
| 110634 | p = p->x.pList->a[0].pExpr; |
| 110635 | continue; |
| 110636 | } |
| 110637 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | |
| 118964 | }else{ |
| 118965 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 118966 | } |
| 118967 | |
| 118968 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 118969 | zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); |
| 118970 | }else{ |
| 118971 | assert( nSql>0 ); |
| 118972 | zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); |
| 118973 | if( zOut ){ |
| 118974 | zBuf1 = &zOut[nSql*2+1]; |
| 118975 | zBuf2 = &zOut[nSql*4+2]; |
| 118976 | } |
| 118977 | } |
| @@ -138772,10 +138711,12 @@ | |
| 138711 | /* Version 3.43.0 and later */ |
| 138712 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138713 | /* Version 3.44.0 and later */ |
| 138714 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138715 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138716 | /* Version 3.50.0 and later */ |
| 138717 | int (*setlk_timeout)(sqlite3*,int,int); |
| 138718 | }; |
| 138719 | |
| 138720 | /* |
| 138721 | ** This is the function signature used for all extension entry points. It |
| 138722 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | |
| 139046 | /* Version 3.43.0 and later */ |
| 139047 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139048 | /* Version 3.44.0 and later */ |
| 139049 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139050 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139051 | /* Version 3.50.0 and later */ |
| 139052 | #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout |
| 139053 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139054 | |
| 139055 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139056 | /* This case when the file really is being compiled as a loadable |
| 139057 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | |
| 139569 | sqlite3_is_interrupted, |
| 139570 | /* Version 3.43.0 and later */ |
| 139571 | sqlite3_stmt_explain, |
| 139572 | /* Version 3.44.0 and later */ |
| 139573 | sqlite3_get_clientdata, |
| 139574 | sqlite3_set_clientdata, |
| 139575 | /* Version 3.50.0 and later */ |
| 139576 | sqlite3_setlk_timeout |
| 139577 | }; |
| 139578 | |
| 139579 | /* True if x is the directory separator character |
| 139580 | */ |
| 139581 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | |
| 145409 | "not present in both tables", zName); |
| 145410 | return 1; |
| 145411 | } |
| 145412 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145413 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145414 | if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ |
| 145415 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145416 | ** JOINs. If only a single table on the left side of this join |
| 145417 | ** contains the zName column, then this branch is a no-op. |
| 145418 | ** But if there are two or more tables on the left side |
| 145419 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | |
| 145425 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145426 | ** adding a new error so as to not break legacy applications. |
| 145427 | */ |
| 145428 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145429 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145430 | assert( pE1!=0 ); |
| 145431 | ExprSetProperty(pE1, EP_CanBeNull); |
| 145432 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145433 | pRight->fg.isSynthUsing)!=0 ){ |
| 145434 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145435 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145436 | ){ |
| @@ -145496,11 +145443,17 @@ | |
| 145443 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145444 | } |
| 145445 | if( pFuncArgs ){ |
| 145446 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145447 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145448 | if( pE1 ){ |
| 145449 | pE1->affExpr = SQLITE_AFF_DEFER; |
| 145450 | } |
| 145451 | } |
| 145452 | }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ |
| 145453 | assert( pE1!=0 ); |
| 145454 | ExprSetProperty(pE1, EP_CanBeNull); |
| 145455 | } |
| 145456 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145457 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145458 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145459 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | |
| 146926 | #else |
| 146927 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146928 | #endif |
| 146929 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146930 | } |
| 146931 | #else |
| 146932 | UNUSED_PARAMETER(pParse); |
| 146933 | UNUSED_PARAMETER(pTabList); |
| 146934 | UNUSED_PARAMETER(pEList); |
| 146935 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146936 | } |
| 146937 | |
| 146938 | |
| 146939 | /* |
| @@ -149104,13 +149061,13 @@ | |
| 149061 | ** other than the one FROM-clause subquery that is a candidate |
| 149062 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149063 | ** from 2015-02-09.) |
| 149064 | ** |
| 149065 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149066 | ** (3a) the subquery may not be a join |
| 149067 | ** (**) Was (3b): "the FROM clause of the subquery may not contain |
| 149068 | ** a virtual table" |
| 149069 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149070 | ** is now managed correctly |
| 149071 | ** (3d) the outer query may not be DISTINCT. |
| 149072 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149073 | ** |
| @@ -149322,11 +149279,11 @@ | |
| 149279 | ** |
| 149280 | ** See also tickets #306, #350, and #3300. |
| 149281 | */ |
| 149282 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149283 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149284 | /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ |
| 149285 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149286 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149287 | ){ |
| 149288 | return 0; |
| 149289 | } |
| @@ -153366,10 +153323,14 @@ | |
| 153323 | } |
| 153324 | |
| 153325 | if( iOrderByCol ){ |
| 153326 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153327 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153328 | while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ |
| 153329 | pX = pBase->pLeft; |
| 153330 | pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153331 | } |
| 153332 | if( ALWAYS(pBase!=0) |
| 153333 | && pBase->op!=TK_AGG_COLUMN |
| 153334 | && pBase->op!=TK_REGISTER |
| 153335 | ){ |
| 153336 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | |
| 157304 | saved_flags = db->flags; |
| 157305 | saved_mDbFlags = db->mDbFlags; |
| 157306 | saved_nChange = db->nChange; |
| 157307 | saved_nTotalChange = db->nTotalChange; |
| 157308 | saved_mTrace = db->mTrace; |
| 157309 | db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments |
| 157310 | | SQLITE_AttachCreate | SQLITE_AttachWrite; |
| 157311 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157312 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157313 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157314 | db->mTrace = 0; |
| 157315 | |
| @@ -161818,16 +161780,17 @@ | |
| 161780 | } |
| 161781 | |
| 161782 | if( pLevel->iLeftJoin==0 ){ |
| 161783 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161784 | ** terms from the query that must be true due to the WHERE clause of |
| 161785 | ** the partial index. This optimization does not work on an outer join, |
| 161786 | ** as shown by: |
| 161787 | ** |
| 161788 | ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) |
| 161789 | ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) |
| 161790 | */ |
| 161791 | if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ |
| 161792 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161793 | } |
| 161794 | }else{ |
| 161795 | testcase( pIdx->pPartIdxWhere ); |
| 161796 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | |
| 168043 | Expr *pExpr; |
| 168044 | pExpr = pTerm->pExpr; |
| 168045 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168046 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168047 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168048 | && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) |
| 168049 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168050 | ){ |
| 168051 | return 1; |
| 168052 | } |
| 168053 | } |
| @@ -188883,11 +188847,11 @@ | |
| 188847 | |
| 188848 | /* |
| 188849 | ** Macros needed to provide flexible arrays in a portable way |
| 188850 | */ |
| 188851 | #ifndef offsetof |
| 188852 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 188853 | #endif |
| 188854 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188855 | # define FLEXARRAY |
| 188856 | #else |
| 188857 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | |
| 209080 | nExtra = 0; |
| 209081 | }else if( szType==12 ){ |
| 209082 | nExtra = 1; |
| 209083 | }else if( szType==13 ){ |
| 209084 | nExtra = 2; |
| 209085 | }else if( szType==14 ){ |
| 209086 | nExtra = 4; |
| 209087 | }else{ |
| 209088 | nExtra = 8; |
| 209089 | } |
| 209090 | if( szPayload<=11 ){ |
| 209091 | nNeeded = 0; |
| 209092 | }else if( szPayload<=0xff ){ |
| 209093 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | |
| 212647 | const char *z; |
| 212648 | u32 n; |
| 212649 | UNUSED_PARAMETER(argc); |
| 212650 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212651 | if( pStr ){ |
| 212652 | z = (const char*)sqlite3_value_text(argv[0]); |
| 212653 | n = sqlite3Strlen30(z); |
| 212654 | if( pStr->zBuf==0 ){ |
| 212655 | jsonStringInit(pStr, ctx); |
| 212656 | jsonAppendChar(pStr, '{'); |
| 212657 | }else if( pStr->nUsed>1 && z!=0 ){ |
| 212658 | jsonAppendChar(pStr, ','); |
| 212659 | } |
| 212660 | pStr->pCtx = ctx; |
| 212661 | if( z!=0 ){ |
| 212662 | jsonAppendString(pStr, z, n); |
| 212663 | jsonAppendChar(pStr, ':'); |
| 212664 | jsonAppendSqlValue(pStr, argv[1]); |
| 212665 | } |
| 212666 | } |
| 212667 | } |
| 212668 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212669 | JsonString *pStr; |
| 212670 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | |
| 213468 | #else |
| 213469 | /* #include "sqlite3.h" */ |
| 213470 | #endif |
| 213471 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213472 | |
| 213473 | /* #include <stddef.h> */ |
| 213474 | |
| 213475 | /* |
| 213476 | ** If building separately, we will need some setup that is normally |
| 213477 | ** found in sqliteInt.h |
| 213478 | */ |
| 213479 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | |
| 213501 | #else |
| 213502 | # define ALWAYS(X) (X) |
| 213503 | # define NEVER(X) (X) |
| 213504 | #endif |
| 213505 | #ifndef offsetof |
| 213506 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 213507 | #endif |
| 213508 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213509 | # define FLEXARRAY |
| 213510 | #else |
| 213511 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | |
| 227818 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227819 | int rc; |
| 227820 | sqlite3 *db = pTab->db; |
| 227821 | Btree *pBt; |
| 227822 | |
| 227823 | UNUSED_PARAMETER(idxStr); |
| 227824 | UNUSED_PARAMETER(argc); |
| 227825 | |
| 227826 | /* Default setting is no rows of result */ |
| 227827 | pCsr->pgno = 1; |
| 227828 | pCsr->mxPgno = 0; |
| 227829 | |
| @@ -231510,18 +231481,19 @@ | |
| 231481 | /* |
| 231482 | ** If the SessionInput object passed as the only argument is a streaming |
| 231483 | ** object and the buffer is full, discard some data to free up space. |
| 231484 | */ |
| 231485 | static void sessionDiscardData(SessionInput *pIn){ |
| 231486 | if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ |
| 231487 | int nMove = pIn->buf.nBuf - pIn->iCurrent; |
| 231488 | assert( nMove>=0 ); |
| 231489 | if( nMove>0 ){ |
| 231490 | memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); |
| 231491 | } |
| 231492 | pIn->buf.nBuf -= pIn->iCurrent; |
| 231493 | pIn->iNext -= pIn->iCurrent; |
| 231494 | pIn->iCurrent = 0; |
| 231495 | pIn->nData = pIn->buf.nBuf; |
| 231496 | } |
| 231497 | } |
| 231498 | |
| 231499 | /* |
| @@ -231871,12 +231843,12 @@ | |
| 231843 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231844 | ** it, or for the two single byte values otherwise. */ |
| 231845 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231846 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231847 | |
| 231848 | p->in.iCurrent = p->in.iNext; |
| 231849 | sessionDiscardData(&p->in); |
| 231850 | |
| 231851 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231852 | if( p->in.iNext>=p->in.nData ){ |
| 231853 | return SQLITE_DONE; |
| 231854 | } |
| @@ -234231,18 +234203,23 @@ | |
| 234203 | */ |
| 234204 | SQLITE_API int sqlite3changegroup_add_change( |
| 234205 | sqlite3_changegroup *pGrp, |
| 234206 | sqlite3_changeset_iter *pIter |
| 234207 | ){ |
| 234208 | int rc = SQLITE_OK; |
| 234209 | |
| 234210 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234211 | || pIter->rc!=SQLITE_OK |
| 234212 | || pIter->bInvert |
| 234213 | ){ |
| 234214 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234215 | rc = SQLITE_ERROR; |
| 234216 | }else{ |
| 234217 | pIter->in.bNoDiscard = 1; |
| 234218 | rc = sessionOneChangeToHash(pGrp, pIter, 0); |
| 234219 | } |
| 234220 | return rc; |
| 234221 | } |
| 234222 | |
| 234223 | /* |
| 234224 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234225 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | |
| 235513 | /* #include "sqlite3ext.h" */ |
| 235514 | SQLITE_EXTENSION_INIT1 |
| 235515 | |
| 235516 | /* #include <string.h> */ |
| 235517 | /* #include <assert.h> */ |
| 235518 | /* #include <stddef.h> */ |
| 235519 | |
| 235520 | #ifndef SQLITE_AMALGAMATION |
| 235521 | |
| 235522 | typedef unsigned char u8; |
| 235523 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | |
| 235573 | |
| 235574 | /* |
| 235575 | ** Macros needed to provide flexible arrays in a portable way |
| 235576 | */ |
| 235577 | #ifndef offsetof |
| 235578 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 235579 | #endif |
| 235580 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235581 | # define FLEXARRAY |
| 235582 | #else |
| 235583 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | |
| 257257 | int nArg, /* Number of args */ |
| 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | ){ |
| 257260 | assert( nArg==0 ); |
| 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); |
| 257263 | } |
| 257264 | |
| 257265 | /* |
| 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | ** |
| 257268 |
+176
-198
| --- extsrc/sqlite3.c | ||
| +++ extsrc/sqlite3.c | ||
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | -** version 3.50.0. By combining all the individual C code files into this | |
| 3 | +** version 3.51.0. By combining all the individual C code files into this | |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | ||
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | -** 336ceeccc6f85bd78f4a26648af7edf9056d with changes in files: | |
| 21 | +** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: | |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | ||
| 463 | 463 | ** |
| 464 | 464 | ** See also: [sqlite3_libversion()], |
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | -#define SQLITE_VERSION "3.50.0" | |
| 469 | -#define SQLITE_VERSION_NUMBER 3050000 | |
| 470 | -#define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" | |
| 468 | +#define SQLITE_VERSION "3.51.0" | |
| 469 | +#define SQLITE_VERSION_NUMBER 3051000 | |
| 470 | +#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| @@ -15174,11 +15174,11 @@ | ||
| 15174 | 15174 | /* |
| 15175 | 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | 15176 | ** ourselves. |
| 15177 | 15177 | */ |
| 15178 | 15178 | #ifndef offsetof |
| 15179 | -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 15179 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 15180 | 15180 | #endif |
| 15181 | 15181 | |
| 15182 | 15182 | /* |
| 15183 | 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | ||
| 17401 | 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | 17402 | #endif |
| 17403 | 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | 17405 | |
| 17406 | -SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); | |
| 17406 | +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); | |
| 17407 | 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | 17410 | |
| 17411 | 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | ||
| 18701 | 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | +#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ | |
| 18706 | 18707 | |
| 18707 | 18708 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18708 | 18709 | |
| 18709 | 18710 | /* |
| 18710 | 18711 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | ||
| 19016 | 19017 | /* |
| 19017 | 19018 | ** An instance of the following structure is passed as the first |
| 19018 | 19019 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19019 | 19020 | ** comparison of the two index keys. |
| 19020 | 19021 | ** |
| 19021 | -** Note that aSortOrder[] and aColl[] have nField+1 slots. There | |
| 19022 | -** are nField slots for the columns of an index then one extra slot | |
| 19023 | -** for the rowid at the end. | |
| 19022 | +** The aSortOrder[] and aColl[] arrays have nAllField slots each. There | |
| 19023 | +** are nKeyField slots for the columns of an index then extra slots | |
| 19024 | +** for the rowid or key at the end. The aSortOrder array is located after | |
| 19025 | +** the aColl[] array. | |
| 19026 | +** | |
| 19027 | +** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL | |
| 19028 | +** to indicate that this object is for use by a preupdate hook. When aSortFlags | |
| 19029 | +** is NULL, then nAllField is uninitialized and no space is allocated for | |
| 19030 | +** aColl[], so those fields may not be used. | |
| 19024 | 19031 | */ |
| 19025 | 19032 | struct KeyInfo { |
| 19026 | 19033 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19027 | 19034 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19028 | 19035 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | ||
| 19030 | 19037 | sqlite3 *db; /* The database connection */ |
| 19031 | 19038 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19032 | 19039 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19033 | 19040 | }; |
| 19034 | 19041 | |
| 19035 | -/* The size (in bytes) of a KeyInfo object with up to N fields */ | |
| 19042 | +/* The size (in bytes) of a KeyInfo object with up to N fields. This includes | |
| 19043 | +** the main body of the KeyInfo object and the aColl[] array of N elements, | |
| 19044 | +** but does not count the memory used to hold aSortFlags[]. */ | |
| 19036 | 19045 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19046 | + | |
| 19047 | +/* The size of a bare KeyInfo with no aColl[] entries */ | |
| 19048 | +#if FLEXARRAY+1 > 1 | |
| 19049 | +# define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) | |
| 19050 | +#else | |
| 19051 | +# define SZ_KEYINFO_0 sizeof(KeyInfo) | |
| 19052 | +#endif | |
| 19037 | 19053 | |
| 19038 | 19054 | /* |
| 19039 | 19055 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19040 | 19056 | */ |
| 19041 | 19057 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | ||
| 19051 | 19067 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19052 | 19068 | ** OP_Column opcode. |
| 19053 | 19069 | ** |
| 19054 | 19070 | ** An instance of this object serves as a "key" for doing a search on |
| 19055 | 19071 | ** an index b+tree. The goal of the search is to find the entry that |
| 19056 | -** is closed to the key described by this object. This object might hold | |
| 19057 | -** just a prefix of the key. The number of fields is given by | |
| 19058 | -** pKeyInfo->nField. | |
| 19072 | +** is closest to the key described by this object. This object might hold | |
| 19073 | +** just a prefix of the key. The number of fields is given by nField. | |
| 19059 | 19074 | ** |
| 19060 | 19075 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19061 | 19076 | ** or greater than a key in the btree, respectively. These are normally |
| 19062 | 19077 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19063 | 19078 | ** is in DESC order. |
| 19064 | 19079 | ** |
| 19065 | 19080 | ** The key comparison functions actually return default_rc when they find |
| 19066 | 19081 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19067 | 19082 | ** multiple entries in the b-tree with the same key (when only looking |
| 19068 | -** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to | |
| 19083 | +** at the first nField elements) then default_rc can be set to -1 to | |
| 19069 | 19084 | ** cause the search to find the last match, or +1 to cause the search to |
| 19070 | 19085 | ** find the first match. |
| 19071 | 19086 | ** |
| 19072 | 19087 | ** The key comparison functions will set eqSeen to true if they ever |
| 19073 | 19088 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | ||
| 19075 | 19090 | ** before the first match or immediately after the last match. The |
| 19076 | 19091 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19077 | 19092 | ** b-tree. |
| 19078 | 19093 | */ |
| 19079 | 19094 | struct UnpackedRecord { |
| 19080 | - KeyInfo *pKeyInfo; /* Collation and sort-order information */ | |
| 19081 | - Mem *aMem; /* Values */ | |
| 19095 | + KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ | |
| 19096 | + Mem *aMem; /* Values for columns of the index */ | |
| 19082 | 19097 | union { |
| 19083 | 19098 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19084 | 19099 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19085 | 19100 | } u; |
| 19086 | 19101 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | ||
| 24132 | 24147 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24133 | 24148 | Mem *aNew; /* Array of new.* values */ |
| 24134 | 24149 | Table *pTab; /* Schema object being updated */ |
| 24135 | 24150 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24136 | 24151 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24137 | - u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ | |
| 24152 | + u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ | |
| 24138 | 24153 | }; |
| 24139 | 24154 | |
| 24140 | 24155 | /* |
| 24141 | 24156 | ** An instance of this object is used to pass an vector of values into |
| 24142 | 24157 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | ||
| 35013 | 35028 | } |
| 35014 | 35029 | |
| 35015 | 35030 | /* |
| 35016 | 35031 | ** Write a single UTF8 character whose value is v into the |
| 35017 | 35032 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35018 | -** least for bytes. Return the number of bytes needed | |
| 35033 | +** least four bytes. Return the number of bytes needed | |
| 35019 | 35034 | ** to encode the new character. |
| 35020 | 35035 | */ |
| 35021 | 35036 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35022 | 35037 | if( v<0x00080 ){ |
| 35023 | 35038 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | ||
| 43872 | 43887 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43873 | 43888 | |
| 43874 | 43889 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43875 | 43890 | ** in the following list than the lock being obtained are already held: |
| 43876 | 43891 | ** |
| 43877 | - ** 1. Checkpointer lock (ofst==1). | |
| 43878 | - ** 2. Write lock (ofst==0). | |
| 43879 | - ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 43892 | + ** 1. Recovery lock (ofst==2). | |
| 43893 | + ** 2. Checkpointer lock (ofst==1). | |
| 43894 | + ** 3. Write lock (ofst==0). | |
| 43895 | + ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 43880 | 43896 | ** |
| 43881 | 43897 | ** In other words, if this is a blocking lock, none of the locks that |
| 43882 | 43898 | ** occur later in the above list than the lock being obtained may be |
| 43883 | 43899 | ** held. |
| 43884 | - ** | |
| 43885 | - ** It is not permitted to block on the RECOVER lock. | |
| 43886 | 43900 | */ |
| 43887 | 43901 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43888 | 43902 | { |
| 43889 | 43903 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43890 | 43904 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43891 | - (ofst!=2) /* not RECOVER */ | |
| 43905 | + (ofst!=2 || lockMask==0) | |
| 43892 | 43906 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43893 | 43907 | && (ofst!=0 || lockMask<3) |
| 43894 | 43908 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43895 | 43909 | )); |
| 43896 | 43910 | } |
| @@ -49851,11 +49865,15 @@ | ||
| 49851 | 49865 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49852 | 49866 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49853 | 49867 | if( res==WAIT_OBJECT_0 ){ |
| 49854 | 49868 | ret = TRUE; |
| 49855 | 49869 | }else if( res==WAIT_TIMEOUT ){ |
| 49870 | +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 | |
| 49856 | 49871 | rc = SQLITE_BUSY_TIMEOUT; |
| 49872 | +#else | |
| 49873 | + rc = SQLITE_BUSY; | |
| 49874 | +#endif | |
| 49857 | 49875 | }else{ |
| 49858 | 49876 | /* Some other error has occurred */ |
| 49859 | 49877 | rc = SQLITE_IOERR_LOCK; |
| 49860 | 49878 | } |
| 49861 | 49879 | |
| @@ -51337,17 +51355,17 @@ | ||
| 51337 | 51355 | int nChar; |
| 51338 | 51356 | LPWSTR zWideFilename; |
| 51339 | 51357 | |
| 51340 | 51358 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51341 | 51359 | && winIsDirSep(zFilename[2])) ){ |
| 51342 | - int nByte; | |
| 51360 | + i64 nByte; | |
| 51343 | 51361 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51344 | 51362 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51345 | - nByte = (int)osCygwin_conv_path(convertflag, | |
| 51363 | + nByte = (i64)osCygwin_conv_path(convertflag, | |
| 51346 | 51364 | zFilename, 0, 0); |
| 51347 | 51365 | if( nByte>0 ){ |
| 51348 | - zConverted = sqlite3MallocZero(nByte+12); | |
| 51366 | + zConverted = sqlite3MallocZero(12+(u64)nByte); | |
| 51349 | 51367 | if ( zConverted==0 ){ |
| 51350 | 51368 | return zConverted; |
| 51351 | 51369 | } |
| 51352 | 51370 | zWideFilename = zConverted; |
| 51353 | 51371 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | ||
| 51662 | 51680 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51663 | 51681 | |
| 51664 | 51682 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51665 | 51683 | ** in the following list than the lock being obtained are already held: |
| 51666 | 51684 | ** |
| 51667 | - ** 1. Checkpointer lock (ofst==1). | |
| 51668 | - ** 2. Write lock (ofst==0). | |
| 51669 | - ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 51685 | + ** 1. Recovery lock (ofst==2). | |
| 51686 | + ** 2. Checkpointer lock (ofst==1). | |
| 51687 | + ** 3. Write lock (ofst==0). | |
| 51688 | + ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). | |
| 51670 | 51689 | ** |
| 51671 | 51690 | ** In other words, if this is a blocking lock, none of the locks that |
| 51672 | 51691 | ** occur later in the above list than the lock being obtained may be |
| 51673 | 51692 | ** held. |
| 51674 | - ** | |
| 51675 | - ** It is not permitted to block on the RECOVER lock. | |
| 51676 | 51693 | */ |
| 51677 | 51694 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51678 | 51695 | { |
| 51679 | 51696 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51680 | 51697 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51681 | - (ofst!=2) /* not RECOVER */ | |
| 51698 | + (ofst!=2 || lockMask==0) | |
| 51682 | 51699 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51683 | 51700 | && (ofst!=0 || lockMask<3) |
| 51684 | 51701 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51685 | 51702 | )); |
| 51686 | 51703 | } |
| @@ -52226,31 +52243,10 @@ | ||
| 52226 | 52243 | ** |
| 52227 | 52244 | ** This division contains the implementation of methods on the |
| 52228 | 52245 | ** sqlite3_vfs object. |
| 52229 | 52246 | */ |
| 52230 | 52247 | |
| 52231 | -#if 0 /* No longer necessary */ | |
| 52232 | -/* | |
| 52233 | -** Convert a filename from whatever the underlying operating system | |
| 52234 | -** supports for filenames into UTF-8. Space to hold the result is | |
| 52235 | -** obtained from malloc and must be freed by the calling function. | |
| 52236 | -*/ | |
| 52237 | -static char *winConvertToUtf8Filename(const void *zFilename){ | |
| 52238 | - char *zConverted = 0; | |
| 52239 | - if( osIsNT() ){ | |
| 52240 | - zConverted = winUnicodeToUtf8(zFilename); | |
| 52241 | - } | |
| 52242 | -#ifdef SQLITE_WIN32_HAS_ANSI | |
| 52243 | - else{ | |
| 52244 | - zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); | |
| 52245 | - } | |
| 52246 | -#endif | |
| 52247 | - /* caller will handle out of memory */ | |
| 52248 | - return zConverted; | |
| 52249 | -} | |
| 52250 | -#endif | |
| 52251 | - | |
| 52252 | 52248 | /* |
| 52253 | 52249 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52254 | 52250 | ** ends with a directory separator character or one was successfully |
| 52255 | 52251 | ** added to it. |
| 52256 | 52252 | */ |
| @@ -52386,46 +52382,10 @@ | ||
| 52386 | 52382 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52387 | 52383 | sqlite3_free(zConverted); |
| 52388 | 52384 | break; |
| 52389 | 52385 | } |
| 52390 | 52386 | sqlite3_free(zConverted); |
| 52391 | -#if 0 /* No longer necessary */ | |
| 52392 | - }else{ | |
| 52393 | - zConverted = sqlite3MallocZero( nMax+1 ); | |
| 52394 | - if( !zConverted ){ | |
| 52395 | - sqlite3_free(zBuf); | |
| 52396 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 52397 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 52398 | - } | |
| 52399 | - if( osCygwin_conv_path( | |
| 52400 | - CCP_POSIX_TO_WIN_W, zDir, | |
| 52401 | - zConverted, nMax+1)<0 ){ | |
| 52402 | - sqlite3_free(zConverted); | |
| 52403 | - sqlite3_free(zBuf); | |
| 52404 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); | |
| 52405 | - return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, | |
| 52406 | - "winGetTempname2", zDir); | |
| 52407 | - } | |
| 52408 | - if( winIsDir(zConverted) ){ | |
| 52409 | - /* At this point, we know the candidate directory exists and should | |
| 52410 | - ** be used. However, we may need to convert the string containing | |
| 52411 | - ** its name into UTF-8 (i.e. if it is UTF-16 right now). | |
| 52412 | - */ | |
| 52413 | - char *zUtf8 = winConvertToUtf8Filename(zConverted); | |
| 52414 | - if( !zUtf8 ){ | |
| 52415 | - sqlite3_free(zConverted); | |
| 52416 | - sqlite3_free(zBuf); | |
| 52417 | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 52418 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 52419 | - } | |
| 52420 | - sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); | |
| 52421 | - sqlite3_free(zUtf8); | |
| 52422 | - sqlite3_free(zConverted); | |
| 52423 | - break; | |
| 52424 | - } | |
| 52425 | - sqlite3_free(zConverted); | |
| 52426 | -#endif /* No longer necessary */ | |
| 52427 | 52387 | } |
| 52428 | 52388 | } |
| 52429 | 52389 | } |
| 52430 | 52390 | #endif |
| 52431 | 52391 | |
| @@ -53320,38 +53280,10 @@ | ||
| 53320 | 53280 | winSimplifyName(zFull); |
| 53321 | 53281 | return rc; |
| 53322 | 53282 | } |
| 53323 | 53283 | } |
| 53324 | 53284 | #endif /* __CYGWIN__ */ |
| 53325 | -#if 0 /* This doesn't work correctly at all! See: | |
| 53326 | - <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> | |
| 53327 | -*/ | |
| 53328 | - SimulateIOError( return SQLITE_ERROR ); | |
| 53329 | - UNUSED_PARAMETER(nFull); | |
| 53330 | - assert( nFull>=pVfs->mxPathname ); | |
| 53331 | - char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); | |
| 53332 | - if( !zOut ){ | |
| 53333 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 53334 | - } | |
| 53335 | - if( osCygwin_conv_path( | |
| 53336 | - CCP_POSIX_TO_WIN_W, | |
| 53337 | - zRelative, zOut, pVfs->mxPathname+1)<0 ){ | |
| 53338 | - sqlite3_free(zOut); | |
| 53339 | - return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, | |
| 53340 | - "winFullPathname2", zRelative); | |
| 53341 | - }else{ | |
| 53342 | - char *zUtf8 = winConvertToUtf8Filename(zOut); | |
| 53343 | - if( !zUtf8 ){ | |
| 53344 | - sqlite3_free(zOut); | |
| 53345 | - return SQLITE_IOERR_NOMEM_BKPT; | |
| 53346 | - } | |
| 53347 | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); | |
| 53348 | - sqlite3_free(zUtf8); | |
| 53349 | - sqlite3_free(zOut); | |
| 53350 | - } | |
| 53351 | - return SQLITE_OK; | |
| 53352 | -#endif | |
| 53353 | 53285 | |
| 53354 | 53286 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53355 | 53287 | SimulateIOError( return SQLITE_ERROR ); |
| 53356 | 53288 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53357 | 53289 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | ||
| 53493 | 53425 | ** Interfaces for opening a shared library, finding entry points |
| 53494 | 53426 | ** within the shared library, and closing the shared library. |
| 53495 | 53427 | */ |
| 53496 | 53428 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53497 | 53429 | HANDLE h; |
| 53498 | -#if 0 /* This doesn't work correctly at all! See: | |
| 53499 | - <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> | |
| 53500 | -*/ | |
| 53501 | - int nFull = pVfs->mxPathname+1; | |
| 53502 | - char *zFull = sqlite3MallocZero( nFull ); | |
| 53503 | - void *zConverted = 0; | |
| 53504 | - if( zFull==0 ){ | |
| 53505 | - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); | |
| 53506 | - return 0; | |
| 53507 | - } | |
| 53508 | - if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ | |
| 53509 | - sqlite3_free(zFull); | |
| 53510 | - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); | |
| 53511 | - return 0; | |
| 53512 | - } | |
| 53513 | - zConverted = winConvertFromUtf8Filename(zFull); | |
| 53514 | - sqlite3_free(zFull); | |
| 53515 | -#else | |
| 53516 | 53430 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53517 | 53431 | UNUSED_PARAMETER(pVfs); |
| 53518 | -#endif | |
| 53519 | 53432 | if( zConverted==0 ){ |
| 53520 | 53433 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53521 | 53434 | return 0; |
| 53522 | 53435 | } |
| 53523 | 53436 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | ||
| 58855 | 58768 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58856 | 58769 | PCache *pPCache; /* Pointer to page cache object */ |
| 58857 | 58770 | #ifndef SQLITE_OMIT_WAL |
| 58858 | 58771 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58859 | 58772 | char *zWal; /* File name for write-ahead log */ |
| 58773 | +#endif | |
| 58774 | +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT | |
| 58775 | + sqlite3 *dbWal; | |
| 58860 | 58776 | #endif |
| 58861 | 58777 | }; |
| 58862 | 58778 | |
| 58863 | 58779 | /* |
| 58864 | 58780 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | ||
| 65737 | 65653 | if( rc==SQLITE_OK ){ |
| 65738 | 65654 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65739 | 65655 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65740 | 65656 | pPager->journalSizeLimit, &pPager->pWal |
| 65741 | 65657 | ); |
| 65658 | +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT | |
| 65659 | + if( rc==SQLITE_OK ){ | |
| 65660 | + sqlite3WalDb(pPager->pWal, pPager->dbWal); | |
| 65661 | + } | |
| 65662 | +#endif | |
| 65742 | 65663 | } |
| 65743 | 65664 | pagerFixMaplimit(pPager); |
| 65744 | 65665 | |
| 65745 | 65666 | return rc; |
| 65746 | 65667 | } |
| @@ -65856,10 +65777,11 @@ | ||
| 65856 | 65777 | /* |
| 65857 | 65778 | ** Set the database handle used by the wal layer to determine if |
| 65858 | 65779 | ** blocking locks are required. |
| 65859 | 65780 | */ |
| 65860 | 65781 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65782 | + pPager->dbWal = db; | |
| 65861 | 65783 | if( pagerUseWal(pPager) ){ |
| 65862 | 65784 | sqlite3WalDb(pPager->pWal, db); |
| 65863 | 65785 | } |
| 65864 | 65786 | } |
| 65865 | 65787 | #endif |
| @@ -69029,11 +68951,10 @@ | ||
| 69029 | 68951 | assert( rc==SQLITE_OK ); |
| 69030 | 68952 | if( pWal->bShmUnreliable==0 ){ |
| 69031 | 68953 | rc = walIndexReadHdr(pWal, pChanged); |
| 69032 | 68954 | } |
| 69033 | 68955 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 69034 | - walDisableBlocking(pWal); | |
| 69035 | 68956 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 69036 | 68957 | rc = SQLITE_BUSY; |
| 69037 | 68958 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 69038 | 68959 | } |
| 69039 | 68960 | #endif |
| @@ -69044,10 +68965,11 @@ | ||
| 69044 | 68965 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 69045 | 68966 | ** would be technically correct. But the race is benign since with |
| 69046 | 68967 | ** WAL_RETRY this routine will be called again and will probably be |
| 69047 | 68968 | ** right on the second iteration. |
| 69048 | 68969 | */ |
| 68970 | + (void)walEnableBlocking(pWal); | |
| 69049 | 68971 | if( pWal->apWiData[0]==0 ){ |
| 69050 | 68972 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 69051 | 68973 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 69052 | 68974 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 69053 | 68975 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | ||
| 69060 | 68982 | rc = WAL_RETRY; |
| 69061 | 68983 | }else if( rc==SQLITE_BUSY ){ |
| 69062 | 68984 | rc = SQLITE_BUSY_RECOVERY; |
| 69063 | 68985 | } |
| 69064 | 68986 | } |
| 68987 | + walDisableBlocking(pWal); | |
| 69065 | 68988 | if( rc!=SQLITE_OK ){ |
| 69066 | 68989 | return rc; |
| 69067 | 68990 | } |
| 69068 | 68991 | else if( pWal->bShmUnreliable ){ |
| 69069 | 68992 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | ||
| 72509 | 72432 | if( pKey ){ |
| 72510 | 72433 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72511 | 72434 | assert( nKey==(i64)(int)nKey ); |
| 72512 | 72435 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72513 | 72436 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72514 | - sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); | |
| 72437 | + sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); | |
| 72515 | 72438 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72516 | 72439 | rc = SQLITE_CORRUPT_BKPT; |
| 72517 | 72440 | }else{ |
| 72518 | 72441 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72519 | 72442 | } |
| @@ -74493,10 +74416,11 @@ | ||
| 74493 | 74416 | removed = 1; |
| 74494 | 74417 | } |
| 74495 | 74418 | sqlite3_mutex_leave(pMainMtx); |
| 74496 | 74419 | return removed; |
| 74497 | 74420 | #else |
| 74421 | + UNUSED_PARAMETER( pBt ); | |
| 74498 | 74422 | return 1; |
| 74499 | 74423 | #endif |
| 74500 | 74424 | } |
| 74501 | 74425 | |
| 74502 | 74426 | /* |
| @@ -75334,10 +75258,17 @@ | ||
| 75334 | 75258 | |
| 75335 | 75259 | if( rc!=SQLITE_OK ){ |
| 75336 | 75260 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75337 | 75261 | unlockBtreeIfUnused(pBt); |
| 75338 | 75262 | } |
| 75263 | +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) | |
| 75264 | + if( rc==SQLITE_BUSY_TIMEOUT ){ | |
| 75265 | + /* If a blocking lock timed out, break out of the loop here so that | |
| 75266 | + ** the busy-handler is not invoked. */ | |
| 75267 | + break; | |
| 75268 | + } | |
| 75269 | +#endif | |
| 75339 | 75270 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75340 | 75271 | btreeInvokeBusyHandler(pBt) ); |
| 75341 | 75272 | sqlite3PagerWalDb(pPager, 0); |
| 75342 | 75273 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75343 | 75274 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | ||
| 82954 | 82885 | ** btree as the argument handle holds an exclusive lock on the |
| 82955 | 82886 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82956 | 82887 | */ |
| 82957 | 82888 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82958 | 82889 | int rc; |
| 82890 | + UNUSED_PARAMETER(p); /* only used in DEBUG builds */ | |
| 82959 | 82891 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82960 | 82892 | sqlite3BtreeEnter(p); |
| 82961 | 82893 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82962 | 82894 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82963 | 82895 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | ||
| 90174 | 90106 | } |
| 90175 | 90107 | } |
| 90176 | 90108 | return; |
| 90177 | 90109 | } |
| 90178 | 90110 | /* |
| 90179 | -** This routine is used to allocate sufficient space for an UnpackedRecord | |
| 90180 | -** structure large enough to be used with sqlite3VdbeRecordUnpack() if | |
| 90181 | -** the first argument is a pointer to KeyInfo structure pKeyInfo. | |
| 90182 | -** | |
| 90183 | -** The space is either allocated using sqlite3DbMallocRaw() or from within | |
| 90184 | -** the unaligned buffer passed via the second and third arguments (presumably | |
| 90185 | -** stack space). If the former, then *ppFree is set to a pointer that should | |
| 90186 | -** be eventually freed by the caller using sqlite3DbFree(). Or, if the | |
| 90187 | -** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL | |
| 90188 | -** before returning. | |
| 90189 | -** | |
| 90190 | -** If an OOM error occurs, NULL is returned. | |
| 90111 | +** Allocate sufficient space for an UnpackedRecord structure large enough | |
| 90112 | +** to hold a decoded index record for pKeyInfo. | |
| 90113 | +** | |
| 90114 | +** The space is allocated using sqlite3DbMallocRaw(). If an OOM error | |
| 90115 | +** occurs, NULL is returned. | |
| 90191 | 90116 | */ |
| 90192 | 90117 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90193 | 90118 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90194 | 90119 | ){ |
| 90195 | 90120 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90196 | - int nByte; /* Number of bytes required for *p */ | |
| 90121 | + u64 nByte; /* Number of bytes required for *p */ | |
| 90197 | 90122 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90198 | 90123 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90199 | 90124 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90200 | 90125 | if( !p ) return 0; |
| 90201 | 90126 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90202 | - assert( pKeyInfo->aSortFlags!=0 ); | |
| 90203 | 90127 | p->pKeyInfo = pKeyInfo; |
| 90204 | 90128 | p->nField = pKeyInfo->nKeyField + 1; |
| 90205 | 90129 | return p; |
| 90206 | 90130 | } |
| 90207 | 90131 | |
| @@ -90209,11 +90133,10 @@ | ||
| 90209 | 90133 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90210 | 90134 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90211 | 90135 | ** contents of the decoded record. |
| 90212 | 90136 | */ |
| 90213 | 90137 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90214 | - KeyInfo *pKeyInfo, /* Information about the record format */ | |
| 90215 | 90138 | int nKey, /* Size of the binary record */ |
| 90216 | 90139 | const void *pKey, /* The binary record */ |
| 90217 | 90140 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90218 | 90141 | ){ |
| 90219 | 90142 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | ||
| 90220 | 90143 | u32 d; |
| 90221 | 90144 | u32 idx; /* Offset in aKey[] to read from */ |
| 90222 | 90145 | u16 u; /* Unsigned loop counter */ |
| 90223 | 90146 | u32 szHdr; |
| 90224 | 90147 | Mem *pMem = p->aMem; |
| 90148 | + KeyInfo *pKeyInfo = p->pKeyInfo; | |
| 90225 | 90149 | |
| 90226 | 90150 | p->default_rc = 0; |
| 90227 | 90151 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90228 | 90152 | idx = getVarint32(aKey, szHdr); |
| 90229 | 90153 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | ||
| 90247 | 90171 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90248 | 90172 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90249 | 90173 | ** warnings from MSAN. */ |
| 90250 | 90174 | sqlite3VdbeMemSetNull(pMem-1); |
| 90251 | 90175 | } |
| 90176 | + testcase( u == pKeyInfo->nKeyField + 1 ); | |
| 90177 | + testcase( u < pKeyInfo->nKeyField + 1 ); | |
| 90252 | 90178 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90253 | 90179 | p->nField = u; |
| 90254 | 90180 | } |
| 90255 | 90181 | |
| 90256 | 90182 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | ||
| 91106 | 91032 | ** is an integer. |
| 91107 | 91033 | ** |
| 91108 | 91034 | ** The easiest way to enforce this limit is to consider only records with |
| 91109 | 91035 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91110 | 91036 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91037 | + assert( p->pKeyInfo->aSortFlags!=0 ); | |
| 91111 | 91038 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91112 | 91039 | int flags = p->aMem[0].flags; |
| 91113 | 91040 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91114 | 91041 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91115 | 91042 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | ||
| 91464 | 91391 | ){ |
| 91465 | 91392 | sqlite3 *db = v->db; |
| 91466 | 91393 | i64 iKey2; |
| 91467 | 91394 | PreUpdate preupdate; |
| 91468 | 91395 | const char *zTbl = pTab->zName; |
| 91469 | - static const u8 fakeSortOrder = 0; | |
| 91470 | 91396 | #ifdef SQLITE_DEBUG |
| 91471 | 91397 | int nRealCol; |
| 91472 | 91398 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91473 | 91399 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91474 | 91400 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | ||
| 91503 | 91429 | preupdate.iNewReg = iReg; |
| 91504 | 91430 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91505 | 91431 | preupdate.pKeyinfo->db = db; |
| 91506 | 91432 | preupdate.pKeyinfo->enc = ENC(db); |
| 91507 | 91433 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91508 | - preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; | |
| 91434 | + preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ | |
| 91509 | 91435 | preupdate.iKey1 = iKey1; |
| 91510 | 91436 | preupdate.iKey2 = iKey2; |
| 91511 | 91437 | preupdate.pTab = pTab; |
| 91512 | 91438 | preupdate.iBlobWrite = iBlobWrite; |
| 91513 | 91439 | |
| @@ -93700,11 +93626,11 @@ | ||
| 93700 | 93626 | UnpackedRecord *pRet; /* Return value */ |
| 93701 | 93627 | |
| 93702 | 93628 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93703 | 93629 | if( pRet ){ |
| 93704 | 93630 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93705 | - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); | |
| 93631 | + sqlite3VdbeRecordUnpack(nKey, pKey, pRet); | |
| 93706 | 93632 | } |
| 93707 | 93633 | return pRet; |
| 93708 | 93634 | } |
| 93709 | 93635 | |
| 93710 | 93636 | /* |
| @@ -96893,10 +96819,11 @@ | ||
| 96893 | 96819 | } |
| 96894 | 96820 | n = pOp->p3; |
| 96895 | 96821 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96896 | 96822 | assert( n>0 ); |
| 96897 | 96823 | assert( pKeyInfo!=0 ); |
| 96824 | + assert( pKeyInfo->aSortFlags!=0 ); | |
| 96898 | 96825 | p1 = pOp->p1; |
| 96899 | 96826 | p2 = pOp->p2; |
| 96900 | 96827 | #ifdef SQLITE_DEBUG |
| 96901 | 96828 | if( aPermute ){ |
| 96902 | 96829 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | ||
| 99766 | 99693 | rc = ExpandBlob(r.aMem); |
| 99767 | 99694 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99768 | 99695 | if( rc ) goto no_mem; |
| 99769 | 99696 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99770 | 99697 | if( pIdxKey==0 ) goto no_mem; |
| 99771 | - sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); | |
| 99698 | + sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); | |
| 99772 | 99699 | pIdxKey->default_rc = 0; |
| 99773 | 99700 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99774 | 99701 | sqlite3DbFreeNN(db, pIdxKey); |
| 99775 | 99702 | } |
| 99776 | 99703 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | ||
| 104942 | 104869 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104943 | 104870 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104944 | 104871 | ){ |
| 104945 | 104872 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104946 | 104873 | if( *pbKey2Cached==0 ){ |
| 104947 | - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); | |
| 104874 | + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); | |
| 104948 | 104875 | *pbKey2Cached = 1; |
| 104949 | 104876 | } |
| 104950 | 104877 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104951 | 104878 | } |
| 104952 | 104879 | |
| @@ -104969,11 +104896,11 @@ | ||
| 104969 | 104896 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104970 | 104897 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104971 | 104898 | ){ |
| 104972 | 104899 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104973 | 104900 | if( !*pbKey2Cached ){ |
| 104974 | - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); | |
| 104901 | + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); | |
| 104975 | 104902 | *pbKey2Cached = 1; |
| 104976 | 104903 | } |
| 104977 | 104904 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104978 | 104905 | } |
| 104979 | 104906 | |
| @@ -105009,10 +104936,11 @@ | ||
| 105009 | 104936 | res = vdbeSorterCompareTail( |
| 105010 | 104937 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105011 | 104938 | ); |
| 105012 | 104939 | } |
| 105013 | 104940 | }else{ |
| 104941 | + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); | |
| 105014 | 104942 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 105015 | 104943 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 105016 | 104944 | res = res * -1; |
| 105017 | 104945 | } |
| 105018 | 104946 | } |
| @@ -105072,10 +105000,11 @@ | ||
| 105072 | 105000 | }else{ |
| 105073 | 105001 | if( *v2 & 0x80 ) res = +1; |
| 105074 | 105002 | } |
| 105075 | 105003 | } |
| 105076 | 105004 | |
| 105005 | + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); | |
| 105077 | 105006 | if( res==0 ){ |
| 105078 | 105007 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105079 | 105008 | res = vdbeSorterCompareTail( |
| 105080 | 105009 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105081 | 105010 | ); |
| @@ -105145,11 +105074,12 @@ | ||
| 105145 | 105074 | assert( pCsr->pKeyInfo ); |
| 105146 | 105075 | assert( !pCsr->isEphemeral ); |
| 105147 | 105076 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105148 | 105077 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105149 | 105078 | < 0x7fffffff ); |
| 105150 | - szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); | |
| 105079 | + assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); | |
| 105080 | + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); | |
| 105151 | 105081 | sz = SZ_VDBESORTER(nWorker+1); |
| 105152 | 105082 | |
| 105153 | 105083 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105154 | 105084 | pCsr->uc.pSorter = pSorter; |
| 105155 | 105085 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | ||
| 105159 | 105089 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105160 | 105090 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105161 | 105091 | pKeyInfo->db = 0; |
| 105162 | 105092 | if( nField && nWorker==0 ){ |
| 105163 | 105093 | pKeyInfo->nKeyField = nField; |
| 105094 | + assert( nField<=pCsr->pKeyInfo->nAllField ); | |
| 105164 | 105095 | } |
| 105096 | + /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, | |
| 105097 | + ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives | |
| 105098 | + ** longer that pSorter. */ | |
| 105099 | + assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); | |
| 105165 | 105100 | sqlite3BtreeEnter(pBt); |
| 105166 | 105101 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105167 | 105102 | sqlite3BtreeLeave(pBt); |
| 105168 | 105103 | pSorter->nTask = nWorker + 1; |
| 105169 | 105104 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | ||
| 106939 | 106874 | r2->nField = nKeyCol; |
| 106940 | 106875 | } |
| 106941 | 106876 | assert( r2->nField==nKeyCol ); |
| 106942 | 106877 | |
| 106943 | 106878 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106944 | - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); | |
| 106879 | + sqlite3VdbeRecordUnpack(nKey, pKey, r2); | |
| 106945 | 106880 | for(i=0; i<nKeyCol; i++){ |
| 106946 | 106881 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106947 | 106882 | *pRes = -1; |
| 106948 | 106883 | return SQLITE_OK; |
| 106949 | 106884 | } |
| @@ -110495,11 +110430,13 @@ | ||
| 110495 | 110430 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110496 | 110431 | return sqlite3ExprAffinity( |
| 110497 | 110432 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110498 | 110433 | ); |
| 110499 | 110434 | } |
| 110500 | - if( op==TK_VECTOR ){ | |
| 110435 | + if( op==TK_VECTOR | |
| 110436 | + || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) | |
| 110437 | + ){ | |
| 110501 | 110438 | assert( ExprUseXList(pExpr) ); |
| 110502 | 110439 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110503 | 110440 | } |
| 110504 | 110441 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110505 | 110442 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | ||
| 110688 | 110625 | } |
| 110689 | 110626 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110690 | 110627 | p = p->pLeft; |
| 110691 | 110628 | continue; |
| 110692 | 110629 | } |
| 110693 | - if( op==TK_VECTOR ){ | |
| 110630 | + if( op==TK_VECTOR | |
| 110631 | + || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) | |
| 110632 | + ){ | |
| 110694 | 110633 | assert( ExprUseXList(p) ); |
| 110695 | 110634 | p = p->x.pList->a[0].pExpr; |
| 110696 | 110635 | continue; |
| 110697 | 110636 | } |
| 110698 | 110637 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | ||
| 119025 | 118964 | }else{ |
| 119026 | 118965 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 119027 | 118966 | } |
| 119028 | 118967 | |
| 119029 | 118968 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 119030 | - zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); | |
| 118969 | + zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); | |
| 119031 | 118970 | }else{ |
| 119032 | 118971 | assert( nSql>0 ); |
| 119033 | - zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); | |
| 118972 | + zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); | |
| 119034 | 118973 | if( zOut ){ |
| 119035 | 118974 | zBuf1 = &zOut[nSql*2+1]; |
| 119036 | 118975 | zBuf2 = &zOut[nSql*4+2]; |
| 119037 | 118976 | } |
| 119038 | 118977 | } |
| @@ -138772,10 +138711,12 @@ | ||
| 138772 | 138711 | /* Version 3.43.0 and later */ |
| 138773 | 138712 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138774 | 138713 | /* Version 3.44.0 and later */ |
| 138775 | 138714 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138776 | 138715 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138716 | + /* Version 3.50.0 and later */ | |
| 138717 | + int (*setlk_timeout)(sqlite3*,int,int); | |
| 138777 | 138718 | }; |
| 138778 | 138719 | |
| 138779 | 138720 | /* |
| 138780 | 138721 | ** This is the function signature used for all extension entry points. It |
| 138781 | 138722 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | ||
| 139105 | 139046 | /* Version 3.43.0 and later */ |
| 139106 | 139047 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139107 | 139048 | /* Version 3.44.0 and later */ |
| 139108 | 139049 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139109 | 139050 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139051 | +/* Version 3.50.0 and later */ | |
| 139052 | +#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout | |
| 139110 | 139053 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139111 | 139054 | |
| 139112 | 139055 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139113 | 139056 | /* This case when the file really is being compiled as a loadable |
| 139114 | 139057 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | ||
| 139626 | 139569 | sqlite3_is_interrupted, |
| 139627 | 139570 | /* Version 3.43.0 and later */ |
| 139628 | 139571 | sqlite3_stmt_explain, |
| 139629 | 139572 | /* Version 3.44.0 and later */ |
| 139630 | 139573 | sqlite3_get_clientdata, |
| 139631 | - sqlite3_set_clientdata | |
| 139574 | + sqlite3_set_clientdata, | |
| 139575 | + /* Version 3.50.0 and later */ | |
| 139576 | + sqlite3_setlk_timeout | |
| 139632 | 139577 | }; |
| 139633 | 139578 | |
| 139634 | 139579 | /* True if x is the directory separator character |
| 139635 | 139580 | */ |
| 139636 | 139581 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | ||
| 145464 | 145409 | "not present in both tables", zName); |
| 145465 | 145410 | return 1; |
| 145466 | 145411 | } |
| 145467 | 145412 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145468 | 145413 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145469 | - if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ | |
| 145414 | + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ | |
| 145470 | 145415 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145471 | 145416 | ** JOINs. If only a single table on the left side of this join |
| 145472 | 145417 | ** contains the zName column, then this branch is a no-op. |
| 145473 | 145418 | ** But if there are two or more tables on the left side |
| 145474 | 145419 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | ||
| 145480 | 145425 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145481 | 145426 | ** adding a new error so as to not break legacy applications. |
| 145482 | 145427 | */ |
| 145483 | 145428 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145484 | 145429 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145430 | + assert( pE1!=0 ); | |
| 145431 | + ExprSetProperty(pE1, EP_CanBeNull); | |
| 145485 | 145432 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145486 | 145433 | pRight->fg.isSynthUsing)!=0 ){ |
| 145487 | 145434 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145488 | 145435 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145489 | 145436 | ){ |
| @@ -145496,11 +145443,17 @@ | ||
| 145496 | 145443 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145497 | 145444 | } |
| 145498 | 145445 | if( pFuncArgs ){ |
| 145499 | 145446 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145500 | 145447 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145448 | + if( pE1 ){ | |
| 145449 | + pE1->affExpr = SQLITE_AFF_DEFER; | |
| 145450 | + } | |
| 145501 | 145451 | } |
| 145452 | + }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ | |
| 145453 | + assert( pE1!=0 ); | |
| 145454 | + ExprSetProperty(pE1, EP_CanBeNull); | |
| 145502 | 145455 | } |
| 145503 | 145456 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145504 | 145457 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145505 | 145458 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145506 | 145459 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | ||
| 146973 | 146926 | #else |
| 146974 | 146927 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146975 | 146928 | #endif |
| 146976 | 146929 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146977 | 146930 | } |
| 146931 | +#else | |
| 146932 | + UNUSED_PARAMETER(pParse); | |
| 146933 | + UNUSED_PARAMETER(pTabList); | |
| 146934 | + UNUSED_PARAMETER(pEList); | |
| 146978 | 146935 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146979 | 146936 | } |
| 146980 | 146937 | |
| 146981 | 146938 | |
| 146982 | 146939 | /* |
| @@ -149104,13 +149061,13 @@ | ||
| 149104 | 149061 | ** other than the one FROM-clause subquery that is a candidate |
| 149105 | 149062 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149106 | 149063 | ** from 2015-02-09.) |
| 149107 | 149064 | ** |
| 149108 | 149065 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149109 | -** (3a) the subquery may not be a join and | |
| 149110 | -** (3b) the FROM clause of the subquery may not contain a virtual | |
| 149111 | -** table and | |
| 149066 | +** (3a) the subquery may not be a join | |
| 149067 | +** (**) Was (3b): "the FROM clause of the subquery may not contain | |
| 149068 | +** a virtual table" | |
| 149112 | 149069 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149113 | 149070 | ** is now managed correctly |
| 149114 | 149071 | ** (3d) the outer query may not be DISTINCT. |
| 149115 | 149072 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149116 | 149073 | ** |
| @@ -149322,11 +149279,11 @@ | ||
| 149322 | 149279 | ** |
| 149323 | 149280 | ** See also tickets #306, #350, and #3300. |
| 149324 | 149281 | */ |
| 149325 | 149282 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149326 | 149283 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149327 | - || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ | |
| 149284 | + /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ | |
| 149328 | 149285 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149329 | 149286 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149330 | 149287 | ){ |
| 149331 | 149288 | return 0; |
| 149332 | 149289 | } |
| @@ -153366,10 +153323,14 @@ | ||
| 153366 | 153323 | } |
| 153367 | 153324 | |
| 153368 | 153325 | if( iOrderByCol ){ |
| 153369 | 153326 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153370 | 153327 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153328 | + while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ | |
| 153329 | + pX = pBase->pLeft; | |
| 153330 | + pBase = sqlite3ExprSkipCollateAndLikely(pX); | |
| 153331 | + } | |
| 153371 | 153332 | if( ALWAYS(pBase!=0) |
| 153372 | 153333 | && pBase->op!=TK_AGG_COLUMN |
| 153373 | 153334 | && pBase->op!=TK_REGISTER |
| 153374 | 153335 | ){ |
| 153375 | 153336 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | ||
| 157343 | 157304 | saved_flags = db->flags; |
| 157344 | 157305 | saved_mDbFlags = db->mDbFlags; |
| 157345 | 157306 | saved_nChange = db->nChange; |
| 157346 | 157307 | saved_nTotalChange = db->nTotalChange; |
| 157347 | 157308 | saved_mTrace = db->mTrace; |
| 157348 | - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; | |
| 157309 | + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments | |
| 157310 | + | SQLITE_AttachCreate | SQLITE_AttachWrite; | |
| 157349 | 157311 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157350 | 157312 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157351 | 157313 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157352 | 157314 | db->mTrace = 0; |
| 157353 | 157315 | |
| @@ -161818,16 +161780,17 @@ | ||
| 161818 | 161780 | } |
| 161819 | 161781 | |
| 161820 | 161782 | if( pLevel->iLeftJoin==0 ){ |
| 161821 | 161783 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161822 | 161784 | ** terms from the query that must be true due to the WHERE clause of |
| 161823 | - ** the partial index. | |
| 161785 | + ** the partial index. This optimization does not work on an outer join, | |
| 161786 | + ** as shown by: | |
| 161824 | 161787 | ** |
| 161825 | - ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work | |
| 161826 | - ** for a LEFT JOIN. | |
| 161788 | + ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) | |
| 161789 | + ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) | |
| 161827 | 161790 | */ |
| 161828 | - if( pIdx->pPartIdxWhere ){ | |
| 161791 | + if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ | |
| 161829 | 161792 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161830 | 161793 | } |
| 161831 | 161794 | }else{ |
| 161832 | 161795 | testcase( pIdx->pPartIdxWhere ); |
| 161833 | 161796 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | ||
| 168080 | 168043 | Expr *pExpr; |
| 168081 | 168044 | pExpr = pTerm->pExpr; |
| 168082 | 168045 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168083 | 168046 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168084 | 168047 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168048 | + && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) | |
| 168085 | 168049 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168086 | 168050 | ){ |
| 168087 | 168051 | return 1; |
| 168088 | 168052 | } |
| 168089 | 168053 | } |
| @@ -188883,11 +188847,11 @@ | ||
| 188883 | 188847 | |
| 188884 | 188848 | /* |
| 188885 | 188849 | ** Macros needed to provide flexible arrays in a portable way |
| 188886 | 188850 | */ |
| 188887 | 188851 | #ifndef offsetof |
| 188888 | -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 188852 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 188889 | 188853 | #endif |
| 188890 | 188854 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188891 | 188855 | # define FLEXARRAY |
| 188892 | 188856 | #else |
| 188893 | 188857 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | ||
| 209116 | 209080 | nExtra = 0; |
| 209117 | 209081 | }else if( szType==12 ){ |
| 209118 | 209082 | nExtra = 1; |
| 209119 | 209083 | }else if( szType==13 ){ |
| 209120 | 209084 | nExtra = 2; |
| 209121 | - }else{ | |
| 209085 | + }else if( szType==14 ){ | |
| 209122 | 209086 | nExtra = 4; |
| 209087 | + }else{ | |
| 209088 | + nExtra = 8; | |
| 209123 | 209089 | } |
| 209124 | 209090 | if( szPayload<=11 ){ |
| 209125 | 209091 | nNeeded = 0; |
| 209126 | 209092 | }else if( szPayload<=0xff ){ |
| 209127 | 209093 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | ||
| 212681 | 212647 | const char *z; |
| 212682 | 212648 | u32 n; |
| 212683 | 212649 | UNUSED_PARAMETER(argc); |
| 212684 | 212650 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212685 | 212651 | if( pStr ){ |
| 212652 | + z = (const char*)sqlite3_value_text(argv[0]); | |
| 212653 | + n = sqlite3Strlen30(z); | |
| 212686 | 212654 | if( pStr->zBuf==0 ){ |
| 212687 | 212655 | jsonStringInit(pStr, ctx); |
| 212688 | 212656 | jsonAppendChar(pStr, '{'); |
| 212689 | - }else if( pStr->nUsed>1 ){ | |
| 212657 | + }else if( pStr->nUsed>1 && z!=0 ){ | |
| 212690 | 212658 | jsonAppendChar(pStr, ','); |
| 212691 | 212659 | } |
| 212692 | 212660 | pStr->pCtx = ctx; |
| 212693 | - z = (const char*)sqlite3_value_text(argv[0]); | |
| 212694 | - n = sqlite3Strlen30(z); | |
| 212695 | - jsonAppendString(pStr, z, n); | |
| 212696 | - jsonAppendChar(pStr, ':'); | |
| 212697 | - jsonAppendSqlValue(pStr, argv[1]); | |
| 212661 | + if( z!=0 ){ | |
| 212662 | + jsonAppendString(pStr, z, n); | |
| 212663 | + jsonAppendChar(pStr, ':'); | |
| 212664 | + jsonAppendSqlValue(pStr, argv[1]); | |
| 212665 | + } | |
| 212698 | 212666 | } |
| 212699 | 212667 | } |
| 212700 | 212668 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212701 | 212669 | JsonString *pStr; |
| 212702 | 212670 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | ||
| 213500 | 213468 | #else |
| 213501 | 213469 | /* #include "sqlite3.h" */ |
| 213502 | 213470 | #endif |
| 213503 | 213471 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213504 | 213472 | |
| 213473 | +/* #include <stddef.h> */ | |
| 213474 | + | |
| 213505 | 213475 | /* |
| 213506 | 213476 | ** If building separately, we will need some setup that is normally |
| 213507 | 213477 | ** found in sqliteInt.h |
| 213508 | 213478 | */ |
| 213509 | 213479 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | ||
| 213531 | 213501 | #else |
| 213532 | 213502 | # define ALWAYS(X) (X) |
| 213533 | 213503 | # define NEVER(X) (X) |
| 213534 | 213504 | #endif |
| 213535 | 213505 | #ifndef offsetof |
| 213536 | -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 213506 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 213537 | 213507 | #endif |
| 213538 | 213508 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213539 | 213509 | # define FLEXARRAY |
| 213540 | 213510 | #else |
| 213541 | 213511 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | ||
| 227848 | 227818 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227849 | 227819 | int rc; |
| 227850 | 227820 | sqlite3 *db = pTab->db; |
| 227851 | 227821 | Btree *pBt; |
| 227852 | 227822 | |
| 227853 | - (void)idxStr; | |
| 227823 | + UNUSED_PARAMETER(idxStr); | |
| 227824 | + UNUSED_PARAMETER(argc); | |
| 227854 | 227825 | |
| 227855 | 227826 | /* Default setting is no rows of result */ |
| 227856 | 227827 | pCsr->pgno = 1; |
| 227857 | 227828 | pCsr->mxPgno = 0; |
| 227858 | 227829 | |
| @@ -231510,18 +231481,19 @@ | ||
| 231510 | 231481 | /* |
| 231511 | 231482 | ** If the SessionInput object passed as the only argument is a streaming |
| 231512 | 231483 | ** object and the buffer is full, discard some data to free up space. |
| 231513 | 231484 | */ |
| 231514 | 231485 | static void sessionDiscardData(SessionInput *pIn){ |
| 231515 | - if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ | |
| 231516 | - int nMove = pIn->buf.nBuf - pIn->iNext; | |
| 231486 | + if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ | |
| 231487 | + int nMove = pIn->buf.nBuf - pIn->iCurrent; | |
| 231517 | 231488 | assert( nMove>=0 ); |
| 231518 | 231489 | if( nMove>0 ){ |
| 231519 | - memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); | |
| 231490 | + memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); | |
| 231520 | 231491 | } |
| 231521 | - pIn->buf.nBuf -= pIn->iNext; | |
| 231522 | - pIn->iNext = 0; | |
| 231492 | + pIn->buf.nBuf -= pIn->iCurrent; | |
| 231493 | + pIn->iNext -= pIn->iCurrent; | |
| 231494 | + pIn->iCurrent = 0; | |
| 231523 | 231495 | pIn->nData = pIn->buf.nBuf; |
| 231524 | 231496 | } |
| 231525 | 231497 | } |
| 231526 | 231498 | |
| 231527 | 231499 | /* |
| @@ -231871,12 +231843,12 @@ | ||
| 231871 | 231843 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231872 | 231844 | ** it, or for the two single byte values otherwise. */ |
| 231873 | 231845 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231874 | 231846 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231875 | 231847 | |
| 231876 | - sessionDiscardData(&p->in); | |
| 231877 | 231848 | p->in.iCurrent = p->in.iNext; |
| 231849 | + sessionDiscardData(&p->in); | |
| 231878 | 231850 | |
| 231879 | 231851 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231880 | 231852 | if( p->in.iNext>=p->in.nData ){ |
| 231881 | 231853 | return SQLITE_DONE; |
| 231882 | 231854 | } |
| @@ -234231,18 +234203,23 @@ | ||
| 234231 | 234203 | */ |
| 234232 | 234204 | SQLITE_API int sqlite3changegroup_add_change( |
| 234233 | 234205 | sqlite3_changegroup *pGrp, |
| 234234 | 234206 | sqlite3_changeset_iter *pIter |
| 234235 | 234207 | ){ |
| 234208 | + int rc = SQLITE_OK; | |
| 234209 | + | |
| 234236 | 234210 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234237 | 234211 | || pIter->rc!=SQLITE_OK |
| 234238 | 234212 | || pIter->bInvert |
| 234239 | 234213 | ){ |
| 234240 | 234214 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234241 | - return SQLITE_ERROR; | |
| 234215 | + rc = SQLITE_ERROR; | |
| 234216 | + }else{ | |
| 234217 | + pIter->in.bNoDiscard = 1; | |
| 234218 | + rc = sessionOneChangeToHash(pGrp, pIter, 0); | |
| 234242 | 234219 | } |
| 234243 | - return sessionOneChangeToHash(pGrp, pIter, 0); | |
| 234220 | + return rc; | |
| 234244 | 234221 | } |
| 234245 | 234222 | |
| 234246 | 234223 | /* |
| 234247 | 234224 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234248 | 234225 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | ||
| 235536 | 235513 | /* #include "sqlite3ext.h" */ |
| 235537 | 235514 | SQLITE_EXTENSION_INIT1 |
| 235538 | 235515 | |
| 235539 | 235516 | /* #include <string.h> */ |
| 235540 | 235517 | /* #include <assert.h> */ |
| 235518 | +/* #include <stddef.h> */ | |
| 235541 | 235519 | |
| 235542 | 235520 | #ifndef SQLITE_AMALGAMATION |
| 235543 | 235521 | |
| 235544 | 235522 | typedef unsigned char u8; |
| 235545 | 235523 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | ||
| 235595 | 235573 | |
| 235596 | 235574 | /* |
| 235597 | 235575 | ** Macros needed to provide flexible arrays in a portable way |
| 235598 | 235576 | */ |
| 235599 | 235577 | #ifndef offsetof |
| 235600 | -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) | |
| 235578 | +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) | |
| 235601 | 235579 | #endif |
| 235602 | 235580 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235603 | 235581 | # define FLEXARRAY |
| 235604 | 235582 | #else |
| 235605 | 235583 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | ||
| 257279 | 257257 | int nArg, /* Number of args */ |
| 257280 | 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257281 | 257259 | ){ |
| 257282 | 257260 | assert( nArg==0 ); |
| 257283 | 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257284 | - sqlite3_result_text(pCtx, "fts5: 2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349", -1, SQLITE_TRANSIENT); | |
| 257262 | + sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); | |
| 257285 | 257263 | } |
| 257286 | 257264 | |
| 257287 | 257265 | /* |
| 257288 | 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257289 | 257267 | ** |
| 257290 | 257268 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.50.0. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** 336ceeccc6f85bd78f4a26648af7edf9056d with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | |
| 463 | ** |
| 464 | ** See also: [sqlite3_libversion()], |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.50.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3050000 |
| 470 | #define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -15174,11 +15174,11 @@ | |
| 15174 | /* |
| 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | ** ourselves. |
| 15177 | */ |
| 15178 | #ifndef offsetof |
| 15179 | #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 15180 | #endif |
| 15181 | |
| 15182 | /* |
| 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | |
| 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | #endif |
| 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | |
| 17406 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | |
| 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | |
| 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | |
| 18707 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18708 | |
| 18709 | /* |
| 18710 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | |
| 19016 | /* |
| 19017 | ** An instance of the following structure is passed as the first |
| 19018 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19019 | ** comparison of the two index keys. |
| 19020 | ** |
| 19021 | ** Note that aSortOrder[] and aColl[] have nField+1 slots. There |
| 19022 | ** are nField slots for the columns of an index then one extra slot |
| 19023 | ** for the rowid at the end. |
| 19024 | */ |
| 19025 | struct KeyInfo { |
| 19026 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19027 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19028 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | |
| 19030 | sqlite3 *db; /* The database connection */ |
| 19031 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19032 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19033 | }; |
| 19034 | |
| 19035 | /* The size (in bytes) of a KeyInfo object with up to N fields */ |
| 19036 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19037 | |
| 19038 | /* |
| 19039 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19040 | */ |
| 19041 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | |
| 19051 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19052 | ** OP_Column opcode. |
| 19053 | ** |
| 19054 | ** An instance of this object serves as a "key" for doing a search on |
| 19055 | ** an index b+tree. The goal of the search is to find the entry that |
| 19056 | ** is closed to the key described by this object. This object might hold |
| 19057 | ** just a prefix of the key. The number of fields is given by |
| 19058 | ** pKeyInfo->nField. |
| 19059 | ** |
| 19060 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19061 | ** or greater than a key in the btree, respectively. These are normally |
| 19062 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19063 | ** is in DESC order. |
| 19064 | ** |
| 19065 | ** The key comparison functions actually return default_rc when they find |
| 19066 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19067 | ** multiple entries in the b-tree with the same key (when only looking |
| 19068 | ** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to |
| 19069 | ** cause the search to find the last match, or +1 to cause the search to |
| 19070 | ** find the first match. |
| 19071 | ** |
| 19072 | ** The key comparison functions will set eqSeen to true if they ever |
| 19073 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | |
| 19075 | ** before the first match or immediately after the last match. The |
| 19076 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19077 | ** b-tree. |
| 19078 | */ |
| 19079 | struct UnpackedRecord { |
| 19080 | KeyInfo *pKeyInfo; /* Collation and sort-order information */ |
| 19081 | Mem *aMem; /* Values */ |
| 19082 | union { |
| 19083 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19084 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19085 | } u; |
| 19086 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | |
| 24132 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24133 | Mem *aNew; /* Array of new.* values */ |
| 24134 | Table *pTab; /* Schema object being updated */ |
| 24135 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24136 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24137 | u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ |
| 24138 | }; |
| 24139 | |
| 24140 | /* |
| 24141 | ** An instance of this object is used to pass an vector of values into |
| 24142 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | |
| 35013 | } |
| 35014 | |
| 35015 | /* |
| 35016 | ** Write a single UTF8 character whose value is v into the |
| 35017 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35018 | ** least for bytes. Return the number of bytes needed |
| 35019 | ** to encode the new character. |
| 35020 | */ |
| 35021 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35022 | if( v<0x00080 ){ |
| 35023 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | |
| 43872 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43873 | |
| 43874 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43875 | ** in the following list than the lock being obtained are already held: |
| 43876 | ** |
| 43877 | ** 1. Checkpointer lock (ofst==1). |
| 43878 | ** 2. Write lock (ofst==0). |
| 43879 | ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 43880 | ** |
| 43881 | ** In other words, if this is a blocking lock, none of the locks that |
| 43882 | ** occur later in the above list than the lock being obtained may be |
| 43883 | ** held. |
| 43884 | ** |
| 43885 | ** It is not permitted to block on the RECOVER lock. |
| 43886 | */ |
| 43887 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43888 | { |
| 43889 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43890 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43891 | (ofst!=2) /* not RECOVER */ |
| 43892 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43893 | && (ofst!=0 || lockMask<3) |
| 43894 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43895 | )); |
| 43896 | } |
| @@ -49851,11 +49865,15 @@ | |
| 49851 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49852 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49853 | if( res==WAIT_OBJECT_0 ){ |
| 49854 | ret = TRUE; |
| 49855 | }else if( res==WAIT_TIMEOUT ){ |
| 49856 | rc = SQLITE_BUSY_TIMEOUT; |
| 49857 | }else{ |
| 49858 | /* Some other error has occurred */ |
| 49859 | rc = SQLITE_IOERR_LOCK; |
| 49860 | } |
| 49861 | |
| @@ -51337,17 +51355,17 @@ | |
| 51337 | int nChar; |
| 51338 | LPWSTR zWideFilename; |
| 51339 | |
| 51340 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51341 | && winIsDirSep(zFilename[2])) ){ |
| 51342 | int nByte; |
| 51343 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51344 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51345 | nByte = (int)osCygwin_conv_path(convertflag, |
| 51346 | zFilename, 0, 0); |
| 51347 | if( nByte>0 ){ |
| 51348 | zConverted = sqlite3MallocZero(nByte+12); |
| 51349 | if ( zConverted==0 ){ |
| 51350 | return zConverted; |
| 51351 | } |
| 51352 | zWideFilename = zConverted; |
| 51353 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | |
| 51662 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51663 | |
| 51664 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51665 | ** in the following list than the lock being obtained are already held: |
| 51666 | ** |
| 51667 | ** 1. Checkpointer lock (ofst==1). |
| 51668 | ** 2. Write lock (ofst==0). |
| 51669 | ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 51670 | ** |
| 51671 | ** In other words, if this is a blocking lock, none of the locks that |
| 51672 | ** occur later in the above list than the lock being obtained may be |
| 51673 | ** held. |
| 51674 | ** |
| 51675 | ** It is not permitted to block on the RECOVER lock. |
| 51676 | */ |
| 51677 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51678 | { |
| 51679 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51680 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51681 | (ofst!=2) /* not RECOVER */ |
| 51682 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51683 | && (ofst!=0 || lockMask<3) |
| 51684 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51685 | )); |
| 51686 | } |
| @@ -52226,31 +52243,10 @@ | |
| 52226 | ** |
| 52227 | ** This division contains the implementation of methods on the |
| 52228 | ** sqlite3_vfs object. |
| 52229 | */ |
| 52230 | |
| 52231 | #if 0 /* No longer necessary */ |
| 52232 | /* |
| 52233 | ** Convert a filename from whatever the underlying operating system |
| 52234 | ** supports for filenames into UTF-8. Space to hold the result is |
| 52235 | ** obtained from malloc and must be freed by the calling function. |
| 52236 | */ |
| 52237 | static char *winConvertToUtf8Filename(const void *zFilename){ |
| 52238 | char *zConverted = 0; |
| 52239 | if( osIsNT() ){ |
| 52240 | zConverted = winUnicodeToUtf8(zFilename); |
| 52241 | } |
| 52242 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 52243 | else{ |
| 52244 | zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); |
| 52245 | } |
| 52246 | #endif |
| 52247 | /* caller will handle out of memory */ |
| 52248 | return zConverted; |
| 52249 | } |
| 52250 | #endif |
| 52251 | |
| 52252 | /* |
| 52253 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52254 | ** ends with a directory separator character or one was successfully |
| 52255 | ** added to it. |
| 52256 | */ |
| @@ -52386,46 +52382,10 @@ | |
| 52386 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52387 | sqlite3_free(zConverted); |
| 52388 | break; |
| 52389 | } |
| 52390 | sqlite3_free(zConverted); |
| 52391 | #if 0 /* No longer necessary */ |
| 52392 | }else{ |
| 52393 | zConverted = sqlite3MallocZero( nMax+1 ); |
| 52394 | if( !zConverted ){ |
| 52395 | sqlite3_free(zBuf); |
| 52396 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 52397 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52398 | } |
| 52399 | if( osCygwin_conv_path( |
| 52400 | CCP_POSIX_TO_WIN_W, zDir, |
| 52401 | zConverted, nMax+1)<0 ){ |
| 52402 | sqlite3_free(zConverted); |
| 52403 | sqlite3_free(zBuf); |
| 52404 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); |
| 52405 | return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, |
| 52406 | "winGetTempname2", zDir); |
| 52407 | } |
| 52408 | if( winIsDir(zConverted) ){ |
| 52409 | /* At this point, we know the candidate directory exists and should |
| 52410 | ** be used. However, we may need to convert the string containing |
| 52411 | ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 52412 | */ |
| 52413 | char *zUtf8 = winConvertToUtf8Filename(zConverted); |
| 52414 | if( !zUtf8 ){ |
| 52415 | sqlite3_free(zConverted); |
| 52416 | sqlite3_free(zBuf); |
| 52417 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 52418 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52419 | } |
| 52420 | sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 52421 | sqlite3_free(zUtf8); |
| 52422 | sqlite3_free(zConverted); |
| 52423 | break; |
| 52424 | } |
| 52425 | sqlite3_free(zConverted); |
| 52426 | #endif /* No longer necessary */ |
| 52427 | } |
| 52428 | } |
| 52429 | } |
| 52430 | #endif |
| 52431 | |
| @@ -53320,38 +53280,10 @@ | |
| 53320 | winSimplifyName(zFull); |
| 53321 | return rc; |
| 53322 | } |
| 53323 | } |
| 53324 | #endif /* __CYGWIN__ */ |
| 53325 | #if 0 /* This doesn't work correctly at all! See: |
| 53326 | <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> |
| 53327 | */ |
| 53328 | SimulateIOError( return SQLITE_ERROR ); |
| 53329 | UNUSED_PARAMETER(nFull); |
| 53330 | assert( nFull>=pVfs->mxPathname ); |
| 53331 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 53332 | if( !zOut ){ |
| 53333 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53334 | } |
| 53335 | if( osCygwin_conv_path( |
| 53336 | CCP_POSIX_TO_WIN_W, |
| 53337 | zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 53338 | sqlite3_free(zOut); |
| 53339 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 53340 | "winFullPathname2", zRelative); |
| 53341 | }else{ |
| 53342 | char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 53343 | if( !zUtf8 ){ |
| 53344 | sqlite3_free(zOut); |
| 53345 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53346 | } |
| 53347 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); |
| 53348 | sqlite3_free(zUtf8); |
| 53349 | sqlite3_free(zOut); |
| 53350 | } |
| 53351 | return SQLITE_OK; |
| 53352 | #endif |
| 53353 | |
| 53354 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53355 | SimulateIOError( return SQLITE_ERROR ); |
| 53356 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53357 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | |
| 53493 | ** Interfaces for opening a shared library, finding entry points |
| 53494 | ** within the shared library, and closing the shared library. |
| 53495 | */ |
| 53496 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53497 | HANDLE h; |
| 53498 | #if 0 /* This doesn't work correctly at all! See: |
| 53499 | <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> |
| 53500 | */ |
| 53501 | int nFull = pVfs->mxPathname+1; |
| 53502 | char *zFull = sqlite3MallocZero( nFull ); |
| 53503 | void *zConverted = 0; |
| 53504 | if( zFull==0 ){ |
| 53505 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53506 | return 0; |
| 53507 | } |
| 53508 | if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ |
| 53509 | sqlite3_free(zFull); |
| 53510 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53511 | return 0; |
| 53512 | } |
| 53513 | zConverted = winConvertFromUtf8Filename(zFull); |
| 53514 | sqlite3_free(zFull); |
| 53515 | #else |
| 53516 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53517 | UNUSED_PARAMETER(pVfs); |
| 53518 | #endif |
| 53519 | if( zConverted==0 ){ |
| 53520 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53521 | return 0; |
| 53522 | } |
| 53523 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | |
| 58855 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58856 | PCache *pPCache; /* Pointer to page cache object */ |
| 58857 | #ifndef SQLITE_OMIT_WAL |
| 58858 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58859 | char *zWal; /* File name for write-ahead log */ |
| 58860 | #endif |
| 58861 | }; |
| 58862 | |
| 58863 | /* |
| 58864 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | |
| 65737 | if( rc==SQLITE_OK ){ |
| 65738 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65739 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65740 | pPager->journalSizeLimit, &pPager->pWal |
| 65741 | ); |
| 65742 | } |
| 65743 | pagerFixMaplimit(pPager); |
| 65744 | |
| 65745 | return rc; |
| 65746 | } |
| @@ -65856,10 +65777,11 @@ | |
| 65856 | /* |
| 65857 | ** Set the database handle used by the wal layer to determine if |
| 65858 | ** blocking locks are required. |
| 65859 | */ |
| 65860 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65861 | if( pagerUseWal(pPager) ){ |
| 65862 | sqlite3WalDb(pPager->pWal, db); |
| 65863 | } |
| 65864 | } |
| 65865 | #endif |
| @@ -69029,11 +68951,10 @@ | |
| 69029 | assert( rc==SQLITE_OK ); |
| 69030 | if( pWal->bShmUnreliable==0 ){ |
| 69031 | rc = walIndexReadHdr(pWal, pChanged); |
| 69032 | } |
| 69033 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 69034 | walDisableBlocking(pWal); |
| 69035 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 69036 | rc = SQLITE_BUSY; |
| 69037 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 69038 | } |
| 69039 | #endif |
| @@ -69044,10 +68965,11 @@ | |
| 69044 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 69045 | ** would be technically correct. But the race is benign since with |
| 69046 | ** WAL_RETRY this routine will be called again and will probably be |
| 69047 | ** right on the second iteration. |
| 69048 | */ |
| 69049 | if( pWal->apWiData[0]==0 ){ |
| 69050 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 69051 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 69052 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 69053 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | |
| 69060 | rc = WAL_RETRY; |
| 69061 | }else if( rc==SQLITE_BUSY ){ |
| 69062 | rc = SQLITE_BUSY_RECOVERY; |
| 69063 | } |
| 69064 | } |
| 69065 | if( rc!=SQLITE_OK ){ |
| 69066 | return rc; |
| 69067 | } |
| 69068 | else if( pWal->bShmUnreliable ){ |
| 69069 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | |
| 72509 | if( pKey ){ |
| 72510 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72511 | assert( nKey==(i64)(int)nKey ); |
| 72512 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72513 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72514 | sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); |
| 72515 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72516 | rc = SQLITE_CORRUPT_BKPT; |
| 72517 | }else{ |
| 72518 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72519 | } |
| @@ -74493,10 +74416,11 @@ | |
| 74493 | removed = 1; |
| 74494 | } |
| 74495 | sqlite3_mutex_leave(pMainMtx); |
| 74496 | return removed; |
| 74497 | #else |
| 74498 | return 1; |
| 74499 | #endif |
| 74500 | } |
| 74501 | |
| 74502 | /* |
| @@ -75334,10 +75258,17 @@ | |
| 75334 | |
| 75335 | if( rc!=SQLITE_OK ){ |
| 75336 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75337 | unlockBtreeIfUnused(pBt); |
| 75338 | } |
| 75339 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75340 | btreeInvokeBusyHandler(pBt) ); |
| 75341 | sqlite3PagerWalDb(pPager, 0); |
| 75342 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75343 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | |
| 82954 | ** btree as the argument handle holds an exclusive lock on the |
| 82955 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82956 | */ |
| 82957 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82958 | int rc; |
| 82959 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82960 | sqlite3BtreeEnter(p); |
| 82961 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82962 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82963 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | |
| 90174 | } |
| 90175 | } |
| 90176 | return; |
| 90177 | } |
| 90178 | /* |
| 90179 | ** This routine is used to allocate sufficient space for an UnpackedRecord |
| 90180 | ** structure large enough to be used with sqlite3VdbeRecordUnpack() if |
| 90181 | ** the first argument is a pointer to KeyInfo structure pKeyInfo. |
| 90182 | ** |
| 90183 | ** The space is either allocated using sqlite3DbMallocRaw() or from within |
| 90184 | ** the unaligned buffer passed via the second and third arguments (presumably |
| 90185 | ** stack space). If the former, then *ppFree is set to a pointer that should |
| 90186 | ** be eventually freed by the caller using sqlite3DbFree(). Or, if the |
| 90187 | ** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL |
| 90188 | ** before returning. |
| 90189 | ** |
| 90190 | ** If an OOM error occurs, NULL is returned. |
| 90191 | */ |
| 90192 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90193 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90194 | ){ |
| 90195 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90196 | int nByte; /* Number of bytes required for *p */ |
| 90197 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90198 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90199 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90200 | if( !p ) return 0; |
| 90201 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90202 | assert( pKeyInfo->aSortFlags!=0 ); |
| 90203 | p->pKeyInfo = pKeyInfo; |
| 90204 | p->nField = pKeyInfo->nKeyField + 1; |
| 90205 | return p; |
| 90206 | } |
| 90207 | |
| @@ -90209,11 +90133,10 @@ | |
| 90209 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90210 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90211 | ** contents of the decoded record. |
| 90212 | */ |
| 90213 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90214 | KeyInfo *pKeyInfo, /* Information about the record format */ |
| 90215 | int nKey, /* Size of the binary record */ |
| 90216 | const void *pKey, /* The binary record */ |
| 90217 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90218 | ){ |
| 90219 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | |
| 90220 | u32 d; |
| 90221 | u32 idx; /* Offset in aKey[] to read from */ |
| 90222 | u16 u; /* Unsigned loop counter */ |
| 90223 | u32 szHdr; |
| 90224 | Mem *pMem = p->aMem; |
| 90225 | |
| 90226 | p->default_rc = 0; |
| 90227 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90228 | idx = getVarint32(aKey, szHdr); |
| 90229 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | |
| 90247 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90248 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90249 | ** warnings from MSAN. */ |
| 90250 | sqlite3VdbeMemSetNull(pMem-1); |
| 90251 | } |
| 90252 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90253 | p->nField = u; |
| 90254 | } |
| 90255 | |
| 90256 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | |
| 91106 | ** is an integer. |
| 91107 | ** |
| 91108 | ** The easiest way to enforce this limit is to consider only records with |
| 91109 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91110 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91111 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91112 | int flags = p->aMem[0].flags; |
| 91113 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91114 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91115 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | |
| 91464 | ){ |
| 91465 | sqlite3 *db = v->db; |
| 91466 | i64 iKey2; |
| 91467 | PreUpdate preupdate; |
| 91468 | const char *zTbl = pTab->zName; |
| 91469 | static const u8 fakeSortOrder = 0; |
| 91470 | #ifdef SQLITE_DEBUG |
| 91471 | int nRealCol; |
| 91472 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91473 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91474 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | |
| 91503 | preupdate.iNewReg = iReg; |
| 91504 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91505 | preupdate.pKeyinfo->db = db; |
| 91506 | preupdate.pKeyinfo->enc = ENC(db); |
| 91507 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91508 | preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; |
| 91509 | preupdate.iKey1 = iKey1; |
| 91510 | preupdate.iKey2 = iKey2; |
| 91511 | preupdate.pTab = pTab; |
| 91512 | preupdate.iBlobWrite = iBlobWrite; |
| 91513 | |
| @@ -93700,11 +93626,11 @@ | |
| 93700 | UnpackedRecord *pRet; /* Return value */ |
| 93701 | |
| 93702 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93703 | if( pRet ){ |
| 93704 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93705 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); |
| 93706 | } |
| 93707 | return pRet; |
| 93708 | } |
| 93709 | |
| 93710 | /* |
| @@ -96893,10 +96819,11 @@ | |
| 96893 | } |
| 96894 | n = pOp->p3; |
| 96895 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96896 | assert( n>0 ); |
| 96897 | assert( pKeyInfo!=0 ); |
| 96898 | p1 = pOp->p1; |
| 96899 | p2 = pOp->p2; |
| 96900 | #ifdef SQLITE_DEBUG |
| 96901 | if( aPermute ){ |
| 96902 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | |
| 99766 | rc = ExpandBlob(r.aMem); |
| 99767 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99768 | if( rc ) goto no_mem; |
| 99769 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99770 | if( pIdxKey==0 ) goto no_mem; |
| 99771 | sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); |
| 99772 | pIdxKey->default_rc = 0; |
| 99773 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99774 | sqlite3DbFreeNN(db, pIdxKey); |
| 99775 | } |
| 99776 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | |
| 104942 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104943 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104944 | ){ |
| 104945 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104946 | if( *pbKey2Cached==0 ){ |
| 104947 | sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); |
| 104948 | *pbKey2Cached = 1; |
| 104949 | } |
| 104950 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104951 | } |
| 104952 | |
| @@ -104969,11 +104896,11 @@ | |
| 104969 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104970 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104971 | ){ |
| 104972 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104973 | if( !*pbKey2Cached ){ |
| 104974 | sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); |
| 104975 | *pbKey2Cached = 1; |
| 104976 | } |
| 104977 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104978 | } |
| 104979 | |
| @@ -105009,10 +104936,11 @@ | |
| 105009 | res = vdbeSorterCompareTail( |
| 105010 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105011 | ); |
| 105012 | } |
| 105013 | }else{ |
| 105014 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 105015 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 105016 | res = res * -1; |
| 105017 | } |
| 105018 | } |
| @@ -105072,10 +105000,11 @@ | |
| 105072 | }else{ |
| 105073 | if( *v2 & 0x80 ) res = +1; |
| 105074 | } |
| 105075 | } |
| 105076 | |
| 105077 | if( res==0 ){ |
| 105078 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105079 | res = vdbeSorterCompareTail( |
| 105080 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105081 | ); |
| @@ -105145,11 +105074,12 @@ | |
| 105145 | assert( pCsr->pKeyInfo ); |
| 105146 | assert( !pCsr->isEphemeral ); |
| 105147 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105148 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105149 | < 0x7fffffff ); |
| 105150 | szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); |
| 105151 | sz = SZ_VDBESORTER(nWorker+1); |
| 105152 | |
| 105153 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105154 | pCsr->uc.pSorter = pSorter; |
| 105155 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | |
| 105159 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105160 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105161 | pKeyInfo->db = 0; |
| 105162 | if( nField && nWorker==0 ){ |
| 105163 | pKeyInfo->nKeyField = nField; |
| 105164 | } |
| 105165 | sqlite3BtreeEnter(pBt); |
| 105166 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105167 | sqlite3BtreeLeave(pBt); |
| 105168 | pSorter->nTask = nWorker + 1; |
| 105169 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | |
| 106939 | r2->nField = nKeyCol; |
| 106940 | } |
| 106941 | assert( r2->nField==nKeyCol ); |
| 106942 | |
| 106943 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106944 | sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); |
| 106945 | for(i=0; i<nKeyCol; i++){ |
| 106946 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106947 | *pRes = -1; |
| 106948 | return SQLITE_OK; |
| 106949 | } |
| @@ -110495,11 +110430,13 @@ | |
| 110495 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110496 | return sqlite3ExprAffinity( |
| 110497 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110498 | ); |
| 110499 | } |
| 110500 | if( op==TK_VECTOR ){ |
| 110501 | assert( ExprUseXList(pExpr) ); |
| 110502 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110503 | } |
| 110504 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110505 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | |
| 110688 | } |
| 110689 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110690 | p = p->pLeft; |
| 110691 | continue; |
| 110692 | } |
| 110693 | if( op==TK_VECTOR ){ |
| 110694 | assert( ExprUseXList(p) ); |
| 110695 | p = p->x.pList->a[0].pExpr; |
| 110696 | continue; |
| 110697 | } |
| 110698 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | |
| 119025 | }else{ |
| 119026 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 119027 | } |
| 119028 | |
| 119029 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 119030 | zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); |
| 119031 | }else{ |
| 119032 | assert( nSql>0 ); |
| 119033 | zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); |
| 119034 | if( zOut ){ |
| 119035 | zBuf1 = &zOut[nSql*2+1]; |
| 119036 | zBuf2 = &zOut[nSql*4+2]; |
| 119037 | } |
| 119038 | } |
| @@ -138772,10 +138711,12 @@ | |
| 138772 | /* Version 3.43.0 and later */ |
| 138773 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138774 | /* Version 3.44.0 and later */ |
| 138775 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138776 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138777 | }; |
| 138778 | |
| 138779 | /* |
| 138780 | ** This is the function signature used for all extension entry points. It |
| 138781 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | |
| 139105 | /* Version 3.43.0 and later */ |
| 139106 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139107 | /* Version 3.44.0 and later */ |
| 139108 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139109 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139110 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139111 | |
| 139112 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139113 | /* This case when the file really is being compiled as a loadable |
| 139114 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | |
| 139626 | sqlite3_is_interrupted, |
| 139627 | /* Version 3.43.0 and later */ |
| 139628 | sqlite3_stmt_explain, |
| 139629 | /* Version 3.44.0 and later */ |
| 139630 | sqlite3_get_clientdata, |
| 139631 | sqlite3_set_clientdata |
| 139632 | }; |
| 139633 | |
| 139634 | /* True if x is the directory separator character |
| 139635 | */ |
| 139636 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | |
| 145464 | "not present in both tables", zName); |
| 145465 | return 1; |
| 145466 | } |
| 145467 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145468 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145469 | if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ |
| 145470 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145471 | ** JOINs. If only a single table on the left side of this join |
| 145472 | ** contains the zName column, then this branch is a no-op. |
| 145473 | ** But if there are two or more tables on the left side |
| 145474 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | |
| 145480 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145481 | ** adding a new error so as to not break legacy applications. |
| 145482 | */ |
| 145483 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145484 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145485 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145486 | pRight->fg.isSynthUsing)!=0 ){ |
| 145487 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145488 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145489 | ){ |
| @@ -145496,11 +145443,17 @@ | |
| 145496 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145497 | } |
| 145498 | if( pFuncArgs ){ |
| 145499 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145500 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145501 | } |
| 145502 | } |
| 145503 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145504 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145505 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145506 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | |
| 146973 | #else |
| 146974 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146975 | #endif |
| 146976 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146977 | } |
| 146978 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146979 | } |
| 146980 | |
| 146981 | |
| 146982 | /* |
| @@ -149104,13 +149061,13 @@ | |
| 149104 | ** other than the one FROM-clause subquery that is a candidate |
| 149105 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149106 | ** from 2015-02-09.) |
| 149107 | ** |
| 149108 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149109 | ** (3a) the subquery may not be a join and |
| 149110 | ** (3b) the FROM clause of the subquery may not contain a virtual |
| 149111 | ** table and |
| 149112 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149113 | ** is now managed correctly |
| 149114 | ** (3d) the outer query may not be DISTINCT. |
| 149115 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149116 | ** |
| @@ -149322,11 +149279,11 @@ | |
| 149322 | ** |
| 149323 | ** See also tickets #306, #350, and #3300. |
| 149324 | */ |
| 149325 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149326 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149327 | || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ |
| 149328 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149329 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149330 | ){ |
| 149331 | return 0; |
| 149332 | } |
| @@ -153366,10 +153323,14 @@ | |
| 153366 | } |
| 153367 | |
| 153368 | if( iOrderByCol ){ |
| 153369 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153370 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153371 | if( ALWAYS(pBase!=0) |
| 153372 | && pBase->op!=TK_AGG_COLUMN |
| 153373 | && pBase->op!=TK_REGISTER |
| 153374 | ){ |
| 153375 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | |
| 157343 | saved_flags = db->flags; |
| 157344 | saved_mDbFlags = db->mDbFlags; |
| 157345 | saved_nChange = db->nChange; |
| 157346 | saved_nTotalChange = db->nTotalChange; |
| 157347 | saved_mTrace = db->mTrace; |
| 157348 | db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; |
| 157349 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157350 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157351 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157352 | db->mTrace = 0; |
| 157353 | |
| @@ -161818,16 +161780,17 @@ | |
| 161818 | } |
| 161819 | |
| 161820 | if( pLevel->iLeftJoin==0 ){ |
| 161821 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161822 | ** terms from the query that must be true due to the WHERE clause of |
| 161823 | ** the partial index. |
| 161824 | ** |
| 161825 | ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work |
| 161826 | ** for a LEFT JOIN. |
| 161827 | */ |
| 161828 | if( pIdx->pPartIdxWhere ){ |
| 161829 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161830 | } |
| 161831 | }else{ |
| 161832 | testcase( pIdx->pPartIdxWhere ); |
| 161833 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | |
| 168080 | Expr *pExpr; |
| 168081 | pExpr = pTerm->pExpr; |
| 168082 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168083 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168084 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168085 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168086 | ){ |
| 168087 | return 1; |
| 168088 | } |
| 168089 | } |
| @@ -188883,11 +188847,11 @@ | |
| 188883 | |
| 188884 | /* |
| 188885 | ** Macros needed to provide flexible arrays in a portable way |
| 188886 | */ |
| 188887 | #ifndef offsetof |
| 188888 | # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 188889 | #endif |
| 188890 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188891 | # define FLEXARRAY |
| 188892 | #else |
| 188893 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | |
| 209116 | nExtra = 0; |
| 209117 | }else if( szType==12 ){ |
| 209118 | nExtra = 1; |
| 209119 | }else if( szType==13 ){ |
| 209120 | nExtra = 2; |
| 209121 | }else{ |
| 209122 | nExtra = 4; |
| 209123 | } |
| 209124 | if( szPayload<=11 ){ |
| 209125 | nNeeded = 0; |
| 209126 | }else if( szPayload<=0xff ){ |
| 209127 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | |
| 212681 | const char *z; |
| 212682 | u32 n; |
| 212683 | UNUSED_PARAMETER(argc); |
| 212684 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212685 | if( pStr ){ |
| 212686 | if( pStr->zBuf==0 ){ |
| 212687 | jsonStringInit(pStr, ctx); |
| 212688 | jsonAppendChar(pStr, '{'); |
| 212689 | }else if( pStr->nUsed>1 ){ |
| 212690 | jsonAppendChar(pStr, ','); |
| 212691 | } |
| 212692 | pStr->pCtx = ctx; |
| 212693 | z = (const char*)sqlite3_value_text(argv[0]); |
| 212694 | n = sqlite3Strlen30(z); |
| 212695 | jsonAppendString(pStr, z, n); |
| 212696 | jsonAppendChar(pStr, ':'); |
| 212697 | jsonAppendSqlValue(pStr, argv[1]); |
| 212698 | } |
| 212699 | } |
| 212700 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212701 | JsonString *pStr; |
| 212702 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | |
| 213500 | #else |
| 213501 | /* #include "sqlite3.h" */ |
| 213502 | #endif |
| 213503 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213504 | |
| 213505 | /* |
| 213506 | ** If building separately, we will need some setup that is normally |
| 213507 | ** found in sqliteInt.h |
| 213508 | */ |
| 213509 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | |
| 213531 | #else |
| 213532 | # define ALWAYS(X) (X) |
| 213533 | # define NEVER(X) (X) |
| 213534 | #endif |
| 213535 | #ifndef offsetof |
| 213536 | #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 213537 | #endif |
| 213538 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213539 | # define FLEXARRAY |
| 213540 | #else |
| 213541 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | |
| 227848 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227849 | int rc; |
| 227850 | sqlite3 *db = pTab->db; |
| 227851 | Btree *pBt; |
| 227852 | |
| 227853 | (void)idxStr; |
| 227854 | |
| 227855 | /* Default setting is no rows of result */ |
| 227856 | pCsr->pgno = 1; |
| 227857 | pCsr->mxPgno = 0; |
| 227858 | |
| @@ -231510,18 +231481,19 @@ | |
| 231510 | /* |
| 231511 | ** If the SessionInput object passed as the only argument is a streaming |
| 231512 | ** object and the buffer is full, discard some data to free up space. |
| 231513 | */ |
| 231514 | static void sessionDiscardData(SessionInput *pIn){ |
| 231515 | if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ |
| 231516 | int nMove = pIn->buf.nBuf - pIn->iNext; |
| 231517 | assert( nMove>=0 ); |
| 231518 | if( nMove>0 ){ |
| 231519 | memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); |
| 231520 | } |
| 231521 | pIn->buf.nBuf -= pIn->iNext; |
| 231522 | pIn->iNext = 0; |
| 231523 | pIn->nData = pIn->buf.nBuf; |
| 231524 | } |
| 231525 | } |
| 231526 | |
| 231527 | /* |
| @@ -231871,12 +231843,12 @@ | |
| 231871 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231872 | ** it, or for the two single byte values otherwise. */ |
| 231873 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231874 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231875 | |
| 231876 | sessionDiscardData(&p->in); |
| 231877 | p->in.iCurrent = p->in.iNext; |
| 231878 | |
| 231879 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231880 | if( p->in.iNext>=p->in.nData ){ |
| 231881 | return SQLITE_DONE; |
| 231882 | } |
| @@ -234231,18 +234203,23 @@ | |
| 234231 | */ |
| 234232 | SQLITE_API int sqlite3changegroup_add_change( |
| 234233 | sqlite3_changegroup *pGrp, |
| 234234 | sqlite3_changeset_iter *pIter |
| 234235 | ){ |
| 234236 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234237 | || pIter->rc!=SQLITE_OK |
| 234238 | || pIter->bInvert |
| 234239 | ){ |
| 234240 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234241 | return SQLITE_ERROR; |
| 234242 | } |
| 234243 | return sessionOneChangeToHash(pGrp, pIter, 0); |
| 234244 | } |
| 234245 | |
| 234246 | /* |
| 234247 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234248 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | |
| 235536 | /* #include "sqlite3ext.h" */ |
| 235537 | SQLITE_EXTENSION_INIT1 |
| 235538 | |
| 235539 | /* #include <string.h> */ |
| 235540 | /* #include <assert.h> */ |
| 235541 | |
| 235542 | #ifndef SQLITE_AMALGAMATION |
| 235543 | |
| 235544 | typedef unsigned char u8; |
| 235545 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | |
| 235595 | |
| 235596 | /* |
| 235597 | ** Macros needed to provide flexible arrays in a portable way |
| 235598 | */ |
| 235599 | #ifndef offsetof |
| 235600 | # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 235601 | #endif |
| 235602 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235603 | # define FLEXARRAY |
| 235604 | #else |
| 235605 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | |
| 257279 | int nArg, /* Number of args */ |
| 257280 | sqlite3_value **apUnused /* Function arguments */ |
| 257281 | ){ |
| 257282 | assert( nArg==0 ); |
| 257283 | UNUSED_PARAM2(nArg, apUnused); |
| 257284 | sqlite3_result_text(pCtx, "fts5: 2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349", -1, SQLITE_TRANSIENT); |
| 257285 | } |
| 257286 | |
| 257287 | /* |
| 257288 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257289 | ** |
| 257290 |
| --- extsrc/sqlite3.c | |
| +++ extsrc/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.51.0. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -16,11 +16,11 @@ | |
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** |
| 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | ** ea1754f7d8a770477a1b19b606b27724fdc0 with changes in files: |
| 22 | ** |
| 23 | ** |
| 24 | */ |
| 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | #define SQLITE_CORE 1 |
| @@ -463,13 +463,13 @@ | |
| 463 | ** |
| 464 | ** See also: [sqlite3_libversion()], |
| 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | */ |
| 468 | #define SQLITE_VERSION "3.51.0" |
| 469 | #define SQLITE_VERSION_NUMBER 3051000 |
| 470 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 471 | |
| 472 | /* |
| 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | ** |
| @@ -15174,11 +15174,11 @@ | |
| 15174 | /* |
| 15175 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15176 | ** ourselves. |
| 15177 | */ |
| 15178 | #ifndef offsetof |
| 15179 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 15180 | #endif |
| 15181 | |
| 15182 | /* |
| 15183 | ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15184 | ** to avoid complaints from -fsanitize=strict-bounds. |
| @@ -17401,11 +17401,11 @@ | |
| 17401 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 17402 | #endif |
| 17403 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 17404 | SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); |
| 17405 | |
| 17406 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); |
| 17407 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 17408 | SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); |
| 17409 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); |
| 17410 | |
| 17411 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| @@ -18701,10 +18701,11 @@ | |
| 18701 | #define SQLITE_AFF_TEXT 0x42 /* 'B' */ |
| 18702 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 18703 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 18704 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 18705 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ |
| 18706 | #define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ |
| 18707 | |
| 18708 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 18709 | |
| 18710 | /* |
| 18711 | ** The SQLITE_AFF_MASK values masks off the significant bits of an |
| @@ -19016,13 +19017,19 @@ | |
| 19017 | /* |
| 19018 | ** An instance of the following structure is passed as the first |
| 19019 | ** argument to sqlite3VdbeKeyCompare and is used to control the |
| 19020 | ** comparison of the two index keys. |
| 19021 | ** |
| 19022 | ** The aSortOrder[] and aColl[] arrays have nAllField slots each. There |
| 19023 | ** are nKeyField slots for the columns of an index then extra slots |
| 19024 | ** for the rowid or key at the end. The aSortOrder array is located after |
| 19025 | ** the aColl[] array. |
| 19026 | ** |
| 19027 | ** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL |
| 19028 | ** to indicate that this object is for use by a preupdate hook. When aSortFlags |
| 19029 | ** is NULL, then nAllField is uninitialized and no space is allocated for |
| 19030 | ** aColl[], so those fields may not be used. |
| 19031 | */ |
| 19032 | struct KeyInfo { |
| 19033 | u32 nRef; /* Number of references to this KeyInfo object */ |
| 19034 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19035 | u16 nKeyField; /* Number of key columns in the index */ |
| @@ -19030,12 +19037,21 @@ | |
| 19037 | sqlite3 *db; /* The database connection */ |
| 19038 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19039 | CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19040 | }; |
| 19041 | |
| 19042 | /* The size (in bytes) of a KeyInfo object with up to N fields. This includes |
| 19043 | ** the main body of the KeyInfo object and the aColl[] array of N elements, |
| 19044 | ** but does not count the memory used to hold aSortFlags[]. */ |
| 19045 | #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19046 | |
| 19047 | /* The size of a bare KeyInfo with no aColl[] entries */ |
| 19048 | #if FLEXARRAY+1 > 1 |
| 19049 | # define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) |
| 19050 | #else |
| 19051 | # define SZ_KEYINFO_0 sizeof(KeyInfo) |
| 19052 | #endif |
| 19053 | |
| 19054 | /* |
| 19055 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19056 | */ |
| 19057 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| @@ -19051,23 +19067,22 @@ | |
| 19067 | ** the OP_MakeRecord opcode of the VDBE and is disassembled by the |
| 19068 | ** OP_Column opcode. |
| 19069 | ** |
| 19070 | ** An instance of this object serves as a "key" for doing a search on |
| 19071 | ** an index b+tree. The goal of the search is to find the entry that |
| 19072 | ** is closest to the key described by this object. This object might hold |
| 19073 | ** just a prefix of the key. The number of fields is given by nField. |
| 19074 | ** |
| 19075 | ** The r1 and r2 fields are the values to return if this key is less than |
| 19076 | ** or greater than a key in the btree, respectively. These are normally |
| 19077 | ** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree |
| 19078 | ** is in DESC order. |
| 19079 | ** |
| 19080 | ** The key comparison functions actually return default_rc when they find |
| 19081 | ** an equals comparison. default_rc can be -1, 0, or +1. If there are |
| 19082 | ** multiple entries in the b-tree with the same key (when only looking |
| 19083 | ** at the first nField elements) then default_rc can be set to -1 to |
| 19084 | ** cause the search to find the last match, or +1 to cause the search to |
| 19085 | ** find the first match. |
| 19086 | ** |
| 19087 | ** The key comparison functions will set eqSeen to true if they ever |
| 19088 | ** get and equal results when comparing this structure to a b-tree record. |
| @@ -19075,12 +19090,12 @@ | |
| 19090 | ** before the first match or immediately after the last match. The |
| 19091 | ** eqSeen field will indicate whether or not an exact match exists in the |
| 19092 | ** b-tree. |
| 19093 | */ |
| 19094 | struct UnpackedRecord { |
| 19095 | KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ |
| 19096 | Mem *aMem; /* Values for columns of the index */ |
| 19097 | union { |
| 19098 | char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ |
| 19099 | i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ |
| 19100 | } u; |
| 19101 | int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ |
| @@ -24132,11 +24147,11 @@ | |
| 24147 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24148 | Mem *aNew; /* Array of new.* values */ |
| 24149 | Table *pTab; /* Schema object being updated */ |
| 24150 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24151 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24152 | u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ |
| 24153 | }; |
| 24154 | |
| 24155 | /* |
| 24156 | ** An instance of this object is used to pass an vector of values into |
| 24157 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| @@ -35013,11 +35028,11 @@ | |
| 35028 | } |
| 35029 | |
| 35030 | /* |
| 35031 | ** Write a single UTF8 character whose value is v into the |
| 35032 | ** buffer starting at zOut. zOut must be sized to hold at |
| 35033 | ** least four bytes. Return the number of bytes needed |
| 35034 | ** to encode the new character. |
| 35035 | */ |
| 35036 | SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ |
| 35037 | if( v<0x00080 ){ |
| 35038 | zOut[0] = (u8)(v & 0xff); |
| @@ -43872,25 +43887,24 @@ | |
| 43887 | assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); |
| 43888 | |
| 43889 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 43890 | ** in the following list than the lock being obtained are already held: |
| 43891 | ** |
| 43892 | ** 1. Recovery lock (ofst==2). |
| 43893 | ** 2. Checkpointer lock (ofst==1). |
| 43894 | ** 3. Write lock (ofst==0). |
| 43895 | ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 43896 | ** |
| 43897 | ** In other words, if this is a blocking lock, none of the locks that |
| 43898 | ** occur later in the above list than the lock being obtained may be |
| 43899 | ** held. |
| 43900 | */ |
| 43901 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 43902 | { |
| 43903 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 43904 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 43905 | (ofst!=2 || lockMask==0) |
| 43906 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 43907 | && (ofst!=0 || lockMask<3) |
| 43908 | && (ofst<3 || lockMask<(1<<ofst)) |
| 43909 | )); |
| 43910 | } |
| @@ -49851,11 +49865,15 @@ | |
| 49865 | DWORD nDelay = (nMs==0 ? INFINITE : nMs); |
| 49866 | DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); |
| 49867 | if( res==WAIT_OBJECT_0 ){ |
| 49868 | ret = TRUE; |
| 49869 | }else if( res==WAIT_TIMEOUT ){ |
| 49870 | #if SQLITE_ENABLE_SETLK_TIMEOUT==1 |
| 49871 | rc = SQLITE_BUSY_TIMEOUT; |
| 49872 | #else |
| 49873 | rc = SQLITE_BUSY; |
| 49874 | #endif |
| 49875 | }else{ |
| 49876 | /* Some other error has occurred */ |
| 49877 | rc = SQLITE_IOERR_LOCK; |
| 49878 | } |
| 49879 | |
| @@ -51337,17 +51355,17 @@ | |
| 51355 | int nChar; |
| 51356 | LPWSTR zWideFilename; |
| 51357 | |
| 51358 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 51359 | && winIsDirSep(zFilename[2])) ){ |
| 51360 | i64 nByte; |
| 51361 | int convertflag = CCP_POSIX_TO_WIN_W; |
| 51362 | if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; |
| 51363 | nByte = (i64)osCygwin_conv_path(convertflag, |
| 51364 | zFilename, 0, 0); |
| 51365 | if( nByte>0 ){ |
| 51366 | zConverted = sqlite3MallocZero(12+(u64)nByte); |
| 51367 | if ( zConverted==0 ){ |
| 51368 | return zConverted; |
| 51369 | } |
| 51370 | zWideFilename = zConverted; |
| 51371 | /* Filenames should be prefixed, except when converted |
| @@ -51662,25 +51680,24 @@ | |
| 51680 | assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); |
| 51681 | |
| 51682 | /* Check that, if this to be a blocking lock, no locks that occur later |
| 51683 | ** in the following list than the lock being obtained are already held: |
| 51684 | ** |
| 51685 | ** 1. Recovery lock (ofst==2). |
| 51686 | ** 2. Checkpointer lock (ofst==1). |
| 51687 | ** 3. Write lock (ofst==0). |
| 51688 | ** 4. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). |
| 51689 | ** |
| 51690 | ** In other words, if this is a blocking lock, none of the locks that |
| 51691 | ** occur later in the above list than the lock being obtained may be |
| 51692 | ** held. |
| 51693 | */ |
| 51694 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) |
| 51695 | { |
| 51696 | u16 lockMask = (p->exclMask|p->sharedMask); |
| 51697 | assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( |
| 51698 | (ofst!=2 || lockMask==0) |
| 51699 | && (ofst!=1 || lockMask==0 || lockMask==2) |
| 51700 | && (ofst!=0 || lockMask<3) |
| 51701 | && (ofst<3 || lockMask<(1<<ofst)) |
| 51702 | )); |
| 51703 | } |
| @@ -52226,31 +52243,10 @@ | |
| 52243 | ** |
| 52244 | ** This division contains the implementation of methods on the |
| 52245 | ** sqlite3_vfs object. |
| 52246 | */ |
| 52247 | |
| 52248 | /* |
| 52249 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 52250 | ** ends with a directory separator character or one was successfully |
| 52251 | ** added to it. |
| 52252 | */ |
| @@ -52386,46 +52382,10 @@ | |
| 52382 | sqlite3_snprintf(nMax, zBuf, "%s", zDir); |
| 52383 | sqlite3_free(zConverted); |
| 52384 | break; |
| 52385 | } |
| 52386 | sqlite3_free(zConverted); |
| 52387 | } |
| 52388 | } |
| 52389 | } |
| 52390 | #endif |
| 52391 | |
| @@ -53320,38 +53280,10 @@ | |
| 53280 | winSimplifyName(zFull); |
| 53281 | return rc; |
| 53282 | } |
| 53283 | } |
| 53284 | #endif /* __CYGWIN__ */ |
| 53285 | |
| 53286 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) |
| 53287 | SimulateIOError( return SQLITE_ERROR ); |
| 53288 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 53289 | /* WinRT has no way to convert a relative path to an absolute one. */ |
| @@ -53493,31 +53425,12 @@ | |
| 53425 | ** Interfaces for opening a shared library, finding entry points |
| 53426 | ** within the shared library, and closing the shared library. |
| 53427 | */ |
| 53428 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53429 | HANDLE h; |
| 53430 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53431 | UNUSED_PARAMETER(pVfs); |
| 53432 | if( zConverted==0 ){ |
| 53433 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53434 | return 0; |
| 53435 | } |
| 53436 | if( osIsNT() ){ |
| @@ -58855,10 +58768,13 @@ | |
| 58768 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 58769 | PCache *pPCache; /* Pointer to page cache object */ |
| 58770 | #ifndef SQLITE_OMIT_WAL |
| 58771 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 58772 | char *zWal; /* File name for write-ahead log */ |
| 58773 | #endif |
| 58774 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 58775 | sqlite3 *dbWal; |
| 58776 | #endif |
| 58777 | }; |
| 58778 | |
| 58779 | /* |
| 58780 | ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains |
| @@ -65737,10 +65653,15 @@ | |
| 65653 | if( rc==SQLITE_OK ){ |
| 65654 | rc = sqlite3WalOpen(pPager->pVfs, |
| 65655 | pPager->fd, pPager->zWal, pPager->exclusiveMode, |
| 65656 | pPager->journalSizeLimit, &pPager->pWal |
| 65657 | ); |
| 65658 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 65659 | if( rc==SQLITE_OK ){ |
| 65660 | sqlite3WalDb(pPager->pWal, pPager->dbWal); |
| 65661 | } |
| 65662 | #endif |
| 65663 | } |
| 65664 | pagerFixMaplimit(pPager); |
| 65665 | |
| 65666 | return rc; |
| 65667 | } |
| @@ -65856,10 +65777,11 @@ | |
| 65777 | /* |
| 65778 | ** Set the database handle used by the wal layer to determine if |
| 65779 | ** blocking locks are required. |
| 65780 | */ |
| 65781 | SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ |
| 65782 | pPager->dbWal = db; |
| 65783 | if( pagerUseWal(pPager) ){ |
| 65784 | sqlite3WalDb(pPager->pWal, db); |
| 65785 | } |
| 65786 | } |
| 65787 | #endif |
| @@ -69029,11 +68951,10 @@ | |
| 68951 | assert( rc==SQLITE_OK ); |
| 68952 | if( pWal->bShmUnreliable==0 ){ |
| 68953 | rc = walIndexReadHdr(pWal, pChanged); |
| 68954 | } |
| 68955 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 68956 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 68957 | rc = SQLITE_BUSY; |
| 68958 | *pCnt |= WAL_RETRY_BLOCKED_MASK; |
| 68959 | } |
| 68960 | #endif |
| @@ -69044,10 +68965,11 @@ | |
| 68965 | ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY |
| 68966 | ** would be technically correct. But the race is benign since with |
| 68967 | ** WAL_RETRY this routine will be called again and will probably be |
| 68968 | ** right on the second iteration. |
| 68969 | */ |
| 68970 | (void)walEnableBlocking(pWal); |
| 68971 | if( pWal->apWiData[0]==0 ){ |
| 68972 | /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. |
| 68973 | ** We assume this is a transient condition, so return WAL_RETRY. The |
| 68974 | ** xShmMap() implementation used by the default unix and win32 VFS |
| 68975 | ** modules may return SQLITE_BUSY due to a race condition in the |
| @@ -69060,10 +68982,11 @@ | |
| 68982 | rc = WAL_RETRY; |
| 68983 | }else if( rc==SQLITE_BUSY ){ |
| 68984 | rc = SQLITE_BUSY_RECOVERY; |
| 68985 | } |
| 68986 | } |
| 68987 | walDisableBlocking(pWal); |
| 68988 | if( rc!=SQLITE_OK ){ |
| 68989 | return rc; |
| 68990 | } |
| 68991 | else if( pWal->bShmUnreliable ){ |
| 68992 | return walBeginShmUnreliable(pWal, pChanged); |
| @@ -72509,11 +72432,11 @@ | |
| 72432 | if( pKey ){ |
| 72433 | KeyInfo *pKeyInfo = pCur->pKeyInfo; |
| 72434 | assert( nKey==(i64)(int)nKey ); |
| 72435 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 72436 | if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; |
| 72437 | sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); |
| 72438 | if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ |
| 72439 | rc = SQLITE_CORRUPT_BKPT; |
| 72440 | }else{ |
| 72441 | rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); |
| 72442 | } |
| @@ -74493,10 +74416,11 @@ | |
| 74416 | removed = 1; |
| 74417 | } |
| 74418 | sqlite3_mutex_leave(pMainMtx); |
| 74419 | return removed; |
| 74420 | #else |
| 74421 | UNUSED_PARAMETER( pBt ); |
| 74422 | return 1; |
| 74423 | #endif |
| 74424 | } |
| 74425 | |
| 74426 | /* |
| @@ -75334,10 +75258,17 @@ | |
| 75258 | |
| 75259 | if( rc!=SQLITE_OK ){ |
| 75260 | (void)sqlite3PagerWalWriteLock(pPager, 0); |
| 75261 | unlockBtreeIfUnused(pBt); |
| 75262 | } |
| 75263 | #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 75264 | if( rc==SQLITE_BUSY_TIMEOUT ){ |
| 75265 | /* If a blocking lock timed out, break out of the loop here so that |
| 75266 | ** the busy-handler is not invoked. */ |
| 75267 | break; |
| 75268 | } |
| 75269 | #endif |
| 75270 | }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && |
| 75271 | btreeInvokeBusyHandler(pBt) ); |
| 75272 | sqlite3PagerWalDb(pPager, 0); |
| 75273 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 75274 | if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; |
| @@ -82954,10 +82885,11 @@ | |
| 82885 | ** btree as the argument handle holds an exclusive lock on the |
| 82886 | ** sqlite_schema table. Otherwise SQLITE_OK. |
| 82887 | */ |
| 82888 | SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ |
| 82889 | int rc; |
| 82890 | UNUSED_PARAMETER(p); /* only used in DEBUG builds */ |
| 82891 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 82892 | sqlite3BtreeEnter(p); |
| 82893 | rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); |
| 82894 | assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); |
| 82895 | sqlite3BtreeLeave(p); |
| @@ -90174,34 +90106,26 @@ | |
| 90106 | } |
| 90107 | } |
| 90108 | return; |
| 90109 | } |
| 90110 | /* |
| 90111 | ** Allocate sufficient space for an UnpackedRecord structure large enough |
| 90112 | ** to hold a decoded index record for pKeyInfo. |
| 90113 | ** |
| 90114 | ** The space is allocated using sqlite3DbMallocRaw(). If an OOM error |
| 90115 | ** occurs, NULL is returned. |
| 90116 | */ |
| 90117 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 90118 | KeyInfo *pKeyInfo /* Description of the record */ |
| 90119 | ){ |
| 90120 | UnpackedRecord *p; /* Unpacked record to return */ |
| 90121 | u64 nByte; /* Number of bytes required for *p */ |
| 90122 | assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); |
| 90123 | nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); |
| 90124 | p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 90125 | if( !p ) return 0; |
| 90126 | p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; |
| 90127 | p->pKeyInfo = pKeyInfo; |
| 90128 | p->nField = pKeyInfo->nKeyField + 1; |
| 90129 | return p; |
| 90130 | } |
| 90131 | |
| @@ -90209,11 +90133,10 @@ | |
| 90133 | ** Given the nKey-byte encoding of a record in pKey[], populate the |
| 90134 | ** UnpackedRecord structure indicated by the fourth argument with the |
| 90135 | ** contents of the decoded record. |
| 90136 | */ |
| 90137 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 90138 | int nKey, /* Size of the binary record */ |
| 90139 | const void *pKey, /* The binary record */ |
| 90140 | UnpackedRecord *p /* Populate this structure before returning. */ |
| 90141 | ){ |
| 90142 | const unsigned char *aKey = (const unsigned char *)pKey; |
| @@ -90220,10 +90143,11 @@ | |
| 90143 | u32 d; |
| 90144 | u32 idx; /* Offset in aKey[] to read from */ |
| 90145 | u16 u; /* Unsigned loop counter */ |
| 90146 | u32 szHdr; |
| 90147 | Mem *pMem = p->aMem; |
| 90148 | KeyInfo *pKeyInfo = p->pKeyInfo; |
| 90149 | |
| 90150 | p->default_rc = 0; |
| 90151 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 90152 | idx = getVarint32(aKey, szHdr); |
| 90153 | d = szHdr; |
| @@ -90247,10 +90171,12 @@ | |
| 90171 | /* In a corrupt record entry, the last pMem might have been set up using |
| 90172 | ** uninitialized memory. Overwrite its value with NULL, to prevent |
| 90173 | ** warnings from MSAN. */ |
| 90174 | sqlite3VdbeMemSetNull(pMem-1); |
| 90175 | } |
| 90176 | testcase( u == pKeyInfo->nKeyField + 1 ); |
| 90177 | testcase( u < pKeyInfo->nKeyField + 1 ); |
| 90178 | assert( u<=pKeyInfo->nKeyField + 1 ); |
| 90179 | p->nField = u; |
| 90180 | } |
| 90181 | |
| 90182 | #ifdef SQLITE_DEBUG |
| @@ -91106,10 +91032,11 @@ | |
| 91032 | ** is an integer. |
| 91033 | ** |
| 91034 | ** The easiest way to enforce this limit is to consider only records with |
| 91035 | ** 13 fields or less. If the first field is an integer, the maximum legal |
| 91036 | ** header size is (12*5 + 1 + 1) bytes. */ |
| 91037 | assert( p->pKeyInfo->aSortFlags!=0 ); |
| 91038 | if( p->pKeyInfo->nAllField<=13 ){ |
| 91039 | int flags = p->aMem[0].flags; |
| 91040 | if( p->pKeyInfo->aSortFlags[0] ){ |
| 91041 | if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ |
| 91042 | return sqlite3VdbeRecordCompare; |
| @@ -91464,11 +91391,10 @@ | |
| 91391 | ){ |
| 91392 | sqlite3 *db = v->db; |
| 91393 | i64 iKey2; |
| 91394 | PreUpdate preupdate; |
| 91395 | const char *zTbl = pTab->zName; |
| 91396 | #ifdef SQLITE_DEBUG |
| 91397 | int nRealCol; |
| 91398 | if( pTab->tabFlags & TF_WithoutRowid ){ |
| 91399 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; |
| 91400 | }else if( pTab->tabFlags & TF_HasVirtual ){ |
| @@ -91503,11 +91429,11 @@ | |
| 91429 | preupdate.iNewReg = iReg; |
| 91430 | preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91431 | preupdate.pKeyinfo->db = db; |
| 91432 | preupdate.pKeyinfo->enc = ENC(db); |
| 91433 | preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91434 | preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ |
| 91435 | preupdate.iKey1 = iKey1; |
| 91436 | preupdate.iKey2 = iKey2; |
| 91437 | preupdate.pTab = pTab; |
| 91438 | preupdate.iBlobWrite = iBlobWrite; |
| 91439 | |
| @@ -93700,11 +93626,11 @@ | |
| 93626 | UnpackedRecord *pRet; /* Return value */ |
| 93627 | |
| 93628 | pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); |
| 93629 | if( pRet ){ |
| 93630 | memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); |
| 93631 | sqlite3VdbeRecordUnpack(nKey, pKey, pRet); |
| 93632 | } |
| 93633 | return pRet; |
| 93634 | } |
| 93635 | |
| 93636 | /* |
| @@ -96893,10 +96819,11 @@ | |
| 96819 | } |
| 96820 | n = pOp->p3; |
| 96821 | pKeyInfo = pOp->p4.pKeyInfo; |
| 96822 | assert( n>0 ); |
| 96823 | assert( pKeyInfo!=0 ); |
| 96824 | assert( pKeyInfo->aSortFlags!=0 ); |
| 96825 | p1 = pOp->p1; |
| 96826 | p2 = pOp->p2; |
| 96827 | #ifdef SQLITE_DEBUG |
| 96828 | if( aPermute ){ |
| 96829 | int k, mx = 0; |
| @@ -99766,11 +99693,11 @@ | |
| 99693 | rc = ExpandBlob(r.aMem); |
| 99694 | assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); |
| 99695 | if( rc ) goto no_mem; |
| 99696 | pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); |
| 99697 | if( pIdxKey==0 ) goto no_mem; |
| 99698 | sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); |
| 99699 | pIdxKey->default_rc = 0; |
| 99700 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); |
| 99701 | sqlite3DbFreeNN(db, pIdxKey); |
| 99702 | } |
| 99703 | if( rc!=SQLITE_OK ){ |
| @@ -104942,11 +104869,11 @@ | |
| 104869 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104870 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104871 | ){ |
| 104872 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104873 | if( *pbKey2Cached==0 ){ |
| 104874 | sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); |
| 104875 | *pbKey2Cached = 1; |
| 104876 | } |
| 104877 | return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); |
| 104878 | } |
| 104879 | |
| @@ -104969,11 +104896,11 @@ | |
| 104896 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 104897 | const void *pKey2, int nKey2 /* Right side of comparison */ |
| 104898 | ){ |
| 104899 | UnpackedRecord *r2 = pTask->pUnpacked; |
| 104900 | if( !*pbKey2Cached ){ |
| 104901 | sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); |
| 104902 | *pbKey2Cached = 1; |
| 104903 | } |
| 104904 | return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 104905 | } |
| 104906 | |
| @@ -105009,10 +104936,11 @@ | |
| 104936 | res = vdbeSorterCompareTail( |
| 104937 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 104938 | ); |
| 104939 | } |
| 104940 | }else{ |
| 104941 | assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); |
| 104942 | assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); |
| 104943 | if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ |
| 104944 | res = res * -1; |
| 104945 | } |
| 104946 | } |
| @@ -105072,10 +105000,11 @@ | |
| 105000 | }else{ |
| 105001 | if( *v2 & 0x80 ) res = +1; |
| 105002 | } |
| 105003 | } |
| 105004 | |
| 105005 | assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); |
| 105006 | if( res==0 ){ |
| 105007 | if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ |
| 105008 | res = vdbeSorterCompareTail( |
| 105009 | pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 |
| 105010 | ); |
| @@ -105145,11 +105074,12 @@ | |
| 105074 | assert( pCsr->pKeyInfo ); |
| 105075 | assert( !pCsr->isEphemeral ); |
| 105076 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 105077 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 105078 | < 0x7fffffff ); |
| 105079 | assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); |
| 105080 | szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); |
| 105081 | sz = SZ_VDBESORTER(nWorker+1); |
| 105082 | |
| 105083 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 105084 | pCsr->uc.pSorter = pSorter; |
| 105085 | if( pSorter==0 ){ |
| @@ -105159,11 +105089,16 @@ | |
| 105089 | pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 105090 | memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 105091 | pKeyInfo->db = 0; |
| 105092 | if( nField && nWorker==0 ){ |
| 105093 | pKeyInfo->nKeyField = nField; |
| 105094 | assert( nField<=pCsr->pKeyInfo->nAllField ); |
| 105095 | } |
| 105096 | /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, |
| 105097 | ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives |
| 105098 | ** longer that pSorter. */ |
| 105099 | assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); |
| 105100 | sqlite3BtreeEnter(pBt); |
| 105101 | pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); |
| 105102 | sqlite3BtreeLeave(pBt); |
| 105103 | pSorter->nTask = nWorker + 1; |
| 105104 | pSorter->iPrev = (u8)(nWorker - 1); |
| @@ -106939,11 +106874,11 @@ | |
| 106874 | r2->nField = nKeyCol; |
| 106875 | } |
| 106876 | assert( r2->nField==nKeyCol ); |
| 106877 | |
| 106878 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 106879 | sqlite3VdbeRecordUnpack(nKey, pKey, r2); |
| 106880 | for(i=0; i<nKeyCol; i++){ |
| 106881 | if( r2->aMem[i].flags & MEM_Null ){ |
| 106882 | *pRes = -1; |
| 106883 | return SQLITE_OK; |
| 106884 | } |
| @@ -110495,11 +110430,13 @@ | |
| 110430 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 110431 | return sqlite3ExprAffinity( |
| 110432 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 110433 | ); |
| 110434 | } |
| 110435 | if( op==TK_VECTOR |
| 110436 | || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) |
| 110437 | ){ |
| 110438 | assert( ExprUseXList(pExpr) ); |
| 110439 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); |
| 110440 | } |
| 110441 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ |
| 110442 | assert( pExpr->op==TK_COLLATE |
| @@ -110688,11 +110625,13 @@ | |
| 110625 | } |
| 110626 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 110627 | p = p->pLeft; |
| 110628 | continue; |
| 110629 | } |
| 110630 | if( op==TK_VECTOR |
| 110631 | || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) |
| 110632 | ){ |
| 110633 | assert( ExprUseXList(p) ); |
| 110634 | p = p->x.pList->a[0].pExpr; |
| 110635 | continue; |
| 110636 | } |
| 110637 | if( op==TK_COLLATE ){ |
| @@ -119025,14 +118964,14 @@ | |
| 118964 | }else{ |
| 118965 | nQuot = sqlite3Strlen30(zQuot)-1; |
| 118966 | } |
| 118967 | |
| 118968 | assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); |
| 118969 | zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); |
| 118970 | }else{ |
| 118971 | assert( nSql>0 ); |
| 118972 | zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); |
| 118973 | if( zOut ){ |
| 118974 | zBuf1 = &zOut[nSql*2+1]; |
| 118975 | zBuf2 = &zOut[nSql*4+2]; |
| 118976 | } |
| 118977 | } |
| @@ -138772,10 +138711,12 @@ | |
| 138711 | /* Version 3.43.0 and later */ |
| 138712 | int (*stmt_explain)(sqlite3_stmt*,int); |
| 138713 | /* Version 3.44.0 and later */ |
| 138714 | void *(*get_clientdata)(sqlite3*,const char*); |
| 138715 | int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); |
| 138716 | /* Version 3.50.0 and later */ |
| 138717 | int (*setlk_timeout)(sqlite3*,int,int); |
| 138718 | }; |
| 138719 | |
| 138720 | /* |
| 138721 | ** This is the function signature used for all extension entry points. It |
| 138722 | ** is also defined in the file "loadext.c". |
| @@ -139105,10 +139046,12 @@ | |
| 139046 | /* Version 3.43.0 and later */ |
| 139047 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain |
| 139048 | /* Version 3.44.0 and later */ |
| 139049 | #define sqlite3_get_clientdata sqlite3_api->get_clientdata |
| 139050 | #define sqlite3_set_clientdata sqlite3_api->set_clientdata |
| 139051 | /* Version 3.50.0 and later */ |
| 139052 | #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout |
| 139053 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 139054 | |
| 139055 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 139056 | /* This case when the file really is being compiled as a loadable |
| 139057 | ** extension */ |
| @@ -139626,11 +139569,13 @@ | |
| 139569 | sqlite3_is_interrupted, |
| 139570 | /* Version 3.43.0 and later */ |
| 139571 | sqlite3_stmt_explain, |
| 139572 | /* Version 3.44.0 and later */ |
| 139573 | sqlite3_get_clientdata, |
| 139574 | sqlite3_set_clientdata, |
| 139575 | /* Version 3.50.0 and later */ |
| 139576 | sqlite3_setlk_timeout |
| 139577 | }; |
| 139578 | |
| 139579 | /* True if x is the directory separator character |
| 139580 | */ |
| 139581 | #if SQLITE_OS_WIN |
| @@ -145464,11 +145409,11 @@ | |
| 145409 | "not present in both tables", zName); |
| 145410 | return 1; |
| 145411 | } |
| 145412 | pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); |
| 145413 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145414 | if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ |
| 145415 | /* This branch runs if the query contains one or more RIGHT or FULL |
| 145416 | ** JOINs. If only a single table on the left side of this join |
| 145417 | ** contains the zName column, then this branch is a no-op. |
| 145418 | ** But if there are two or more tables on the left side |
| 145419 | ** of the join, construct a coalesce() function that gathers all |
| @@ -145480,10 +145425,12 @@ | |
| 145425 | ** JOIN. But older versions of SQLite do not do that, so we avoid |
| 145426 | ** adding a new error so as to not break legacy applications. |
| 145427 | */ |
| 145428 | ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ |
| 145429 | static const Token tkCoalesce = { "coalesce", 8 }; |
| 145430 | assert( pE1!=0 ); |
| 145431 | ExprSetProperty(pE1, EP_CanBeNull); |
| 145432 | while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, |
| 145433 | pRight->fg.isSynthUsing)!=0 ){ |
| 145434 | if( pSrc->a[iLeft].fg.isUsing==0 |
| 145435 | || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 |
| 145436 | ){ |
| @@ -145496,11 +145443,17 @@ | |
| 145443 | sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); |
| 145444 | } |
| 145445 | if( pFuncArgs ){ |
| 145446 | pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); |
| 145447 | pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); |
| 145448 | if( pE1 ){ |
| 145449 | pE1->affExpr = SQLITE_AFF_DEFER; |
| 145450 | } |
| 145451 | } |
| 145452 | }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ |
| 145453 | assert( pE1!=0 ); |
| 145454 | ExprSetProperty(pE1, EP_CanBeNull); |
| 145455 | } |
| 145456 | pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); |
| 145457 | sqlite3SrcItemColumnUsed(pRight, iRightCol); |
| 145458 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); |
| 145459 | assert( pE2!=0 || pEq==0 ); |
| @@ -146973,10 +146926,14 @@ | |
| 146926 | #else |
| 146927 | zType = columnType(&sNC, p, 0, 0, 0); |
| 146928 | #endif |
| 146929 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); |
| 146930 | } |
| 146931 | #else |
| 146932 | UNUSED_PARAMETER(pParse); |
| 146933 | UNUSED_PARAMETER(pTabList); |
| 146934 | UNUSED_PARAMETER(pEList); |
| 146935 | #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ |
| 146936 | } |
| 146937 | |
| 146938 | |
| 146939 | /* |
| @@ -149104,13 +149061,13 @@ | |
| 149061 | ** other than the one FROM-clause subquery that is a candidate |
| 149062 | ** for flattening. (This is due to ticket [2f7170d73bf9abf80] |
| 149063 | ** from 2015-02-09.) |
| 149064 | ** |
| 149065 | ** (3) If the subquery is the right operand of a LEFT JOIN then |
| 149066 | ** (3a) the subquery may not be a join |
| 149067 | ** (**) Was (3b): "the FROM clause of the subquery may not contain |
| 149068 | ** a virtual table" |
| 149069 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 149070 | ** is now managed correctly |
| 149071 | ** (3d) the outer query may not be DISTINCT. |
| 149072 | ** See also (26) for restrictions on RIGHT JOIN. |
| 149073 | ** |
| @@ -149322,11 +149279,11 @@ | |
| 149279 | ** |
| 149280 | ** See also tickets #306, #350, and #3300. |
| 149281 | */ |
| 149282 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 149283 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 149284 | /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ |
| 149285 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 149286 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| 149287 | ){ |
| 149288 | return 0; |
| 149289 | } |
| @@ -153366,10 +153323,14 @@ | |
| 153323 | } |
| 153324 | |
| 153325 | if( iOrderByCol ){ |
| 153326 | Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; |
| 153327 | Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153328 | while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ |
| 153329 | pX = pBase->pLeft; |
| 153330 | pBase = sqlite3ExprSkipCollateAndLikely(pX); |
| 153331 | } |
| 153332 | if( ALWAYS(pBase!=0) |
| 153333 | && pBase->op!=TK_AGG_COLUMN |
| 153334 | && pBase->op!=TK_REGISTER |
| 153335 | ){ |
| 153336 | sqlite3ExprToRegister(pX, iAMem+j); |
| @@ -157343,11 +157304,12 @@ | |
| 157304 | saved_flags = db->flags; |
| 157305 | saved_mDbFlags = db->mDbFlags; |
| 157306 | saved_nChange = db->nChange; |
| 157307 | saved_nTotalChange = db->nTotalChange; |
| 157308 | saved_mTrace = db->mTrace; |
| 157309 | db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments |
| 157310 | | SQLITE_AttachCreate | SQLITE_AttachWrite; |
| 157311 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 157312 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 157313 | | SQLITE_Defensive | SQLITE_CountRows); |
| 157314 | db->mTrace = 0; |
| 157315 | |
| @@ -161818,16 +161780,17 @@ | |
| 161780 | } |
| 161781 | |
| 161782 | if( pLevel->iLeftJoin==0 ){ |
| 161783 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 161784 | ** terms from the query that must be true due to the WHERE clause of |
| 161785 | ** the partial index. This optimization does not work on an outer join, |
| 161786 | ** as shown by: |
| 161787 | ** |
| 161788 | ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) |
| 161789 | ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) |
| 161790 | */ |
| 161791 | if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ |
| 161792 | whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); |
| 161793 | } |
| 161794 | }else{ |
| 161795 | testcase( pIdx->pPartIdxWhere ); |
| 161796 | /* The following assert() is not a requirement, merely an observation: |
| @@ -168080,10 +168043,11 @@ | |
| 168043 | Expr *pExpr; |
| 168044 | pExpr = pTerm->pExpr; |
| 168045 | if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) |
| 168046 | && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) |
| 168047 | && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) |
| 168048 | && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) |
| 168049 | && (pTerm->wtFlags & TERM_VNULL)==0 |
| 168050 | ){ |
| 168051 | return 1; |
| 168052 | } |
| 168053 | } |
| @@ -188883,11 +188847,11 @@ | |
| 188847 | |
| 188848 | /* |
| 188849 | ** Macros needed to provide flexible arrays in a portable way |
| 188850 | */ |
| 188851 | #ifndef offsetof |
| 188852 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 188853 | #endif |
| 188854 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188855 | # define FLEXARRAY |
| 188856 | #else |
| 188857 | # define FLEXARRAY 1 |
| @@ -209116,12 +209080,14 @@ | |
| 209080 | nExtra = 0; |
| 209081 | }else if( szType==12 ){ |
| 209082 | nExtra = 1; |
| 209083 | }else if( szType==13 ){ |
| 209084 | nExtra = 2; |
| 209085 | }else if( szType==14 ){ |
| 209086 | nExtra = 4; |
| 209087 | }else{ |
| 209088 | nExtra = 8; |
| 209089 | } |
| 209090 | if( szPayload<=11 ){ |
| 209091 | nNeeded = 0; |
| 209092 | }else if( szPayload<=0xff ){ |
| 209093 | nNeeded = 1; |
| @@ -212681,22 +212647,24 @@ | |
| 212647 | const char *z; |
| 212648 | u32 n; |
| 212649 | UNUSED_PARAMETER(argc); |
| 212650 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); |
| 212651 | if( pStr ){ |
| 212652 | z = (const char*)sqlite3_value_text(argv[0]); |
| 212653 | n = sqlite3Strlen30(z); |
| 212654 | if( pStr->zBuf==0 ){ |
| 212655 | jsonStringInit(pStr, ctx); |
| 212656 | jsonAppendChar(pStr, '{'); |
| 212657 | }else if( pStr->nUsed>1 && z!=0 ){ |
| 212658 | jsonAppendChar(pStr, ','); |
| 212659 | } |
| 212660 | pStr->pCtx = ctx; |
| 212661 | if( z!=0 ){ |
| 212662 | jsonAppendString(pStr, z, n); |
| 212663 | jsonAppendChar(pStr, ':'); |
| 212664 | jsonAppendSqlValue(pStr, argv[1]); |
| 212665 | } |
| 212666 | } |
| 212667 | } |
| 212668 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 212669 | JsonString *pStr; |
| 212670 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| @@ -213500,10 +213468,12 @@ | |
| 213468 | #else |
| 213469 | /* #include "sqlite3.h" */ |
| 213470 | #endif |
| 213471 | SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ |
| 213472 | |
| 213473 | /* #include <stddef.h> */ |
| 213474 | |
| 213475 | /* |
| 213476 | ** If building separately, we will need some setup that is normally |
| 213477 | ** found in sqliteInt.h |
| 213478 | */ |
| 213479 | #if !defined(SQLITE_AMALGAMATION) |
| @@ -213531,11 +213501,11 @@ | |
| 213501 | #else |
| 213502 | # define ALWAYS(X) (X) |
| 213503 | # define NEVER(X) (X) |
| 213504 | #endif |
| 213505 | #ifndef offsetof |
| 213506 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 213507 | #endif |
| 213508 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213509 | # define FLEXARRAY |
| 213510 | #else |
| 213511 | # define FLEXARRAY 1 |
| @@ -227848,11 +227818,12 @@ | |
| 227818 | DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; |
| 227819 | int rc; |
| 227820 | sqlite3 *db = pTab->db; |
| 227821 | Btree *pBt; |
| 227822 | |
| 227823 | UNUSED_PARAMETER(idxStr); |
| 227824 | UNUSED_PARAMETER(argc); |
| 227825 | |
| 227826 | /* Default setting is no rows of result */ |
| 227827 | pCsr->pgno = 1; |
| 227828 | pCsr->mxPgno = 0; |
| 227829 | |
| @@ -231510,18 +231481,19 @@ | |
| 231481 | /* |
| 231482 | ** If the SessionInput object passed as the only argument is a streaming |
| 231483 | ** object and the buffer is full, discard some data to free up space. |
| 231484 | */ |
| 231485 | static void sessionDiscardData(SessionInput *pIn){ |
| 231486 | if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ |
| 231487 | int nMove = pIn->buf.nBuf - pIn->iCurrent; |
| 231488 | assert( nMove>=0 ); |
| 231489 | if( nMove>0 ){ |
| 231490 | memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); |
| 231491 | } |
| 231492 | pIn->buf.nBuf -= pIn->iCurrent; |
| 231493 | pIn->iNext -= pIn->iCurrent; |
| 231494 | pIn->iCurrent = 0; |
| 231495 | pIn->nData = pIn->buf.nBuf; |
| 231496 | } |
| 231497 | } |
| 231498 | |
| 231499 | /* |
| @@ -231871,12 +231843,12 @@ | |
| 231843 | ** sufficient either for the 'T' or 'P' byte and the varint that follows |
| 231844 | ** it, or for the two single byte values otherwise. */ |
| 231845 | p->rc = sessionInputBuffer(&p->in, 2); |
| 231846 | if( p->rc!=SQLITE_OK ) return p->rc; |
| 231847 | |
| 231848 | p->in.iCurrent = p->in.iNext; |
| 231849 | sessionDiscardData(&p->in); |
| 231850 | |
| 231851 | /* If the iterator is already at the end of the changeset, return DONE. */ |
| 231852 | if( p->in.iNext>=p->in.nData ){ |
| 231853 | return SQLITE_DONE; |
| 231854 | } |
| @@ -234231,18 +234203,23 @@ | |
| 234203 | */ |
| 234204 | SQLITE_API int sqlite3changegroup_add_change( |
| 234205 | sqlite3_changegroup *pGrp, |
| 234206 | sqlite3_changeset_iter *pIter |
| 234207 | ){ |
| 234208 | int rc = SQLITE_OK; |
| 234209 | |
| 234210 | if( pIter->in.iCurrent==pIter->in.iNext |
| 234211 | || pIter->rc!=SQLITE_OK |
| 234212 | || pIter->bInvert |
| 234213 | ){ |
| 234214 | /* Iterator does not point to any valid entry or is an INVERT iterator. */ |
| 234215 | rc = SQLITE_ERROR; |
| 234216 | }else{ |
| 234217 | pIter->in.bNoDiscard = 1; |
| 234218 | rc = sessionOneChangeToHash(pGrp, pIter, 0); |
| 234219 | } |
| 234220 | return rc; |
| 234221 | } |
| 234222 | |
| 234223 | /* |
| 234224 | ** Obtain a buffer containing a changeset representing the concatenation |
| 234225 | ** of all changesets added to the group so far. |
| @@ -235536,10 +235513,11 @@ | |
| 235513 | /* #include "sqlite3ext.h" */ |
| 235514 | SQLITE_EXTENSION_INIT1 |
| 235515 | |
| 235516 | /* #include <string.h> */ |
| 235517 | /* #include <assert.h> */ |
| 235518 | /* #include <stddef.h> */ |
| 235519 | |
| 235520 | #ifndef SQLITE_AMALGAMATION |
| 235521 | |
| 235522 | typedef unsigned char u8; |
| 235523 | typedef unsigned int u32; |
| @@ -235595,11 +235573,11 @@ | |
| 235573 | |
| 235574 | /* |
| 235575 | ** Macros needed to provide flexible arrays in a portable way |
| 235576 | */ |
| 235577 | #ifndef offsetof |
| 235578 | # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) |
| 235579 | #endif |
| 235580 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235581 | # define FLEXARRAY |
| 235582 | #else |
| 235583 | # define FLEXARRAY 1 |
| @@ -257279,11 +257257,11 @@ | |
| 257257 | int nArg, /* Number of args */ |
| 257258 | sqlite3_value **apUnused /* Function arguments */ |
| 257259 | ){ |
| 257260 | assert( nArg==0 ); |
| 257261 | UNUSED_PARAM2(nArg, apUnused); |
| 257262 | sqlite3_result_text(pCtx, "fts5: 2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5", -1, SQLITE_TRANSIENT); |
| 257263 | } |
| 257264 | |
| 257265 | /* |
| 257266 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 257267 | ** |
| 257268 |
+3
-3
| --- extsrc/sqlite3.h | ||
| +++ extsrc/sqlite3.h | ||
| @@ -144,13 +144,13 @@ | ||
| 144 | 144 | ** |
| 145 | 145 | ** See also: [sqlite3_libversion()], |
| 146 | 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | 148 | */ |
| 149 | -#define SQLITE_VERSION "3.50.0" | |
| 150 | -#define SQLITE_VERSION_NUMBER 3050000 | |
| 151 | -#define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" | |
| 149 | +#define SQLITE_VERSION "3.51.0" | |
| 150 | +#define SQLITE_VERSION_NUMBER 3051000 | |
| 151 | +#define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" | |
| 152 | 152 | |
| 153 | 153 | /* |
| 154 | 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | 156 | ** |
| 157 | 157 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -144,13 +144,13 @@ | |
| 144 | ** |
| 145 | ** See also: [sqlite3_libversion()], |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.50.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3050000 |
| 151 | #define SQLITE_SOURCE_ID "2025-05-15 11:20:54 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| 157 |
| --- extsrc/sqlite3.h | |
| +++ extsrc/sqlite3.h | |
| @@ -144,13 +144,13 @@ | |
| 144 | ** |
| 145 | ** See also: [sqlite3_libversion()], |
| 146 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 147 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 148 | */ |
| 149 | #define SQLITE_VERSION "3.51.0" |
| 150 | #define SQLITE_VERSION_NUMBER 3051000 |
| 151 | #define SQLITE_SOURCE_ID "2025-06-03 10:49:51 ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5" |
| 152 | |
| 153 | /* |
| 154 | ** CAPI3REF: Run-Time Library Version Numbers |
| 155 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 156 | ** |
| 157 |
+1
-1
| --- src/ajax.c | ||
| +++ src/ajax.c | ||
| @@ -307,11 +307,11 @@ | ||
| 307 | 307 | Blob content = empty_blob; |
| 308 | 308 | const char * zRenderMode = 0; |
| 309 | 309 | |
| 310 | 310 | ajax_get_fnci_args( &zFilename, 0 ); |
| 311 | 311 | |
| 312 | - if(!ajax_route_bootstrap(1,1)){ | |
| 312 | + if(!ajax_route_bootstrap(0,1)){ | |
| 313 | 313 | return; |
| 314 | 314 | } |
| 315 | 315 | if(zFilename==0){ |
| 316 | 316 | /* The filename is only used for mimetype determination, |
| 317 | 317 | ** so we can default it... */ |
| 318 | 318 |
| --- src/ajax.c | |
| +++ src/ajax.c | |
| @@ -307,11 +307,11 @@ | |
| 307 | Blob content = empty_blob; |
| 308 | const char * zRenderMode = 0; |
| 309 | |
| 310 | ajax_get_fnci_args( &zFilename, 0 ); |
| 311 | |
| 312 | if(!ajax_route_bootstrap(1,1)){ |
| 313 | return; |
| 314 | } |
| 315 | if(zFilename==0){ |
| 316 | /* The filename is only used for mimetype determination, |
| 317 | ** so we can default it... */ |
| 318 |
| --- src/ajax.c | |
| +++ src/ajax.c | |
| @@ -307,11 +307,11 @@ | |
| 307 | Blob content = empty_blob; |
| 308 | const char * zRenderMode = 0; |
| 309 | |
| 310 | ajax_get_fnci_args( &zFilename, 0 ); |
| 311 | |
| 312 | if(!ajax_route_bootstrap(0,1)){ |
| 313 | return; |
| 314 | } |
| 315 | if(zFilename==0){ |
| 316 | /* The filename is only used for mimetype determination, |
| 317 | ** so we can default it... */ |
| 318 |
+2
-2
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -505,11 +505,11 @@ | ||
| 505 | 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | 506 | ){ |
| 507 | 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | 509 | ** be different every time. */ |
| 510 | - blob_appendf(&hdr, "ETag: %s\r\n", etag_tag()); | |
| 510 | + blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag()); | |
| 511 | 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | 512 | if( etag_mtime()>0 ){ |
| 513 | 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | 515 | } |
| @@ -2146,11 +2146,11 @@ | ||
| 2146 | 2146 | } |
| 2147 | 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | 2150 | ){ |
| 2151 | - malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports" | |
| 2151 | + malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports " | |
| 2152 | 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | 2153 | } |
| 2154 | 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | 2156 | zToken = extract_token(z, &z); |
| 2157 | 2157 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -505,11 +505,11 @@ | |
| 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | ){ |
| 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | ** be different every time. */ |
| 510 | blob_appendf(&hdr, "ETag: %s\r\n", etag_tag()); |
| 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | if( etag_mtime()>0 ){ |
| 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | } |
| @@ -2146,11 +2146,11 @@ | |
| 2146 | } |
| 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | ){ |
| 2151 | malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports" |
| 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | } |
| 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | zToken = extract_token(z, &z); |
| 2157 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -505,11 +505,11 @@ | |
| 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | ){ |
| 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | ** be different every time. */ |
| 510 | blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag()); |
| 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | if( etag_mtime()>0 ){ |
| 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | } |
| @@ -2146,11 +2146,11 @@ | |
| 2146 | } |
| 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | ){ |
| 2151 | malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports " |
| 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | } |
| 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | zToken = extract_token(z, &z); |
| 2157 |
+2
-2
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -505,11 +505,11 @@ | ||
| 505 | 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | 506 | ){ |
| 507 | 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | 509 | ** be different every time. */ |
| 510 | - blob_appendf(&hdr, "ETag: %s\r\n", etag_tag()); | |
| 510 | + blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag()); | |
| 511 | 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | 512 | if( etag_mtime()>0 ){ |
| 513 | 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | 515 | } |
| @@ -2146,11 +2146,11 @@ | ||
| 2146 | 2146 | } |
| 2147 | 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | 2150 | ){ |
| 2151 | - malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports" | |
| 2151 | + malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports " | |
| 2152 | 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | 2153 | } |
| 2154 | 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | 2156 | zToken = extract_token(z, &z); |
| 2157 | 2157 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -505,11 +505,11 @@ | |
| 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | ){ |
| 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | ** be different every time. */ |
| 510 | blob_appendf(&hdr, "ETag: %s\r\n", etag_tag()); |
| 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | if( etag_mtime()>0 ){ |
| 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | } |
| @@ -2146,11 +2146,11 @@ | |
| 2146 | } |
| 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | ){ |
| 2151 | malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports" |
| 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | } |
| 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | zToken = extract_token(z, &z); |
| 2157 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -505,11 +505,11 @@ | |
| 505 | && strcmp(zContentType,"text/html")!=0 |
| 506 | ){ |
| 507 | /* Do not cache HTML replies as those will have been generated and |
| 508 | ** will likely, therefore, contains a nonce and we want that nonce to |
| 509 | ** be different every time. */ |
| 510 | blob_appendf(&hdr, "ETag: \"%s\"\r\n", etag_tag()); |
| 511 | blob_appendf(&hdr, "Cache-Control: max-age=%d\r\n", etag_maxage()); |
| 512 | if( etag_mtime()>0 ){ |
| 513 | blob_appendf(&hdr, "Last-Modified: %s\r\n", |
| 514 | cgi_rfc822_datestamp(etag_mtime())); |
| 515 | } |
| @@ -2146,11 +2146,11 @@ | |
| 2146 | } |
| 2147 | if( fossil_strcmp(zToken,"GET")!=0 |
| 2148 | && fossil_strcmp(zToken,"POST")!=0 |
| 2149 | && fossil_strcmp(zToken,"HEAD")!=0 |
| 2150 | ){ |
| 2151 | malformed_request("unsupported HTTP method: \"%s\" - Fossil only supports " |
| 2152 | "GET, POST, and HEAD", zToken); |
| 2153 | } |
| 2154 | cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); |
| 2155 | cgi_setenv("REQUEST_METHOD",zToken); |
| 2156 | zToken = extract_token(z, &z); |
| 2157 |
+1
-6
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -667,16 +667,11 @@ | ||
| 667 | 667 | blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1); |
| 668 | 668 | blob_append_escaped_arg(&cmd, zFile2, 1); |
| 669 | 669 | } |
| 670 | 670 | |
| 671 | 671 | /* Run the external diff command */ |
| 672 | - if( fossil_system(blob_str(&cmd)) ){ | |
| 673 | -#if !defined(_WIN32) | |
| 674 | - /* On Windows, exit codes are unreliable. */ | |
| 675 | - fossil_warning("External diff command failed: %b\n", &cmd); | |
| 676 | -#endif | |
| 677 | - } | |
| 672 | + fossil_system(blob_str(&cmd)); | |
| 678 | 673 | |
| 679 | 674 | /* Delete the temporary file and clean up memory used */ |
| 680 | 675 | if( useTempfile ) file_delete(blob_str(&nameFile1)); |
| 681 | 676 | blob_reset(&nameFile1); |
| 682 | 677 | blob_reset(&cmd); |
| 683 | 678 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -667,16 +667,11 @@ | |
| 667 | blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1); |
| 668 | blob_append_escaped_arg(&cmd, zFile2, 1); |
| 669 | } |
| 670 | |
| 671 | /* Run the external diff command */ |
| 672 | if( fossil_system(blob_str(&cmd)) ){ |
| 673 | #if !defined(_WIN32) |
| 674 | /* On Windows, exit codes are unreliable. */ |
| 675 | fossil_warning("External diff command failed: %b\n", &cmd); |
| 676 | #endif |
| 677 | } |
| 678 | |
| 679 | /* Delete the temporary file and clean up memory used */ |
| 680 | if( useTempfile ) file_delete(blob_str(&nameFile1)); |
| 681 | blob_reset(&nameFile1); |
| 682 | blob_reset(&cmd); |
| 683 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -667,16 +667,11 @@ | |
| 667 | blob_append_escaped_arg(&cmd, blob_str(&nameFile1), 1); |
| 668 | blob_append_escaped_arg(&cmd, zFile2, 1); |
| 669 | } |
| 670 | |
| 671 | /* Run the external diff command */ |
| 672 | fossil_system(blob_str(&cmd)); |
| 673 | |
| 674 | /* Delete the temporary file and clean up memory used */ |
| 675 | if( useTempfile ) file_delete(blob_str(&nameFile1)); |
| 676 | blob_reset(&nameFile1); |
| 677 | blob_reset(&cmd); |
| 678 |
+11
-3
| --- src/etag.c | ||
| +++ src/etag.c | ||
| @@ -94,10 +94,12 @@ | ||
| 94 | 94 | ** Generate an ETag |
| 95 | 95 | */ |
| 96 | 96 | void etag_check(unsigned eFlags, const char *zHash){ |
| 97 | 97 | const char *zIfNoneMatch; |
| 98 | 98 | char zBuf[50]; |
| 99 | + const int cchETag = 32; /* Not including NULL terminator. */ | |
| 100 | + int cch; /* Length of zIfNoneMatch header. */ | |
| 99 | 101 | assert( zETag[0]==0 ); /* Only call this routine once! */ |
| 100 | 102 | |
| 101 | 103 | if( etagCancelled ) return; |
| 102 | 104 | |
| 103 | 105 | /* By default, ETagged URLs never expire since the ETag will change |
| @@ -157,17 +159,23 @@ | ||
| 157 | 159 | md5sum_step_text("\n", 1); |
| 158 | 160 | } |
| 159 | 161 | } |
| 160 | 162 | |
| 161 | 163 | /* Generate the ETag */ |
| 162 | - memcpy(zETag, md5sum_finish(0), 33); | |
| 164 | + memcpy(zETag, md5sum_finish(0), cchETag+1); | |
| 163 | 165 | |
| 164 | 166 | /* Check to see if the generated ETag matches If-None-Match and |
| 165 | - ** generate a 304 reply if it does. */ | |
| 167 | + ** generate a 304 reply if it does. Test both with and without | |
| 168 | + ** double quotes. */ | |
| 166 | 169 | zIfNoneMatch = P("HTTP_IF_NONE_MATCH"); |
| 167 | 170 | if( zIfNoneMatch==0 ) return; |
| 168 | - if( strcmp(zIfNoneMatch,zETag)!=0 ) return; | |
| 171 | + cch = strlen(zIfNoneMatch); | |
| 172 | + if( cch==cchETag+2 && zIfNoneMatch[0]=='"' && zIfNoneMatch[cch-1]=='"' ){ | |
| 173 | + if( memcmp(&zIfNoneMatch[1],zETag,cchETag)!=0 ) return; | |
| 174 | + }else{ | |
| 175 | + if( strcmp(zIfNoneMatch,zETag)!=0 ) return; | |
| 176 | + } | |
| 169 | 177 | |
| 170 | 178 | /* If we get this far, it means that the content has |
| 171 | 179 | ** not changed and we can do a 304 reply */ |
| 172 | 180 | cgi_reset_content(); |
| 173 | 181 | cgi_set_status(304, "Not Modified"); |
| 174 | 182 |
| --- src/etag.c | |
| +++ src/etag.c | |
| @@ -94,10 +94,12 @@ | |
| 94 | ** Generate an ETag |
| 95 | */ |
| 96 | void etag_check(unsigned eFlags, const char *zHash){ |
| 97 | const char *zIfNoneMatch; |
| 98 | char zBuf[50]; |
| 99 | assert( zETag[0]==0 ); /* Only call this routine once! */ |
| 100 | |
| 101 | if( etagCancelled ) return; |
| 102 | |
| 103 | /* By default, ETagged URLs never expire since the ETag will change |
| @@ -157,17 +159,23 @@ | |
| 157 | md5sum_step_text("\n", 1); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /* Generate the ETag */ |
| 162 | memcpy(zETag, md5sum_finish(0), 33); |
| 163 | |
| 164 | /* Check to see if the generated ETag matches If-None-Match and |
| 165 | ** generate a 304 reply if it does. */ |
| 166 | zIfNoneMatch = P("HTTP_IF_NONE_MATCH"); |
| 167 | if( zIfNoneMatch==0 ) return; |
| 168 | if( strcmp(zIfNoneMatch,zETag)!=0 ) return; |
| 169 | |
| 170 | /* If we get this far, it means that the content has |
| 171 | ** not changed and we can do a 304 reply */ |
| 172 | cgi_reset_content(); |
| 173 | cgi_set_status(304, "Not Modified"); |
| 174 |
| --- src/etag.c | |
| +++ src/etag.c | |
| @@ -94,10 +94,12 @@ | |
| 94 | ** Generate an ETag |
| 95 | */ |
| 96 | void etag_check(unsigned eFlags, const char *zHash){ |
| 97 | const char *zIfNoneMatch; |
| 98 | char zBuf[50]; |
| 99 | const int cchETag = 32; /* Not including NULL terminator. */ |
| 100 | int cch; /* Length of zIfNoneMatch header. */ |
| 101 | assert( zETag[0]==0 ); /* Only call this routine once! */ |
| 102 | |
| 103 | if( etagCancelled ) return; |
| 104 | |
| 105 | /* By default, ETagged URLs never expire since the ETag will change |
| @@ -157,17 +159,23 @@ | |
| 159 | md5sum_step_text("\n", 1); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | /* Generate the ETag */ |
| 164 | memcpy(zETag, md5sum_finish(0), cchETag+1); |
| 165 | |
| 166 | /* Check to see if the generated ETag matches If-None-Match and |
| 167 | ** generate a 304 reply if it does. Test both with and without |
| 168 | ** double quotes. */ |
| 169 | zIfNoneMatch = P("HTTP_IF_NONE_MATCH"); |
| 170 | if( zIfNoneMatch==0 ) return; |
| 171 | cch = strlen(zIfNoneMatch); |
| 172 | if( cch==cchETag+2 && zIfNoneMatch[0]=='"' && zIfNoneMatch[cch-1]=='"' ){ |
| 173 | if( memcmp(&zIfNoneMatch[1],zETag,cchETag)!=0 ) return; |
| 174 | }else{ |
| 175 | if( strcmp(zIfNoneMatch,zETag)!=0 ) return; |
| 176 | } |
| 177 | |
| 178 | /* If we get this far, it means that the content has |
| 179 | ** not changed and we can do a 304 reply */ |
| 180 | cgi_reset_content(); |
| 181 | cgi_set_status(304, "Not Modified"); |
| 182 |
+1
-1
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -765,11 +765,11 @@ | ||
| 765 | 765 | ** COMMAND: test-httpmsg |
| 766 | 766 | ** |
| 767 | 767 | ** Usage: %fossil test-httpmsg ?OPTIONS? URL ?PAYLOAD? ?OUTPUT? |
| 768 | 768 | ** |
| 769 | 769 | ** Send an HTTP message to URL and get the reply. PAYLOAD is a file containing |
| 770 | -** the payload, or "-" to read payload from standard input. a POST message | |
| 770 | +** the payload, or "-" to read payload from standard input. A POST message | |
| 771 | 771 | ** is sent if PAYLOAD is specified and is non-empty. If PAYLOAD is omitted |
| 772 | 772 | ** or is an empty file, then a GET message is sent. |
| 773 | 773 | ** |
| 774 | 774 | ** If a second filename (OUTPUT) is given after PAYLOAD, then the reply |
| 775 | 775 | ** is written into that second file instead of being written on standard |
| 776 | 776 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -765,11 +765,11 @@ | |
| 765 | ** COMMAND: test-httpmsg |
| 766 | ** |
| 767 | ** Usage: %fossil test-httpmsg ?OPTIONS? URL ?PAYLOAD? ?OUTPUT? |
| 768 | ** |
| 769 | ** Send an HTTP message to URL and get the reply. PAYLOAD is a file containing |
| 770 | ** the payload, or "-" to read payload from standard input. a POST message |
| 771 | ** is sent if PAYLOAD is specified and is non-empty. If PAYLOAD is omitted |
| 772 | ** or is an empty file, then a GET message is sent. |
| 773 | ** |
| 774 | ** If a second filename (OUTPUT) is given after PAYLOAD, then the reply |
| 775 | ** is written into that second file instead of being written on standard |
| 776 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -765,11 +765,11 @@ | |
| 765 | ** COMMAND: test-httpmsg |
| 766 | ** |
| 767 | ** Usage: %fossil test-httpmsg ?OPTIONS? URL ?PAYLOAD? ?OUTPUT? |
| 768 | ** |
| 769 | ** Send an HTTP message to URL and get the reply. PAYLOAD is a file containing |
| 770 | ** the payload, or "-" to read payload from standard input. A POST message |
| 771 | ** is sent if PAYLOAD is specified and is non-empty. If PAYLOAD is omitted |
| 772 | ** or is an empty file, then a GET message is sent. |
| 773 | ** |
| 774 | ** If a second filename (OUTPUT) is given after PAYLOAD, then the reply |
| 775 | ** is written into that second file instead of being written on standard |
| 776 |
+1
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -3064,11 +3064,11 @@ | ||
| 3064 | 3064 | ** |
| 3065 | 3065 | ** echo 'GET /timeline' >request.txt |
| 3066 | 3066 | ** |
| 3067 | 3067 | ** Then run (in a debugger) a command like this: |
| 3068 | 3068 | ** |
| 3069 | -** fossil test-http --debug <request.txt | |
| 3069 | +** fossil test-http <request.txt | |
| 3070 | 3070 | ** |
| 3071 | 3071 | ** This command is also used internally by the "ssh" sync protocol. Some |
| 3072 | 3072 | ** special processing to support sync happens when this command is run |
| 3073 | 3073 | ** and the SSH_CONNECTION environment variable is set. Use the --test |
| 3074 | 3074 | ** option on interactive sessions to avoid that special processing when |
| 3075 | 3075 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -3064,11 +3064,11 @@ | |
| 3064 | ** |
| 3065 | ** echo 'GET /timeline' >request.txt |
| 3066 | ** |
| 3067 | ** Then run (in a debugger) a command like this: |
| 3068 | ** |
| 3069 | ** fossil test-http --debug <request.txt |
| 3070 | ** |
| 3071 | ** This command is also used internally by the "ssh" sync protocol. Some |
| 3072 | ** special processing to support sync happens when this command is run |
| 3073 | ** and the SSH_CONNECTION environment variable is set. Use the --test |
| 3074 | ** option on interactive sessions to avoid that special processing when |
| 3075 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -3064,11 +3064,11 @@ | |
| 3064 | ** |
| 3065 | ** echo 'GET /timeline' >request.txt |
| 3066 | ** |
| 3067 | ** Then run (in a debugger) a command like this: |
| 3068 | ** |
| 3069 | ** fossil test-http <request.txt |
| 3070 | ** |
| 3071 | ** This command is also used internally by the "ssh" sync protocol. Some |
| 3072 | ** special processing to support sync happens when this command is run |
| 3073 | ** and the SSH_CONNECTION environment variable is set. Use the --test |
| 3074 | ** option on interactive sessions to avoid that special processing when |
| 3075 |
+5
-3
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -268,16 +268,18 @@ | ||
| 268 | 268 | } |
| 269 | 269 | @ <tr><th>Project Age:</th><td> |
| 270 | 270 | z = db_text(0, "SELECT timediff('now',(SELECT min(mtime) FROM event));"); |
| 271 | 271 | sscanf(z, "+%d-%d-%d", &Y, &M, &D); |
| 272 | 272 | if( Y>0 ){ |
| 273 | - @ %d(Y) years, \ | |
| 273 | + @ %d(Y) year%s(Y==1?"":"s") \ | |
| 274 | 274 | } |
| 275 | 275 | if( M>0 ){ |
| 276 | - @ %d(M) months, \ | |
| 276 | + @ %d(M) month%s(M==1?"":"s") \ | |
| 277 | 277 | } |
| 278 | - @ %d(D) days | |
| 278 | + if( D>0 || (Y==0 && M==0) ){ | |
| 279 | + @ %d(D) day%s(D==1?"":"s") | |
| 280 | + } | |
| 279 | 281 | @ </td></tr> |
| 280 | 282 | p = db_get("project-code", 0); |
| 281 | 283 | if( p ){ |
| 282 | 284 | @ <tr><th>Project ID:</th> |
| 283 | 285 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| 284 | 286 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -268,16 +268,18 @@ | |
| 268 | } |
| 269 | @ <tr><th>Project Age:</th><td> |
| 270 | z = db_text(0, "SELECT timediff('now',(SELECT min(mtime) FROM event));"); |
| 271 | sscanf(z, "+%d-%d-%d", &Y, &M, &D); |
| 272 | if( Y>0 ){ |
| 273 | @ %d(Y) years, \ |
| 274 | } |
| 275 | if( M>0 ){ |
| 276 | @ %d(M) months, \ |
| 277 | } |
| 278 | @ %d(D) days |
| 279 | @ </td></tr> |
| 280 | p = db_get("project-code", 0); |
| 281 | if( p ){ |
| 282 | @ <tr><th>Project ID:</th> |
| 283 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| 284 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -268,16 +268,18 @@ | |
| 268 | } |
| 269 | @ <tr><th>Project Age:</th><td> |
| 270 | z = db_text(0, "SELECT timediff('now',(SELECT min(mtime) FROM event));"); |
| 271 | sscanf(z, "+%d-%d-%d", &Y, &M, &D); |
| 272 | if( Y>0 ){ |
| 273 | @ %d(Y) year%s(Y==1?"":"s") \ |
| 274 | } |
| 275 | if( M>0 ){ |
| 276 | @ %d(M) month%s(M==1?"":"s") \ |
| 277 | } |
| 278 | if( D>0 || (Y==0 && M==0) ){ |
| 279 | @ %d(D) day%s(D==1?"":"s") |
| 280 | } |
| 281 | @ </td></tr> |
| 282 | p = db_get("project-code", 0); |
| 283 | if( p ){ |
| 284 | @ <tr><th>Project ID:</th> |
| 285 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| 286 |
+41
-5
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1273,11 +1273,11 @@ | ||
| 1273 | 1273 | */ |
| 1274 | 1274 | static void addFileGlobExclusion( |
| 1275 | 1275 | const char *zChng, /* The filename GLOB list */ |
| 1276 | 1276 | Blob *pSql /* The SELECT statement under construction */ |
| 1277 | 1277 | ){ |
| 1278 | - if( zChng==0 || zChng[0]==0 ) return; | |
| 1278 | + if( zChng==0 ) return; | |
| 1279 | 1279 | blob_append_sql(pSql," AND event.objid IN (" |
| 1280 | 1280 | "SELECT mlink.mid FROM mlink, filename\n" |
| 1281 | 1281 | " WHERE mlink.fnid=filename.fnid\n" |
| 1282 | 1282 | " AND %s)", |
| 1283 | 1283 | glob_expr("filename.name", mprintf("\"%s\"", zChng))); |
| @@ -1284,14 +1284,33 @@ | ||
| 1284 | 1284 | } |
| 1285 | 1285 | static void addFileGlobDescription( |
| 1286 | 1286 | const char *zChng, /* The filename GLOB list */ |
| 1287 | 1287 | Blob *pDescription /* Result description */ |
| 1288 | 1288 | ){ |
| 1289 | - if( zChng==0 || zChng[0]==0 ) return; | |
| 1289 | + if( zChng==0 ) return; | |
| 1290 | 1290 | blob_appendf(pDescription, " that include changes to files matching '%h'", |
| 1291 | 1291 | zChng); |
| 1292 | 1292 | } |
| 1293 | + | |
| 1294 | +/* | |
| 1295 | +** If zChng is not NULL, then use it as a comma-separated list of | |
| 1296 | +** glob patterns for filenames, and remove from the "ok" table any | |
| 1297 | +** check-ins that do not modify one or more of the files identified | |
| 1298 | +** by zChng. | |
| 1299 | +*/ | |
| 1300 | +static void removeFileGlobFromOk( | |
| 1301 | + const char *zChng /* The filename GLOB list */ | |
| 1302 | +){ | |
| 1303 | + if( zChng==0 ) return; | |
| 1304 | + db_multi_exec( | |
| 1305 | + "DELETE FROM ok WHERE rid NOT IN (\n" | |
| 1306 | + " SELECT mlink.mid FROM mlink, filename\n" | |
| 1307 | + " WHERE mlink.fnid=filename.fnid\n" | |
| 1308 | + " AND %z);\n", | |
| 1309 | + glob_expr("filename.name", zChng) | |
| 1310 | + ); | |
| 1311 | +} | |
| 1293 | 1312 | |
| 1294 | 1313 | /* |
| 1295 | 1314 | ** Similar to fossil_expand_datetime() |
| 1296 | 1315 | ** |
| 1297 | 1316 | ** Add missing "-" characters into a date/time. Examples: |
| @@ -1777,10 +1796,11 @@ | ||
| 1777 | 1796 | nEntry = 0; |
| 1778 | 1797 | useDividers = 0; |
| 1779 | 1798 | cgi_replace_query_parameter("d",fossil_strdup(z)); |
| 1780 | 1799 | zDPNameD = zDPNameP = z; |
| 1781 | 1800 | } |
| 1801 | + if( zChng && zChng[0]==0 ) zChng = 0; | |
| 1782 | 1802 | |
| 1783 | 1803 | /* Undocumented query parameter to set JS mode */ |
| 1784 | 1804 | builtin_set_js_delivery_mode(P("jsmode"),1); |
| 1785 | 1805 | |
| 1786 | 1806 | secondaryRid = name_to_typed_rid(P("sel2"),"ci"); |
| @@ -2174,12 +2194,14 @@ | ||
| 2174 | 2194 | ); |
| 2175 | 2195 | } |
| 2176 | 2196 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2177 | 2197 | } |
| 2178 | 2198 | add_extra_rids("pathnode",P("x")); |
| 2199 | + add_extra_rids("pathnode",P("sel1")); | |
| 2200 | + add_extra_rids("pathnode",P("sel2")); | |
| 2179 | 2201 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2180 | - if( zChng && zChng[0] ){ | |
| 2202 | + if( zChng ){ | |
| 2181 | 2203 | db_multi_exec( |
| 2182 | 2204 | "DELETE FROM pathnode\n" |
| 2183 | 2205 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| 2184 | 2206 | " WHERE mlink.mid=x\n" |
| 2185 | 2207 | " AND mlink.fnid=filename.fnid\n" |
| @@ -2248,10 +2270,12 @@ | ||
| 2248 | 2270 | } |
| 2249 | 2271 | db_multi_exec( |
| 2250 | 2272 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2251 | 2273 | ); |
| 2252 | 2274 | add_extra_rids("ok", P("x")); |
| 2275 | + add_extra_rids("ok", P("sel1")); | |
| 2276 | + add_extra_rids("ok", P("sel2")); | |
| 2253 | 2277 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| 2254 | 2278 | nd = 0; |
| 2255 | 2279 | if( d_rid ){ |
| 2256 | 2280 | double rStopTime = 9e99; |
| 2257 | 2281 | zFwdTo = P("ft"); |
| @@ -2299,14 +2323,16 @@ | ||
| 2299 | 2323 | db_multi_exec( |
| 2300 | 2324 | "INSERT INTO ok_d SELECT rid FROM ok;" |
| 2301 | 2325 | "DELETE FROM ok;" |
| 2302 | 2326 | ); |
| 2303 | 2327 | }else{ |
| 2328 | + removeFileGlobFromOk(zChng); | |
| 2304 | 2329 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2305 | 2330 | if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql)); |
| 2306 | 2331 | if( nd>0 || p_rid==0 ){ |
| 2307 | - blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); | |
| 2332 | + blob_appendf(&desc, "%d descendant%s", | |
| 2333 | + nd>=0 ? nd : 0,(1==nd)?"":"s"); | |
| 2308 | 2334 | } |
| 2309 | 2335 | if( useDividers && !selectedRid ) selectedRid = d_rid; |
| 2310 | 2336 | db_multi_exec("DELETE FROM ok"); |
| 2311 | 2337 | } |
| 2312 | 2338 | } |
| @@ -2335,21 +2361,25 @@ | ||
| 2335 | 2361 | db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo); |
| 2336 | 2362 | bBackAdded = 1; |
| 2337 | 2363 | } |
| 2338 | 2364 | if( bSeparateDandP ){ |
| 2339 | 2365 | db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;"); |
| 2366 | + removeFileGlobFromOk(zChng); | |
| 2340 | 2367 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2341 | 2368 | }else{ |
| 2369 | + removeFileGlobFromOk(zChng); | |
| 2342 | 2370 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2343 | 2371 | if( np>0 || nd==0 ){ |
| 2344 | 2372 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 2345 | - blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s"); | |
| 2373 | + blob_appendf(&desc, "%d ancestor%s", | |
| 2374 | + np>=0 ? np : 0, (1==np)?"":"s"); | |
| 2346 | 2375 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2347 | 2376 | } |
| 2348 | 2377 | if( useDividers && !selectedRid ) selectedRid = p_rid; |
| 2349 | 2378 | } |
| 2350 | 2379 | } |
| 2380 | + | |
| 2351 | 2381 | if( bSeparateDandP ){ |
| 2352 | 2382 | int n = db_int(0, "SELECT count(*) FROM ok"); |
| 2353 | 2383 | blob_reset(&desc); |
| 2354 | 2384 | blob_appendf(&desc, |
| 2355 | 2385 | "%d check-ins that are derived from %z%h</a>" |
| @@ -2392,10 +2422,14 @@ | ||
| 2392 | 2422 | blob_appendf(&desc, " up to %z%h</a>%s", |
| 2393 | 2423 | href("%R/info?name=%h",zFwdTo), zFwdTo, |
| 2394 | 2424 | bFwdAdded ? " (not a direct descendant)":""); |
| 2395 | 2425 | } |
| 2396 | 2426 | } |
| 2427 | + if( zChng ){ | |
| 2428 | + if( strstr(blob_str(&desc)," that ") ) blob_appendf(&desc, " and"); | |
| 2429 | + blob_appendf(&desc, " that make changes to files matching \"%h\"", zChng); | |
| 2430 | + } | |
| 2397 | 2431 | if( advancedMenu ){ |
| 2398 | 2432 | style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0); |
| 2399 | 2433 | } |
| 2400 | 2434 | style_submenu_entry("n","Max:",4,0); |
| 2401 | 2435 | timeline_y_submenu(1); |
| @@ -2730,10 +2764,12 @@ | ||
| 2730 | 2764 | int ridMark = name_to_rid(zMark); |
| 2731 | 2765 | db_multi_exec( |
| 2732 | 2766 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2733 | 2767 | } |
| 2734 | 2768 | add_extra_rids("selected_nodes",P("x")); |
| 2769 | + add_extra_rids("selected_nodes",P("sel1")); | |
| 2770 | + add_extra_rids("selected_nodes",P("sel2")); | |
| 2735 | 2771 | if( related==0 ){ |
| 2736 | 2772 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2737 | 2773 | }else{ |
| 2738 | 2774 | db_multi_exec( |
| 2739 | 2775 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2740 | 2776 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1273,11 +1273,11 @@ | |
| 1273 | */ |
| 1274 | static void addFileGlobExclusion( |
| 1275 | const char *zChng, /* The filename GLOB list */ |
| 1276 | Blob *pSql /* The SELECT statement under construction */ |
| 1277 | ){ |
| 1278 | if( zChng==0 || zChng[0]==0 ) return; |
| 1279 | blob_append_sql(pSql," AND event.objid IN (" |
| 1280 | "SELECT mlink.mid FROM mlink, filename\n" |
| 1281 | " WHERE mlink.fnid=filename.fnid\n" |
| 1282 | " AND %s)", |
| 1283 | glob_expr("filename.name", mprintf("\"%s\"", zChng))); |
| @@ -1284,14 +1284,33 @@ | |
| 1284 | } |
| 1285 | static void addFileGlobDescription( |
| 1286 | const char *zChng, /* The filename GLOB list */ |
| 1287 | Blob *pDescription /* Result description */ |
| 1288 | ){ |
| 1289 | if( zChng==0 || zChng[0]==0 ) return; |
| 1290 | blob_appendf(pDescription, " that include changes to files matching '%h'", |
| 1291 | zChng); |
| 1292 | } |
| 1293 | |
| 1294 | /* |
| 1295 | ** Similar to fossil_expand_datetime() |
| 1296 | ** |
| 1297 | ** Add missing "-" characters into a date/time. Examples: |
| @@ -1777,10 +1796,11 @@ | |
| 1777 | nEntry = 0; |
| 1778 | useDividers = 0; |
| 1779 | cgi_replace_query_parameter("d",fossil_strdup(z)); |
| 1780 | zDPNameD = zDPNameP = z; |
| 1781 | } |
| 1782 | |
| 1783 | /* Undocumented query parameter to set JS mode */ |
| 1784 | builtin_set_js_delivery_mode(P("jsmode"),1); |
| 1785 | |
| 1786 | secondaryRid = name_to_typed_rid(P("sel2"),"ci"); |
| @@ -2174,12 +2194,14 @@ | |
| 2174 | ); |
| 2175 | } |
| 2176 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2177 | } |
| 2178 | add_extra_rids("pathnode",P("x")); |
| 2179 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2180 | if( zChng && zChng[0] ){ |
| 2181 | db_multi_exec( |
| 2182 | "DELETE FROM pathnode\n" |
| 2183 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| 2184 | " WHERE mlink.mid=x\n" |
| 2185 | " AND mlink.fnid=filename.fnid\n" |
| @@ -2248,10 +2270,12 @@ | |
| 2248 | } |
| 2249 | db_multi_exec( |
| 2250 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2251 | ); |
| 2252 | add_extra_rids("ok", P("x")); |
| 2253 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| 2254 | nd = 0; |
| 2255 | if( d_rid ){ |
| 2256 | double rStopTime = 9e99; |
| 2257 | zFwdTo = P("ft"); |
| @@ -2299,14 +2323,16 @@ | |
| 2299 | db_multi_exec( |
| 2300 | "INSERT INTO ok_d SELECT rid FROM ok;" |
| 2301 | "DELETE FROM ok;" |
| 2302 | ); |
| 2303 | }else{ |
| 2304 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2305 | if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql)); |
| 2306 | if( nd>0 || p_rid==0 ){ |
| 2307 | blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); |
| 2308 | } |
| 2309 | if( useDividers && !selectedRid ) selectedRid = d_rid; |
| 2310 | db_multi_exec("DELETE FROM ok"); |
| 2311 | } |
| 2312 | } |
| @@ -2335,21 +2361,25 @@ | |
| 2335 | db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo); |
| 2336 | bBackAdded = 1; |
| 2337 | } |
| 2338 | if( bSeparateDandP ){ |
| 2339 | db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;"); |
| 2340 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2341 | }else{ |
| 2342 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2343 | if( np>0 || nd==0 ){ |
| 2344 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 2345 | blob_appendf(&desc, "%d ancestor%s", np, (1==np)?"":"s"); |
| 2346 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2347 | } |
| 2348 | if( useDividers && !selectedRid ) selectedRid = p_rid; |
| 2349 | } |
| 2350 | } |
| 2351 | if( bSeparateDandP ){ |
| 2352 | int n = db_int(0, "SELECT count(*) FROM ok"); |
| 2353 | blob_reset(&desc); |
| 2354 | blob_appendf(&desc, |
| 2355 | "%d check-ins that are derived from %z%h</a>" |
| @@ -2392,10 +2422,14 @@ | |
| 2392 | blob_appendf(&desc, " up to %z%h</a>%s", |
| 2393 | href("%R/info?name=%h",zFwdTo), zFwdTo, |
| 2394 | bFwdAdded ? " (not a direct descendant)":""); |
| 2395 | } |
| 2396 | } |
| 2397 | if( advancedMenu ){ |
| 2398 | style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0); |
| 2399 | } |
| 2400 | style_submenu_entry("n","Max:",4,0); |
| 2401 | timeline_y_submenu(1); |
| @@ -2730,10 +2764,12 @@ | |
| 2730 | int ridMark = name_to_rid(zMark); |
| 2731 | db_multi_exec( |
| 2732 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2733 | } |
| 2734 | add_extra_rids("selected_nodes",P("x")); |
| 2735 | if( related==0 ){ |
| 2736 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2737 | }else{ |
| 2738 | db_multi_exec( |
| 2739 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2740 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1273,11 +1273,11 @@ | |
| 1273 | */ |
| 1274 | static void addFileGlobExclusion( |
| 1275 | const char *zChng, /* The filename GLOB list */ |
| 1276 | Blob *pSql /* The SELECT statement under construction */ |
| 1277 | ){ |
| 1278 | if( zChng==0 ) return; |
| 1279 | blob_append_sql(pSql," AND event.objid IN (" |
| 1280 | "SELECT mlink.mid FROM mlink, filename\n" |
| 1281 | " WHERE mlink.fnid=filename.fnid\n" |
| 1282 | " AND %s)", |
| 1283 | glob_expr("filename.name", mprintf("\"%s\"", zChng))); |
| @@ -1284,14 +1284,33 @@ | |
| 1284 | } |
| 1285 | static void addFileGlobDescription( |
| 1286 | const char *zChng, /* The filename GLOB list */ |
| 1287 | Blob *pDescription /* Result description */ |
| 1288 | ){ |
| 1289 | if( zChng==0 ) return; |
| 1290 | blob_appendf(pDescription, " that include changes to files matching '%h'", |
| 1291 | zChng); |
| 1292 | } |
| 1293 | |
| 1294 | /* |
| 1295 | ** If zChng is not NULL, then use it as a comma-separated list of |
| 1296 | ** glob patterns for filenames, and remove from the "ok" table any |
| 1297 | ** check-ins that do not modify one or more of the files identified |
| 1298 | ** by zChng. |
| 1299 | */ |
| 1300 | static void removeFileGlobFromOk( |
| 1301 | const char *zChng /* The filename GLOB list */ |
| 1302 | ){ |
| 1303 | if( zChng==0 ) return; |
| 1304 | db_multi_exec( |
| 1305 | "DELETE FROM ok WHERE rid NOT IN (\n" |
| 1306 | " SELECT mlink.mid FROM mlink, filename\n" |
| 1307 | " WHERE mlink.fnid=filename.fnid\n" |
| 1308 | " AND %z);\n", |
| 1309 | glob_expr("filename.name", zChng) |
| 1310 | ); |
| 1311 | } |
| 1312 | |
| 1313 | /* |
| 1314 | ** Similar to fossil_expand_datetime() |
| 1315 | ** |
| 1316 | ** Add missing "-" characters into a date/time. Examples: |
| @@ -1777,10 +1796,11 @@ | |
| 1796 | nEntry = 0; |
| 1797 | useDividers = 0; |
| 1798 | cgi_replace_query_parameter("d",fossil_strdup(z)); |
| 1799 | zDPNameD = zDPNameP = z; |
| 1800 | } |
| 1801 | if( zChng && zChng[0]==0 ) zChng = 0; |
| 1802 | |
| 1803 | /* Undocumented query parameter to set JS mode */ |
| 1804 | builtin_set_js_delivery_mode(P("jsmode"),1); |
| 1805 | |
| 1806 | secondaryRid = name_to_typed_rid(P("sel2"),"ci"); |
| @@ -2174,12 +2194,14 @@ | |
| 2194 | ); |
| 2195 | } |
| 2196 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2197 | } |
| 2198 | add_extra_rids("pathnode",P("x")); |
| 2199 | add_extra_rids("pathnode",P("sel1")); |
| 2200 | add_extra_rids("pathnode",P("sel2")); |
| 2201 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2202 | if( zChng ){ |
| 2203 | db_multi_exec( |
| 2204 | "DELETE FROM pathnode\n" |
| 2205 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| 2206 | " WHERE mlink.mid=x\n" |
| 2207 | " AND mlink.fnid=filename.fnid\n" |
| @@ -2248,10 +2270,12 @@ | |
| 2270 | } |
| 2271 | db_multi_exec( |
| 2272 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2273 | ); |
| 2274 | add_extra_rids("ok", P("x")); |
| 2275 | add_extra_rids("ok", P("sel1")); |
| 2276 | add_extra_rids("ok", P("sel2")); |
| 2277 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| 2278 | nd = 0; |
| 2279 | if( d_rid ){ |
| 2280 | double rStopTime = 9e99; |
| 2281 | zFwdTo = P("ft"); |
| @@ -2299,14 +2323,16 @@ | |
| 2323 | db_multi_exec( |
| 2324 | "INSERT INTO ok_d SELECT rid FROM ok;" |
| 2325 | "DELETE FROM ok;" |
| 2326 | ); |
| 2327 | }else{ |
| 2328 | removeFileGlobFromOk(zChng); |
| 2329 | nd = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2330 | if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql)); |
| 2331 | if( nd>0 || p_rid==0 ){ |
| 2332 | blob_appendf(&desc, "%d descendant%s", |
| 2333 | nd>=0 ? nd : 0,(1==nd)?"":"s"); |
| 2334 | } |
| 2335 | if( useDividers && !selectedRid ) selectedRid = d_rid; |
| 2336 | db_multi_exec("DELETE FROM ok"); |
| 2337 | } |
| 2338 | } |
| @@ -2335,21 +2361,25 @@ | |
| 2361 | db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo); |
| 2362 | bBackAdded = 1; |
| 2363 | } |
| 2364 | if( bSeparateDandP ){ |
| 2365 | db_multi_exec("DELETE FROM ok WHERE rid NOT IN ok_d;"); |
| 2366 | removeFileGlobFromOk(zChng); |
| 2367 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2368 | }else{ |
| 2369 | removeFileGlobFromOk(zChng); |
| 2370 | np = db_int(0, "SELECT count(*)-1 FROM ok"); |
| 2371 | if( np>0 || nd==0 ){ |
| 2372 | if( nd>0 ) blob_appendf(&desc, " and "); |
| 2373 | blob_appendf(&desc, "%d ancestor%s", |
| 2374 | np>=0 ? np : 0, (1==np)?"":"s"); |
| 2375 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 2376 | } |
| 2377 | if( useDividers && !selectedRid ) selectedRid = p_rid; |
| 2378 | } |
| 2379 | } |
| 2380 | |
| 2381 | if( bSeparateDandP ){ |
| 2382 | int n = db_int(0, "SELECT count(*) FROM ok"); |
| 2383 | blob_reset(&desc); |
| 2384 | blob_appendf(&desc, |
| 2385 | "%d check-ins that are derived from %z%h</a>" |
| @@ -2392,10 +2422,14 @@ | |
| 2422 | blob_appendf(&desc, " up to %z%h</a>%s", |
| 2423 | href("%R/info?name=%h",zFwdTo), zFwdTo, |
| 2424 | bFwdAdded ? " (not a direct descendant)":""); |
| 2425 | } |
| 2426 | } |
| 2427 | if( zChng ){ |
| 2428 | if( strstr(blob_str(&desc)," that ") ) blob_appendf(&desc, " and"); |
| 2429 | blob_appendf(&desc, " that make changes to files matching \"%h\"", zChng); |
| 2430 | } |
| 2431 | if( advancedMenu ){ |
| 2432 | style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0); |
| 2433 | } |
| 2434 | style_submenu_entry("n","Max:",4,0); |
| 2435 | timeline_y_submenu(1); |
| @@ -2730,10 +2764,12 @@ | |
| 2764 | int ridMark = name_to_rid(zMark); |
| 2765 | db_multi_exec( |
| 2766 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2767 | } |
| 2768 | add_extra_rids("selected_nodes",P("x")); |
| 2769 | add_extra_rids("selected_nodes",P("sel1")); |
| 2770 | add_extra_rids("selected_nodes",P("sel2")); |
| 2771 | if( related==0 ){ |
| 2772 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2773 | }else{ |
| 2774 | db_multi_exec( |
| 2775 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2776 |
+2
-1
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -1,10 +1,11 @@ | ||
| 1 | 1 | <title>Change Log</title> |
| 2 | 2 | |
| 3 | 3 | <h2 id='v2_27'>Changes for version 2.27 (pending)</h2> |
| 4 | 4 | |
| 5 | - * <i>(pending)</i> | |
| 5 | + * Enhance the chng= query parameter on the [/help?cmd=/timeline|timeline page] | |
| 6 | + so that it works with other query parameters like p=, d=, from=, and to=. | |
| 6 | 7 | |
| 7 | 8 | <h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol> |
| 8 | 9 | <li>Enhancements to [/help?cmd=diff|fossil diff] and similar: |
| 9 | 10 | <ol type="a"> |
| 10 | 11 | <li> The argument to the --from option can be a directory name, causing |
| 11 | 12 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,11 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2 id='v2_27'>Changes for version 2.27 (pending)</h2> |
| 4 | |
| 5 | * <i>(pending)</i> |
| 6 | |
| 7 | <h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol> |
| 8 | <li>Enhancements to [/help?cmd=diff|fossil diff] and similar: |
| 9 | <ol type="a"> |
| 10 | <li> The argument to the --from option can be a directory name, causing |
| 11 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,10 +1,11 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2 id='v2_27'>Changes for version 2.27 (pending)</h2> |
| 4 | |
| 5 | * Enhance the chng= query parameter on the [/help?cmd=/timeline|timeline page] |
| 6 | so that it works with other query parameters like p=, d=, from=, and to=. |
| 7 | |
| 8 | <h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol> |
| 9 | <li>Enhancements to [/help?cmd=diff|fossil diff] and similar: |
| 10 | <ol type="a"> |
| 11 | <li> The argument to the --from option can be a directory name, causing |
| 12 |
+1
-1
| --- www/fossil-v-git.wiki | ||
| +++ www/fossil-v-git.wiki | ||
| @@ -274,11 +274,11 @@ | ||
| 274 | 274 | Git lets you see "what came before". Fossil makes it just as |
| 275 | 275 | easy to also see "what came after". |
| 276 | 276 | |
| 277 | 277 | Leaf check-ins in Git that lack a "ref" become "detached," making them |
| 278 | 278 | difficult to locate and subject to garbage collection. This |
| 279 | -[http://gitfaq.org/1/01/what-is-a-detached-head/|detached head | |
| 279 | +[https://stackoverflow.com/q/3965676 | detached head | |
| 280 | 280 | state] problem has caused grief for |
| 281 | 281 | [https://www.google.com/search?q=git+detached+head+state | many |
| 282 | 282 | Git users]. With |
| 283 | 283 | Fossil, detached heads are simply impossible because we can always find |
| 284 | 284 | our way back into the Merkle tree using one or more of the relations |
| 285 | 285 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -274,11 +274,11 @@ | |
| 274 | Git lets you see "what came before". Fossil makes it just as |
| 275 | easy to also see "what came after". |
| 276 | |
| 277 | Leaf check-ins in Git that lack a "ref" become "detached," making them |
| 278 | difficult to locate and subject to garbage collection. This |
| 279 | [http://gitfaq.org/1/01/what-is-a-detached-head/|detached head |
| 280 | state] problem has caused grief for |
| 281 | [https://www.google.com/search?q=git+detached+head+state | many |
| 282 | Git users]. With |
| 283 | Fossil, detached heads are simply impossible because we can always find |
| 284 | our way back into the Merkle tree using one or more of the relations |
| 285 |
| --- www/fossil-v-git.wiki | |
| +++ www/fossil-v-git.wiki | |
| @@ -274,11 +274,11 @@ | |
| 274 | Git lets you see "what came before". Fossil makes it just as |
| 275 | easy to also see "what came after". |
| 276 | |
| 277 | Leaf check-ins in Git that lack a "ref" become "detached," making them |
| 278 | difficult to locate and subject to garbage collection. This |
| 279 | [https://stackoverflow.com/q/3965676 | detached head |
| 280 | state] problem has caused grief for |
| 281 | [https://www.google.com/search?q=git+detached+head+state | many |
| 282 | Git users]. With |
| 283 | Fossil, detached heads are simply impossible because we can always find |
| 284 | our way back into the Merkle tree using one or more of the relations |
| 285 |
+1
-1
| --- www/th1.md | ||
| +++ www/th1.md | ||
| @@ -140,11 +140,11 @@ | ||
| 140 | 140 | custom TH1 scripts for headers or footers or tickets are added to a |
| 141 | 141 | repository. Note that the tainted/untainted distinction in strings does |
| 142 | 142 | not make it impossible to introduce XSS and SQL-injections vulnerabilities |
| 143 | 143 | using poorly-written TH1 scripts; it just makes it more difficult and |
| 144 | 144 | less likely to happen by accident. Developers must still consider the |
| 145 | -security implications TH1 customizations they add to Fossil, and take | |
| 145 | +security implications of TH1 customizations they add to Fossil, and take | |
| 146 | 146 | appropriate precautions when writing custom TH1. Peer review of TH1 |
| 147 | 147 | script changes is encouraged. |
| 148 | 148 | |
| 149 | 149 | In Fossil version 2.26, if the vuln-report setting is set to "block" |
| 150 | 150 | or "fatal", the [html](#html) and [query](#query) TH1 commands will |
| 151 | 151 |
| --- www/th1.md | |
| +++ www/th1.md | |
| @@ -140,11 +140,11 @@ | |
| 140 | custom TH1 scripts for headers or footers or tickets are added to a |
| 141 | repository. Note that the tainted/untainted distinction in strings does |
| 142 | not make it impossible to introduce XSS and SQL-injections vulnerabilities |
| 143 | using poorly-written TH1 scripts; it just makes it more difficult and |
| 144 | less likely to happen by accident. Developers must still consider the |
| 145 | security implications TH1 customizations they add to Fossil, and take |
| 146 | appropriate precautions when writing custom TH1. Peer review of TH1 |
| 147 | script changes is encouraged. |
| 148 | |
| 149 | In Fossil version 2.26, if the vuln-report setting is set to "block" |
| 150 | or "fatal", the [html](#html) and [query](#query) TH1 commands will |
| 151 |
| --- www/th1.md | |
| +++ www/th1.md | |
| @@ -140,11 +140,11 @@ | |
| 140 | custom TH1 scripts for headers or footers or tickets are added to a |
| 141 | repository. Note that the tainted/untainted distinction in strings does |
| 142 | not make it impossible to introduce XSS and SQL-injections vulnerabilities |
| 143 | using poorly-written TH1 scripts; it just makes it more difficult and |
| 144 | less likely to happen by accident. Developers must still consider the |
| 145 | security implications of TH1 customizations they add to Fossil, and take |
| 146 | appropriate precautions when writing custom TH1. Peer review of TH1 |
| 147 | script changes is encouraged. |
| 148 | |
| 149 | In Fossil version 2.26, if the vuln-report setting is set to "block" |
| 150 | or "fatal", the [html](#html) and [query](#query) TH1 commands will |
| 151 |