| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.8.6. By combining all the individual C code files into this |
| 3 | +** version 3.8.7. 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. |
| | @@ -220,13 +220,13 @@ |
| 220 | 220 | ** |
| 221 | 221 | ** See also: [sqlite3_libversion()], |
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | | -#define SQLITE_VERSION "3.8.6" |
| 226 | | -#define SQLITE_VERSION_NUMBER 3008006 |
| 227 | | -#define SQLITE_SOURCE_ID "2014-08-15 11:46:33 9491ba7d738528f168657adb43a198238abde19e" |
| 225 | +#define SQLITE_VERSION "3.8.7" |
| 226 | +#define SQLITE_VERSION_NUMBER 3008007 |
| 227 | +#define SQLITE_SOURCE_ID "2014-09-01 18:21:27 672e7387b1bda8d007da7de4244226577d7ab2dc" |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| | @@ -3191,10 +3191,14 @@ |
| 3191 | 3191 | ** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt> |
| 3192 | 3192 | ** <dd>The maximum index number of any [parameter] in an SQL statement.)^ |
| 3193 | 3193 | ** |
| 3194 | 3194 | ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt> |
| 3195 | 3195 | ** <dd>The maximum depth of recursion for triggers.</dd>)^ |
| 3196 | +** |
| 3197 | +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt> |
| 3198 | +** <dd>The maximum number of auxiliary worker threads that a single |
| 3199 | +** [prepared statement] may start.</dd>)^ |
| 3196 | 3200 | ** </dl> |
| 3197 | 3201 | */ |
| 3198 | 3202 | #define SQLITE_LIMIT_LENGTH 0 |
| 3199 | 3203 | #define SQLITE_LIMIT_SQL_LENGTH 1 |
| 3200 | 3204 | #define SQLITE_LIMIT_COLUMN 2 |
| | @@ -3204,10 +3208,11 @@ |
| 3204 | 3208 | #define SQLITE_LIMIT_FUNCTION_ARG 6 |
| 3205 | 3209 | #define SQLITE_LIMIT_ATTACHED 7 |
| 3206 | 3210 | #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 |
| 3207 | 3211 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 |
| 3208 | 3212 | #define SQLITE_LIMIT_TRIGGER_DEPTH 10 |
| 3213 | +#define SQLITE_LIMIT_WORKER_THREADS 11 |
| 3209 | 3214 | |
| 3210 | 3215 | /* |
| 3211 | 3216 | ** CAPI3REF: Compiling An SQL Statement |
| 3212 | 3217 | ** KEYWORDS: {SQL statement compiler} |
| 3213 | 3218 | ** |
| | @@ -6278,11 +6283,12 @@ |
| 6278 | 6283 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6279 | 6284 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6280 | 6285 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6281 | 6286 | #define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6282 | 6287 | #define SQLITE_TESTCTRL_ISINIT 23 |
| 6283 | | -#define SQLITE_TESTCTRL_LAST 23 |
| 6288 | +#define SQLITE_TESTCTRL_SORTER_MMAP 24 |
| 6289 | +#define SQLITE_TESTCTRL_LAST 24 |
| 6284 | 6290 | |
| 6285 | 6291 | /* |
| 6286 | 6292 | ** CAPI3REF: SQLite Runtime Status |
| 6287 | 6293 | ** |
| 6288 | 6294 | ** ^This interface is used to retrieve runtime status information |
| | @@ -7889,10 +7895,22 @@ |
| 7889 | 7895 | #else /* Generates a warning - but it always works */ |
| 7890 | 7896 | # define SQLITE_INT_TO_PTR(X) ((void*)(X)) |
| 7891 | 7897 | # define SQLITE_PTR_TO_INT(X) ((int)(X)) |
| 7892 | 7898 | #endif |
| 7893 | 7899 | |
| 7900 | +/* |
| 7901 | +** A macro to hint to the compiler that a function should not be |
| 7902 | +** inlined. |
| 7903 | +*/ |
| 7904 | +#if defined(__GNUC__) |
| 7905 | +# define SQLITE_NOINLINE __attribute__((noinline)) |
| 7906 | +#elif defined(_MSC_VER) |
| 7907 | +# define SQLITE_NOINLINE __declspec(noinline) |
| 7908 | +#else |
| 7909 | +# define SQLITE_NOINLINE |
| 7910 | +#endif |
| 7911 | + |
| 7894 | 7912 | /* |
| 7895 | 7913 | ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. |
| 7896 | 7914 | ** 0 means mutexes are permanently disable and the library is never |
| 7897 | 7915 | ** threadsafe. 1 means the library is serialized which is the highest |
| 7898 | 7916 | ** level of threadsafety. 2 means the library is multithreaded - multiple |
| | @@ -8154,19 +8172,19 @@ |
| 8154 | 8172 | ** be opaque because it is used by macros. |
| 8155 | 8173 | */ |
| 8156 | 8174 | struct HashElem { |
| 8157 | 8175 | HashElem *next, *prev; /* Next and previous elements in the table */ |
| 8158 | 8176 | void *data; /* Data associated with this element */ |
| 8159 | | - const char *pKey; int nKey; /* Key associated with this element */ |
| 8177 | + const char *pKey; /* Key associated with this element */ |
| 8160 | 8178 | }; |
| 8161 | 8179 | |
| 8162 | 8180 | /* |
| 8163 | 8181 | ** Access routines. To delete, insert a NULL pointer. |
| 8164 | 8182 | */ |
| 8165 | 8183 | SQLITE_PRIVATE void sqlite3HashInit(Hash*); |
| 8166 | | -SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData); |
| 8167 | | -SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey, int nKey); |
| 8184 | +SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); |
| 8185 | +SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey); |
| 8168 | 8186 | SQLITE_PRIVATE void sqlite3HashClear(Hash*); |
| 8169 | 8187 | |
| 8170 | 8188 | /* |
| 8171 | 8189 | ** Macros for looping over all elements of a hash table. The idiom is |
| 8172 | 8190 | ** like this: |
| | @@ -8420,10 +8438,31 @@ |
| 8420 | 8438 | */ |
| 8421 | 8439 | #ifndef SQLITE_TEMP_STORE |
| 8422 | 8440 | # define SQLITE_TEMP_STORE 1 |
| 8423 | 8441 | # define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ |
| 8424 | 8442 | #endif |
| 8443 | + |
| 8444 | +/* |
| 8445 | +** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if |
| 8446 | +** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it |
| 8447 | +** to zero. |
| 8448 | +*/ |
| 8449 | +#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0 |
| 8450 | +# undef SQLITE_MAX_WORKER_THREADS |
| 8451 | +# define SQLITE_MAX_WORKER_THREADS 0 |
| 8452 | +#endif |
| 8453 | +#ifndef SQLITE_MAX_WORKER_THREADS |
| 8454 | +# define SQLITE_MAX_WORKER_THREADS 8 |
| 8455 | +#endif |
| 8456 | +#ifndef SQLITE_DEFAULT_WORKER_THREADS |
| 8457 | +# define SQLITE_DEFAULT_WORKER_THREADS 0 |
| 8458 | +#endif |
| 8459 | +#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS |
| 8460 | +# undef SQLITE_MAX_WORKER_THREADS |
| 8461 | +# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS |
| 8462 | +#endif |
| 8463 | + |
| 8425 | 8464 | |
| 8426 | 8465 | /* |
| 8427 | 8466 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 8428 | 8467 | ** ourselves. |
| 8429 | 8468 | */ |
| | @@ -8804,10 +8843,11 @@ |
| 8804 | 8843 | typedef struct Parse Parse; |
| 8805 | 8844 | typedef struct PrintfArguments PrintfArguments; |
| 8806 | 8845 | typedef struct RowSet RowSet; |
| 8807 | 8846 | typedef struct Savepoint Savepoint; |
| 8808 | 8847 | typedef struct Select Select; |
| 8848 | +typedef struct SQLiteThread SQLiteThread; |
| 8809 | 8849 | typedef struct SelectDest SelectDest; |
| 8810 | 8850 | typedef struct SrcList SrcList; |
| 8811 | 8851 | typedef struct StrAccum StrAccum; |
| 8812 | 8852 | typedef struct Table Table; |
| 8813 | 8853 | typedef struct TableLock TableLock; |
| | @@ -8998,11 +9038,12 @@ |
| 8998 | 9038 | UnpackedRecord *pUnKey, |
| 8999 | 9039 | i64 intKey, |
| 9000 | 9040 | int bias, |
| 9001 | 9041 | int *pRes |
| 9002 | 9042 | ); |
| 9003 | | -SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*); |
| 9043 | +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); |
| 9044 | +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); |
| 9004 | 9045 | SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*); |
| 9005 | 9046 | SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, |
| 9006 | 9047 | const void *pData, int nData, |
| 9007 | 9048 | int nZero, int bias, int seekResult); |
| 9008 | 9049 | SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); |
| | @@ -9289,55 +9330,55 @@ |
| 9289 | 9330 | #define OP_ResultRow 35 /* synopsis: output=r[P1@P2] */ |
| 9290 | 9331 | #define OP_CollSeq 36 |
| 9291 | 9332 | #define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ |
| 9292 | 9333 | #define OP_MustBeInt 38 |
| 9293 | 9334 | #define OP_RealAffinity 39 |
| 9294 | | -#define OP_Permutation 40 |
| 9295 | | -#define OP_Compare 41 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 9296 | | -#define OP_Jump 42 |
| 9297 | | -#define OP_Once 43 |
| 9298 | | -#define OP_If 44 |
| 9299 | | -#define OP_IfNot 45 |
| 9300 | | -#define OP_Column 46 /* synopsis: r[P3]=PX */ |
| 9301 | | -#define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */ |
| 9302 | | -#define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9303 | | -#define OP_Count 49 /* synopsis: r[P2]=count() */ |
| 9304 | | -#define OP_ReadCookie 50 |
| 9305 | | -#define OP_SetCookie 51 |
| 9306 | | -#define OP_ReopenIdx 52 /* synopsis: root=P2 iDb=P3 */ |
| 9307 | | -#define OP_OpenRead 53 /* synopsis: root=P2 iDb=P3 */ |
| 9308 | | -#define OP_OpenWrite 54 /* synopsis: root=P2 iDb=P3 */ |
| 9309 | | -#define OP_OpenAutoindex 55 /* synopsis: nColumn=P2 */ |
| 9310 | | -#define OP_OpenEphemeral 56 /* synopsis: nColumn=P2 */ |
| 9311 | | -#define OP_SorterOpen 57 |
| 9312 | | -#define OP_OpenPseudo 58 /* synopsis: P3 columns in r[P2] */ |
| 9313 | | -#define OP_Close 59 |
| 9314 | | -#define OP_SeekLT 60 /* synopsis: key=r[P3@P4] */ |
| 9315 | | -#define OP_SeekLE 61 /* synopsis: key=r[P3@P4] */ |
| 9316 | | -#define OP_SeekGE 62 /* synopsis: key=r[P3@P4] */ |
| 9317 | | -#define OP_SeekGT 63 /* synopsis: key=r[P3@P4] */ |
| 9318 | | -#define OP_Seek 64 /* synopsis: intkey=r[P2] */ |
| 9319 | | -#define OP_NoConflict 65 /* synopsis: key=r[P3@P4] */ |
| 9320 | | -#define OP_NotFound 66 /* synopsis: key=r[P3@P4] */ |
| 9321 | | -#define OP_Found 67 /* synopsis: key=r[P3@P4] */ |
| 9322 | | -#define OP_NotExists 68 /* synopsis: intkey=r[P3] */ |
| 9323 | | -#define OP_Sequence 69 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9324 | | -#define OP_NewRowid 70 /* synopsis: r[P2]=rowid */ |
| 9335 | +#define OP_Cast 40 /* synopsis: affinity(r[P1]) */ |
| 9336 | +#define OP_Permutation 41 |
| 9337 | +#define OP_Compare 42 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 9338 | +#define OP_Jump 43 |
| 9339 | +#define OP_Once 44 |
| 9340 | +#define OP_If 45 |
| 9341 | +#define OP_IfNot 46 |
| 9342 | +#define OP_Column 47 /* synopsis: r[P3]=PX */ |
| 9343 | +#define OP_Affinity 48 /* synopsis: affinity(r[P1@P2]) */ |
| 9344 | +#define OP_MakeRecord 49 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9345 | +#define OP_Count 50 /* synopsis: r[P2]=count() */ |
| 9346 | +#define OP_ReadCookie 51 |
| 9347 | +#define OP_SetCookie 52 |
| 9348 | +#define OP_ReopenIdx 53 /* synopsis: root=P2 iDb=P3 */ |
| 9349 | +#define OP_OpenRead 54 /* synopsis: root=P2 iDb=P3 */ |
| 9350 | +#define OP_OpenWrite 55 /* synopsis: root=P2 iDb=P3 */ |
| 9351 | +#define OP_OpenAutoindex 56 /* synopsis: nColumn=P2 */ |
| 9352 | +#define OP_OpenEphemeral 57 /* synopsis: nColumn=P2 */ |
| 9353 | +#define OP_SorterOpen 58 |
| 9354 | +#define OP_SequenceTest 59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ |
| 9355 | +#define OP_OpenPseudo 60 /* synopsis: P3 columns in r[P2] */ |
| 9356 | +#define OP_Close 61 |
| 9357 | +#define OP_SeekLT 62 /* synopsis: key=r[P3@P4] */ |
| 9358 | +#define OP_SeekLE 63 /* synopsis: key=r[P3@P4] */ |
| 9359 | +#define OP_SeekGE 64 /* synopsis: key=r[P3@P4] */ |
| 9360 | +#define OP_SeekGT 65 /* synopsis: key=r[P3@P4] */ |
| 9361 | +#define OP_Seek 66 /* synopsis: intkey=r[P2] */ |
| 9362 | +#define OP_NoConflict 67 /* synopsis: key=r[P3@P4] */ |
| 9363 | +#define OP_NotFound 68 /* synopsis: key=r[P3@P4] */ |
| 9364 | +#define OP_Found 69 /* synopsis: key=r[P3@P4] */ |
| 9365 | +#define OP_NotExists 70 /* synopsis: intkey=r[P3] */ |
| 9325 | 9366 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9326 | 9367 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9327 | | -#define OP_Insert 73 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9328 | | -#define OP_InsertInt 74 /* synopsis: intkey=P3 data=r[P2] */ |
| 9329 | | -#define OP_Delete 75 |
| 9368 | +#define OP_Sequence 73 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9369 | +#define OP_NewRowid 74 /* synopsis: r[P2]=rowid */ |
| 9370 | +#define OP_Insert 75 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9330 | 9371 | #define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9331 | 9372 | #define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9332 | 9373 | #define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9333 | 9374 | #define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9334 | 9375 | #define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9335 | 9376 | #define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9336 | 9377 | #define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9337 | 9378 | #define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9338 | | -#define OP_ResetCount 84 |
| 9379 | +#define OP_InsertInt 84 /* synopsis: intkey=P3 data=r[P2] */ |
| 9339 | 9380 | #define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9340 | 9381 | #define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9341 | 9382 | #define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9342 | 9383 | #define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9343 | 9384 | #define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| | @@ -9344,74 +9385,71 @@ |
| 9344 | 9385 | #define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9345 | 9386 | #define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9346 | 9387 | #define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9347 | 9388 | #define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9348 | 9389 | #define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9349 | | -#define OP_SorterCompare 95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 9390 | +#define OP_Delete 95 |
| 9350 | 9391 | #define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9351 | 9392 | #define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9352 | | -#define OP_SorterData 98 /* synopsis: r[P2]=data */ |
| 9353 | | -#define OP_RowKey 99 /* synopsis: r[P2]=key */ |
| 9354 | | -#define OP_RowData 100 /* synopsis: r[P2]=data */ |
| 9355 | | -#define OP_Rowid 101 /* synopsis: r[P2]=rowid */ |
| 9356 | | -#define OP_NullRow 102 |
| 9357 | | -#define OP_Last 103 |
| 9358 | | -#define OP_SorterSort 104 |
| 9359 | | -#define OP_Sort 105 |
| 9360 | | -#define OP_Rewind 106 |
| 9361 | | -#define OP_SorterInsert 107 |
| 9362 | | -#define OP_IdxInsert 108 /* synopsis: key=r[P2] */ |
| 9363 | | -#define OP_IdxDelete 109 /* synopsis: key=r[P2@P3] */ |
| 9364 | | -#define OP_IdxRowid 110 /* synopsis: r[P2]=rowid */ |
| 9365 | | -#define OP_IdxLE 111 /* synopsis: key=r[P3@P4] */ |
| 9366 | | -#define OP_IdxGT 112 /* synopsis: key=r[P3@P4] */ |
| 9367 | | -#define OP_IdxLT 113 /* synopsis: key=r[P3@P4] */ |
| 9368 | | -#define OP_IdxGE 114 /* synopsis: key=r[P3@P4] */ |
| 9369 | | -#define OP_Destroy 115 |
| 9370 | | -#define OP_Clear 116 |
| 9371 | | -#define OP_ResetSorter 117 |
| 9372 | | -#define OP_CreateIndex 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9373 | | -#define OP_CreateTable 119 /* synopsis: r[P2]=root iDb=P1 */ |
| 9374 | | -#define OP_ParseSchema 120 |
| 9375 | | -#define OP_LoadAnalysis 121 |
| 9376 | | -#define OP_DropTable 122 |
| 9377 | | -#define OP_DropIndex 123 |
| 9378 | | -#define OP_DropTrigger 124 |
| 9379 | | -#define OP_IntegrityCk 125 |
| 9380 | | -#define OP_RowSetAdd 126 /* synopsis: rowset(P1)=r[P2] */ |
| 9381 | | -#define OP_RowSetRead 127 /* synopsis: r[P3]=rowset(P1) */ |
| 9382 | | -#define OP_RowSetTest 128 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9383 | | -#define OP_Program 129 |
| 9384 | | -#define OP_Param 130 |
| 9385 | | -#define OP_FkCounter 131 /* synopsis: fkctr[P1]+=P2 */ |
| 9386 | | -#define OP_FkIfZero 132 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9393 | +#define OP_ResetCount 98 |
| 9394 | +#define OP_SorterCompare 99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ |
| 9395 | +#define OP_SorterData 100 /* synopsis: r[P2]=data */ |
| 9396 | +#define OP_RowKey 101 /* synopsis: r[P2]=key */ |
| 9397 | +#define OP_RowData 102 /* synopsis: r[P2]=data */ |
| 9398 | +#define OP_Rowid 103 /* synopsis: r[P2]=rowid */ |
| 9399 | +#define OP_NullRow 104 |
| 9400 | +#define OP_Last 105 |
| 9401 | +#define OP_SorterSort 106 |
| 9402 | +#define OP_Sort 107 |
| 9403 | +#define OP_Rewind 108 |
| 9404 | +#define OP_SorterInsert 109 |
| 9405 | +#define OP_IdxInsert 110 /* synopsis: key=r[P2] */ |
| 9406 | +#define OP_IdxDelete 111 /* synopsis: key=r[P2@P3] */ |
| 9407 | +#define OP_IdxRowid 112 /* synopsis: r[P2]=rowid */ |
| 9408 | +#define OP_IdxLE 113 /* synopsis: key=r[P3@P4] */ |
| 9409 | +#define OP_IdxGT 114 /* synopsis: key=r[P3@P4] */ |
| 9410 | +#define OP_IdxLT 115 /* synopsis: key=r[P3@P4] */ |
| 9411 | +#define OP_IdxGE 116 /* synopsis: key=r[P3@P4] */ |
| 9412 | +#define OP_Destroy 117 |
| 9413 | +#define OP_Clear 118 |
| 9414 | +#define OP_ResetSorter 119 |
| 9415 | +#define OP_CreateIndex 120 /* synopsis: r[P2]=root iDb=P1 */ |
| 9416 | +#define OP_CreateTable 121 /* synopsis: r[P2]=root iDb=P1 */ |
| 9417 | +#define OP_ParseSchema 122 |
| 9418 | +#define OP_LoadAnalysis 123 |
| 9419 | +#define OP_DropTable 124 |
| 9420 | +#define OP_DropIndex 125 |
| 9421 | +#define OP_DropTrigger 126 |
| 9422 | +#define OP_IntegrityCk 127 |
| 9423 | +#define OP_RowSetAdd 128 /* synopsis: rowset(P1)=r[P2] */ |
| 9424 | +#define OP_RowSetRead 129 /* synopsis: r[P3]=rowset(P1) */ |
| 9425 | +#define OP_RowSetTest 130 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9426 | +#define OP_Program 131 |
| 9427 | +#define OP_Param 132 |
| 9387 | 9428 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9388 | | -#define OP_MemMax 134 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9389 | | -#define OP_IfPos 135 /* synopsis: if r[P1]>0 goto P2 */ |
| 9390 | | -#define OP_IfNeg 136 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ |
| 9391 | | -#define OP_IfZero 137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9392 | | -#define OP_AggFinal 138 /* synopsis: accum=r[P1] N=P2 */ |
| 9393 | | -#define OP_IncrVacuum 139 |
| 9394 | | -#define OP_Expire 140 |
| 9395 | | -#define OP_TableLock 141 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9396 | | -#define OP_VBegin 142 |
| 9397 | | -#define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9398 | | -#define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9399 | | -#define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9400 | | -#define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9401 | | -#define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9402 | | -#define OP_VCreate 148 |
| 9403 | | -#define OP_VDestroy 149 |
| 9404 | | -#define OP_VOpen 150 |
| 9405 | | -#define OP_VColumn 151 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9406 | | -#define OP_VNext 152 |
| 9407 | | -#define OP_VRename 153 |
| 9408 | | -#define OP_Pagecount 154 |
| 9409 | | -#define OP_MaxPgcnt 155 |
| 9410 | | -#define OP_Init 156 /* synopsis: Start at P2 */ |
| 9411 | | -#define OP_Noop 157 |
| 9412 | | -#define OP_Explain 158 |
| 9429 | +#define OP_FkCounter 134 /* synopsis: fkctr[P1]+=P2 */ |
| 9430 | +#define OP_FkIfZero 135 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9431 | +#define OP_MemMax 136 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9432 | +#define OP_IfPos 137 /* synopsis: if r[P1]>0 goto P2 */ |
| 9433 | +#define OP_IfNeg 138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ |
| 9434 | +#define OP_IfZero 139 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9435 | +#define OP_AggFinal 140 /* synopsis: accum=r[P1] N=P2 */ |
| 9436 | +#define OP_IncrVacuum 141 |
| 9437 | +#define OP_Expire 142 |
| 9438 | +#define OP_TableLock 143 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9439 | +#define OP_VBegin 144 |
| 9440 | +#define OP_VCreate 145 |
| 9441 | +#define OP_VDestroy 146 |
| 9442 | +#define OP_VOpen 147 |
| 9443 | +#define OP_VColumn 148 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9444 | +#define OP_VNext 149 |
| 9445 | +#define OP_VRename 150 |
| 9446 | +#define OP_Pagecount 151 |
| 9447 | +#define OP_MaxPgcnt 152 |
| 9448 | +#define OP_Init 153 /* synopsis: Start at P2 */ |
| 9449 | +#define OP_Noop 154 |
| 9450 | +#define OP_Explain 155 |
| 9413 | 9451 | |
| 9414 | 9452 | |
| 9415 | 9453 | /* Properties such as "out2" or "jump" that are specified in |
| 9416 | 9454 | ** comments following the "case" for each opcode in the vdbe.c |
| 9417 | 9455 | ** are encoded into bitvectors as follows: |
| | @@ -9427,25 +9465,25 @@ |
| 9427 | 9465 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\ |
| 9428 | 9466 | /* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\ |
| 9429 | 9467 | /* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\ |
| 9430 | 9468 | /* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\ |
| 9431 | 9469 | /* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\ |
| 9432 | | -/* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\ |
| 9433 | | -/* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 9434 | | -/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\ |
| 9435 | | -/* 64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\ |
| 9436 | | -/* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9470 | +/* 40 */ 0x04, 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00,\ |
| 9471 | +/* 48 */ 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00,\ |
| 9472 | +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ |
| 9473 | +/* 64 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x4c,\ |
| 9474 | +/* 72 */ 0x4c, 0x02, 0x02, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9437 | 9475 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9438 | 9476 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9439 | | -/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ |
| 9440 | | -/* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\ |
| 9441 | | -/* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\ |
| 9442 | | -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ |
| 9443 | | -/* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\ |
| 9444 | | -/* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\ |
| 9445 | | -/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\ |
| 9446 | | -/* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9477 | +/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\ |
| 9478 | +/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08, 0x00,\ |
| 9479 | +/* 112 */ 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00,\ |
| 9480 | +/* 120 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 9481 | +/* 128 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x02, 0x00, 0x01,\ |
| 9482 | +/* 136 */ 0x08, 0x05, 0x05, 0x05, 0x00, 0x01, 0x00, 0x00,\ |
| 9483 | +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,\ |
| 9484 | +/* 152 */ 0x02, 0x01, 0x00, 0x00,} |
| 9447 | 9485 | |
| 9448 | 9486 | /************** End of opcodes.h *********************************************/ |
| 9449 | 9487 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9450 | 9488 | |
| 9451 | 9489 | /* |
| | @@ -9860,31 +9898,33 @@ |
| 9860 | 9898 | |
| 9861 | 9899 | /* Create a new pager cache. |
| 9862 | 9900 | ** Under memory stress, invoke xStress to try to make pages clean. |
| 9863 | 9901 | ** Only clean and unpinned pages can be reclaimed. |
| 9864 | 9902 | */ |
| 9865 | | -SQLITE_PRIVATE void sqlite3PcacheOpen( |
| 9903 | +SQLITE_PRIVATE int sqlite3PcacheOpen( |
| 9866 | 9904 | int szPage, /* Size of every page */ |
| 9867 | 9905 | int szExtra, /* Extra space associated with each page */ |
| 9868 | 9906 | int bPurgeable, /* True if pages are on backing store */ |
| 9869 | 9907 | int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ |
| 9870 | 9908 | void *pStress, /* Argument to xStress */ |
| 9871 | 9909 | PCache *pToInit /* Preallocated space for the PCache */ |
| 9872 | 9910 | ); |
| 9873 | 9911 | |
| 9874 | 9912 | /* Modify the page-size after the cache has been created. */ |
| 9875 | | -SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int); |
| 9913 | +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); |
| 9876 | 9914 | |
| 9877 | 9915 | /* Return the size in bytes of a PCache object. Used to preallocate |
| 9878 | 9916 | ** storage space. |
| 9879 | 9917 | */ |
| 9880 | 9918 | SQLITE_PRIVATE int sqlite3PcacheSize(void); |
| 9881 | 9919 | |
| 9882 | 9920 | /* One release per successful fetch. Page is pinned until released. |
| 9883 | 9921 | ** Reference counted. |
| 9884 | 9922 | */ |
| 9885 | | -SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**); |
| 9923 | +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); |
| 9924 | +SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); |
| 9925 | +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); |
| 9886 | 9926 | SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); |
| 9887 | 9927 | |
| 9888 | 9928 | SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ |
| 9889 | 9929 | SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ |
| 9890 | 9930 | SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ |
| | @@ -10379,11 +10419,11 @@ |
| 10379 | 10419 | |
| 10380 | 10420 | /* |
| 10381 | 10421 | ** The number of different kinds of things that can be limited |
| 10382 | 10422 | ** using the sqlite3_limit() interface. |
| 10383 | 10423 | */ |
| 10384 | | -#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1) |
| 10424 | +#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) |
| 10385 | 10425 | |
| 10386 | 10426 | /* |
| 10387 | 10427 | ** Lookaside malloc is a set of fixed-size buffers that can be used |
| 10388 | 10428 | ** to satisfy small transient memory allocation requests for objects |
| 10389 | 10429 | ** associated with a particular database connection. The use of |
| | @@ -10456,10 +10496,11 @@ |
| 10456 | 10496 | int nextPagesize; /* Pagesize after VACUUM if >0 */ |
| 10457 | 10497 | u32 magic; /* Magic number for detect library misuse */ |
| 10458 | 10498 | int nChange; /* Value returned by sqlite3_changes() */ |
| 10459 | 10499 | int nTotalChange; /* Value returned by sqlite3_total_changes() */ |
| 10460 | 10500 | int aLimit[SQLITE_N_LIMIT]; /* Limits */ |
| 10501 | + int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ |
| 10461 | 10502 | struct sqlite3InitInfo { /* Information used during initialization */ |
| 10462 | 10503 | int newTnum; /* Rootpage of table being initialized */ |
| 10463 | 10504 | u8 iDb; /* Which db file is being initialized */ |
| 10464 | 10505 | u8 busy; /* TRUE if currently initializing */ |
| 10465 | 10506 | u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ |
| | @@ -11119,11 +11160,11 @@ |
| 11119 | 11160 | */ |
| 11120 | 11161 | struct UnpackedRecord { |
| 11121 | 11162 | KeyInfo *pKeyInfo; /* Collation and sort-order information */ |
| 11122 | 11163 | u16 nField; /* Number of entries in apMem[] */ |
| 11123 | 11164 | i8 default_rc; /* Comparison result if keys are equal */ |
| 11124 | | - u8 isCorrupt; /* Corruption detected by xRecordCompare() */ |
| 11165 | + u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ |
| 11125 | 11166 | Mem *aMem; /* Values */ |
| 11126 | 11167 | int r1; /* Value to return if (lhs > rhs) */ |
| 11127 | 11168 | int r2; /* Value to return if (rhs < lhs) */ |
| 11128 | 11169 | }; |
| 11129 | 11170 | |
| | @@ -12767,42 +12808,27 @@ |
| 12767 | 12808 | SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); |
| 12768 | 12809 | |
| 12769 | 12810 | /* |
| 12770 | 12811 | ** Routines to read and write variable-length integers. These used to |
| 12771 | 12812 | ** be defined locally, but now we use the varint routines in the util.c |
| 12772 | | -** file. Code should use the MACRO forms below, as the Varint32 versions |
| 12773 | | -** are coded to assume the single byte case is already handled (which |
| 12774 | | -** the MACRO form does). |
| 12813 | +** file. |
| 12775 | 12814 | */ |
| 12776 | 12815 | SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); |
| 12777 | | -SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32); |
| 12778 | 12816 | SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); |
| 12779 | 12817 | SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); |
| 12780 | 12818 | SQLITE_PRIVATE int sqlite3VarintLen(u64 v); |
| 12781 | 12819 | |
| 12782 | 12820 | /* |
| 12783 | | -** The header of a record consists of a sequence variable-length integers. |
| 12784 | | -** These integers are almost always small and are encoded as a single byte. |
| 12785 | | -** The following macros take advantage this fact to provide a fast encode |
| 12786 | | -** and decode of the integers in a record header. It is faster for the common |
| 12787 | | -** case where the integer is a single byte. It is a little slower when the |
| 12788 | | -** integer is two or more bytes. But overall it is faster. |
| 12789 | | -** |
| 12790 | | -** The following expressions are equivalent: |
| 12791 | | -** |
| 12792 | | -** x = sqlite3GetVarint32( A, &B ); |
| 12793 | | -** x = sqlite3PutVarint32( A, B ); |
| 12794 | | -** |
| 12795 | | -** x = getVarint32( A, B ); |
| 12796 | | -** x = putVarint32( A, B ); |
| 12797 | | -** |
| 12821 | +** The common case is for a varint to be a single byte. They following |
| 12822 | +** macros handle the common case without a procedure call, but then call |
| 12823 | +** the procedure for larger varints. |
| 12798 | 12824 | */ |
| 12799 | 12825 | #define getVarint32(A,B) \ |
| 12800 | 12826 | (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) |
| 12801 | 12827 | #define putVarint32(A,B) \ |
| 12802 | 12828 | (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ |
| 12803 | | - sqlite3PutVarint32((A),(B))) |
| 12829 | + sqlite3PutVarint((A),(B))) |
| 12804 | 12830 | #define getVarint sqlite3GetVarint |
| 12805 | 12831 | #define putVarint sqlite3PutVarint |
| 12806 | 12832 | |
| 12807 | 12833 | |
| 12808 | 12834 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *); |
| | @@ -12810,11 +12836,12 @@ |
| 12810 | 12836 | SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); |
| 12811 | 12837 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); |
| 12812 | 12838 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 12813 | 12839 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12814 | 12840 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 12815 | | -SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12841 | +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); |
| 12842 | +SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); |
| 12816 | 12843 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12817 | 12844 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12818 | 12845 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12819 | 12846 | |
| 12820 | 12847 | #if defined(SQLITE_TEST) |
| | @@ -13177,10 +13204,18 @@ |
| 13177 | 13204 | #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ |
| 13178 | 13205 | #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ |
| 13179 | 13206 | #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ |
| 13180 | 13207 | #define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */ |
| 13181 | 13208 | |
| 13209 | +/* |
| 13210 | +** Threading interface |
| 13211 | +*/ |
| 13212 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 13213 | +SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); |
| 13214 | +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); |
| 13215 | +#endif |
| 13216 | + |
| 13182 | 13217 | #endif /* _SQLITEINT_H_ */ |
| 13183 | 13218 | |
| 13184 | 13219 | /************** End of sqliteInt.h *******************************************/ |
| 13185 | 13220 | /************** Begin file global.c ******************************************/ |
| 13186 | 13221 | /* |
| | @@ -14122,12 +14157,12 @@ |
| 14122 | 14157 | ** |
| 14123 | 14158 | ** This structure is defined inside of vdbeInt.h because it uses substructures |
| 14124 | 14159 | ** (Mem) which are only defined there. |
| 14125 | 14160 | */ |
| 14126 | 14161 | struct sqlite3_context { |
| 14162 | + Mem *pOut; /* The return value is stored here */ |
| 14127 | 14163 | FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ |
| 14128 | | - Mem s; /* The return value is stored here */ |
| 14129 | 14164 | Mem *pMem; /* Memory cell used to store aggregate context */ |
| 14130 | 14165 | CollSeq *pColl; /* Collating sequence */ |
| 14131 | 14166 | Vdbe *pVdbe; /* The VM that owns this context */ |
| 14132 | 14167 | int iOp; /* Instruction number of OP_Function */ |
| 14133 | 14168 | int isError; /* Error code returned by the function. */ |
| | @@ -14274,39 +14309,40 @@ |
| 14274 | 14309 | #endif |
| 14275 | 14310 | SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); |
| 14276 | 14311 | SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); |
| 14277 | 14312 | SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); |
| 14278 | 14313 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); |
| 14279 | | -SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int); |
| 14314 | +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); |
| 14280 | 14315 | SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); |
| 14281 | 14316 | SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); |
| 14282 | 14317 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); |
| 14283 | 14318 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); |
| 14284 | 14319 | SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); |
| 14285 | 14320 | SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); |
| 14321 | +SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); |
| 14286 | 14322 | SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); |
| 14287 | 14323 | SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); |
| 14288 | 14324 | SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); |
| 14289 | 14325 | #define VdbeMemDynamic(X) \ |
| 14290 | 14326 | (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) |
| 14291 | | -#define VdbeMemRelease(X) \ |
| 14327 | +#define VdbeMemReleaseExtern(X) \ |
| 14292 | 14328 | if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); |
| 14293 | 14329 | SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); |
| 14294 | 14330 | SQLITE_PRIVATE const char *sqlite3OpcodeName(int); |
| 14295 | 14331 | SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); |
| 14296 | 14332 | SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); |
| 14297 | 14333 | SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); |
| 14298 | 14334 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); |
| 14299 | 14335 | SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); |
| 14300 | 14336 | |
| 14301 | | -SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 14337 | +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); |
| 14302 | 14338 | SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); |
| 14303 | 14339 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 14304 | 14340 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); |
| 14305 | 14341 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); |
| 14306 | | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); |
| 14307 | | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); |
| 14342 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); |
| 14343 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); |
| 14308 | 14344 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); |
| 14309 | 14345 | |
| 14310 | 14346 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 14311 | 14347 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 14312 | 14348 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| | @@ -19387,10 +19423,20 @@ |
| 19387 | 19423 | */ |
| 19388 | 19424 | #if !defined(SQLITE_OS_WINRT) |
| 19389 | 19425 | # define SQLITE_OS_WINRT 0 |
| 19390 | 19426 | #endif |
| 19391 | 19427 | |
| 19428 | +/* |
| 19429 | +** For WinCE, some API function parameters do not appear to be declared as |
| 19430 | +** volatile. |
| 19431 | +*/ |
| 19432 | +#if SQLITE_OS_WINCE |
| 19433 | +# define SQLITE_WIN32_VOLATILE |
| 19434 | +#else |
| 19435 | +# define SQLITE_WIN32_VOLATILE volatile |
| 19436 | +#endif |
| 19437 | + |
| 19392 | 19438 | #endif /* _OS_WIN_H_ */ |
| 19393 | 19439 | |
| 19394 | 19440 | /************** End of os_win.h **********************************************/ |
| 19395 | 19441 | /************** Continuing where we left off in mutex_w32.c ******************/ |
| 19396 | 19442 | #endif |
| | @@ -19467,11 +19513,11 @@ |
| 19467 | 19513 | |
| 19468 | 19514 | /* As the winMutexInit() and winMutexEnd() functions are called as part |
| 19469 | 19515 | ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the |
| 19470 | 19516 | ** "interlocked" magic used here is probably not strictly necessary. |
| 19471 | 19517 | */ |
| 19472 | | -static LONG volatile winMutex_lock = 0; |
| 19518 | +static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; |
| 19473 | 19519 | |
| 19474 | 19520 | SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ |
| 19475 | 19521 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 19476 | 19522 | |
| 19477 | 19523 | static int winMutexInit(void){ |
| | @@ -20093,26 +20139,24 @@ |
| 20093 | 20139 | SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ |
| 20094 | 20140 | void *p; |
| 20095 | 20141 | assert( n>0 ); |
| 20096 | 20142 | |
| 20097 | 20143 | sqlite3_mutex_enter(mem0.mutex); |
| 20144 | + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); |
| 20098 | 20145 | if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ |
| 20099 | 20146 | p = mem0.pScratchFree; |
| 20100 | 20147 | mem0.pScratchFree = mem0.pScratchFree->pNext; |
| 20101 | 20148 | mem0.nScratchFree--; |
| 20102 | 20149 | sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); |
| 20103 | | - sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); |
| 20104 | | - sqlite3_mutex_leave(mem0.mutex); |
| 20105 | | - }else{ |
| 20106 | | - if( sqlite3GlobalConfig.bMemstat ){ |
| 20107 | | - sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); |
| 20108 | | - n = mallocWithAlarm(n, &p); |
| 20109 | | - if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n); |
| 20110 | | - sqlite3_mutex_leave(mem0.mutex); |
| 20111 | | - }else{ |
| 20112 | | - sqlite3_mutex_leave(mem0.mutex); |
| 20113 | | - p = sqlite3GlobalConfig.m.xMalloc(n); |
| 20150 | + sqlite3_mutex_leave(mem0.mutex); |
| 20151 | + }else{ |
| 20152 | + sqlite3_mutex_leave(mem0.mutex); |
| 20153 | + p = sqlite3Malloc(n); |
| 20154 | + if( sqlite3GlobalConfig.bMemstat && p ){ |
| 20155 | + sqlite3_mutex_enter(mem0.mutex); |
| 20156 | + sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); |
| 20157 | + sqlite3_mutex_leave(mem0.mutex); |
| 20114 | 20158 | } |
| 20115 | 20159 | sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); |
| 20116 | 20160 | } |
| 20117 | 20161 | assert( sqlite3_mutex_notheld(mem0.mutex) ); |
| 20118 | 20162 | |
| | @@ -20219,10 +20263,18 @@ |
| 20219 | 20263 | sqlite3_mutex_leave(mem0.mutex); |
| 20220 | 20264 | }else{ |
| 20221 | 20265 | sqlite3GlobalConfig.m.xFree(p); |
| 20222 | 20266 | } |
| 20223 | 20267 | } |
| 20268 | + |
| 20269 | +/* |
| 20270 | +** Add the size of memory allocation "p" to the count in |
| 20271 | +** *db->pnBytesFreed. |
| 20272 | +*/ |
| 20273 | +static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ |
| 20274 | + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); |
| 20275 | +} |
| 20224 | 20276 | |
| 20225 | 20277 | /* |
| 20226 | 20278 | ** Free memory that might be associated with a particular database |
| 20227 | 20279 | ** connection. |
| 20228 | 20280 | */ |
| | @@ -20229,11 +20281,11 @@ |
| 20229 | 20281 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ |
| 20230 | 20282 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); |
| 20231 | 20283 | if( p==0 ) return; |
| 20232 | 20284 | if( db ){ |
| 20233 | 20285 | if( db->pnBytesFreed ){ |
| 20234 | | - *db->pnBytesFreed += sqlite3DbMallocSize(db, p); |
| 20286 | + measureAllocationSize(db, p); |
| 20235 | 20287 | return; |
| 20236 | 20288 | } |
| 20237 | 20289 | if( isLookaside(db, p) ){ |
| 20238 | 20290 | LookasideSlot *pBuf = (LookasideSlot*)p; |
| 20239 | 20291 | #if SQLITE_DEBUG |
| | @@ -20496,10 +20548,18 @@ |
| 20496 | 20548 | va_end(ap); |
| 20497 | 20549 | sqlite3DbFree(db, *pz); |
| 20498 | 20550 | *pz = z; |
| 20499 | 20551 | } |
| 20500 | 20552 | |
| 20553 | +/* |
| 20554 | +** Take actions at the end of an API call to indicate an OOM error |
| 20555 | +*/ |
| 20556 | +static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ |
| 20557 | + db->mallocFailed = 0; |
| 20558 | + sqlite3Error(db, SQLITE_NOMEM); |
| 20559 | + return SQLITE_NOMEM; |
| 20560 | +} |
| 20501 | 20561 | |
| 20502 | 20562 | /* |
| 20503 | 20563 | ** This function must be called before exiting any API function (i.e. |
| 20504 | 20564 | ** returning control to the user) that has called sqlite3_malloc or |
| 20505 | 20565 | ** sqlite3_realloc. |
| | @@ -20516,16 +20576,15 @@ |
| 20516 | 20576 | /* If the db handle is not NULL, then we must hold the connection handle |
| 20517 | 20577 | ** mutex here. Otherwise the read (and possible write) of db->mallocFailed |
| 20518 | 20578 | ** is unsafe, as is the call to sqlite3Error(). |
| 20519 | 20579 | */ |
| 20520 | 20580 | assert( !db || sqlite3_mutex_held(db->mutex) ); |
| 20521 | | - if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){ |
| 20522 | | - sqlite3Error(db, SQLITE_NOMEM, 0); |
| 20523 | | - db->mallocFailed = 0; |
| 20524 | | - rc = SQLITE_NOMEM; |
| 20581 | + if( db==0 ) return rc & 0xff; |
| 20582 | + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ |
| 20583 | + return apiOomError(db); |
| 20525 | 20584 | } |
| 20526 | | - return rc & (db ? db->errMask : 0xff); |
| 20585 | + return rc & db->errMask; |
| 20527 | 20586 | } |
| 20528 | 20587 | |
| 20529 | 20588 | /************** End of malloc.c **********************************************/ |
| 20530 | 20589 | /************** Begin file printf.c ******************************************/ |
| 20531 | 20590 | /* |
| | @@ -21311,11 +21370,11 @@ |
| 21311 | 21370 | ** |
| 21312 | 21371 | ** This is a helper routine to sqlite3StrAccumAppend() that does special-case |
| 21313 | 21372 | ** work (enlarging the buffer) using tail recursion, so that the |
| 21314 | 21373 | ** sqlite3StrAccumAppend() routine can use fast calling semantics. |
| 21315 | 21374 | */ |
| 21316 | | -static void enlargeAndAppend(StrAccum *p, const char *z, int N){ |
| 21375 | +static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ |
| 21317 | 21376 | N = sqlite3StrAccumEnlarge(p, N); |
| 21318 | 21377 | if( N>0 ){ |
| 21319 | 21378 | memcpy(&p->zText[p->nChar], z, N); |
| 21320 | 21379 | p->nChar += N; |
| 21321 | 21380 | } |
| | @@ -21330,15 +21389,15 @@ |
| 21330 | 21389 | assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 21331 | 21390 | assert( N>=0 ); |
| 21332 | 21391 | assert( p->accError==0 || p->nAlloc==0 ); |
| 21333 | 21392 | if( p->nChar+N >= p->nAlloc ){ |
| 21334 | 21393 | enlargeAndAppend(p,z,N); |
| 21335 | | - return; |
| 21394 | + }else{ |
| 21395 | + assert( p->zText ); |
| 21396 | + p->nChar += N; |
| 21397 | + memcpy(&p->zText[p->nChar-N], z, N); |
| 21336 | 21398 | } |
| 21337 | | - assert( p->zText ); |
| 21338 | | - memcpy(&p->zText[p->nChar], z, N); |
| 21339 | | - p->nChar += N; |
| 21340 | 21399 | } |
| 21341 | 21400 | |
| 21342 | 21401 | /* |
| 21343 | 21402 | ** Append the complete text of zero-terminated string z[] to the p string. |
| 21344 | 21403 | */ |
| | @@ -21703,10 +21762,274 @@ |
| 21703 | 21762 | ); |
| 21704 | 21763 | } |
| 21705 | 21764 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 21706 | 21765 | |
| 21707 | 21766 | /************** End of random.c **********************************************/ |
| 21767 | +/************** Begin file threads.c *****************************************/ |
| 21768 | +/* |
| 21769 | +** 2012 July 21 |
| 21770 | +** |
| 21771 | +** The author disclaims copyright to this source code. In place of |
| 21772 | +** a legal notice, here is a blessing: |
| 21773 | +** |
| 21774 | +** May you do good and not evil. |
| 21775 | +** May you find forgiveness for yourself and forgive others. |
| 21776 | +** May you share freely, never taking more than you give. |
| 21777 | +** |
| 21778 | +****************************************************************************** |
| 21779 | +** |
| 21780 | +** This file presents a simple cross-platform threading interface for |
| 21781 | +** use internally by SQLite. |
| 21782 | +** |
| 21783 | +** A "thread" can be created using sqlite3ThreadCreate(). This thread |
| 21784 | +** runs independently of its creator until it is joined using |
| 21785 | +** sqlite3ThreadJoin(), at which point it terminates. |
| 21786 | +** |
| 21787 | +** Threads do not have to be real. It could be that the work of the |
| 21788 | +** "thread" is done by the main thread at either the sqlite3ThreadCreate() |
| 21789 | +** or sqlite3ThreadJoin() call. This is, in fact, what happens in |
| 21790 | +** single threaded systems. Nothing in SQLite requires multiple threads. |
| 21791 | +** This interface exists so that applications that want to take advantage |
| 21792 | +** of multiple cores can do so, while also allowing applications to stay |
| 21793 | +** single-threaded if desired. |
| 21794 | +*/ |
| 21795 | + |
| 21796 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 21797 | + |
| 21798 | +/********************************* Unix Pthreads ****************************/ |
| 21799 | +#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 |
| 21800 | + |
| 21801 | +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ |
| 21802 | +/* #include <pthread.h> */ |
| 21803 | + |
| 21804 | +/* A running thread */ |
| 21805 | +struct SQLiteThread { |
| 21806 | + pthread_t tid; /* Thread ID */ |
| 21807 | + int done; /* Set to true when thread finishes */ |
| 21808 | + void *pOut; /* Result returned by the thread */ |
| 21809 | + void *(*xTask)(void*); /* The thread routine */ |
| 21810 | + void *pIn; /* Argument to the thread */ |
| 21811 | +}; |
| 21812 | + |
| 21813 | +/* Create a new thread */ |
| 21814 | +SQLITE_PRIVATE int sqlite3ThreadCreate( |
| 21815 | + SQLiteThread **ppThread, /* OUT: Write the thread object here */ |
| 21816 | + void *(*xTask)(void*), /* Routine to run in a separate thread */ |
| 21817 | + void *pIn /* Argument passed into xTask() */ |
| 21818 | +){ |
| 21819 | + SQLiteThread *p; |
| 21820 | + int rc; |
| 21821 | + |
| 21822 | + assert( ppThread!=0 ); |
| 21823 | + assert( xTask!=0 ); |
| 21824 | + /* This routine is never used in single-threaded mode */ |
| 21825 | + assert( sqlite3GlobalConfig.bCoreMutex!=0 ); |
| 21826 | + |
| 21827 | + *ppThread = 0; |
| 21828 | + p = sqlite3Malloc(sizeof(*p)); |
| 21829 | + if( p==0 ) return SQLITE_NOMEM; |
| 21830 | + memset(p, 0, sizeof(*p)); |
| 21831 | + p->xTask = xTask; |
| 21832 | + p->pIn = pIn; |
| 21833 | + if( sqlite3FaultSim(200) ){ |
| 21834 | + rc = 1; |
| 21835 | + }else{ |
| 21836 | + rc = pthread_create(&p->tid, 0, xTask, pIn); |
| 21837 | + } |
| 21838 | + if( rc ){ |
| 21839 | + p->done = 1; |
| 21840 | + p->pOut = xTask(pIn); |
| 21841 | + } |
| 21842 | + *ppThread = p; |
| 21843 | + return SQLITE_OK; |
| 21844 | +} |
| 21845 | + |
| 21846 | +/* Get the results of the thread */ |
| 21847 | +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ |
| 21848 | + int rc; |
| 21849 | + |
| 21850 | + assert( ppOut!=0 ); |
| 21851 | + if( NEVER(p==0) ) return SQLITE_NOMEM; |
| 21852 | + if( p->done ){ |
| 21853 | + *ppOut = p->pOut; |
| 21854 | + rc = SQLITE_OK; |
| 21855 | + }else{ |
| 21856 | + rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; |
| 21857 | + } |
| 21858 | + sqlite3_free(p); |
| 21859 | + return rc; |
| 21860 | +} |
| 21861 | + |
| 21862 | +#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ |
| 21863 | +/******************************** End Unix Pthreads *************************/ |
| 21864 | + |
| 21865 | + |
| 21866 | +/********************************* Win32 Threads ****************************/ |
| 21867 | +#if SQLITE_OS_WIN && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 |
| 21868 | + |
| 21869 | +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ |
| 21870 | +#include <process.h> |
| 21871 | + |
| 21872 | +/* A running thread */ |
| 21873 | +struct SQLiteThread { |
| 21874 | + uintptr_t tid; /* The thread handle */ |
| 21875 | + unsigned id; /* The thread identifier */ |
| 21876 | + void *(*xTask)(void*); /* The routine to run as a thread */ |
| 21877 | + void *pIn; /* Argument to xTask */ |
| 21878 | + void *pResult; /* Result of xTask */ |
| 21879 | +}; |
| 21880 | + |
| 21881 | +/* Thread procedure Win32 compatibility shim */ |
| 21882 | +static unsigned __stdcall sqlite3ThreadProc( |
| 21883 | + void *pArg /* IN: Pointer to the SQLiteThread structure */ |
| 21884 | +){ |
| 21885 | + SQLiteThread *p = (SQLiteThread *)pArg; |
| 21886 | + |
| 21887 | + assert( p!=0 ); |
| 21888 | +#if 0 |
| 21889 | + /* |
| 21890 | + ** This assert appears to trigger spuriously on certain |
| 21891 | + ** versions of Windows, possibly due to _beginthreadex() |
| 21892 | + ** and/or CreateThread() not fully setting their thread |
| 21893 | + ** ID parameter before starting the thread. |
| 21894 | + */ |
| 21895 | + assert( p->id==GetCurrentThreadId() ); |
| 21896 | +#endif |
| 21897 | + assert( p->xTask!=0 ); |
| 21898 | + p->pResult = p->xTask(p->pIn); |
| 21899 | + |
| 21900 | + _endthreadex(0); |
| 21901 | + return 0; /* NOT REACHED */ |
| 21902 | +} |
| 21903 | + |
| 21904 | +/* Create a new thread */ |
| 21905 | +SQLITE_PRIVATE int sqlite3ThreadCreate( |
| 21906 | + SQLiteThread **ppThread, /* OUT: Write the thread object here */ |
| 21907 | + void *(*xTask)(void*), /* Routine to run in a separate thread */ |
| 21908 | + void *pIn /* Argument passed into xTask() */ |
| 21909 | +){ |
| 21910 | + SQLiteThread *p; |
| 21911 | + |
| 21912 | + assert( ppThread!=0 ); |
| 21913 | + assert( xTask!=0 ); |
| 21914 | + *ppThread = 0; |
| 21915 | + p = sqlite3Malloc(sizeof(*p)); |
| 21916 | + if( p==0 ) return SQLITE_NOMEM; |
| 21917 | + if( sqlite3GlobalConfig.bCoreMutex==0 ){ |
| 21918 | + memset(p, 0, sizeof(*p)); |
| 21919 | + }else{ |
| 21920 | + p->xTask = xTask; |
| 21921 | + p->pIn = pIn; |
| 21922 | + p->tid = _beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); |
| 21923 | + if( p->tid==0 ){ |
| 21924 | + memset(p, 0, sizeof(*p)); |
| 21925 | + } |
| 21926 | + } |
| 21927 | + if( p->xTask==0 ){ |
| 21928 | + p->id = GetCurrentThreadId(); |
| 21929 | + p->pResult = xTask(pIn); |
| 21930 | + } |
| 21931 | + *ppThread = p; |
| 21932 | + return SQLITE_OK; |
| 21933 | +} |
| 21934 | + |
| 21935 | +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ |
| 21936 | + |
| 21937 | +/* Get the results of the thread */ |
| 21938 | +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ |
| 21939 | + DWORD rc; |
| 21940 | + BOOL bRc; |
| 21941 | + |
| 21942 | + assert( ppOut!=0 ); |
| 21943 | + if( NEVER(p==0) ) return SQLITE_NOMEM; |
| 21944 | + if( p->xTask==0 ){ |
| 21945 | + assert( p->id==GetCurrentThreadId() ); |
| 21946 | + rc = WAIT_OBJECT_0; |
| 21947 | + assert( p->tid==0 ); |
| 21948 | + }else{ |
| 21949 | + assert( p->id!=0 && p->id!=GetCurrentThreadId() ); |
| 21950 | + rc = sqlite3Win32Wait((HANDLE)p->tid); |
| 21951 | + assert( rc!=WAIT_IO_COMPLETION ); |
| 21952 | + bRc = CloseHandle((HANDLE)p->tid); |
| 21953 | + assert( bRc ); |
| 21954 | + } |
| 21955 | + if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; |
| 21956 | + sqlite3_free(p); |
| 21957 | + return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; |
| 21958 | +} |
| 21959 | + |
| 21960 | +#endif /* SQLITE_OS_WIN && !SQLITE_OS_WINRT */ |
| 21961 | +/******************************** End Win32 Threads *************************/ |
| 21962 | + |
| 21963 | + |
| 21964 | +/********************************* Single-Threaded **************************/ |
| 21965 | +#ifndef SQLITE_THREADS_IMPLEMENTED |
| 21966 | +/* |
| 21967 | +** This implementation does not actually create a new thread. It does the |
| 21968 | +** work of the thread in the main thread, when either the thread is created |
| 21969 | +** or when it is joined |
| 21970 | +*/ |
| 21971 | + |
| 21972 | +/* A running thread */ |
| 21973 | +struct SQLiteThread { |
| 21974 | + void *(*xTask)(void*); /* The routine to run as a thread */ |
| 21975 | + void *pIn; /* Argument to xTask */ |
| 21976 | + void *pResult; /* Result of xTask */ |
| 21977 | +}; |
| 21978 | + |
| 21979 | +/* Create a new thread */ |
| 21980 | +SQLITE_PRIVATE int sqlite3ThreadCreate( |
| 21981 | + SQLiteThread **ppThread, /* OUT: Write the thread object here */ |
| 21982 | + void *(*xTask)(void*), /* Routine to run in a separate thread */ |
| 21983 | + void *pIn /* Argument passed into xTask() */ |
| 21984 | +){ |
| 21985 | + SQLiteThread *p; |
| 21986 | + |
| 21987 | + assert( ppThread!=0 ); |
| 21988 | + assert( xTask!=0 ); |
| 21989 | + *ppThread = 0; |
| 21990 | + p = sqlite3Malloc(sizeof(*p)); |
| 21991 | + if( p==0 ) return SQLITE_NOMEM; |
| 21992 | + if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ |
| 21993 | + p->xTask = xTask; |
| 21994 | + p->pIn = pIn; |
| 21995 | + }else{ |
| 21996 | + p->xTask = 0; |
| 21997 | + p->pResult = xTask(pIn); |
| 21998 | + } |
| 21999 | + *ppThread = p; |
| 22000 | + return SQLITE_OK; |
| 22001 | +} |
| 22002 | + |
| 22003 | +/* Get the results of the thread */ |
| 22004 | +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ |
| 22005 | + |
| 22006 | + assert( ppOut!=0 ); |
| 22007 | + if( NEVER(p==0) ) return SQLITE_NOMEM; |
| 22008 | + if( p->xTask ){ |
| 22009 | + *ppOut = p->xTask(p->pIn); |
| 22010 | + }else{ |
| 22011 | + *ppOut = p->pResult; |
| 22012 | + } |
| 22013 | + sqlite3_free(p); |
| 22014 | + |
| 22015 | +#if defined(SQLITE_TEST) |
| 22016 | + { |
| 22017 | + void *pTstAlloc = sqlite3Malloc(10); |
| 22018 | + if (!pTstAlloc) return SQLITE_NOMEM; |
| 22019 | + sqlite3_free(pTstAlloc); |
| 22020 | + } |
| 22021 | +#endif |
| 22022 | + |
| 22023 | + return SQLITE_OK; |
| 22024 | +} |
| 22025 | + |
| 22026 | +#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */ |
| 22027 | +/****************************** End Single-Threaded *************************/ |
| 22028 | +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ |
| 22029 | + |
| 22030 | +/************** End of threads.c *********************************************/ |
| 21708 | 22031 | /************** Begin file utf.c *********************************************/ |
| 21709 | 22032 | /* |
| 21710 | 22033 | ** 2004 April 13 |
| 21711 | 22034 | ** |
| 21712 | 22035 | ** The author disclaims copyright to this source code. In place of |
| | @@ -21903,11 +22226,11 @@ |
| 21903 | 22226 | /* |
| 21904 | 22227 | ** This routine transforms the internal text encoding used by pMem to |
| 21905 | 22228 | ** desiredEnc. It is an error if the string is already of the desired |
| 21906 | 22229 | ** encoding, or if *pMem does not contain a string value. |
| 21907 | 22230 | */ |
| 21908 | | -SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ |
| 22231 | +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ |
| 21909 | 22232 | int len; /* Maximum length of output string in bytes */ |
| 21910 | 22233 | unsigned char *zOut; /* Output buffer */ |
| 21911 | 22234 | unsigned char *zIn; /* Input iterator */ |
| 21912 | 22235 | unsigned char *zTerm; /* End of input */ |
| 21913 | 22236 | unsigned char *z; /* Output iterator */ |
| | @@ -22345,10 +22668,19 @@ |
| 22345 | 22668 | const char *z2 = z; |
| 22346 | 22669 | if( z==0 ) return 0; |
| 22347 | 22670 | while( *z2 ){ z2++; } |
| 22348 | 22671 | return 0x3fffffff & (int)(z2 - z); |
| 22349 | 22672 | } |
| 22673 | + |
| 22674 | +/* |
| 22675 | +** Set the current error code to err_code and clear any prior error message. |
| 22676 | +*/ |
| 22677 | +SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ |
| 22678 | + assert( db!=0 ); |
| 22679 | + db->errCode = err_code; |
| 22680 | + if( db->pErr ) sqlite3ValueSetNull(db->pErr); |
| 22681 | +} |
| 22350 | 22682 | |
| 22351 | 22683 | /* |
| 22352 | 22684 | ** Set the most recent error code and error string for the sqlite |
| 22353 | 22685 | ** handle "db". The error code is set to "err_code". |
| 22354 | 22686 | ** |
| | @@ -22367,22 +22699,22 @@ |
| 22367 | 22699 | ** |
| 22368 | 22700 | ** To clear the most recent error for sqlite handle "db", sqlite3Error |
| 22369 | 22701 | ** should be called with err_code set to SQLITE_OK and zFormat set |
| 22370 | 22702 | ** to NULL. |
| 22371 | 22703 | */ |
| 22372 | | -SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){ |
| 22704 | +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ |
| 22373 | 22705 | assert( db!=0 ); |
| 22374 | 22706 | db->errCode = err_code; |
| 22375 | | - if( zFormat && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ |
| 22707 | + if( zFormat==0 ){ |
| 22708 | + sqlite3Error(db, err_code); |
| 22709 | + }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ |
| 22376 | 22710 | char *z; |
| 22377 | 22711 | va_list ap; |
| 22378 | 22712 | va_start(ap, zFormat); |
| 22379 | 22713 | z = sqlite3VMPrintf(db, zFormat, ap); |
| 22380 | 22714 | va_end(ap); |
| 22381 | 22715 | sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); |
| 22382 | | - }else if( db->pErr ){ |
| 22383 | | - sqlite3ValueSetNull(db->pErr); |
| 22384 | 22716 | } |
| 22385 | 22717 | } |
| 22386 | 22718 | |
| 22387 | 22719 | /* |
| 22388 | 22720 | ** Add an error message to pParse->zErrMsg and increment pParse->nErr. |
| | @@ -22392,16 +22724,16 @@ |
| 22392 | 22724 | ** %z A string that should be freed after use |
| 22393 | 22725 | ** %d Insert an integer |
| 22394 | 22726 | ** %T Insert a token |
| 22395 | 22727 | ** %S Insert the first element of a SrcList |
| 22396 | 22728 | ** |
| 22397 | | -** This function should be used to report any error that occurs whilst |
| 22729 | +** This function should be used to report any error that occurs while |
| 22398 | 22730 | ** compiling an SQL statement (i.e. within sqlite3_prepare()). The |
| 22399 | 22731 | ** last thing the sqlite3_prepare() function does is copy the error |
| 22400 | 22732 | ** stored by this function into the database handle using sqlite3Error(). |
| 22401 | | -** Function sqlite3Error() should be used during statement execution |
| 22402 | | -** (sqlite3_step() etc.). |
| 22733 | +** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used |
| 22734 | +** during statement execution (sqlite3_step() etc.). |
| 22403 | 22735 | */ |
| 22404 | 22736 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ |
| 22405 | 22737 | char *zMsg; |
| 22406 | 22738 | va_list ap; |
| 22407 | 22739 | sqlite3 *db = pParse->db; |
| | @@ -22934,11 +23266,11 @@ |
| 22934 | 23266 | ** A variable-length integer consists of the lower 7 bits of each byte |
| 22935 | 23267 | ** for all bytes that have the 8th bit set and one byte with the 8th |
| 22936 | 23268 | ** bit clear. Except, if we get to the 9th byte, it stores the full |
| 22937 | 23269 | ** 8 bits and is the last byte. |
| 22938 | 23270 | */ |
| 22939 | | -SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ |
| 23271 | +static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ |
| 22940 | 23272 | int i, j, n; |
| 22941 | 23273 | u8 buf[10]; |
| 22942 | 23274 | if( v & (((u64)0xff000000)<<32) ){ |
| 22943 | 23275 | p[8] = (u8)v; |
| 22944 | 23276 | v >>= 8; |
| | @@ -22958,32 +23290,21 @@ |
| 22958 | 23290 | for(i=0, j=n-1; j>=0; j--, i++){ |
| 22959 | 23291 | p[i] = buf[j]; |
| 22960 | 23292 | } |
| 22961 | 23293 | return n; |
| 22962 | 23294 | } |
| 22963 | | - |
| 22964 | | -/* |
| 22965 | | -** This routine is a faster version of sqlite3PutVarint() that only |
| 22966 | | -** works for 32-bit positive integers and which is optimized for |
| 22967 | | -** the common case of small integers. A MACRO version, putVarint32, |
| 22968 | | -** is provided which inlines the single-byte case. All code should use |
| 22969 | | -** the MACRO version as this function assumes the single-byte case has |
| 22970 | | -** already been handled. |
| 22971 | | -*/ |
| 22972 | | -SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){ |
| 22973 | | -#ifndef putVarint32 |
| 22974 | | - if( (v & ~0x7f)==0 ){ |
| 22975 | | - p[0] = v; |
| 23295 | +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ |
| 23296 | + if( v<=0x7f ){ |
| 23297 | + p[0] = v&0x7f; |
| 22976 | 23298 | return 1; |
| 22977 | 23299 | } |
| 22978 | | -#endif |
| 22979 | | - if( (v & ~0x3fff)==0 ){ |
| 22980 | | - p[0] = (u8)((v>>7) | 0x80); |
| 22981 | | - p[1] = (u8)(v & 0x7f); |
| 23300 | + if( v<=0x3fff ){ |
| 23301 | + p[0] = ((v>>7)&0x7f)|0x80; |
| 23302 | + p[1] = v&0x7f; |
| 22982 | 23303 | return 2; |
| 22983 | 23304 | } |
| 22984 | | - return sqlite3PutVarint(p, v); |
| 23305 | + return putVarint64(p,v); |
| 22985 | 23306 | } |
| 22986 | 23307 | |
| 22987 | 23308 | /* |
| 22988 | 23309 | ** Bitmasks used by sqlite3GetVarint(). These precomputed constants |
| 22989 | 23310 | ** are defined here rather than simply putting the constant expressions |
| | @@ -23655,16 +23976,15 @@ |
| 23655 | 23976 | } |
| 23656 | 23977 | |
| 23657 | 23978 | /* |
| 23658 | 23979 | ** The hashing function. |
| 23659 | 23980 | */ |
| 23660 | | -static unsigned int strHash(const char *z, int nKey){ |
| 23981 | +static unsigned int strHash(const char *z){ |
| 23661 | 23982 | unsigned int h = 0; |
| 23662 | | - assert( nKey>=0 ); |
| 23663 | | - while( nKey > 0 ){ |
| 23664 | | - h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; |
| 23665 | | - nKey--; |
| 23983 | + unsigned char c; |
| 23984 | + while( (c = (unsigned char)*z++)!=0 ){ |
| 23985 | + h = (h<<3) ^ h ^ sqlite3UpperToLower[c]; |
| 23666 | 23986 | } |
| 23667 | 23987 | return h; |
| 23668 | 23988 | } |
| 23669 | 23989 | |
| 23670 | 23990 | |
| | @@ -23732,40 +24052,45 @@ |
| 23732 | 24052 | sqlite3_free(pH->ht); |
| 23733 | 24053 | pH->ht = new_ht; |
| 23734 | 24054 | pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); |
| 23735 | 24055 | memset(new_ht, 0, new_size*sizeof(struct _ht)); |
| 23736 | 24056 | for(elem=pH->first, pH->first=0; elem; elem = next_elem){ |
| 23737 | | - unsigned int h = strHash(elem->pKey, elem->nKey) % new_size; |
| 24057 | + unsigned int h = strHash(elem->pKey) % new_size; |
| 23738 | 24058 | next_elem = elem->next; |
| 23739 | 24059 | insertElement(pH, &new_ht[h], elem); |
| 23740 | 24060 | } |
| 23741 | 24061 | return 1; |
| 23742 | 24062 | } |
| 23743 | 24063 | |
| 23744 | 24064 | /* This function (for internal use only) locates an element in an |
| 23745 | | -** hash table that matches the given key. The hash for this key has |
| 23746 | | -** already been computed and is passed as the 4th parameter. |
| 24065 | +** hash table that matches the given key. The hash for this key is |
| 24066 | +** also computed and returned in the *pH parameter. |
| 23747 | 24067 | */ |
| 23748 | | -static HashElem *findElementGivenHash( |
| 24068 | +static HashElem *findElementWithHash( |
| 23749 | 24069 | const Hash *pH, /* The pH to be searched */ |
| 23750 | 24070 | const char *pKey, /* The key we are searching for */ |
| 23751 | | - int nKey, /* Bytes in key (not counting zero terminator) */ |
| 23752 | | - unsigned int h /* The hash for this key. */ |
| 24071 | + unsigned int *pHash /* Write the hash value here */ |
| 23753 | 24072 | ){ |
| 23754 | 24073 | HashElem *elem; /* Used to loop thru the element list */ |
| 23755 | 24074 | int count; /* Number of elements left to test */ |
| 24075 | + unsigned int h; /* The computed hash */ |
| 23756 | 24076 | |
| 23757 | 24077 | if( pH->ht ){ |
| 23758 | | - struct _ht *pEntry = &pH->ht[h]; |
| 24078 | + struct _ht *pEntry; |
| 24079 | + h = strHash(pKey) % pH->htsize; |
| 24080 | + pEntry = &pH->ht[h]; |
| 23759 | 24081 | elem = pEntry->chain; |
| 23760 | 24082 | count = pEntry->count; |
| 23761 | 24083 | }else{ |
| 24084 | + h = 0; |
| 23762 | 24085 | elem = pH->first; |
| 23763 | 24086 | count = pH->count; |
| 23764 | 24087 | } |
| 23765 | | - while( count-- && ALWAYS(elem) ){ |
| 23766 | | - if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ |
| 24088 | + *pHash = h; |
| 24089 | + while( count-- ){ |
| 24090 | + assert( elem!=0 ); |
| 24091 | + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ |
| 23767 | 24092 | return elem; |
| 23768 | 24093 | } |
| 23769 | 24094 | elem = elem->next; |
| 23770 | 24095 | } |
| 23771 | 24096 | return 0; |
| | @@ -23804,30 +24129,24 @@ |
| 23804 | 24129 | sqlite3HashClear(pH); |
| 23805 | 24130 | } |
| 23806 | 24131 | } |
| 23807 | 24132 | |
| 23808 | 24133 | /* Attempt to locate an element of the hash table pH with a key |
| 23809 | | -** that matches pKey,nKey. Return the data for this element if it is |
| 24134 | +** that matches pKey. Return the data for this element if it is |
| 23810 | 24135 | ** found, or NULL if there is no match. |
| 23811 | 24136 | */ |
| 23812 | | -SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){ |
| 24137 | +SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ |
| 23813 | 24138 | HashElem *elem; /* The element that matches key */ |
| 23814 | 24139 | unsigned int h; /* A hash on key */ |
| 23815 | 24140 | |
| 23816 | 24141 | assert( pH!=0 ); |
| 23817 | 24142 | assert( pKey!=0 ); |
| 23818 | | - assert( nKey>=0 ); |
| 23819 | | - if( pH->ht ){ |
| 23820 | | - h = strHash(pKey, nKey) % pH->htsize; |
| 23821 | | - }else{ |
| 23822 | | - h = 0; |
| 23823 | | - } |
| 23824 | | - elem = findElementGivenHash(pH, pKey, nKey, h); |
| 24143 | + elem = findElementWithHash(pH, pKey, &h); |
| 23825 | 24144 | return elem ? elem->data : 0; |
| 23826 | 24145 | } |
| 23827 | 24146 | |
| 23828 | | -/* Insert an element into the hash table pH. The key is pKey,nKey |
| 24147 | +/* Insert an element into the hash table pH. The key is pKey |
| 23829 | 24148 | ** and the data is "data". |
| 23830 | 24149 | ** |
| 23831 | 24150 | ** If no element exists with a matching key, then a new |
| 23832 | 24151 | ** element is created and NULL is returned. |
| 23833 | 24152 | ** |
| | @@ -23837,53 +24156,41 @@ |
| 23837 | 24156 | ** the new data is returned and the hash table is unchanged. |
| 23838 | 24157 | ** |
| 23839 | 24158 | ** If the "data" parameter to this function is NULL, then the |
| 23840 | 24159 | ** element corresponding to "key" is removed from the hash table. |
| 23841 | 24160 | */ |
| 23842 | | -SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){ |
| 24161 | +SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ |
| 23843 | 24162 | unsigned int h; /* the hash of the key modulo hash table size */ |
| 23844 | 24163 | HashElem *elem; /* Used to loop thru the element list */ |
| 23845 | 24164 | HashElem *new_elem; /* New element added to the pH */ |
| 23846 | 24165 | |
| 23847 | 24166 | assert( pH!=0 ); |
| 23848 | 24167 | assert( pKey!=0 ); |
| 23849 | | - assert( nKey>=0 ); |
| 23850 | | - if( pH->htsize ){ |
| 23851 | | - h = strHash(pKey, nKey) % pH->htsize; |
| 23852 | | - }else{ |
| 23853 | | - h = 0; |
| 23854 | | - } |
| 23855 | | - elem = findElementGivenHash(pH,pKey,nKey,h); |
| 24168 | + elem = findElementWithHash(pH,pKey,&h); |
| 23856 | 24169 | if( elem ){ |
| 23857 | 24170 | void *old_data = elem->data; |
| 23858 | 24171 | if( data==0 ){ |
| 23859 | 24172 | removeElementGivenHash(pH,elem,h); |
| 23860 | 24173 | }else{ |
| 23861 | 24174 | elem->data = data; |
| 23862 | 24175 | elem->pKey = pKey; |
| 23863 | | - assert(nKey==elem->nKey); |
| 23864 | 24176 | } |
| 23865 | 24177 | return old_data; |
| 23866 | 24178 | } |
| 23867 | 24179 | if( data==0 ) return 0; |
| 23868 | 24180 | new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); |
| 23869 | 24181 | if( new_elem==0 ) return data; |
| 23870 | 24182 | new_elem->pKey = pKey; |
| 23871 | | - new_elem->nKey = nKey; |
| 23872 | 24183 | new_elem->data = data; |
| 23873 | 24184 | pH->count++; |
| 23874 | 24185 | if( pH->count>=10 && pH->count > 2*pH->htsize ){ |
| 23875 | 24186 | if( rehash(pH, pH->count*2) ){ |
| 23876 | 24187 | assert( pH->htsize>0 ); |
| 23877 | | - h = strHash(pKey, nKey) % pH->htsize; |
| 24188 | + h = strHash(pKey) % pH->htsize; |
| 23878 | 24189 | } |
| 23879 | 24190 | } |
| 23880 | | - if( pH->ht ){ |
| 23881 | | - insertElement(pH, &pH->ht[h], new_elem); |
| 23882 | | - }else{ |
| 23883 | | - insertElement(pH, 0, new_elem); |
| 23884 | | - } |
| 24191 | + insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); |
| 23885 | 24192 | return 0; |
| 23886 | 24193 | } |
| 23887 | 24194 | |
| 23888 | 24195 | /************** End of hash.c ************************************************/ |
| 23889 | 24196 | /************** Begin file opcodes.c *****************************************/ |
| | @@ -23934,55 +24241,55 @@ |
| 23934 | 24241 | /* 35 */ "ResultRow" OpHelp("output=r[P1@P2]"), |
| 23935 | 24242 | /* 36 */ "CollSeq" OpHelp(""), |
| 23936 | 24243 | /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 23937 | 24244 | /* 38 */ "MustBeInt" OpHelp(""), |
| 23938 | 24245 | /* 39 */ "RealAffinity" OpHelp(""), |
| 23939 | | - /* 40 */ "Permutation" OpHelp(""), |
| 23940 | | - /* 41 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 23941 | | - /* 42 */ "Jump" OpHelp(""), |
| 23942 | | - /* 43 */ "Once" OpHelp(""), |
| 23943 | | - /* 44 */ "If" OpHelp(""), |
| 23944 | | - /* 45 */ "IfNot" OpHelp(""), |
| 23945 | | - /* 46 */ "Column" OpHelp("r[P3]=PX"), |
| 23946 | | - /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23947 | | - /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23948 | | - /* 49 */ "Count" OpHelp("r[P2]=count()"), |
| 23949 | | - /* 50 */ "ReadCookie" OpHelp(""), |
| 23950 | | - /* 51 */ "SetCookie" OpHelp(""), |
| 23951 | | - /* 52 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 23952 | | - /* 53 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23953 | | - /* 54 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23954 | | - /* 55 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23955 | | - /* 56 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23956 | | - /* 57 */ "SorterOpen" OpHelp(""), |
| 23957 | | - /* 58 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 23958 | | - /* 59 */ "Close" OpHelp(""), |
| 23959 | | - /* 60 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 23960 | | - /* 61 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 23961 | | - /* 62 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 23962 | | - /* 63 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 23963 | | - /* 64 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23964 | | - /* 65 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23965 | | - /* 66 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23966 | | - /* 67 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23967 | | - /* 68 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23968 | | - /* 69 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23969 | | - /* 70 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 24246 | + /* 40 */ "Cast" OpHelp("affinity(r[P1])"), |
| 24247 | + /* 41 */ "Permutation" OpHelp(""), |
| 24248 | + /* 42 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 24249 | + /* 43 */ "Jump" OpHelp(""), |
| 24250 | + /* 44 */ "Once" OpHelp(""), |
| 24251 | + /* 45 */ "If" OpHelp(""), |
| 24252 | + /* 46 */ "IfNot" OpHelp(""), |
| 24253 | + /* 47 */ "Column" OpHelp("r[P3]=PX"), |
| 24254 | + /* 48 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 24255 | + /* 49 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 24256 | + /* 50 */ "Count" OpHelp("r[P2]=count()"), |
| 24257 | + /* 51 */ "ReadCookie" OpHelp(""), |
| 24258 | + /* 52 */ "SetCookie" OpHelp(""), |
| 24259 | + /* 53 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), |
| 24260 | + /* 54 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 24261 | + /* 55 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 24262 | + /* 56 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 24263 | + /* 57 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 24264 | + /* 58 */ "SorterOpen" OpHelp(""), |
| 24265 | + /* 59 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), |
| 24266 | + /* 60 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 24267 | + /* 61 */ "Close" OpHelp(""), |
| 24268 | + /* 62 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 24269 | + /* 63 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 24270 | + /* 64 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 24271 | + /* 65 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 24272 | + /* 66 */ "Seek" OpHelp("intkey=r[P2]"), |
| 24273 | + /* 67 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 24274 | + /* 68 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 24275 | + /* 69 */ "Found" OpHelp("key=r[P3@P4]"), |
| 24276 | + /* 70 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23970 | 24277 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23971 | 24278 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23972 | | - /* 73 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23973 | | - /* 74 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23974 | | - /* 75 */ "Delete" OpHelp(""), |
| 24279 | + /* 73 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 24280 | + /* 74 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 24281 | + /* 75 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23975 | 24282 | /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 23976 | 24283 | /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 23977 | 24284 | /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 23978 | 24285 | /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 23979 | 24286 | /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 23980 | 24287 | /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 23981 | 24288 | /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 23982 | 24289 | /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 23983 | | - /* 84 */ "ResetCount" OpHelp(""), |
| 24290 | + /* 84 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23984 | 24291 | /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 23985 | 24292 | /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 23986 | 24293 | /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 23987 | 24294 | /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 23988 | 24295 | /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| | @@ -23989,74 +24296,71 @@ |
| 23989 | 24296 | /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 23990 | 24297 | /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 23991 | 24298 | /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23992 | 24299 | /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 23993 | 24300 | /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 23994 | | - /* 95 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 24301 | + /* 95 */ "Delete" OpHelp(""), |
| 23995 | 24302 | /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 23996 | 24303 | /* 97 */ "String8" OpHelp("r[P2]='P4'"), |
| 23997 | | - /* 98 */ "SorterData" OpHelp("r[P2]=data"), |
| 23998 | | - /* 99 */ "RowKey" OpHelp("r[P2]=key"), |
| 23999 | | - /* 100 */ "RowData" OpHelp("r[P2]=data"), |
| 24000 | | - /* 101 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 24001 | | - /* 102 */ "NullRow" OpHelp(""), |
| 24002 | | - /* 103 */ "Last" OpHelp(""), |
| 24003 | | - /* 104 */ "SorterSort" OpHelp(""), |
| 24004 | | - /* 105 */ "Sort" OpHelp(""), |
| 24005 | | - /* 106 */ "Rewind" OpHelp(""), |
| 24006 | | - /* 107 */ "SorterInsert" OpHelp(""), |
| 24007 | | - /* 108 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 24008 | | - /* 109 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 24009 | | - /* 110 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 24010 | | - /* 111 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 24011 | | - /* 112 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 24012 | | - /* 113 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 24013 | | - /* 114 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 24014 | | - /* 115 */ "Destroy" OpHelp(""), |
| 24015 | | - /* 116 */ "Clear" OpHelp(""), |
| 24016 | | - /* 117 */ "ResetSorter" OpHelp(""), |
| 24017 | | - /* 118 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 24018 | | - /* 119 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 24019 | | - /* 120 */ "ParseSchema" OpHelp(""), |
| 24020 | | - /* 121 */ "LoadAnalysis" OpHelp(""), |
| 24021 | | - /* 122 */ "DropTable" OpHelp(""), |
| 24022 | | - /* 123 */ "DropIndex" OpHelp(""), |
| 24023 | | - /* 124 */ "DropTrigger" OpHelp(""), |
| 24024 | | - /* 125 */ "IntegrityCk" OpHelp(""), |
| 24025 | | - /* 126 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 24026 | | - /* 127 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 24027 | | - /* 128 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 24028 | | - /* 129 */ "Program" OpHelp(""), |
| 24029 | | - /* 130 */ "Param" OpHelp(""), |
| 24030 | | - /* 131 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24031 | | - /* 132 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24304 | + /* 98 */ "ResetCount" OpHelp(""), |
| 24305 | + /* 99 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), |
| 24306 | + /* 100 */ "SorterData" OpHelp("r[P2]=data"), |
| 24307 | + /* 101 */ "RowKey" OpHelp("r[P2]=key"), |
| 24308 | + /* 102 */ "RowData" OpHelp("r[P2]=data"), |
| 24309 | + /* 103 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 24310 | + /* 104 */ "NullRow" OpHelp(""), |
| 24311 | + /* 105 */ "Last" OpHelp(""), |
| 24312 | + /* 106 */ "SorterSort" OpHelp(""), |
| 24313 | + /* 107 */ "Sort" OpHelp(""), |
| 24314 | + /* 108 */ "Rewind" OpHelp(""), |
| 24315 | + /* 109 */ "SorterInsert" OpHelp(""), |
| 24316 | + /* 110 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 24317 | + /* 111 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 24318 | + /* 112 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 24319 | + /* 113 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 24320 | + /* 114 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 24321 | + /* 115 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 24322 | + /* 116 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 24323 | + /* 117 */ "Destroy" OpHelp(""), |
| 24324 | + /* 118 */ "Clear" OpHelp(""), |
| 24325 | + /* 119 */ "ResetSorter" OpHelp(""), |
| 24326 | + /* 120 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 24327 | + /* 121 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 24328 | + /* 122 */ "ParseSchema" OpHelp(""), |
| 24329 | + /* 123 */ "LoadAnalysis" OpHelp(""), |
| 24330 | + /* 124 */ "DropTable" OpHelp(""), |
| 24331 | + /* 125 */ "DropIndex" OpHelp(""), |
| 24332 | + /* 126 */ "DropTrigger" OpHelp(""), |
| 24333 | + /* 127 */ "IntegrityCk" OpHelp(""), |
| 24334 | + /* 128 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 24335 | + /* 129 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 24336 | + /* 130 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 24337 | + /* 131 */ "Program" OpHelp(""), |
| 24338 | + /* 132 */ "Param" OpHelp(""), |
| 24032 | 24339 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 24033 | | - /* 134 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24034 | | - /* 135 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24035 | | - /* 136 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), |
| 24036 | | - /* 137 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24037 | | - /* 138 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24038 | | - /* 139 */ "IncrVacuum" OpHelp(""), |
| 24039 | | - /* 140 */ "Expire" OpHelp(""), |
| 24040 | | - /* 141 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 24041 | | - /* 142 */ "VBegin" OpHelp(""), |
| 24042 | | - /* 143 */ "ToText" OpHelp(""), |
| 24043 | | - /* 144 */ "ToBlob" OpHelp(""), |
| 24044 | | - /* 145 */ "ToNumeric" OpHelp(""), |
| 24045 | | - /* 146 */ "ToInt" OpHelp(""), |
| 24046 | | - /* 147 */ "ToReal" OpHelp(""), |
| 24047 | | - /* 148 */ "VCreate" OpHelp(""), |
| 24048 | | - /* 149 */ "VDestroy" OpHelp(""), |
| 24049 | | - /* 150 */ "VOpen" OpHelp(""), |
| 24050 | | - /* 151 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 24051 | | - /* 152 */ "VNext" OpHelp(""), |
| 24052 | | - /* 153 */ "VRename" OpHelp(""), |
| 24053 | | - /* 154 */ "Pagecount" OpHelp(""), |
| 24054 | | - /* 155 */ "MaxPgcnt" OpHelp(""), |
| 24055 | | - /* 156 */ "Init" OpHelp("Start at P2"), |
| 24056 | | - /* 157 */ "Noop" OpHelp(""), |
| 24057 | | - /* 158 */ "Explain" OpHelp(""), |
| 24340 | + /* 134 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 24341 | + /* 135 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 24342 | + /* 136 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 24343 | + /* 137 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 24344 | + /* 138 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), |
| 24345 | + /* 139 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 24346 | + /* 140 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 24347 | + /* 141 */ "IncrVacuum" OpHelp(""), |
| 24348 | + /* 142 */ "Expire" OpHelp(""), |
| 24349 | + /* 143 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 24350 | + /* 144 */ "VBegin" OpHelp(""), |
| 24351 | + /* 145 */ "VCreate" OpHelp(""), |
| 24352 | + /* 146 */ "VDestroy" OpHelp(""), |
| 24353 | + /* 147 */ "VOpen" OpHelp(""), |
| 24354 | + /* 148 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 24355 | + /* 149 */ "VNext" OpHelp(""), |
| 24356 | + /* 150 */ "VRename" OpHelp(""), |
| 24357 | + /* 151 */ "Pagecount" OpHelp(""), |
| 24358 | + /* 152 */ "MaxPgcnt" OpHelp(""), |
| 24359 | + /* 153 */ "Init" OpHelp("Start at P2"), |
| 24360 | + /* 154 */ "Noop" OpHelp(""), |
| 24361 | + /* 155 */ "Explain" OpHelp(""), |
| 24058 | 24362 | }; |
| 24059 | 24363 | return azName[i]; |
| 24060 | 24364 | } |
| 24061 | 24365 | #endif |
| 24062 | 24366 | |
| | @@ -30154,11 +30458,11 @@ |
| 30154 | 30458 | UNUSED_PARAMETER(NotUsed); |
| 30155 | 30459 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 30156 | 30460 | if( osUnlink(zPath)==(-1) ){ |
| 30157 | 30461 | if( errno==ENOENT |
| 30158 | 30462 | #if OS_VXWORKS |
| 30159 | | - || errno==0x380003 |
| 30463 | + || osAccess(zPath,0)!=0 |
| 30160 | 30464 | #endif |
| 30161 | 30465 | ){ |
| 30162 | 30466 | rc = SQLITE_IOERR_DELETE_NOENT; |
| 30163 | 30467 | }else{ |
| 30164 | 30468 | rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); |
| | @@ -32391,13 +32695,13 @@ |
| 32391 | 32695 | ** |
| 32392 | 32696 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 32393 | 32697 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 32394 | 32698 | */ |
| 32395 | 32699 | #ifdef SQLITE_TEST |
| 32396 | | -SQLITE_API LONG volatile sqlite3_os_type = 0; |
| 32700 | +SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; |
| 32397 | 32701 | #else |
| 32398 | | -static LONG volatile sqlite3_os_type = 0; |
| 32702 | +static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; |
| 32399 | 32703 | #endif |
| 32400 | 32704 | |
| 32401 | 32705 | #ifndef SYSCALL |
| 32402 | 32706 | # define SYSCALL sqlite3_syscall_ptr |
| 32403 | 32707 | #endif |
| | @@ -32924,15 +33228,11 @@ |
| 32924 | 33228 | #endif |
| 32925 | 33229 | |
| 32926 | 33230 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 32927 | 33231 | DWORD))aSyscall[63].pCurrent) |
| 32928 | 33232 | |
| 32929 | | -#if SQLITE_OS_WINRT |
| 32930 | 33233 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 32931 | | -#else |
| 32932 | | - { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 32933 | | -#endif |
| 32934 | 33234 | |
| 32935 | 33235 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 32936 | 33236 | BOOL))aSyscall[64].pCurrent) |
| 32937 | 33237 | |
| 32938 | 33238 | #if SQLITE_OS_WINRT |
| | @@ -33036,12 +33336,12 @@ |
| 33036 | 33336 | |
| 33037 | 33337 | #define osInterlockedCompareExchange InterlockedCompareExchange |
| 33038 | 33338 | #else |
| 33039 | 33339 | { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, |
| 33040 | 33340 | |
| 33041 | | -#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \ |
| 33042 | | - LONG,LONG))aSyscall[76].pCurrent) |
| 33341 | +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ |
| 33342 | + SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) |
| 33043 | 33343 | #endif /* defined(InterlockedCompareExchange) */ |
| 33044 | 33344 | |
| 33045 | 33345 | }; /* End of the overrideable system calls */ |
| 33046 | 33346 | |
| 33047 | 33347 | /* |
| | @@ -33270,10 +33570,17 @@ |
| 33270 | 33570 | osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); |
| 33271 | 33571 | #else |
| 33272 | 33572 | osSleep(milliseconds); |
| 33273 | 33573 | #endif |
| 33274 | 33574 | } |
| 33575 | + |
| 33576 | +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ |
| 33577 | + DWORD rc; |
| 33578 | + while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, |
| 33579 | + TRUE))==WAIT_IO_COMPLETION ){} |
| 33580 | + return rc; |
| 33581 | +} |
| 33275 | 33582 | |
| 33276 | 33583 | /* |
| 33277 | 33584 | ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
| 33278 | 33585 | ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
| 33279 | 33586 | ** |
| | @@ -37984,88 +38291,100 @@ |
| 37984 | 38291 | } |
| 37985 | 38292 | return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0); |
| 37986 | 38293 | } |
| 37987 | 38294 | #endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ |
| 37988 | 38295 | |
| 37989 | | -/* |
| 37990 | | -** Remove page pPage from the list of dirty pages. |
| 37991 | | -*/ |
| 37992 | | -static void pcacheRemoveFromDirtyList(PgHdr *pPage){ |
| 37993 | | - PCache *p = pPage->pCache; |
| 37994 | | - |
| 37995 | | - assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); |
| 37996 | | - assert( pPage->pDirtyPrev || pPage==p->pDirty ); |
| 37997 | | - |
| 37998 | | - /* Update the PCache1.pSynced variable if necessary. */ |
| 37999 | | - if( p->pSynced==pPage ){ |
| 38000 | | - PgHdr *pSynced = pPage->pDirtyPrev; |
| 38001 | | - while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ |
| 38002 | | - pSynced = pSynced->pDirtyPrev; |
| 38003 | | - } |
| 38004 | | - p->pSynced = pSynced; |
| 38005 | | - } |
| 38006 | | - |
| 38007 | | - if( pPage->pDirtyNext ){ |
| 38008 | | - pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; |
| 38009 | | - }else{ |
| 38010 | | - assert( pPage==p->pDirtyTail ); |
| 38011 | | - p->pDirtyTail = pPage->pDirtyPrev; |
| 38012 | | - } |
| 38013 | | - if( pPage->pDirtyPrev ){ |
| 38014 | | - pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; |
| 38015 | | - }else{ |
| 38016 | | - assert( pPage==p->pDirty ); |
| 38017 | | - p->pDirty = pPage->pDirtyNext; |
| 38018 | | - if( p->pDirty==0 && p->bPurgeable ){ |
| 38019 | | - assert( p->eCreate==1 ); |
| 38020 | | - p->eCreate = 2; |
| 38021 | | - } |
| 38022 | | - } |
| 38023 | | - pPage->pDirtyNext = 0; |
| 38024 | | - pPage->pDirtyPrev = 0; |
| 38025 | | - |
| 38026 | | - expensive_assert( pcacheCheckSynced(p) ); |
| 38027 | | -} |
| 38028 | | - |
| 38029 | | -/* |
| 38030 | | -** Add page pPage to the head of the dirty list (PCache1.pDirty is set to |
| 38031 | | -** pPage). |
| 38032 | | -*/ |
| 38033 | | -static void pcacheAddToDirtyList(PgHdr *pPage){ |
| 38034 | | - PCache *p = pPage->pCache; |
| 38035 | | - |
| 38036 | | - assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); |
| 38037 | | - |
| 38038 | | - pPage->pDirtyNext = p->pDirty; |
| 38039 | | - if( pPage->pDirtyNext ){ |
| 38040 | | - assert( pPage->pDirtyNext->pDirtyPrev==0 ); |
| 38041 | | - pPage->pDirtyNext->pDirtyPrev = pPage; |
| 38042 | | - }else if( p->bPurgeable ){ |
| 38043 | | - assert( p->eCreate==2 ); |
| 38044 | | - p->eCreate = 1; |
| 38045 | | - } |
| 38046 | | - p->pDirty = pPage; |
| 38047 | | - if( !p->pDirtyTail ){ |
| 38048 | | - p->pDirtyTail = pPage; |
| 38049 | | - } |
| 38050 | | - if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ |
| 38051 | | - p->pSynced = pPage; |
| 38052 | | - } |
| 38053 | | - expensive_assert( pcacheCheckSynced(p) ); |
| 38296 | +/* Allowed values for second argument to pcacheManageDirtyList() */ |
| 38297 | +#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ |
| 38298 | +#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ |
| 38299 | +#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ |
| 38300 | + |
| 38301 | +/* |
| 38302 | +** Manage pPage's participation on the dirty list. Bits of the addRemove |
| 38303 | +** argument determines what operation to do. The 0x01 bit means first |
| 38304 | +** remove pPage from the dirty list. The 0x02 means add pPage back to |
| 38305 | +** the dirty list. Doing both moves pPage to the front of the dirty list. |
| 38306 | +*/ |
| 38307 | +static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ |
| 38308 | + PCache *p = pPage->pCache; |
| 38309 | + |
| 38310 | + if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ |
| 38311 | + assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); |
| 38312 | + assert( pPage->pDirtyPrev || pPage==p->pDirty ); |
| 38313 | + |
| 38314 | + /* Update the PCache1.pSynced variable if necessary. */ |
| 38315 | + if( p->pSynced==pPage ){ |
| 38316 | + PgHdr *pSynced = pPage->pDirtyPrev; |
| 38317 | + while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ |
| 38318 | + pSynced = pSynced->pDirtyPrev; |
| 38319 | + } |
| 38320 | + p->pSynced = pSynced; |
| 38321 | + } |
| 38322 | + |
| 38323 | + if( pPage->pDirtyNext ){ |
| 38324 | + pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; |
| 38325 | + }else{ |
| 38326 | + assert( pPage==p->pDirtyTail ); |
| 38327 | + p->pDirtyTail = pPage->pDirtyPrev; |
| 38328 | + } |
| 38329 | + if( pPage->pDirtyPrev ){ |
| 38330 | + pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; |
| 38331 | + }else{ |
| 38332 | + assert( pPage==p->pDirty ); |
| 38333 | + p->pDirty = pPage->pDirtyNext; |
| 38334 | + if( p->pDirty==0 && p->bPurgeable ){ |
| 38335 | + assert( p->eCreate==1 ); |
| 38336 | + p->eCreate = 2; |
| 38337 | + } |
| 38338 | + } |
| 38339 | + pPage->pDirtyNext = 0; |
| 38340 | + pPage->pDirtyPrev = 0; |
| 38341 | + expensive_assert( pcacheCheckSynced(p) ); |
| 38342 | + } |
| 38343 | + if( addRemove & PCACHE_DIRTYLIST_ADD ){ |
| 38344 | + assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); |
| 38345 | + |
| 38346 | + pPage->pDirtyNext = p->pDirty; |
| 38347 | + if( pPage->pDirtyNext ){ |
| 38348 | + assert( pPage->pDirtyNext->pDirtyPrev==0 ); |
| 38349 | + pPage->pDirtyNext->pDirtyPrev = pPage; |
| 38350 | + }else if( p->bPurgeable ){ |
| 38351 | + assert( p->eCreate==2 ); |
| 38352 | + p->eCreate = 1; |
| 38353 | + } |
| 38354 | + p->pDirty = pPage; |
| 38355 | + if( !p->pDirtyTail ){ |
| 38356 | + p->pDirtyTail = pPage; |
| 38357 | + } |
| 38358 | + if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ |
| 38359 | + p->pSynced = pPage; |
| 38360 | + } |
| 38361 | + expensive_assert( pcacheCheckSynced(p) ); |
| 38362 | + } |
| 38054 | 38363 | } |
| 38055 | 38364 | |
| 38056 | 38365 | /* |
| 38057 | 38366 | ** Wrapper around the pluggable caches xUnpin method. If the cache is |
| 38058 | 38367 | ** being used for an in-memory database, this function is a no-op. |
| 38059 | 38368 | */ |
| 38060 | 38369 | static void pcacheUnpin(PgHdr *p){ |
| 38061 | | - PCache *pCache = p->pCache; |
| 38062 | | - if( pCache->bPurgeable ){ |
| 38370 | + if( p->pCache->bPurgeable ){ |
| 38063 | 38371 | if( p->pgno==1 ){ |
| 38064 | | - pCache->pPage1 = 0; |
| 38372 | + p->pCache->pPage1 = 0; |
| 38065 | 38373 | } |
| 38066 | | - sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0); |
| 38374 | + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); |
| 38375 | + } |
| 38376 | +} |
| 38377 | + |
| 38378 | +/* |
| 38379 | +** Compute the number of pages of cache requested. |
| 38380 | +*/ |
| 38381 | +static int numberOfCachePages(PCache *p){ |
| 38382 | + if( p->szCache>=0 ){ |
| 38383 | + return p->szCache; |
| 38384 | + }else{ |
| 38385 | + return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); |
| 38067 | 38386 | } |
| 38068 | 38387 | } |
| 38069 | 38388 | |
| 38070 | 38389 | /*************************************************** General Interfaces ****** |
| 38071 | 38390 | ** |
| | @@ -38097,179 +38416,225 @@ |
| 38097 | 38416 | ** Create a new PCache object. Storage space to hold the object |
| 38098 | 38417 | ** has already been allocated and is passed in as the p pointer. |
| 38099 | 38418 | ** The caller discovers how much space needs to be allocated by |
| 38100 | 38419 | ** calling sqlite3PcacheSize(). |
| 38101 | 38420 | */ |
| 38102 | | -SQLITE_PRIVATE void sqlite3PcacheOpen( |
| 38421 | +SQLITE_PRIVATE int sqlite3PcacheOpen( |
| 38103 | 38422 | int szPage, /* Size of every page */ |
| 38104 | 38423 | int szExtra, /* Extra space associated with each page */ |
| 38105 | 38424 | int bPurgeable, /* True if pages are on backing store */ |
| 38106 | 38425 | int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ |
| 38107 | 38426 | void *pStress, /* Argument to xStress */ |
| 38108 | 38427 | PCache *p /* Preallocated space for the PCache */ |
| 38109 | 38428 | ){ |
| 38110 | 38429 | memset(p, 0, sizeof(PCache)); |
| 38111 | | - p->szPage = szPage; |
| 38430 | + p->szPage = 1; |
| 38112 | 38431 | p->szExtra = szExtra; |
| 38113 | 38432 | p->bPurgeable = bPurgeable; |
| 38114 | 38433 | p->eCreate = 2; |
| 38115 | 38434 | p->xStress = xStress; |
| 38116 | 38435 | p->pStress = pStress; |
| 38117 | 38436 | p->szCache = 100; |
| 38437 | + return sqlite3PcacheSetPageSize(p, szPage); |
| 38118 | 38438 | } |
| 38119 | 38439 | |
| 38120 | 38440 | /* |
| 38121 | 38441 | ** Change the page size for PCache object. The caller must ensure that there |
| 38122 | 38442 | ** are no outstanding page references when this function is called. |
| 38123 | 38443 | */ |
| 38124 | | -SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ |
| 38444 | +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ |
| 38125 | 38445 | assert( pCache->nRef==0 && pCache->pDirty==0 ); |
| 38126 | | - if( pCache->pCache ){ |
| 38127 | | - sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
| 38128 | | - pCache->pCache = 0; |
| 38446 | + if( pCache->szPage ){ |
| 38447 | + sqlite3_pcache *pNew; |
| 38448 | + pNew = sqlite3GlobalConfig.pcache2.xCreate( |
| 38449 | + szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable |
| 38450 | + ); |
| 38451 | + if( pNew==0 ) return SQLITE_NOMEM; |
| 38452 | + sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); |
| 38453 | + if( pCache->pCache ){ |
| 38454 | + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
| 38455 | + } |
| 38456 | + pCache->pCache = pNew; |
| 38129 | 38457 | pCache->pPage1 = 0; |
| 38130 | | - } |
| 38131 | | - pCache->szPage = szPage; |
| 38132 | | -} |
| 38133 | | - |
| 38134 | | -/* |
| 38135 | | -** Compute the number of pages of cache requested. |
| 38136 | | -*/ |
| 38137 | | -static int numberOfCachePages(PCache *p){ |
| 38138 | | - if( p->szCache>=0 ){ |
| 38139 | | - return p->szCache; |
| 38140 | | - }else{ |
| 38141 | | - return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); |
| 38142 | | - } |
| 38458 | + pCache->szPage = szPage; |
| 38459 | + } |
| 38460 | + return SQLITE_OK; |
| 38143 | 38461 | } |
| 38144 | 38462 | |
| 38145 | 38463 | /* |
| 38146 | 38464 | ** Try to obtain a page from the cache. |
| 38465 | +** |
| 38466 | +** This routine returns a pointer to an sqlite3_pcache_page object if |
| 38467 | +** such an object is already in cache, or if a new one is created. |
| 38468 | +** This routine returns a NULL pointer if the object was not in cache |
| 38469 | +** and could not be created. |
| 38470 | +** |
| 38471 | +** The createFlags should be 0 to check for existing pages and should |
| 38472 | +** be 3 (not 1, but 3) to try to create a new page. |
| 38473 | +** |
| 38474 | +** If the createFlag is 0, then NULL is always returned if the page |
| 38475 | +** is not already in the cache. If createFlag is 1, then a new page |
| 38476 | +** is created only if that can be done without spilling dirty pages |
| 38477 | +** and without exceeding the cache size limit. |
| 38478 | +** |
| 38479 | +** The caller needs to invoke sqlite3PcacheFetchFinish() to properly |
| 38480 | +** initialize the sqlite3_pcache_page object and convert it into a |
| 38481 | +** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() |
| 38482 | +** routines are split this way for performance reasons. When separated |
| 38483 | +** they can both (usually) operate without having to push values to |
| 38484 | +** the stack on entry and pop them back off on exit, which saves a |
| 38485 | +** lot of pushing and popping. |
| 38147 | 38486 | */ |
| 38148 | | -SQLITE_PRIVATE int sqlite3PcacheFetch( |
| 38487 | +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( |
| 38149 | 38488 | PCache *pCache, /* Obtain the page from this cache */ |
| 38150 | 38489 | Pgno pgno, /* Page number to obtain */ |
| 38151 | | - int createFlag, /* If true, create page if it does not exist already */ |
| 38152 | | - PgHdr **ppPage /* Write the page here */ |
| 38490 | + int createFlag /* If true, create page if it does not exist already */ |
| 38153 | 38491 | ){ |
| 38154 | | - sqlite3_pcache_page *pPage; |
| 38155 | | - PgHdr *pPgHdr = 0; |
| 38156 | 38492 | int eCreate; |
| 38157 | 38493 | |
| 38158 | 38494 | assert( pCache!=0 ); |
| 38159 | | - assert( createFlag==1 || createFlag==0 ); |
| 38495 | + assert( pCache->pCache!=0 ); |
| 38496 | + assert( createFlag==3 || createFlag==0 ); |
| 38160 | 38497 | assert( pgno>0 ); |
| 38161 | 38498 | |
| 38162 | | - /* If the pluggable cache (sqlite3_pcache*) has not been allocated, |
| 38163 | | - ** allocate it now. |
| 38164 | | - */ |
| 38165 | | - if( !pCache->pCache ){ |
| 38166 | | - sqlite3_pcache *p; |
| 38167 | | - if( !createFlag ){ |
| 38168 | | - *ppPage = 0; |
| 38169 | | - return SQLITE_OK; |
| 38170 | | - } |
| 38171 | | - p = sqlite3GlobalConfig.pcache2.xCreate( |
| 38172 | | - pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable |
| 38173 | | - ); |
| 38174 | | - if( !p ){ |
| 38175 | | - return SQLITE_NOMEM; |
| 38176 | | - } |
| 38177 | | - sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache)); |
| 38178 | | - pCache->pCache = p; |
| 38179 | | - } |
| 38180 | | - |
| 38181 | 38499 | /* eCreate defines what to do if the page does not exist. |
| 38182 | 38500 | ** 0 Do not allocate a new page. (createFlag==0) |
| 38183 | 38501 | ** 1 Allocate a new page if doing so is inexpensive. |
| 38184 | 38502 | ** (createFlag==1 AND bPurgeable AND pDirty) |
| 38185 | 38503 | ** 2 Allocate a new page even it doing so is difficult. |
| 38186 | 38504 | ** (createFlag==1 AND !(bPurgeable AND pDirty) |
| 38187 | 38505 | */ |
| 38188 | | - eCreate = createFlag==0 ? 0 : pCache->eCreate; |
| 38189 | | - assert( (createFlag*(1+(!pCache->bPurgeable||!pCache->pDirty)))==eCreate ); |
| 38190 | | - pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); |
| 38191 | | - if( !pPage && eCreate==1 ){ |
| 38192 | | - PgHdr *pPg; |
| 38193 | | - |
| 38194 | | - /* Find a dirty page to write-out and recycle. First try to find a |
| 38195 | | - ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC |
| 38196 | | - ** cleared), but if that is not possible settle for any other |
| 38197 | | - ** unreferenced dirty page. |
| 38198 | | - */ |
| 38199 | | - expensive_assert( pcacheCheckSynced(pCache) ); |
| 38200 | | - for(pPg=pCache->pSynced; |
| 38201 | | - pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); |
| 38202 | | - pPg=pPg->pDirtyPrev |
| 38203 | | - ); |
| 38204 | | - pCache->pSynced = pPg; |
| 38205 | | - if( !pPg ){ |
| 38206 | | - for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 38207 | | - } |
| 38208 | | - if( pPg ){ |
| 38209 | | - int rc; |
| 38506 | + eCreate = createFlag & pCache->eCreate; |
| 38507 | + assert( eCreate==0 || eCreate==1 || eCreate==2 ); |
| 38508 | + assert( createFlag==0 || pCache->eCreate==eCreate ); |
| 38509 | + assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); |
| 38510 | + return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); |
| 38511 | +} |
| 38512 | + |
| 38513 | +/* |
| 38514 | +** If the sqlite3PcacheFetch() routine is unable to allocate a new |
| 38515 | +** page because new clean pages are available for reuse and the cache |
| 38516 | +** size limit has been reached, then this routine can be invoked to |
| 38517 | +** try harder to allocate a page. This routine might invoke the stress |
| 38518 | +** callback to spill dirty pages to the journal. It will then try to |
| 38519 | +** allocate the new page and will only fail to allocate a new page on |
| 38520 | +** an OOM error. |
| 38521 | +** |
| 38522 | +** This routine should be invoked only after sqlite3PcacheFetch() fails. |
| 38523 | +*/ |
| 38524 | +SQLITE_PRIVATE int sqlite3PcacheFetchStress( |
| 38525 | + PCache *pCache, /* Obtain the page from this cache */ |
| 38526 | + Pgno pgno, /* Page number to obtain */ |
| 38527 | + sqlite3_pcache_page **ppPage /* Write result here */ |
| 38528 | +){ |
| 38529 | + PgHdr *pPg; |
| 38530 | + if( pCache->eCreate==2 ) return 0; |
| 38531 | + |
| 38532 | + |
| 38533 | + /* Find a dirty page to write-out and recycle. First try to find a |
| 38534 | + ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC |
| 38535 | + ** cleared), but if that is not possible settle for any other |
| 38536 | + ** unreferenced dirty page. |
| 38537 | + */ |
| 38538 | + expensive_assert( pcacheCheckSynced(pCache) ); |
| 38539 | + for(pPg=pCache->pSynced; |
| 38540 | + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); |
| 38541 | + pPg=pPg->pDirtyPrev |
| 38542 | + ); |
| 38543 | + pCache->pSynced = pPg; |
| 38544 | + if( !pPg ){ |
| 38545 | + for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 38546 | + } |
| 38547 | + if( pPg ){ |
| 38548 | + int rc; |
| 38210 | 38549 | #ifdef SQLITE_LOG_CACHE_SPILL |
| 38211 | | - sqlite3_log(SQLITE_FULL, |
| 38212 | | - "spill page %d making room for %d - cache used: %d/%d", |
| 38213 | | - pPg->pgno, pgno, |
| 38214 | | - sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), |
| 38215 | | - numberOfCachePages(pCache)); |
| 38216 | | -#endif |
| 38217 | | - rc = pCache->xStress(pCache->pStress, pPg); |
| 38218 | | - if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 38219 | | - return rc; |
| 38220 | | - } |
| 38221 | | - } |
| 38222 | | - |
| 38223 | | - pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); |
| 38224 | | - } |
| 38225 | | - |
| 38226 | | - if( pPage ){ |
| 38227 | | - pPgHdr = (PgHdr *)pPage->pExtra; |
| 38228 | | - |
| 38229 | | - if( !pPgHdr->pPage ){ |
| 38230 | | - memset(pPgHdr, 0, sizeof(PgHdr)); |
| 38231 | | - pPgHdr->pPage = pPage; |
| 38232 | | - pPgHdr->pData = pPage->pBuf; |
| 38233 | | - pPgHdr->pExtra = (void *)&pPgHdr[1]; |
| 38234 | | - memset(pPgHdr->pExtra, 0, pCache->szExtra); |
| 38235 | | - pPgHdr->pCache = pCache; |
| 38236 | | - pPgHdr->pgno = pgno; |
| 38237 | | - } |
| 38238 | | - assert( pPgHdr->pCache==pCache ); |
| 38239 | | - assert( pPgHdr->pgno==pgno ); |
| 38240 | | - assert( pPgHdr->pData==pPage->pBuf ); |
| 38241 | | - assert( pPgHdr->pExtra==(void *)&pPgHdr[1] ); |
| 38242 | | - |
| 38243 | | - if( 0==pPgHdr->nRef ){ |
| 38244 | | - pCache->nRef++; |
| 38245 | | - } |
| 38246 | | - pPgHdr->nRef++; |
| 38247 | | - if( pgno==1 ){ |
| 38248 | | - pCache->pPage1 = pPgHdr; |
| 38249 | | - } |
| 38250 | | - } |
| 38251 | | - *ppPage = pPgHdr; |
| 38252 | | - return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK; |
| 38550 | + sqlite3_log(SQLITE_FULL, |
| 38551 | + "spill page %d making room for %d - cache used: %d/%d", |
| 38552 | + pPg->pgno, pgno, |
| 38553 | + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), |
| 38554 | + numberOfCachePages(pCache)); |
| 38555 | +#endif |
| 38556 | + rc = pCache->xStress(pCache->pStress, pPg); |
| 38557 | + if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 38558 | + return rc; |
| 38559 | + } |
| 38560 | + } |
| 38561 | + *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); |
| 38562 | + return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK; |
| 38563 | +} |
| 38564 | + |
| 38565 | +/* |
| 38566 | +** This is a helper routine for sqlite3PcacheFetchFinish() |
| 38567 | +** |
| 38568 | +** In the uncommon case where the page being fetched has not been |
| 38569 | +** initialized, this routine is invoked to do the initialization. |
| 38570 | +** This routine is broken out into a separate function since it |
| 38571 | +** requires extra stack manipulation that can be avoided in the common |
| 38572 | +** case. |
| 38573 | +*/ |
| 38574 | +static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( |
| 38575 | + PCache *pCache, /* Obtain the page from this cache */ |
| 38576 | + Pgno pgno, /* Page number obtained */ |
| 38577 | + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ |
| 38578 | +){ |
| 38579 | + PgHdr *pPgHdr; |
| 38580 | + assert( pPage!=0 ); |
| 38581 | + pPgHdr = (PgHdr*)pPage->pExtra; |
| 38582 | + assert( pPgHdr->pPage==0 ); |
| 38583 | + memset(pPgHdr, 0, sizeof(PgHdr)); |
| 38584 | + pPgHdr->pPage = pPage; |
| 38585 | + pPgHdr->pData = pPage->pBuf; |
| 38586 | + pPgHdr->pExtra = (void *)&pPgHdr[1]; |
| 38587 | + memset(pPgHdr->pExtra, 0, pCache->szExtra); |
| 38588 | + pPgHdr->pCache = pCache; |
| 38589 | + pPgHdr->pgno = pgno; |
| 38590 | + return sqlite3PcacheFetchFinish(pCache,pgno,pPage); |
| 38591 | +} |
| 38592 | + |
| 38593 | +/* |
| 38594 | +** This routine converts the sqlite3_pcache_page object returned by |
| 38595 | +** sqlite3PcacheFetch() into an initialized PgHdr object. This routine |
| 38596 | +** must be called after sqlite3PcacheFetch() in order to get a usable |
| 38597 | +** result. |
| 38598 | +*/ |
| 38599 | +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( |
| 38600 | + PCache *pCache, /* Obtain the page from this cache */ |
| 38601 | + Pgno pgno, /* Page number obtained */ |
| 38602 | + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ |
| 38603 | +){ |
| 38604 | + PgHdr *pPgHdr; |
| 38605 | + |
| 38606 | + if( pPage==0 ) return 0; |
| 38607 | + pPgHdr = (PgHdr *)pPage->pExtra; |
| 38608 | + |
| 38609 | + if( !pPgHdr->pPage ){ |
| 38610 | + return pcacheFetchFinishWithInit(pCache, pgno, pPage); |
| 38611 | + } |
| 38612 | + if( 0==pPgHdr->nRef ){ |
| 38613 | + pCache->nRef++; |
| 38614 | + } |
| 38615 | + pPgHdr->nRef++; |
| 38616 | + if( pgno==1 ){ |
| 38617 | + pCache->pPage1 = pPgHdr; |
| 38618 | + } |
| 38619 | + return pPgHdr; |
| 38253 | 38620 | } |
| 38254 | 38621 | |
| 38255 | 38622 | /* |
| 38256 | 38623 | ** Decrement the reference count on a page. If the page is clean and the |
| 38257 | 38624 | ** reference count drops to 0, then it is made elible for recycling. |
| 38258 | 38625 | */ |
| 38259 | | -SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){ |
| 38626 | +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ |
| 38260 | 38627 | assert( p->nRef>0 ); |
| 38261 | 38628 | p->nRef--; |
| 38262 | 38629 | if( p->nRef==0 ){ |
| 38263 | | - PCache *pCache = p->pCache; |
| 38264 | | - pCache->nRef--; |
| 38630 | + p->pCache->nRef--; |
| 38265 | 38631 | if( (p->flags&PGHDR_DIRTY)==0 ){ |
| 38266 | 38632 | pcacheUnpin(p); |
| 38267 | 38633 | }else{ |
| 38268 | 38634 | /* Move the page to the head of the dirty list. */ |
| 38269 | | - pcacheRemoveFromDirtyList(p); |
| 38270 | | - pcacheAddToDirtyList(p); |
| 38635 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
| 38271 | 38636 | } |
| 38272 | 38637 | } |
| 38273 | 38638 | } |
| 38274 | 38639 | |
| 38275 | 38640 | /* |
| | @@ -38284,21 +38649,19 @@ |
| 38284 | 38649 | ** Drop a page from the cache. There must be exactly one reference to the |
| 38285 | 38650 | ** page. This function deletes that reference, so after it returns the |
| 38286 | 38651 | ** page pointed to by p is invalid. |
| 38287 | 38652 | */ |
| 38288 | 38653 | SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ |
| 38289 | | - PCache *pCache; |
| 38290 | 38654 | assert( p->nRef==1 ); |
| 38291 | 38655 | if( p->flags&PGHDR_DIRTY ){ |
| 38292 | | - pcacheRemoveFromDirtyList(p); |
| 38656 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
| 38293 | 38657 | } |
| 38294 | | - pCache = p->pCache; |
| 38295 | | - pCache->nRef--; |
| 38658 | + p->pCache->nRef--; |
| 38296 | 38659 | if( p->pgno==1 ){ |
| 38297 | | - pCache->pPage1 = 0; |
| 38660 | + p->pCache->pPage1 = 0; |
| 38298 | 38661 | } |
| 38299 | | - sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1); |
| 38662 | + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); |
| 38300 | 38663 | } |
| 38301 | 38664 | |
| 38302 | 38665 | /* |
| 38303 | 38666 | ** Make sure the page is marked as dirty. If it isn't dirty already, |
| 38304 | 38667 | ** make it so. |
| | @@ -38306,21 +38669,21 @@ |
| 38306 | 38669 | SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ |
| 38307 | 38670 | p->flags &= ~PGHDR_DONT_WRITE; |
| 38308 | 38671 | assert( p->nRef>0 ); |
| 38309 | 38672 | if( 0==(p->flags & PGHDR_DIRTY) ){ |
| 38310 | 38673 | p->flags |= PGHDR_DIRTY; |
| 38311 | | - pcacheAddToDirtyList( p); |
| 38674 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); |
| 38312 | 38675 | } |
| 38313 | 38676 | } |
| 38314 | 38677 | |
| 38315 | 38678 | /* |
| 38316 | 38679 | ** Make sure the page is marked as clean. If it isn't clean already, |
| 38317 | 38680 | ** make it so. |
| 38318 | 38681 | */ |
| 38319 | 38682 | SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ |
| 38320 | 38683 | if( (p->flags & PGHDR_DIRTY) ){ |
| 38321 | | - pcacheRemoveFromDirtyList(p); |
| 38684 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); |
| 38322 | 38685 | p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC); |
| 38323 | 38686 | if( p->nRef==0 ){ |
| 38324 | 38687 | pcacheUnpin(p); |
| 38325 | 38688 | } |
| 38326 | 38689 | } |
| | @@ -38355,12 +38718,11 @@ |
| 38355 | 38718 | assert( p->nRef>0 ); |
| 38356 | 38719 | assert( newPgno>0 ); |
| 38357 | 38720 | sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); |
| 38358 | 38721 | p->pgno = newPgno; |
| 38359 | 38722 | if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ |
| 38360 | | - pcacheRemoveFromDirtyList(p); |
| 38361 | | - pcacheAddToDirtyList(p); |
| 38723 | + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
| 38362 | 38724 | } |
| 38363 | 38725 | } |
| 38364 | 38726 | |
| 38365 | 38727 | /* |
| 38366 | 38728 | ** Drop every cache entry whose page number is greater than "pgno". The |
| | @@ -38397,13 +38759,12 @@ |
| 38397 | 38759 | |
| 38398 | 38760 | /* |
| 38399 | 38761 | ** Close a cache. |
| 38400 | 38762 | */ |
| 38401 | 38763 | SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ |
| 38402 | | - if( pCache->pCache ){ |
| 38403 | | - sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
| 38404 | | - } |
| 38764 | + assert( pCache->pCache!=0 ); |
| 38765 | + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); |
| 38405 | 38766 | } |
| 38406 | 38767 | |
| 38407 | 38768 | /* |
| 38408 | 38769 | ** Discard the contents of the cache. |
| 38409 | 38770 | */ |
| | @@ -38508,15 +38869,12 @@ |
| 38508 | 38869 | |
| 38509 | 38870 | /* |
| 38510 | 38871 | ** Return the total number of pages in the cache. |
| 38511 | 38872 | */ |
| 38512 | 38873 | SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ |
| 38513 | | - int nPage = 0; |
| 38514 | | - if( pCache->pCache ){ |
| 38515 | | - nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); |
| 38516 | | - } |
| 38517 | | - return nPage; |
| 38874 | + assert( pCache->pCache!=0 ); |
| 38875 | + return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); |
| 38518 | 38876 | } |
| 38519 | 38877 | |
| 38520 | 38878 | #ifdef SQLITE_TEST |
| 38521 | 38879 | /* |
| 38522 | 38880 | ** Get the suggested cache-size value. |
| | @@ -38528,24 +38886,22 @@ |
| 38528 | 38886 | |
| 38529 | 38887 | /* |
| 38530 | 38888 | ** Set the suggested cache-size value. |
| 38531 | 38889 | */ |
| 38532 | 38890 | SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ |
| 38891 | + assert( pCache->pCache!=0 ); |
| 38533 | 38892 | pCache->szCache = mxPage; |
| 38534 | | - if( pCache->pCache ){ |
| 38535 | | - sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, |
| 38536 | | - numberOfCachePages(pCache)); |
| 38537 | | - } |
| 38893 | + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, |
| 38894 | + numberOfCachePages(pCache)); |
| 38538 | 38895 | } |
| 38539 | 38896 | |
| 38540 | 38897 | /* |
| 38541 | 38898 | ** Free up as much memory as possible from the page cache. |
| 38542 | 38899 | */ |
| 38543 | 38900 | SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ |
| 38544 | | - if( pCache->pCache ){ |
| 38545 | | - sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); |
| 38546 | | - } |
| 38901 | + assert( pCache->pCache!=0 ); |
| 38902 | + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); |
| 38547 | 38903 | } |
| 38548 | 38904 | |
| 38549 | 38905 | #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) |
| 38550 | 38906 | /* |
| 38551 | 38907 | ** For all dirty pages currently in the cache, invoke the specified |
| | @@ -38944,11 +39300,11 @@ |
| 38944 | 39300 | ** This function is used to resize the hash table used by the cache passed |
| 38945 | 39301 | ** as the first argument. |
| 38946 | 39302 | ** |
| 38947 | 39303 | ** The PCache mutex must be held when this function is called. |
| 38948 | 39304 | */ |
| 38949 | | -static int pcache1ResizeHash(PCache1 *p){ |
| 39305 | +static void pcache1ResizeHash(PCache1 *p){ |
| 38950 | 39306 | PgHdr1 **apNew; |
| 38951 | 39307 | unsigned int nNew; |
| 38952 | 39308 | unsigned int i; |
| 38953 | 39309 | |
| 38954 | 39310 | assert( sqlite3_mutex_held(p->pGroup->mutex) ); |
| | @@ -38976,12 +39332,10 @@ |
| 38976 | 39332 | } |
| 38977 | 39333 | sqlite3_free(p->apHash); |
| 38978 | 39334 | p->apHash = apNew; |
| 38979 | 39335 | p->nHash = nNew; |
| 38980 | 39336 | } |
| 38981 | | - |
| 38982 | | - return (p->apHash ? SQLITE_OK : SQLITE_NOMEM); |
| 38983 | 39337 | } |
| 38984 | 39338 | |
| 38985 | 39339 | /* |
| 38986 | 39340 | ** This function is used internally to remove the page pPage from the |
| 38987 | 39341 | ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup |
| | @@ -39112,10 +39466,13 @@ |
| 39112 | 39466 | UNUSED_PARAMETER(NotUsed); |
| 39113 | 39467 | assert( pcache1.isInit!=0 ); |
| 39114 | 39468 | memset(&pcache1, 0, sizeof(pcache1)); |
| 39115 | 39469 | } |
| 39116 | 39470 | |
| 39471 | +/* forward declaration */ |
| 39472 | +static void pcache1Destroy(sqlite3_pcache *p); |
| 39473 | + |
| 39117 | 39474 | /* |
| 39118 | 39475 | ** Implementation of the sqlite3_pcache.xCreate method. |
| 39119 | 39476 | ** |
| 39120 | 39477 | ** Allocate a new cache. |
| 39121 | 39478 | */ |
| | @@ -39156,16 +39513,21 @@ |
| 39156 | 39513 | } |
| 39157 | 39514 | pCache->pGroup = pGroup; |
| 39158 | 39515 | pCache->szPage = szPage; |
| 39159 | 39516 | pCache->szExtra = szExtra; |
| 39160 | 39517 | pCache->bPurgeable = (bPurgeable ? 1 : 0); |
| 39518 | + pcache1EnterMutex(pGroup); |
| 39519 | + pcache1ResizeHash(pCache); |
| 39161 | 39520 | if( bPurgeable ){ |
| 39162 | 39521 | pCache->nMin = 10; |
| 39163 | | - pcache1EnterMutex(pGroup); |
| 39164 | 39522 | pGroup->nMinPage += pCache->nMin; |
| 39165 | 39523 | pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; |
| 39166 | | - pcache1LeaveMutex(pGroup); |
| 39524 | + } |
| 39525 | + pcache1LeaveMutex(pGroup); |
| 39526 | + if( pCache->nHash==0 ){ |
| 39527 | + pcache1Destroy((sqlite3_pcache*)pCache); |
| 39528 | + pCache = 0; |
| 39167 | 39529 | } |
| 39168 | 39530 | } |
| 39169 | 39531 | return (sqlite3_pcache *)pCache; |
| 39170 | 39532 | } |
| 39171 | 39533 | |
| | @@ -39217,10 +39579,99 @@ |
| 39217 | 39579 | n = pCache->nPage; |
| 39218 | 39580 | pcache1LeaveMutex(pCache->pGroup); |
| 39219 | 39581 | return n; |
| 39220 | 39582 | } |
| 39221 | 39583 | |
| 39584 | + |
| 39585 | +/* |
| 39586 | +** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described |
| 39587 | +** in the header of the pcache1Fetch() procedure. |
| 39588 | +** |
| 39589 | +** This steps are broken out into a separate procedure because they are |
| 39590 | +** usually not needed, and by avoiding the stack initialization required |
| 39591 | +** for these steps, the main pcache1Fetch() procedure can run faster. |
| 39592 | +*/ |
| 39593 | +static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( |
| 39594 | + PCache1 *pCache, |
| 39595 | + unsigned int iKey, |
| 39596 | + int createFlag |
| 39597 | +){ |
| 39598 | + unsigned int nPinned; |
| 39599 | + PGroup *pGroup = pCache->pGroup; |
| 39600 | + PgHdr1 *pPage = 0; |
| 39601 | + |
| 39602 | + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ |
| 39603 | + assert( pCache->nPage >= pCache->nRecyclable ); |
| 39604 | + nPinned = pCache->nPage - pCache->nRecyclable; |
| 39605 | + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); |
| 39606 | + assert( pCache->n90pct == pCache->nMax*9/10 ); |
| 39607 | + if( createFlag==1 && ( |
| 39608 | + nPinned>=pGroup->mxPinned |
| 39609 | + || nPinned>=pCache->n90pct |
| 39610 | + || pcache1UnderMemoryPressure(pCache) |
| 39611 | + )){ |
| 39612 | + return 0; |
| 39613 | + } |
| 39614 | + |
| 39615 | + if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); |
| 39616 | + assert( pCache->nHash>0 && pCache->apHash ); |
| 39617 | + |
| 39618 | + /* Step 4. Try to recycle a page. */ |
| 39619 | + if( pCache->bPurgeable && pGroup->pLruTail && ( |
| 39620 | + (pCache->nPage+1>=pCache->nMax) |
| 39621 | + || pGroup->nCurrentPage>=pGroup->nMaxPage |
| 39622 | + || pcache1UnderMemoryPressure(pCache) |
| 39623 | + )){ |
| 39624 | + PCache1 *pOther; |
| 39625 | + pPage = pGroup->pLruTail; |
| 39626 | + assert( pPage->isPinned==0 ); |
| 39627 | + pcache1RemoveFromHash(pPage); |
| 39628 | + pcache1PinPage(pPage); |
| 39629 | + pOther = pPage->pCache; |
| 39630 | + |
| 39631 | + /* We want to verify that szPage and szExtra are the same for pOther |
| 39632 | + ** and pCache. Assert that we can verify this by comparing sums. */ |
| 39633 | + assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); |
| 39634 | + assert( pCache->szExtra<512 ); |
| 39635 | + assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); |
| 39636 | + assert( pOther->szExtra<512 ); |
| 39637 | + |
| 39638 | + if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ |
| 39639 | + pcache1FreePage(pPage); |
| 39640 | + pPage = 0; |
| 39641 | + }else{ |
| 39642 | + pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); |
| 39643 | + } |
| 39644 | + } |
| 39645 | + |
| 39646 | + /* Step 5. If a usable page buffer has still not been found, |
| 39647 | + ** attempt to allocate a new one. |
| 39648 | + */ |
| 39649 | + if( !pPage ){ |
| 39650 | + if( createFlag==1 ) sqlite3BeginBenignMalloc(); |
| 39651 | + pPage = pcache1AllocPage(pCache); |
| 39652 | + if( createFlag==1 ) sqlite3EndBenignMalloc(); |
| 39653 | + } |
| 39654 | + |
| 39655 | + if( pPage ){ |
| 39656 | + unsigned int h = iKey % pCache->nHash; |
| 39657 | + pCache->nPage++; |
| 39658 | + pPage->iKey = iKey; |
| 39659 | + pPage->pNext = pCache->apHash[h]; |
| 39660 | + pPage->pCache = pCache; |
| 39661 | + pPage->pLruPrev = 0; |
| 39662 | + pPage->pLruNext = 0; |
| 39663 | + pPage->isPinned = 1; |
| 39664 | + *(void **)pPage->page.pExtra = 0; |
| 39665 | + pCache->apHash[h] = pPage; |
| 39666 | + if( iKey>pCache->iMaxKey ){ |
| 39667 | + pCache->iMaxKey = iKey; |
| 39668 | + } |
| 39669 | + } |
| 39670 | + return pPage; |
| 39671 | +} |
| 39672 | + |
| 39222 | 39673 | /* |
| 39223 | 39674 | ** Implementation of the sqlite3_pcache.xFetch method. |
| 39224 | 39675 | ** |
| 39225 | 39676 | ** Fetch a page by key value. |
| 39226 | 39677 | ** |
| | @@ -39276,121 +39727,34 @@ |
| 39276 | 39727 | static sqlite3_pcache_page *pcache1Fetch( |
| 39277 | 39728 | sqlite3_pcache *p, |
| 39278 | 39729 | unsigned int iKey, |
| 39279 | 39730 | int createFlag |
| 39280 | 39731 | ){ |
| 39281 | | - unsigned int nPinned; |
| 39282 | 39732 | PCache1 *pCache = (PCache1 *)p; |
| 39283 | | - PGroup *pGroup; |
| 39284 | 39733 | PgHdr1 *pPage = 0; |
| 39285 | 39734 | |
| 39286 | 39735 | assert( offsetof(PgHdr1,page)==0 ); |
| 39287 | 39736 | assert( pCache->bPurgeable || createFlag!=1 ); |
| 39288 | 39737 | assert( pCache->bPurgeable || pCache->nMin==0 ); |
| 39289 | 39738 | assert( pCache->bPurgeable==0 || pCache->nMin==10 ); |
| 39290 | 39739 | assert( pCache->nMin==0 || pCache->bPurgeable ); |
| 39291 | | - pcache1EnterMutex(pGroup = pCache->pGroup); |
| 39740 | + assert( pCache->nHash>0 ); |
| 39741 | + pcache1EnterMutex(pCache->pGroup); |
| 39292 | 39742 | |
| 39293 | 39743 | /* Step 1: Search the hash table for an existing entry. */ |
| 39294 | | - if( pCache->nHash>0 ){ |
| 39295 | | - unsigned int h = iKey % pCache->nHash; |
| 39296 | | - for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext); |
| 39297 | | - } |
| 39744 | + pPage = pCache->apHash[iKey % pCache->nHash]; |
| 39745 | + while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } |
| 39298 | 39746 | |
| 39299 | 39747 | /* Step 2: Abort if no existing page is found and createFlag is 0 */ |
| 39300 | 39748 | if( pPage ){ |
| 39301 | 39749 | if( !pPage->isPinned ) pcache1PinPage(pPage); |
| 39302 | | - goto fetch_out; |
| 39303 | | - } |
| 39304 | | - if( createFlag==0 ){ |
| 39305 | | - goto fetch_out; |
| 39306 | | - } |
| 39307 | | - |
| 39308 | | - /* The pGroup local variable will normally be initialized by the |
| 39309 | | - ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined, |
| 39310 | | - ** then pcache1EnterMutex() is a no-op, so we have to initialize the |
| 39311 | | - ** local variable here. Delaying the initialization of pGroup is an |
| 39312 | | - ** optimization: The common case is to exit the module before reaching |
| 39313 | | - ** this point. |
| 39314 | | - */ |
| 39315 | | -#ifdef SQLITE_MUTEX_OMIT |
| 39316 | | - pGroup = pCache->pGroup; |
| 39317 | | -#endif |
| 39318 | | - |
| 39319 | | - /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ |
| 39320 | | - assert( pCache->nPage >= pCache->nRecyclable ); |
| 39321 | | - nPinned = pCache->nPage - pCache->nRecyclable; |
| 39322 | | - assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); |
| 39323 | | - assert( pCache->n90pct == pCache->nMax*9/10 ); |
| 39324 | | - if( createFlag==1 && ( |
| 39325 | | - nPinned>=pGroup->mxPinned |
| 39326 | | - || nPinned>=pCache->n90pct |
| 39327 | | - || pcache1UnderMemoryPressure(pCache) |
| 39328 | | - )){ |
| 39329 | | - goto fetch_out; |
| 39330 | | - } |
| 39331 | | - |
| 39332 | | - if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){ |
| 39333 | | - goto fetch_out; |
| 39334 | | - } |
| 39335 | | - assert( pCache->nHash>0 && pCache->apHash ); |
| 39336 | | - |
| 39337 | | - /* Step 4. Try to recycle a page. */ |
| 39338 | | - if( pCache->bPurgeable && pGroup->pLruTail && ( |
| 39339 | | - (pCache->nPage+1>=pCache->nMax) |
| 39340 | | - || pGroup->nCurrentPage>=pGroup->nMaxPage |
| 39341 | | - || pcache1UnderMemoryPressure(pCache) |
| 39342 | | - )){ |
| 39343 | | - PCache1 *pOther; |
| 39344 | | - pPage = pGroup->pLruTail; |
| 39345 | | - assert( pPage->isPinned==0 ); |
| 39346 | | - pcache1RemoveFromHash(pPage); |
| 39347 | | - pcache1PinPage(pPage); |
| 39348 | | - pOther = pPage->pCache; |
| 39349 | | - |
| 39350 | | - /* We want to verify that szPage and szExtra are the same for pOther |
| 39351 | | - ** and pCache. Assert that we can verify this by comparing sums. */ |
| 39352 | | - assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); |
| 39353 | | - assert( pCache->szExtra<512 ); |
| 39354 | | - assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); |
| 39355 | | - assert( pOther->szExtra<512 ); |
| 39356 | | - |
| 39357 | | - if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ |
| 39358 | | - pcache1FreePage(pPage); |
| 39359 | | - pPage = 0; |
| 39360 | | - }else{ |
| 39361 | | - pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); |
| 39362 | | - } |
| 39363 | | - } |
| 39364 | | - |
| 39365 | | - /* Step 5. If a usable page buffer has still not been found, |
| 39366 | | - ** attempt to allocate a new one. |
| 39367 | | - */ |
| 39368 | | - if( !pPage ){ |
| 39369 | | - if( createFlag==1 ) sqlite3BeginBenignMalloc(); |
| 39370 | | - pPage = pcache1AllocPage(pCache); |
| 39371 | | - if( createFlag==1 ) sqlite3EndBenignMalloc(); |
| 39372 | | - } |
| 39373 | | - |
| 39374 | | - if( pPage ){ |
| 39375 | | - unsigned int h = iKey % pCache->nHash; |
| 39376 | | - pCache->nPage++; |
| 39377 | | - pPage->iKey = iKey; |
| 39378 | | - pPage->pNext = pCache->apHash[h]; |
| 39379 | | - pPage->pCache = pCache; |
| 39380 | | - pPage->pLruPrev = 0; |
| 39381 | | - pPage->pLruNext = 0; |
| 39382 | | - pPage->isPinned = 1; |
| 39383 | | - *(void **)pPage->page.pExtra = 0; |
| 39384 | | - pCache->apHash[h] = pPage; |
| 39385 | | - } |
| 39386 | | - |
| 39387 | | -fetch_out: |
| 39388 | | - if( pPage && iKey>pCache->iMaxKey ){ |
| 39389 | | - pCache->iMaxKey = iKey; |
| 39390 | | - } |
| 39391 | | - pcache1LeaveMutex(pGroup); |
| 39750 | + }else if( createFlag ){ |
| 39751 | + /* Steps 3, 4, and 5 implemented by this subroutine */ |
| 39752 | + pPage = pcache1FetchStage2(pCache, iKey, createFlag); |
| 39753 | + } |
| 39754 | + assert( pPage==0 || pCache->iMaxKey>=iKey ); |
| 39755 | + pcache1LeaveMutex(pCache->pGroup); |
| 39392 | 39756 | return (sqlite3_pcache_page*)pPage; |
| 39393 | 39757 | } |
| 39394 | 39758 | |
| 39395 | 39759 | |
| 39396 | 39760 | /* |
| | @@ -41921,25 +42285,10 @@ |
| 41921 | 42285 | rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); |
| 41922 | 42286 | } |
| 41923 | 42287 | return rc; |
| 41924 | 42288 | } |
| 41925 | 42289 | |
| 41926 | | -/* |
| 41927 | | -** Find a page in the hash table given its page number. Return |
| 41928 | | -** a pointer to the page or NULL if the requested page is not |
| 41929 | | -** already in memory. |
| 41930 | | -*/ |
| 41931 | | -static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ |
| 41932 | | - PgHdr *p = 0; /* Return value */ |
| 41933 | | - |
| 41934 | | - /* It is not possible for a call to PcacheFetch() with createFlag==0 to |
| 41935 | | - ** fail, since no attempt to allocate dynamic memory will be made. |
| 41936 | | - */ |
| 41937 | | - (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p); |
| 41938 | | - return p; |
| 41939 | | -} |
| 41940 | | - |
| 41941 | 42290 | /* |
| 41942 | 42291 | ** Discard the entire contents of the in-memory page-cache. |
| 41943 | 42292 | */ |
| 41944 | 42293 | static void pager_reset(Pager *pPager){ |
| 41945 | 42294 | sqlite3BackupRestart(pPager->pBackup); |
| | @@ -42228,11 +42577,11 @@ |
| 42228 | 42577 | } |
| 42229 | 42578 | |
| 42230 | 42579 | #ifdef SQLITE_CHECK_PAGES |
| 42231 | 42580 | sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); |
| 42232 | 42581 | if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ |
| 42233 | | - PgHdr *p = pager_lookup(pPager, 1); |
| 42582 | + PgHdr *p = sqlite3PagerLookup(pPager, 1); |
| 42234 | 42583 | if( p ){ |
| 42235 | 42584 | p->pageHash = 0; |
| 42236 | 42585 | sqlite3PagerUnrefNotNull(p); |
| 42237 | 42586 | } |
| 42238 | 42587 | } |
| | @@ -42507,11 +42856,11 @@ |
| 42507 | 42856 | ** Do not attempt to write if database file has never been opened. |
| 42508 | 42857 | */ |
| 42509 | 42858 | if( pagerUseWal(pPager) ){ |
| 42510 | 42859 | pPg = 0; |
| 42511 | 42860 | }else{ |
| 42512 | | - pPg = pager_lookup(pPager, pgno); |
| 42861 | + pPg = sqlite3PagerLookup(pPager, pgno); |
| 42513 | 42862 | } |
| 42514 | 42863 | assert( pPg || !MEMDB ); |
| 42515 | 42864 | assert( pPager->eState!=PAGER_OPEN || pPg==0 ); |
| 42516 | 42865 | PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", |
| 42517 | 42866 | PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), |
| | @@ -43881,11 +44230,11 @@ |
| 43881 | 44230 | pager_reset(pPager); |
| 43882 | 44231 | pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); |
| 43883 | 44232 | pPager->pageSize = pageSize; |
| 43884 | 44233 | sqlite3PageFree(pPager->pTmpSpace); |
| 43885 | 44234 | pPager->pTmpSpace = pNew; |
| 43886 | | - sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); |
| 44235 | + rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); |
| 43887 | 44236 | } |
| 43888 | 44237 | } |
| 43889 | 44238 | |
| 43890 | 44239 | *pPageSize = pPager->pageSize; |
| 43891 | 44240 | if( rc==SQLITE_OK ){ |
| | @@ -44644,11 +44993,11 @@ |
| 44644 | 44993 | ** regardless of whether or not a sync is required. This is set during |
| 44645 | 44994 | ** a rollback or by user request, respectively. |
| 44646 | 44995 | ** |
| 44647 | 44996 | ** Spilling is also prohibited when in an error state since that could |
| 44648 | 44997 | ** lead to database corruption. In the current implementaton it |
| 44649 | | - ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 |
| 44998 | + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 |
| 44650 | 44999 | ** while in the error state, hence it is impossible for this routine to |
| 44651 | 45000 | ** be called in the error state. Nevertheless, we include a NEVER() |
| 44652 | 45001 | ** test for the error state as a safeguard against future changes. |
| 44653 | 45002 | */ |
| 44654 | 45003 | if( NEVER(pPager->errCode) ) return SQLITE_OK; |
| | @@ -44980,26 +45329,27 @@ |
| 44980 | 45329 | assert( pPager->memDb==0 ); |
| 44981 | 45330 | rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); |
| 44982 | 45331 | testcase( rc!=SQLITE_OK ); |
| 44983 | 45332 | } |
| 44984 | 45333 | |
| 44985 | | - /* If an error occurred in either of the blocks above, free the |
| 44986 | | - ** Pager structure and close the file. |
| 45334 | + /* Initialize the PCache object. */ |
| 45335 | + if( rc==SQLITE_OK ){ |
| 45336 | + assert( nExtra<1000 ); |
| 45337 | + nExtra = ROUND8(nExtra); |
| 45338 | + rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, |
| 45339 | + !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); |
| 45340 | + } |
| 45341 | + |
| 45342 | + /* If an error occurred above, free the Pager structure and close the file. |
| 44987 | 45343 | */ |
| 44988 | 45344 | if( rc!=SQLITE_OK ){ |
| 44989 | | - assert( !pPager->pTmpSpace ); |
| 44990 | 45345 | sqlite3OsClose(pPager->fd); |
| 45346 | + sqlite3PageFree(pPager->pTmpSpace); |
| 44991 | 45347 | sqlite3_free(pPager); |
| 44992 | 45348 | return rc; |
| 44993 | 45349 | } |
| 44994 | 45350 | |
| 44995 | | - /* Initialize the PCache object. */ |
| 44996 | | - assert( nExtra<1000 ); |
| 44997 | | - nExtra = ROUND8(nExtra); |
| 44998 | | - sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, |
| 44999 | | - !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); |
| 45000 | | - |
| 45001 | 45351 | PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); |
| 45002 | 45352 | IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) |
| 45003 | 45353 | |
| 45004 | 45354 | pPager->useJournal = (u8)useJournal; |
| 45005 | 45355 | /* pPager->stmtOpen = 0; */ |
| | @@ -45544,11 +45894,10 @@ |
| 45544 | 45894 | /* If the pager is in the error state, return an error immediately. |
| 45545 | 45895 | ** Otherwise, request the page from the PCache layer. */ |
| 45546 | 45896 | if( pPager->errCode!=SQLITE_OK ){ |
| 45547 | 45897 | rc = pPager->errCode; |
| 45548 | 45898 | }else{ |
| 45549 | | - |
| 45550 | 45899 | if( bMmapOk && pagerUseWal(pPager) ){ |
| 45551 | 45900 | rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 45552 | 45901 | if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 45553 | 45902 | } |
| 45554 | 45903 | |
| | @@ -45559,11 +45908,11 @@ |
| 45559 | 45908 | (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData |
| 45560 | 45909 | ); |
| 45561 | 45910 | |
| 45562 | 45911 | if( rc==SQLITE_OK && pData ){ |
| 45563 | 45912 | if( pPager->eState>PAGER_READER ){ |
| 45564 | | - (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); |
| 45913 | + pPg = sqlite3PagerLookup(pPager, pgno); |
| 45565 | 45914 | } |
| 45566 | 45915 | if( pPg==0 ){ |
| 45567 | 45916 | rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); |
| 45568 | 45917 | }else{ |
| 45569 | 45918 | sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); |
| | @@ -45577,11 +45926,20 @@ |
| 45577 | 45926 | if( rc!=SQLITE_OK ){ |
| 45578 | 45927 | goto pager_acquire_err; |
| 45579 | 45928 | } |
| 45580 | 45929 | } |
| 45581 | 45930 | |
| 45582 | | - rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); |
| 45931 | + { |
| 45932 | + sqlite3_pcache_page *pBase; |
| 45933 | + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); |
| 45934 | + if( pBase==0 ){ |
| 45935 | + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); |
| 45936 | + if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 45937 | + } |
| 45938 | + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); |
| 45939 | + if( pPg==0 ) rc = SQLITE_NOMEM; |
| 45940 | + } |
| 45583 | 45941 | } |
| 45584 | 45942 | |
| 45585 | 45943 | if( rc!=SQLITE_OK ){ |
| 45586 | 45944 | /* Either the call to sqlite3PcacheFetch() returned an error or the |
| 45587 | 45945 | ** pager was already in the error-state when this function was called. |
| | @@ -45674,17 +46032,16 @@ |
| 45674 | 46032 | ** in the page if the page is not already in cache. This routine |
| 45675 | 46033 | ** returns NULL if the page is not in cache or if a disk I/O error |
| 45676 | 46034 | ** has ever happened. |
| 45677 | 46035 | */ |
| 45678 | 46036 | SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ |
| 45679 | | - PgHdr *pPg = 0; |
| 46037 | + sqlite3_pcache_page *pPage; |
| 45680 | 46038 | assert( pPager!=0 ); |
| 45681 | 46039 | assert( pgno!=0 ); |
| 45682 | 46040 | assert( pPager->pPCache!=0 ); |
| 45683 | | - assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR ); |
| 45684 | | - sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); |
| 45685 | | - return pPg; |
| 46041 | + pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); |
| 46042 | + return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); |
| 45686 | 46043 | } |
| 45687 | 46044 | |
| 45688 | 46045 | /* |
| 45689 | 46046 | ** Release a page reference. |
| 45690 | 46047 | ** |
| | @@ -46015,10 +46372,101 @@ |
| 46015 | 46372 | if( pPager->dbSize<pPg->pgno ){ |
| 46016 | 46373 | pPager->dbSize = pPg->pgno; |
| 46017 | 46374 | } |
| 46018 | 46375 | return rc; |
| 46019 | 46376 | } |
| 46377 | + |
| 46378 | +/* |
| 46379 | +** This is a variant of sqlite3PagerWrite() that runs when the sector size |
| 46380 | +** is larger than the page size. SQLite makes the (reasonable) assumption that |
| 46381 | +** all bytes of a sector are written together by hardware. Hence, all bytes of |
| 46382 | +** a sector need to be journalled in case of a power loss in the middle of |
| 46383 | +** a write. |
| 46384 | +** |
| 46385 | +** Usually, the sector size is less than or equal to the page size, in which |
| 46386 | +** case pages can be individually written. This routine only runs in the exceptional |
| 46387 | +** case where the page size is smaller than the sector size. |
| 46388 | +*/ |
| 46389 | +static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ |
| 46390 | + int rc = SQLITE_OK; /* Return code */ |
| 46391 | + Pgno nPageCount; /* Total number of pages in database file */ |
| 46392 | + Pgno pg1; /* First page of the sector pPg is located on. */ |
| 46393 | + int nPage = 0; /* Number of pages starting at pg1 to journal */ |
| 46394 | + int ii; /* Loop counter */ |
| 46395 | + int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 46396 | + Pager *pPager = pPg->pPager; /* The pager that owns pPg */ |
| 46397 | + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 46398 | + |
| 46399 | + /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow |
| 46400 | + ** a journal header to be written between the pages journaled by |
| 46401 | + ** this function. |
| 46402 | + */ |
| 46403 | + assert( !MEMDB ); |
| 46404 | + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); |
| 46405 | + pPager->doNotSpill |= SPILLFLAG_NOSYNC; |
| 46406 | + |
| 46407 | + /* This trick assumes that both the page-size and sector-size are |
| 46408 | + ** an integer power of 2. It sets variable pg1 to the identifier |
| 46409 | + ** of the first page of the sector pPg is located on. |
| 46410 | + */ |
| 46411 | + pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
| 46412 | + |
| 46413 | + nPageCount = pPager->dbSize; |
| 46414 | + if( pPg->pgno>nPageCount ){ |
| 46415 | + nPage = (pPg->pgno - pg1)+1; |
| 46416 | + }else if( (pg1+nPagePerSector-1)>nPageCount ){ |
| 46417 | + nPage = nPageCount+1-pg1; |
| 46418 | + }else{ |
| 46419 | + nPage = nPagePerSector; |
| 46420 | + } |
| 46421 | + assert(nPage>0); |
| 46422 | + assert(pg1<=pPg->pgno); |
| 46423 | + assert((pg1+nPage)>pPg->pgno); |
| 46424 | + |
| 46425 | + for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
| 46426 | + Pgno pg = pg1+ii; |
| 46427 | + PgHdr *pPage; |
| 46428 | + if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
| 46429 | + if( pg!=PAGER_MJ_PGNO(pPager) ){ |
| 46430 | + rc = sqlite3PagerGet(pPager, pg, &pPage); |
| 46431 | + if( rc==SQLITE_OK ){ |
| 46432 | + rc = pager_write(pPage); |
| 46433 | + if( pPage->flags&PGHDR_NEED_SYNC ){ |
| 46434 | + needSync = 1; |
| 46435 | + } |
| 46436 | + sqlite3PagerUnrefNotNull(pPage); |
| 46437 | + } |
| 46438 | + } |
| 46439 | + }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ |
| 46440 | + if( pPage->flags&PGHDR_NEED_SYNC ){ |
| 46441 | + needSync = 1; |
| 46442 | + } |
| 46443 | + sqlite3PagerUnrefNotNull(pPage); |
| 46444 | + } |
| 46445 | + } |
| 46446 | + |
| 46447 | + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages |
| 46448 | + ** starting at pg1, then it needs to be set for all of them. Because |
| 46449 | + ** writing to any of these nPage pages may damage the others, the |
| 46450 | + ** journal file must contain sync()ed copies of all of them |
| 46451 | + ** before any of them can be written out to the database file. |
| 46452 | + */ |
| 46453 | + if( rc==SQLITE_OK && needSync ){ |
| 46454 | + assert( !MEMDB ); |
| 46455 | + for(ii=0; ii<nPage; ii++){ |
| 46456 | + PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii); |
| 46457 | + if( pPage ){ |
| 46458 | + pPage->flags |= PGHDR_NEED_SYNC; |
| 46459 | + sqlite3PagerUnrefNotNull(pPage); |
| 46460 | + } |
| 46461 | + } |
| 46462 | + } |
| 46463 | + |
| 46464 | + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); |
| 46465 | + pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; |
| 46466 | + return rc; |
| 46467 | +} |
| 46020 | 46468 | |
| 46021 | 46469 | /* |
| 46022 | 46470 | ** Mark a data page as writeable. This routine must be called before |
| 46023 | 46471 | ** making changes to a page. The caller must check the return value |
| 46024 | 46472 | ** of this function and be careful not to change any page data unless |
| | @@ -46030,100 +46478,20 @@ |
| 46030 | 46478 | ** must have been written to the journal file before returning. |
| 46031 | 46479 | ** |
| 46032 | 46480 | ** If an error occurs, SQLITE_NOMEM or an IO error code is returned |
| 46033 | 46481 | ** as appropriate. Otherwise, SQLITE_OK. |
| 46034 | 46482 | */ |
| 46035 | | -SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ |
| 46036 | | - int rc = SQLITE_OK; |
| 46037 | | - |
| 46038 | | - PgHdr *pPg = pDbPage; |
| 46039 | | - Pager *pPager = pPg->pPager; |
| 46040 | | - |
| 46483 | +SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ |
| 46041 | 46484 | assert( (pPg->flags & PGHDR_MMAP)==0 ); |
| 46042 | | - assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
| 46043 | | - assert( pPager->eState!=PAGER_ERROR ); |
| 46044 | | - assert( assert_pager_state(pPager) ); |
| 46045 | | - |
| 46046 | | - if( pPager->sectorSize > (u32)pPager->pageSize ){ |
| 46047 | | - Pgno nPageCount; /* Total number of pages in database file */ |
| 46048 | | - Pgno pg1; /* First page of the sector pPg is located on. */ |
| 46049 | | - int nPage = 0; /* Number of pages starting at pg1 to journal */ |
| 46050 | | - int ii; /* Loop counter */ |
| 46051 | | - int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 46052 | | - Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 46053 | | - |
| 46054 | | - /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow |
| 46055 | | - ** a journal header to be written between the pages journaled by |
| 46056 | | - ** this function. |
| 46057 | | - */ |
| 46058 | | - assert( !MEMDB ); |
| 46059 | | - assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); |
| 46060 | | - pPager->doNotSpill |= SPILLFLAG_NOSYNC; |
| 46061 | | - |
| 46062 | | - /* This trick assumes that both the page-size and sector-size are |
| 46063 | | - ** an integer power of 2. It sets variable pg1 to the identifier |
| 46064 | | - ** of the first page of the sector pPg is located on. |
| 46065 | | - */ |
| 46066 | | - pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
| 46067 | | - |
| 46068 | | - nPageCount = pPager->dbSize; |
| 46069 | | - if( pPg->pgno>nPageCount ){ |
| 46070 | | - nPage = (pPg->pgno - pg1)+1; |
| 46071 | | - }else if( (pg1+nPagePerSector-1)>nPageCount ){ |
| 46072 | | - nPage = nPageCount+1-pg1; |
| 46073 | | - }else{ |
| 46074 | | - nPage = nPagePerSector; |
| 46075 | | - } |
| 46076 | | - assert(nPage>0); |
| 46077 | | - assert(pg1<=pPg->pgno); |
| 46078 | | - assert((pg1+nPage)>pPg->pgno); |
| 46079 | | - |
| 46080 | | - for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
| 46081 | | - Pgno pg = pg1+ii; |
| 46082 | | - PgHdr *pPage; |
| 46083 | | - if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
| 46084 | | - if( pg!=PAGER_MJ_PGNO(pPager) ){ |
| 46085 | | - rc = sqlite3PagerGet(pPager, pg, &pPage); |
| 46086 | | - if( rc==SQLITE_OK ){ |
| 46087 | | - rc = pager_write(pPage); |
| 46088 | | - if( pPage->flags&PGHDR_NEED_SYNC ){ |
| 46089 | | - needSync = 1; |
| 46090 | | - } |
| 46091 | | - sqlite3PagerUnrefNotNull(pPage); |
| 46092 | | - } |
| 46093 | | - } |
| 46094 | | - }else if( (pPage = pager_lookup(pPager, pg))!=0 ){ |
| 46095 | | - if( pPage->flags&PGHDR_NEED_SYNC ){ |
| 46096 | | - needSync = 1; |
| 46097 | | - } |
| 46098 | | - sqlite3PagerUnrefNotNull(pPage); |
| 46099 | | - } |
| 46100 | | - } |
| 46101 | | - |
| 46102 | | - /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages |
| 46103 | | - ** starting at pg1, then it needs to be set for all of them. Because |
| 46104 | | - ** writing to any of these nPage pages may damage the others, the |
| 46105 | | - ** journal file must contain sync()ed copies of all of them |
| 46106 | | - ** before any of them can be written out to the database file. |
| 46107 | | - */ |
| 46108 | | - if( rc==SQLITE_OK && needSync ){ |
| 46109 | | - assert( !MEMDB ); |
| 46110 | | - for(ii=0; ii<nPage; ii++){ |
| 46111 | | - PgHdr *pPage = pager_lookup(pPager, pg1+ii); |
| 46112 | | - if( pPage ){ |
| 46113 | | - pPage->flags |= PGHDR_NEED_SYNC; |
| 46114 | | - sqlite3PagerUnrefNotNull(pPage); |
| 46115 | | - } |
| 46116 | | - } |
| 46117 | | - } |
| 46118 | | - |
| 46119 | | - assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); |
| 46120 | | - pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; |
| 46121 | | - }else{ |
| 46122 | | - rc = pager_write(pDbPage); |
| 46123 | | - } |
| 46124 | | - return rc; |
| 46485 | + assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED ); |
| 46486 | + assert( pPg->pPager->eState!=PAGER_ERROR ); |
| 46487 | + assert( assert_pager_state(pPg->pPager) ); |
| 46488 | + if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){ |
| 46489 | + return pagerWriteLargeSector(pPg); |
| 46490 | + }else{ |
| 46491 | + return pager_write(pPg); |
| 46492 | + } |
| 46125 | 46493 | } |
| 46126 | 46494 | |
| 46127 | 46495 | /* |
| 46128 | 46496 | ** Return TRUE if the page given in the argument was previously passed |
| 46129 | 46497 | ** to sqlite3PagerWrite(). In other words, return TRUE if it is ok |
| | @@ -47015,11 +47383,11 @@ |
| 47015 | 47383 | ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for |
| 47016 | 47384 | ** page pgno before the 'move' operation, it needs to be retained |
| 47017 | 47385 | ** for the page moved there. |
| 47018 | 47386 | */ |
| 47019 | 47387 | pPg->flags &= ~PGHDR_NEED_SYNC; |
| 47020 | | - pPgOld = pager_lookup(pPager, pgno); |
| 47388 | + pPgOld = sqlite3PagerLookup(pPager, pgno); |
| 47021 | 47389 | assert( !pPgOld || pPgOld->nRef==1 ); |
| 47022 | 47390 | if( pPgOld ){ |
| 47023 | 47391 | pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); |
| 47024 | 47392 | if( MEMDB ){ |
| 47025 | 47393 | /* Do not discard pages from an in-memory database since we might |
| | @@ -51286,11 +51654,11 @@ |
| 51286 | 51654 | |
| 51287 | 51655 | /* |
| 51288 | 51656 | ** Release the BtShared mutex associated with B-Tree handle p and |
| 51289 | 51657 | ** clear the p->locked boolean. |
| 51290 | 51658 | */ |
| 51291 | | -static void unlockBtreeMutex(Btree *p){ |
| 51659 | +static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ |
| 51292 | 51660 | BtShared *pBt = p->pBt; |
| 51293 | 51661 | assert( p->locked==1 ); |
| 51294 | 51662 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51295 | 51663 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 51296 | 51664 | assert( p->db==pBt->db ); |
| | @@ -51297,10 +51665,13 @@ |
| 51297 | 51665 | |
| 51298 | 51666 | sqlite3_mutex_leave(pBt->mutex); |
| 51299 | 51667 | p->locked = 0; |
| 51300 | 51668 | } |
| 51301 | 51669 | |
| 51670 | +/* Forward reference */ |
| 51671 | +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); |
| 51672 | + |
| 51302 | 51673 | /* |
| 51303 | 51674 | ** Enter a mutex on the given BTree object. |
| 51304 | 51675 | ** |
| 51305 | 51676 | ** If the object is not sharable, then no mutex is ever required |
| 51306 | 51677 | ** and this routine is a no-op. The underlying mutex is non-recursive. |
| | @@ -51314,12 +51685,10 @@ |
| 51314 | 51685 | ** p, then first unlock all of the others on p->pNext, then wait |
| 51315 | 51686 | ** for the lock to become available on p, then relock all of the |
| 51316 | 51687 | ** subsequent Btrees that desire a lock. |
| 51317 | 51688 | */ |
| 51318 | 51689 | SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ |
| 51319 | | - Btree *pLater; |
| 51320 | | - |
| 51321 | 51690 | /* Some basic sanity checking on the Btree. The list of Btrees |
| 51322 | 51691 | ** connected by pNext and pPrev should be in sorted order by |
| 51323 | 51692 | ** Btree.pBt value. All elements of the list should belong to |
| 51324 | 51693 | ** the same connection. Only shared Btrees are on the list. */ |
| 51325 | 51694 | assert( p->pNext==0 || p->pNext->pBt>p->pBt ); |
| | @@ -51340,10 +51709,21 @@ |
| 51340 | 51709 | assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); |
| 51341 | 51710 | |
| 51342 | 51711 | if( !p->sharable ) return; |
| 51343 | 51712 | p->wantToLock++; |
| 51344 | 51713 | if( p->locked ) return; |
| 51714 | + btreeLockCarefully(p); |
| 51715 | +} |
| 51716 | + |
| 51717 | +/* This is a helper function for sqlite3BtreeLock(). By moving |
| 51718 | +** complex, but seldom used logic, out of sqlite3BtreeLock() and |
| 51719 | +** into this routine, we avoid unnecessary stack pointer changes |
| 51720 | +** and thus help the sqlite3BtreeLock() routine to run much faster |
| 51721 | +** in the common case. |
| 51722 | +*/ |
| 51723 | +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ |
| 51724 | + Btree *pLater; |
| 51345 | 51725 | |
| 51346 | 51726 | /* In most cases, we should be able to acquire the lock we |
| 51347 | 51727 | ** want without having to go throught the ascending lock |
| 51348 | 51728 | ** procedure that follows. Just be sure not to block. |
| 51349 | 51729 | */ |
| | @@ -51371,10 +51751,11 @@ |
| 51371 | 51751 | if( pLater->wantToLock ){ |
| 51372 | 51752 | lockBtreeMutex(pLater); |
| 51373 | 51753 | } |
| 51374 | 51754 | } |
| 51375 | 51755 | } |
| 51756 | + |
| 51376 | 51757 | |
| 51377 | 51758 | /* |
| 51378 | 51759 | ** Exit the recursive mutex on a Btree. |
| 51379 | 51760 | */ |
| 51380 | 51761 | SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ |
| | @@ -52166,20 +52547,46 @@ |
| 52166 | 52547 | |
| 52167 | 52548 | invalidateOverflowCache(pCur); |
| 52168 | 52549 | return rc; |
| 52169 | 52550 | } |
| 52170 | 52551 | |
| 52552 | +/* Forward reference */ |
| 52553 | +static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); |
| 52554 | + |
| 52171 | 52555 | /* |
| 52172 | 52556 | ** Save the positions of all cursors (except pExcept) that are open on |
| 52173 | | -** the table with root-page iRoot. Usually, this is called just before cursor |
| 52174 | | -** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()). |
| 52557 | +** the table with root-page iRoot. "Saving the cursor position" means that |
| 52558 | +** the location in the btree is remembered in such a way that it can be |
| 52559 | +** moved back to the same spot after the btree has been modified. This |
| 52560 | +** routine is called just before cursor pExcept is used to modify the |
| 52561 | +** table, for example in BtreeDelete() or BtreeInsert(). |
| 52562 | +** |
| 52563 | +** Implementation note: This routine merely checks to see if any cursors |
| 52564 | +** need to be saved. It calls out to saveCursorsOnList() in the (unusual) |
| 52565 | +** event that cursors are in need to being saved. |
| 52175 | 52566 | */ |
| 52176 | 52567 | static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ |
| 52177 | 52568 | BtCursor *p; |
| 52178 | 52569 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 52179 | 52570 | assert( pExcept==0 || pExcept->pBt==pBt ); |
| 52180 | 52571 | for(p=pBt->pCursor; p; p=p->pNext){ |
| 52572 | + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; |
| 52573 | + } |
| 52574 | + return p ? saveCursorsOnList(p, iRoot, pExcept) : SQLITE_OK; |
| 52575 | +} |
| 52576 | + |
| 52577 | +/* This helper routine to saveAllCursors does the actual work of saving |
| 52578 | +** the cursors if and when a cursor is found that actually requires saving. |
| 52579 | +** The common case is that no cursors need to be saved, so this routine is |
| 52580 | +** broken out from its caller to avoid unnecessary stack pointer movement. |
| 52581 | +*/ |
| 52582 | +static int SQLITE_NOINLINE saveCursorsOnList( |
| 52583 | + BtCursor *p, /* The first cursor that needs saving */ |
| 52584 | + Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */ |
| 52585 | + BtCursor *pExcept /* Do not save this cursor */ |
| 52586 | +){ |
| 52587 | + do{ |
| 52181 | 52588 | if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ |
| 52182 | 52589 | if( p->eState==CURSOR_VALID ){ |
| 52183 | 52590 | int rc = saveCursorPosition(p); |
| 52184 | 52591 | if( SQLITE_OK!=rc ){ |
| 52185 | 52592 | return rc; |
| | @@ -52187,11 +52594,12 @@ |
| 52187 | 52594 | }else{ |
| 52188 | 52595 | testcase( p->iPage>0 ); |
| 52189 | 52596 | btreeReleaseAllCursorPages(p); |
| 52190 | 52597 | } |
| 52191 | 52598 | } |
| 52192 | | - } |
| 52599 | + p = p->pNext; |
| 52600 | + }while( p ); |
| 52193 | 52601 | return SQLITE_OK; |
| 52194 | 52602 | } |
| 52195 | 52603 | |
| 52196 | 52604 | /* |
| 52197 | 52605 | ** Clear the current cursor position. |
| | @@ -52272,41 +52680,52 @@ |
| 52272 | 52680 | (p->eState>=CURSOR_REQUIRESEEK ? \ |
| 52273 | 52681 | btreeRestoreCursorPosition(p) : \ |
| 52274 | 52682 | SQLITE_OK) |
| 52275 | 52683 | |
| 52276 | 52684 | /* |
| 52277 | | -** Determine whether or not a cursor has moved from the position it |
| 52278 | | -** was last placed at. Cursors can move when the row they are pointing |
| 52279 | | -** at is deleted out from under them. |
| 52280 | | -** |
| 52281 | | -** This routine returns an error code if something goes wrong. The |
| 52282 | | -** integer *pHasMoved is set as follows: |
| 52283 | | -** |
| 52284 | | -** 0: The cursor is unchanged |
| 52285 | | -** 1: The cursor is still pointing at the same row, but the pointers |
| 52286 | | -** returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch() |
| 52287 | | -** might now be invalid because of a balance() or other change to the |
| 52288 | | -** b-tree. |
| 52289 | | -** 2: The cursor is no longer pointing to the row. The row might have |
| 52290 | | -** been deleted out from under the cursor. |
| 52291 | | -*/ |
| 52292 | | -SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ |
| 52685 | +** Determine whether or not a cursor has moved from the position where |
| 52686 | +** it was last placed, or has been invalidated for any other reason. |
| 52687 | +** Cursors can move when the row they are pointing at is deleted out |
| 52688 | +** from under them, for example. Cursor might also move if a btree |
| 52689 | +** is rebalanced. |
| 52690 | +** |
| 52691 | +** Calling this routine with a NULL cursor pointer returns false. |
| 52692 | +** |
| 52693 | +** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor |
| 52694 | +** back to where it ought to be if this routine returns true. |
| 52695 | +*/ |
| 52696 | +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ |
| 52697 | + return pCur && pCur->eState!=CURSOR_VALID; |
| 52698 | +} |
| 52699 | + |
| 52700 | +/* |
| 52701 | +** This routine restores a cursor back to its original position after it |
| 52702 | +** has been moved by some outside activity (such as a btree rebalance or |
| 52703 | +** a row having been deleted out from under the cursor). |
| 52704 | +** |
| 52705 | +** On success, the *pDifferentRow parameter is false if the cursor is left |
| 52706 | +** pointing at exactly the same row. *pDifferntRow is the row the cursor |
| 52707 | +** was pointing to has been deleted, forcing the cursor to point to some |
| 52708 | +** nearby row. |
| 52709 | +** |
| 52710 | +** This routine should only be called for a cursor that just returned |
| 52711 | +** TRUE from sqlite3BtreeCursorHasMoved(). |
| 52712 | +*/ |
| 52713 | +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ |
| 52293 | 52714 | int rc; |
| 52294 | 52715 | |
| 52295 | | - if( pCur->eState==CURSOR_VALID ){ |
| 52296 | | - *pHasMoved = 0; |
| 52297 | | - return SQLITE_OK; |
| 52298 | | - } |
| 52716 | + assert( pCur!=0 ); |
| 52717 | + assert( pCur->eState!=CURSOR_VALID ); |
| 52299 | 52718 | rc = restoreCursorPosition(pCur); |
| 52300 | 52719 | if( rc ){ |
| 52301 | | - *pHasMoved = 2; |
| 52720 | + *pDifferentRow = 1; |
| 52302 | 52721 | return rc; |
| 52303 | 52722 | } |
| 52304 | 52723 | if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){ |
| 52305 | | - *pHasMoved = 2; |
| 52724 | + *pDifferentRow = 1; |
| 52306 | 52725 | }else{ |
| 52307 | | - *pHasMoved = 1; |
| 52726 | + *pDifferentRow = 0; |
| 52308 | 52727 | } |
| 52309 | 52728 | return SQLITE_OK; |
| 52310 | 52729 | } |
| 52311 | 52730 | |
| 52312 | 52731 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| | @@ -52734,11 +53153,10 @@ |
| 52734 | 53153 | ** also end up needing a new cell pointer. |
| 52735 | 53154 | */ |
| 52736 | 53155 | static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ |
| 52737 | 53156 | const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ |
| 52738 | 53157 | u8 * const data = pPage->aData; /* Local cache of pPage->aData */ |
| 52739 | | - int nFrag; /* Number of fragmented bytes on pPage */ |
| 52740 | 53158 | int top; /* First byte of cell content area */ |
| 52741 | 53159 | int gap; /* First byte of gap between cell pointers and cell content */ |
| 52742 | 53160 | int rc; /* Integer return code */ |
| 52743 | 53161 | int usableSize; /* Usable size of the page */ |
| 52744 | 53162 | |
| | @@ -52749,29 +53167,30 @@ |
| 52749 | 53167 | assert( pPage->nFree>=nByte ); |
| 52750 | 53168 | assert( pPage->nOverflow==0 ); |
| 52751 | 53169 | usableSize = pPage->pBt->usableSize; |
| 52752 | 53170 | assert( nByte < usableSize-8 ); |
| 52753 | 53171 | |
| 52754 | | - nFrag = data[hdr+7]; |
| 52755 | 53172 | assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); |
| 52756 | 53173 | gap = pPage->cellOffset + 2*pPage->nCell; |
| 52757 | | - top = get2byteNotZero(&data[hdr+5]); |
| 52758 | | - if( gap>top ) return SQLITE_CORRUPT_BKPT; |
| 53174 | + assert( gap<=65536 ); |
| 53175 | + top = get2byte(&data[hdr+5]); |
| 53176 | + if( gap>top ){ |
| 53177 | + if( top==0 ){ |
| 53178 | + top = 65536; |
| 53179 | + }else{ |
| 53180 | + return SQLITE_CORRUPT_BKPT; |
| 53181 | + } |
| 53182 | + } |
| 53183 | + |
| 53184 | + /* If there is enough space between gap and top for one more cell pointer |
| 53185 | + ** array entry offset, and if the freelist is not empty, then search the |
| 53186 | + ** freelist looking for a free slot big enough to satisfy the request. |
| 53187 | + */ |
| 52759 | 53188 | testcase( gap+2==top ); |
| 52760 | 53189 | testcase( gap+1==top ); |
| 52761 | 53190 | testcase( gap==top ); |
| 52762 | | - |
| 52763 | | - if( nFrag>=60 ){ |
| 52764 | | - /* Always defragment highly fragmented pages */ |
| 52765 | | - rc = defragmentPage(pPage); |
| 52766 | | - if( rc ) return rc; |
| 52767 | | - top = get2byteNotZero(&data[hdr+5]); |
| 52768 | | - }else if( gap+2<=top ){ |
| 52769 | | - /* Search the freelist looking for a free slot big enough to satisfy |
| 52770 | | - ** the request. The allocation is made from the first free slot in |
| 52771 | | - ** the list that is large enough to accommodate it. |
| 52772 | | - */ |
| 53191 | + if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){ |
| 52773 | 53192 | int pc, addr; |
| 52774 | 53193 | for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){ |
| 52775 | 53194 | int size; /* Size of the free slot */ |
| 52776 | 53195 | if( pc>usableSize-4 || pc<addr+4 ){ |
| 52777 | 53196 | return SQLITE_CORRUPT_BKPT; |
| | @@ -52780,14 +53199,15 @@ |
| 52780 | 53199 | if( size>=nByte ){ |
| 52781 | 53200 | int x = size - nByte; |
| 52782 | 53201 | testcase( x==4 ); |
| 52783 | 53202 | testcase( x==3 ); |
| 52784 | 53203 | if( x<4 ){ |
| 53204 | + if( data[hdr+7]>=60 ) goto defragment_page; |
| 52785 | 53205 | /* Remove the slot from the free-list. Update the number of |
| 52786 | 53206 | ** fragmented bytes within the page. */ |
| 52787 | 53207 | memcpy(&data[addr], &data[pc], 2); |
| 52788 | | - data[hdr+7] = (u8)(nFrag + x); |
| 53208 | + data[hdr+7] += (u8)x; |
| 52789 | 53209 | }else if( size+pc > usableSize ){ |
| 52790 | 53210 | return SQLITE_CORRUPT_BKPT; |
| 52791 | 53211 | }else{ |
| 52792 | 53212 | /* The slot remains on the free-list. Reduce its size to account |
| 52793 | 53213 | ** for the portion used by the new allocation. */ |
| | @@ -52797,15 +53217,17 @@ |
| 52797 | 53217 | return SQLITE_OK; |
| 52798 | 53218 | } |
| 52799 | 53219 | } |
| 52800 | 53220 | } |
| 52801 | 53221 | |
| 52802 | | - /* Check to make sure there is enough space in the gap to satisfy |
| 52803 | | - ** the allocation. If not, defragment. |
| 53222 | + /* The request could not be fulfilled using a freelist slot. Check |
| 53223 | + ** to see if defragmentation is necessary. |
| 52804 | 53224 | */ |
| 52805 | 53225 | testcase( gap+2+nByte==top ); |
| 52806 | 53226 | if( gap+2+nByte>top ){ |
| 53227 | +defragment_page: |
| 53228 | + testcase( pPage->nCell==0 ); |
| 52807 | 53229 | rc = defragmentPage(pPage); |
| 52808 | 53230 | if( rc ) return rc; |
| 52809 | 53231 | top = get2byteNotZero(&data[hdr+5]); |
| 52810 | 53232 | assert( gap+nByte<=top ); |
| 52811 | 53233 | } |
| | @@ -52824,94 +53246,104 @@ |
| 52824 | 53246 | return SQLITE_OK; |
| 52825 | 53247 | } |
| 52826 | 53248 | |
| 52827 | 53249 | /* |
| 52828 | 53250 | ** Return a section of the pPage->aData to the freelist. |
| 52829 | | -** The first byte of the new free block is pPage->aDisk[start] |
| 52830 | | -** and the size of the block is "size" bytes. |
| 53251 | +** The first byte of the new free block is pPage->aData[iStart] |
| 53252 | +** and the size of the block is iSize bytes. |
| 52831 | 53253 | ** |
| 52832 | | -** Most of the effort here is involved in coalesing adjacent |
| 52833 | | -** free blocks into a single big free block. |
| 53254 | +** Adjacent freeblocks are coalesced. |
| 53255 | +** |
| 53256 | +** Note that even though the freeblock list was checked by btreeInitPage(), |
| 53257 | +** that routine will not detect overlap between cells or freeblocks. Nor |
| 53258 | +** does it detect cells or freeblocks that encrouch into the reserved bytes |
| 53259 | +** at the end of the page. So do additional corruption checks inside this |
| 53260 | +** routine and return SQLITE_CORRUPT if any problems are found. |
| 52834 | 53261 | */ |
| 52835 | | -static int freeSpace(MemPage *pPage, int start, int size){ |
| 52836 | | - int addr, pbegin, hdr; |
| 52837 | | - int iLast; /* Largest possible freeblock offset */ |
| 52838 | | - unsigned char *data = pPage->aData; |
| 53262 | +static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ |
| 53263 | + u16 iPtr; /* Address of pointer to next freeblock */ |
| 53264 | + u16 iFreeBlk; /* Address of the next freeblock */ |
| 53265 | + u8 hdr; /* Page header size. 0 or 100 */ |
| 53266 | + u8 nFrag = 0; /* Reduction in fragmentation */ |
| 53267 | + u16 iOrigSize = iSize; /* Original value of iSize */ |
| 53268 | + u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ |
| 53269 | + u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ |
| 53270 | + unsigned char *data = pPage->aData; /* Page content */ |
| 52839 | 53271 | |
| 52840 | 53272 | assert( pPage->pBt!=0 ); |
| 52841 | 53273 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 52842 | | - assert( start>=pPage->hdrOffset+6+pPage->childPtrSize ); |
| 52843 | | - assert( (start + size) <= (int)pPage->pBt->usableSize ); |
| 53274 | + assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); |
| 53275 | + assert( iEnd <= pPage->pBt->usableSize ); |
| 52844 | 53276 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 52845 | | - assert( size>=0 ); /* Minimum cell size is 4 */ |
| 53277 | + assert( iSize>=4 ); /* Minimum cell size is 4 */ |
| 53278 | + assert( iStart<=iLast ); |
| 52846 | 53279 | |
| 53280 | + /* Overwrite deleted information with zeros when the secure_delete |
| 53281 | + ** option is enabled */ |
| 52847 | 53282 | if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ |
| 52848 | | - /* Overwrite deleted information with zeros when the secure_delete |
| 52849 | | - ** option is enabled */ |
| 52850 | | - memset(&data[start], 0, size); |
| 53283 | + memset(&data[iStart], 0, iSize); |
| 52851 | 53284 | } |
| 52852 | 53285 | |
| 52853 | | - /* Add the space back into the linked list of freeblocks. Note that |
| 52854 | | - ** even though the freeblock list was checked by btreeInitPage(), |
| 52855 | | - ** btreeInitPage() did not detect overlapping cells or |
| 52856 | | - ** freeblocks that overlapped cells. Nor does it detect when the |
| 52857 | | - ** cell content area exceeds the value in the page header. If these |
| 52858 | | - ** situations arise, then subsequent insert operations might corrupt |
| 52859 | | - ** the freelist. So we do need to check for corruption while scanning |
| 52860 | | - ** the freelist. |
| 53286 | + /* The list of freeblocks must be in ascending order. Find the |
| 53287 | + ** spot on the list where iStart should be inserted. |
| 52861 | 53288 | */ |
| 52862 | 53289 | hdr = pPage->hdrOffset; |
| 52863 | | - addr = hdr + 1; |
| 52864 | | - iLast = pPage->pBt->usableSize - 4; |
| 52865 | | - assert( start<=iLast ); |
| 52866 | | - while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){ |
| 52867 | | - if( pbegin<addr+4 ){ |
| 52868 | | - return SQLITE_CORRUPT_BKPT; |
| 52869 | | - } |
| 52870 | | - addr = pbegin; |
| 52871 | | - } |
| 52872 | | - if( pbegin>iLast ){ |
| 52873 | | - return SQLITE_CORRUPT_BKPT; |
| 52874 | | - } |
| 52875 | | - assert( pbegin>addr || pbegin==0 ); |
| 52876 | | - put2byte(&data[addr], start); |
| 52877 | | - put2byte(&data[start], pbegin); |
| 52878 | | - put2byte(&data[start+2], size); |
| 52879 | | - pPage->nFree = pPage->nFree + (u16)size; |
| 52880 | | - |
| 52881 | | - /* Coalesce adjacent free blocks */ |
| 52882 | | - addr = hdr + 1; |
| 52883 | | - while( (pbegin = get2byte(&data[addr]))>0 ){ |
| 52884 | | - int pnext, psize, x; |
| 52885 | | - assert( pbegin>addr ); |
| 52886 | | - assert( pbegin <= (int)pPage->pBt->usableSize-4 ); |
| 52887 | | - pnext = get2byte(&data[pbegin]); |
| 52888 | | - psize = get2byte(&data[pbegin+2]); |
| 52889 | | - if( pbegin + psize + 3 >= pnext && pnext>0 ){ |
| 52890 | | - int frag = pnext - (pbegin+psize); |
| 52891 | | - if( (frag<0) || (frag>(int)data[hdr+7]) ){ |
| 52892 | | - return SQLITE_CORRUPT_BKPT; |
| 52893 | | - } |
| 52894 | | - data[hdr+7] -= (u8)frag; |
| 52895 | | - x = get2byte(&data[pnext]); |
| 52896 | | - put2byte(&data[pbegin], x); |
| 52897 | | - x = pnext + get2byte(&data[pnext+2]) - pbegin; |
| 52898 | | - put2byte(&data[pbegin+2], x); |
| 52899 | | - }else{ |
| 52900 | | - addr = pbegin; |
| 52901 | | - } |
| 52902 | | - } |
| 52903 | | - |
| 52904 | | - /* If the cell content area begins with a freeblock, remove it. */ |
| 52905 | | - if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){ |
| 52906 | | - int top; |
| 52907 | | - pbegin = get2byte(&data[hdr+1]); |
| 52908 | | - memcpy(&data[hdr+1], &data[pbegin], 2); |
| 52909 | | - top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]); |
| 52910 | | - put2byte(&data[hdr+5], top); |
| 52911 | | - } |
| 52912 | | - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 53290 | + iPtr = hdr + 1; |
| 53291 | + if( data[iPtr+1]==0 && data[iPtr]==0 ){ |
| 53292 | + iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ |
| 53293 | + }else{ |
| 53294 | + while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){ |
| 53295 | + if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT; |
| 53296 | + iPtr = iFreeBlk; |
| 53297 | + } |
| 53298 | + if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT; |
| 53299 | + assert( iFreeBlk>iPtr || iFreeBlk==0 ); |
| 53300 | + |
| 53301 | + /* At this point: |
| 53302 | + ** iFreeBlk: First freeblock after iStart, or zero if none |
| 53303 | + ** iPtr: The address of a pointer iFreeBlk |
| 53304 | + ** |
| 53305 | + ** Check to see if iFreeBlk should be coalesced onto the end of iStart. |
| 53306 | + */ |
| 53307 | + if( iFreeBlk && iEnd+3>=iFreeBlk ){ |
| 53308 | + nFrag = iFreeBlk - iEnd; |
| 53309 | + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; |
| 53310 | + iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); |
| 53311 | + iSize = iEnd - iStart; |
| 53312 | + iFreeBlk = get2byte(&data[iFreeBlk]); |
| 53313 | + } |
| 53314 | + |
| 53315 | + /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer |
| 53316 | + ** in the page header) then check to see if iStart should be coalesced |
| 53317 | + ** onto the end of iPtr. |
| 53318 | + */ |
| 53319 | + if( iPtr>hdr+1 ){ |
| 53320 | + int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); |
| 53321 | + if( iPtrEnd+3>=iStart ){ |
| 53322 | + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; |
| 53323 | + nFrag += iStart - iPtrEnd; |
| 53324 | + iSize = iEnd - iPtr; |
| 53325 | + iStart = iPtr; |
| 53326 | + } |
| 53327 | + } |
| 53328 | + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; |
| 53329 | + data[hdr+7] -= nFrag; |
| 53330 | + } |
| 53331 | + if( iStart==get2byte(&data[hdr+5]) ){ |
| 53332 | + /* The new freeblock is at the beginning of the cell content area, |
| 53333 | + ** so just extend the cell content area rather than create another |
| 53334 | + ** freelist entry */ |
| 53335 | + if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT; |
| 53336 | + put2byte(&data[hdr+1], iFreeBlk); |
| 53337 | + put2byte(&data[hdr+5], iEnd); |
| 53338 | + }else{ |
| 53339 | + /* Insert the new freeblock into the freelist */ |
| 53340 | + put2byte(&data[iPtr], iStart); |
| 53341 | + put2byte(&data[iStart], iFreeBlk); |
| 53342 | + put2byte(&data[iStart+2], iSize); |
| 53343 | + } |
| 53344 | + pPage->nFree += iOrigSize; |
| 52913 | 53345 | return SQLITE_OK; |
| 52914 | 53346 | } |
| 52915 | 53347 | |
| 52916 | 53348 | /* |
| 52917 | 53349 | ** Decode the flags byte (the first byte of the header) for a page |
| | @@ -55999,21 +56431,20 @@ |
| 55999 | 56431 | int rc = SQLITE_OK; |
| 56000 | 56432 | MemPage *pPage = 0; |
| 56001 | 56433 | |
| 56002 | 56434 | assert( cursorHoldsMutex(pCur) ); |
| 56003 | 56435 | assert( pCur->eState==CURSOR_VALID ); |
| 56004 | | - while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ |
| 56436 | + while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ |
| 56005 | 56437 | pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); |
| 56006 | 56438 | pCur->aiIdx[pCur->iPage] = pPage->nCell; |
| 56007 | 56439 | rc = moveToChild(pCur, pgno); |
| 56440 | + if( rc ) return rc; |
| 56008 | 56441 | } |
| 56009 | | - if( rc==SQLITE_OK ){ |
| 56010 | | - pCur->aiIdx[pCur->iPage] = pPage->nCell-1; |
| 56011 | | - pCur->info.nSize = 0; |
| 56012 | | - pCur->curFlags &= ~BTCF_ValidNKey; |
| 56013 | | - } |
| 56014 | | - return rc; |
| 56442 | + pCur->aiIdx[pCur->iPage] = pPage->nCell-1; |
| 56443 | + assert( pCur->info.nSize==0 ); |
| 56444 | + assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); |
| 56445 | + return SQLITE_OK; |
| 56015 | 56446 | } |
| 56016 | 56447 | |
| 56017 | 56448 | /* Move the cursor to the first entry in the table. Return SQLITE_OK |
| 56018 | 56449 | ** on success. Set *pRes to 0 if the cursor actually points to something |
| 56019 | 56450 | ** or set *pRes to 1 if the table is empty. |
| | @@ -56140,11 +56571,11 @@ |
| 56140 | 56571 | } |
| 56141 | 56572 | } |
| 56142 | 56573 | |
| 56143 | 56574 | if( pIdxKey ){ |
| 56144 | 56575 | xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); |
| 56145 | | - pIdxKey->isCorrupt = 0; |
| 56576 | + pIdxKey->errCode = 0; |
| 56146 | 56577 | assert( pIdxKey->default_rc==1 |
| 56147 | 56578 | || pIdxKey->default_rc==0 |
| 56148 | 56579 | || pIdxKey->default_rc==-1 |
| 56149 | 56580 | ); |
| 56150 | 56581 | }else{ |
| | @@ -56264,21 +56695,24 @@ |
| 56264 | 56695 | goto moveto_finish; |
| 56265 | 56696 | } |
| 56266 | 56697 | c = xRecordCompare(nCell, pCellKey, pIdxKey, 0); |
| 56267 | 56698 | sqlite3_free(pCellKey); |
| 56268 | 56699 | } |
| 56269 | | - assert( pIdxKey->isCorrupt==0 || c==0 ); |
| 56700 | + assert( |
| 56701 | + (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) |
| 56702 | + && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) |
| 56703 | + ); |
| 56270 | 56704 | if( c<0 ){ |
| 56271 | 56705 | lwr = idx+1; |
| 56272 | 56706 | }else if( c>0 ){ |
| 56273 | 56707 | upr = idx-1; |
| 56274 | 56708 | }else{ |
| 56275 | 56709 | assert( c==0 ); |
| 56276 | 56710 | *pRes = 0; |
| 56277 | 56711 | rc = SQLITE_OK; |
| 56278 | 56712 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 56279 | | - if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT; |
| 56713 | + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; |
| 56280 | 56714 | goto moveto_finish; |
| 56281 | 56715 | } |
| 56282 | 56716 | if( lwr>upr ) break; |
| 56283 | 56717 | assert( lwr+upr>=0 ); |
| 56284 | 56718 | idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ |
| | @@ -56328,10 +56762,16 @@ |
| 56328 | 56762 | /* |
| 56329 | 56763 | ** Advance the cursor to the next entry in the database. If |
| 56330 | 56764 | ** successful then set *pRes=0. If the cursor |
| 56331 | 56765 | ** was already pointing to the last entry in the database before |
| 56332 | 56766 | ** this routine was called, then set *pRes=1. |
| 56767 | +** |
| 56768 | +** The main entry point is sqlite3BtreeNext(). That routine is optimized |
| 56769 | +** for the common case of merely incrementing the cell counter BtCursor.aiIdx |
| 56770 | +** to the next cell on the current page. The (slower) btreeNext() helper |
| 56771 | +** routine is called when it is necessary to move to a different page or |
| 56772 | +** to restore the cursor. |
| 56333 | 56773 | ** |
| 56334 | 56774 | ** The calling function will set *pRes to 0 or 1. The initial *pRes value |
| 56335 | 56775 | ** will be 1 if the cursor being stepped corresponds to an SQL index and |
| 56336 | 56776 | ** if this routine could have been skipped if that SQL index had been |
| 56337 | 56777 | ** a unique index. Otherwise the caller will have set *pRes to zero. |
| | @@ -56338,24 +56778,22 @@ |
| 56338 | 56778 | ** Zero is the common case. The btree implementation is free to use the |
| 56339 | 56779 | ** initial *pRes value as a hint to improve performance, but the current |
| 56340 | 56780 | ** SQLite btree implementation does not. (Note that the comdb2 btree |
| 56341 | 56781 | ** implementation does use this hint, however.) |
| 56342 | 56782 | */ |
| 56343 | | -SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ |
| 56783 | +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){ |
| 56344 | 56784 | int rc; |
| 56345 | 56785 | int idx; |
| 56346 | 56786 | MemPage *pPage; |
| 56347 | 56787 | |
| 56348 | 56788 | assert( cursorHoldsMutex(pCur) ); |
| 56349 | | - assert( pRes!=0 ); |
| 56350 | | - assert( *pRes==0 || *pRes==1 ); |
| 56351 | 56789 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 56790 | + assert( *pRes==0 ); |
| 56352 | 56791 | if( pCur->eState!=CURSOR_VALID ){ |
| 56353 | | - invalidateOverflowCache(pCur); |
| 56792 | + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| 56354 | 56793 | rc = restoreCursorPosition(pCur); |
| 56355 | 56794 | if( rc!=SQLITE_OK ){ |
| 56356 | | - *pRes = 0; |
| 56357 | 56795 | return rc; |
| 56358 | 56796 | } |
| 56359 | 56797 | if( CURSOR_INVALID==pCur->eState ){ |
| 56360 | 56798 | *pRes = 1; |
| 56361 | 56799 | return SQLITE_OK; |
| | @@ -56363,11 +56801,10 @@ |
| 56363 | 56801 | if( pCur->skipNext ){ |
| 56364 | 56802 | assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); |
| 56365 | 56803 | pCur->eState = CURSOR_VALID; |
| 56366 | 56804 | if( pCur->skipNext>0 ){ |
| 56367 | 56805 | pCur->skipNext = 0; |
| 56368 | | - *pRes = 0; |
| 56369 | 56806 | return SQLITE_OK; |
| 56370 | 56807 | } |
| 56371 | 56808 | pCur->skipNext = 0; |
| 56372 | 56809 | } |
| 56373 | 56810 | } |
| | @@ -56381,22 +56818,15 @@ |
| 56381 | 56818 | ** the page while cursor pCur is holding a reference to it. Which can |
| 56382 | 56819 | ** only happen if the database is corrupt in such a way as to link the |
| 56383 | 56820 | ** page into more than one b-tree structure. */ |
| 56384 | 56821 | testcase( idx>pPage->nCell ); |
| 56385 | 56822 | |
| 56386 | | - pCur->info.nSize = 0; |
| 56387 | | - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 56388 | 56823 | if( idx>=pPage->nCell ){ |
| 56389 | 56824 | if( !pPage->leaf ){ |
| 56390 | 56825 | rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); |
| 56391 | | - if( rc ){ |
| 56392 | | - *pRes = 0; |
| 56393 | | - return rc; |
| 56394 | | - } |
| 56395 | | - rc = moveToLeftmost(pCur); |
| 56396 | | - *pRes = 0; |
| 56397 | | - return rc; |
| 56826 | + if( rc ) return rc; |
| 56827 | + return moveToLeftmost(pCur); |
| 56398 | 56828 | } |
| 56399 | 56829 | do{ |
| 56400 | 56830 | if( pCur->iPage==0 ){ |
| 56401 | 56831 | *pRes = 1; |
| 56402 | 56832 | pCur->eState = CURSOR_INVALID; |
| | @@ -56403,32 +56833,55 @@ |
| 56403 | 56833 | return SQLITE_OK; |
| 56404 | 56834 | } |
| 56405 | 56835 | moveToParent(pCur); |
| 56406 | 56836 | pPage = pCur->apPage[pCur->iPage]; |
| 56407 | 56837 | }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); |
| 56408 | | - *pRes = 0; |
| 56409 | 56838 | if( pPage->intKey ){ |
| 56410 | | - rc = sqlite3BtreeNext(pCur, pRes); |
| 56839 | + return sqlite3BtreeNext(pCur, pRes); |
| 56411 | 56840 | }else{ |
| 56412 | | - rc = SQLITE_OK; |
| 56841 | + return SQLITE_OK; |
| 56413 | 56842 | } |
| 56414 | | - return rc; |
| 56415 | 56843 | } |
| 56844 | + if( pPage->leaf ){ |
| 56845 | + return SQLITE_OK; |
| 56846 | + }else{ |
| 56847 | + return moveToLeftmost(pCur); |
| 56848 | + } |
| 56849 | +} |
| 56850 | +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ |
| 56851 | + MemPage *pPage; |
| 56852 | + assert( cursorHoldsMutex(pCur) ); |
| 56853 | + assert( pRes!=0 ); |
| 56854 | + assert( *pRes==0 || *pRes==1 ); |
| 56855 | + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 56856 | + pCur->info.nSize = 0; |
| 56857 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 56416 | 56858 | *pRes = 0; |
| 56859 | + if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes); |
| 56860 | + pPage = pCur->apPage[pCur->iPage]; |
| 56861 | + if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){ |
| 56862 | + pCur->aiIdx[pCur->iPage]--; |
| 56863 | + return btreeNext(pCur, pRes); |
| 56864 | + } |
| 56417 | 56865 | if( pPage->leaf ){ |
| 56418 | 56866 | return SQLITE_OK; |
| 56867 | + }else{ |
| 56868 | + return moveToLeftmost(pCur); |
| 56419 | 56869 | } |
| 56420 | | - rc = moveToLeftmost(pCur); |
| 56421 | | - return rc; |
| 56422 | 56870 | } |
| 56423 | | - |
| 56424 | 56871 | |
| 56425 | 56872 | /* |
| 56426 | 56873 | ** Step the cursor to the back to the previous entry in the database. If |
| 56427 | 56874 | ** successful then set *pRes=0. If the cursor |
| 56428 | 56875 | ** was already pointing to the first entry in the database before |
| 56429 | 56876 | ** this routine was called, then set *pRes=1. |
| 56877 | +** |
| 56878 | +** The main entry point is sqlite3BtreePrevious(). That routine is optimized |
| 56879 | +** for the common case of merely decrementing the cell counter BtCursor.aiIdx |
| 56880 | +** to the previous cell on the current page. The (slower) btreePrevious() helper |
| 56881 | +** routine is called when it is necessary to move to a different page or |
| 56882 | +** to restore the cursor. |
| 56430 | 56883 | ** |
| 56431 | 56884 | ** The calling function will set *pRes to 0 or 1. The initial *pRes value |
| 56432 | 56885 | ** will be 1 if the cursor being stepped corresponds to an SQL index and |
| 56433 | 56886 | ** if this routine could have been skipped if that SQL index had been |
| 56434 | 56887 | ** a unique index. Otherwise the caller will have set *pRes to zero. |
| | @@ -56435,26 +56888,25 @@ |
| 56435 | 56888 | ** Zero is the common case. The btree implementation is free to use the |
| 56436 | 56889 | ** initial *pRes value as a hint to improve performance, but the current |
| 56437 | 56890 | ** SQLite btree implementation does not. (Note that the comdb2 btree |
| 56438 | 56891 | ** implementation does use this hint, however.) |
| 56439 | 56892 | */ |
| 56440 | | -SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ |
| 56893 | +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ |
| 56441 | 56894 | int rc; |
| 56442 | 56895 | MemPage *pPage; |
| 56443 | 56896 | |
| 56444 | 56897 | assert( cursorHoldsMutex(pCur) ); |
| 56445 | 56898 | assert( pRes!=0 ); |
| 56446 | | - assert( *pRes==0 || *pRes==1 ); |
| 56899 | + assert( *pRes==0 ); |
| 56447 | 56900 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 56448 | | - pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl); |
| 56901 | + assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); |
| 56902 | + assert( pCur->info.nSize==0 ); |
| 56449 | 56903 | if( pCur->eState!=CURSOR_VALID ){ |
| 56450 | | - if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ |
| 56451 | | - rc = btreeRestoreCursorPosition(pCur); |
| 56452 | | - if( rc!=SQLITE_OK ){ |
| 56453 | | - *pRes = 0; |
| 56454 | | - return rc; |
| 56455 | | - } |
| 56904 | + assert( pCur->eState>=CURSOR_REQUIRESEEK ); |
| 56905 | + rc = btreeRestoreCursorPosition(pCur); |
| 56906 | + if( rc!=SQLITE_OK ){ |
| 56907 | + return rc; |
| 56456 | 56908 | } |
| 56457 | 56909 | if( CURSOR_INVALID==pCur->eState ){ |
| 56458 | 56910 | *pRes = 1; |
| 56459 | 56911 | return SQLITE_OK; |
| 56460 | 56912 | } |
| | @@ -56461,11 +56913,10 @@ |
| 56461 | 56913 | if( pCur->skipNext ){ |
| 56462 | 56914 | assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); |
| 56463 | 56915 | pCur->eState = CURSOR_VALID; |
| 56464 | 56916 | if( pCur->skipNext<0 ){ |
| 56465 | 56917 | pCur->skipNext = 0; |
| 56466 | | - *pRes = 0; |
| 56467 | 56918 | return SQLITE_OK; |
| 56468 | 56919 | } |
| 56469 | 56920 | pCur->skipNext = 0; |
| 56470 | 56921 | } |
| 56471 | 56922 | } |
| | @@ -56473,14 +56924,11 @@ |
| 56473 | 56924 | pPage = pCur->apPage[pCur->iPage]; |
| 56474 | 56925 | assert( pPage->isInit ); |
| 56475 | 56926 | if( !pPage->leaf ){ |
| 56476 | 56927 | int idx = pCur->aiIdx[pCur->iPage]; |
| 56477 | 56928 | rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); |
| 56478 | | - if( rc ){ |
| 56479 | | - *pRes = 0; |
| 56480 | | - return rc; |
| 56481 | | - } |
| 56929 | + if( rc ) return rc; |
| 56482 | 56930 | rc = moveToRightmost(pCur); |
| 56483 | 56931 | }else{ |
| 56484 | 56932 | while( pCur->aiIdx[pCur->iPage]==0 ){ |
| 56485 | 56933 | if( pCur->iPage==0 ){ |
| 56486 | 56934 | pCur->eState = CURSOR_INVALID; |
| | @@ -56487,23 +56935,39 @@ |
| 56487 | 56935 | *pRes = 1; |
| 56488 | 56936 | return SQLITE_OK; |
| 56489 | 56937 | } |
| 56490 | 56938 | moveToParent(pCur); |
| 56491 | 56939 | } |
| 56492 | | - pCur->info.nSize = 0; |
| 56493 | | - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 56940 | + assert( pCur->info.nSize==0 ); |
| 56941 | + assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 ); |
| 56494 | 56942 | |
| 56495 | 56943 | pCur->aiIdx[pCur->iPage]--; |
| 56496 | 56944 | pPage = pCur->apPage[pCur->iPage]; |
| 56497 | 56945 | if( pPage->intKey && !pPage->leaf ){ |
| 56498 | 56946 | rc = sqlite3BtreePrevious(pCur, pRes); |
| 56499 | 56947 | }else{ |
| 56500 | 56948 | rc = SQLITE_OK; |
| 56501 | 56949 | } |
| 56502 | 56950 | } |
| 56951 | + return rc; |
| 56952 | +} |
| 56953 | +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ |
| 56954 | + assert( cursorHoldsMutex(pCur) ); |
| 56955 | + assert( pRes!=0 ); |
| 56956 | + assert( *pRes==0 || *pRes==1 ); |
| 56957 | + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 56503 | 56958 | *pRes = 0; |
| 56504 | | - return rc; |
| 56959 | + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); |
| 56960 | + pCur->info.nSize = 0; |
| 56961 | + if( pCur->eState!=CURSOR_VALID |
| 56962 | + || pCur->aiIdx[pCur->iPage]==0 |
| 56963 | + || pCur->apPage[pCur->iPage]->leaf==0 |
| 56964 | + ){ |
| 56965 | + return btreePrevious(pCur, pRes); |
| 56966 | + } |
| 56967 | + pCur->aiIdx[pCur->iPage]--; |
| 56968 | + return SQLITE_OK; |
| 56505 | 56969 | } |
| 56506 | 56970 | |
| 56507 | 56971 | /* |
| 56508 | 56972 | ** Allocate a new page from the database file. |
| 56509 | 56973 | ** |
| | @@ -60155,16 +60619,16 @@ |
| 60155 | 60619 | if( i==1 ){ |
| 60156 | 60620 | Parse *pParse; |
| 60157 | 60621 | int rc = 0; |
| 60158 | 60622 | pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); |
| 60159 | 60623 | if( pParse==0 ){ |
| 60160 | | - sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory"); |
| 60624 | + sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory"); |
| 60161 | 60625 | rc = SQLITE_NOMEM; |
| 60162 | 60626 | }else{ |
| 60163 | 60627 | pParse->db = pDb; |
| 60164 | 60628 | if( sqlite3OpenTempDatabase(pParse) ){ |
| 60165 | | - sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); |
| 60629 | + sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); |
| 60166 | 60630 | rc = SQLITE_ERROR; |
| 60167 | 60631 | } |
| 60168 | 60632 | sqlite3DbFree(pErrorDb, pParse->zErrMsg); |
| 60169 | 60633 | sqlite3ParserReset(pParse); |
| 60170 | 60634 | sqlite3StackFree(pErrorDb, pParse); |
| | @@ -60173,11 +60637,11 @@ |
| 60173 | 60637 | return 0; |
| 60174 | 60638 | } |
| 60175 | 60639 | } |
| 60176 | 60640 | |
| 60177 | 60641 | if( i<0 ){ |
| 60178 | | - sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); |
| 60642 | + sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); |
| 60179 | 60643 | return 0; |
| 60180 | 60644 | } |
| 60181 | 60645 | |
| 60182 | 60646 | return pDb->aDb[i].pBt; |
| 60183 | 60647 | } |
| | @@ -60218,11 +60682,11 @@ |
| 60218 | 60682 | */ |
| 60219 | 60683 | sqlite3_mutex_enter(pSrcDb->mutex); |
| 60220 | 60684 | sqlite3_mutex_enter(pDestDb->mutex); |
| 60221 | 60685 | |
| 60222 | 60686 | if( pSrcDb==pDestDb ){ |
| 60223 | | - sqlite3Error( |
| 60687 | + sqlite3ErrorWithMsg( |
| 60224 | 60688 | pDestDb, SQLITE_ERROR, "source and destination must be distinct" |
| 60225 | 60689 | ); |
| 60226 | 60690 | p = 0; |
| 60227 | 60691 | }else { |
| 60228 | 60692 | /* Allocate space for a new sqlite3_backup object... |
| | @@ -60229,11 +60693,11 @@ |
| 60229 | 60693 | ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 60230 | 60694 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 60231 | 60695 | ** sqlite3_backup_finish(). */ |
| 60232 | 60696 | p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); |
| 60233 | 60697 | if( !p ){ |
| 60234 | | - sqlite3Error(pDestDb, SQLITE_NOMEM, 0); |
| 60698 | + sqlite3Error(pDestDb, SQLITE_NOMEM); |
| 60235 | 60699 | } |
| 60236 | 60700 | } |
| 60237 | 60701 | |
| 60238 | 60702 | /* If the allocation succeeded, populate the new object. */ |
| 60239 | 60703 | if( p ){ |
| | @@ -60670,11 +61134,11 @@ |
| 60670 | 61134 | sqlite3BtreeRollback(p->pDest, SQLITE_OK); |
| 60671 | 61135 | |
| 60672 | 61136 | /* Set the error code of the destination database handle. */ |
| 60673 | 61137 | rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; |
| 60674 | 61138 | if( p->pDestDb ){ |
| 60675 | | - sqlite3Error(p->pDestDb, rc, 0); |
| 61139 | + sqlite3Error(p->pDestDb, rc); |
| 60676 | 61140 | |
| 60677 | 61141 | /* Exit the mutexes and free the backup context structure. */ |
| 60678 | 61142 | sqlite3LeaveMutexAndCloseZombie(p->pDestDb); |
| 60679 | 61143 | } |
| 60680 | 61144 | sqlite3BtreeLeave(p->pSrc); |
| | @@ -60938,11 +61402,11 @@ |
| 60938 | 61402 | }else{ |
| 60939 | 61403 | sqlite3DbFree(pMem->db, pMem->zMalloc); |
| 60940 | 61404 | pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); |
| 60941 | 61405 | } |
| 60942 | 61406 | if( pMem->zMalloc==0 ){ |
| 60943 | | - VdbeMemRelease(pMem); |
| 61407 | + VdbeMemReleaseExtern(pMem); |
| 60944 | 61408 | pMem->z = 0; |
| 60945 | 61409 | pMem->flags = MEM_Null; |
| 60946 | 61410 | return SQLITE_NOMEM; |
| 60947 | 61411 | } |
| 60948 | 61412 | } |
| | @@ -61017,43 +61481,53 @@ |
| 61017 | 61481 | } |
| 61018 | 61482 | return SQLITE_OK; |
| 61019 | 61483 | } |
| 61020 | 61484 | #endif |
| 61021 | 61485 | |
| 61022 | | - |
| 61023 | 61486 | /* |
| 61024 | | -** Make sure the given Mem is \u0000 terminated. |
| 61487 | +** It is already known that pMem contains an unterminated string. |
| 61488 | +** Add the zero terminator. |
| 61025 | 61489 | */ |
| 61026 | | -SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ |
| 61027 | | - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 61028 | | - if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ |
| 61029 | | - return SQLITE_OK; /* Nothing to do */ |
| 61030 | | - } |
| 61490 | +static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ |
| 61031 | 61491 | if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ |
| 61032 | 61492 | return SQLITE_NOMEM; |
| 61033 | 61493 | } |
| 61034 | 61494 | pMem->z[pMem->n] = 0; |
| 61035 | 61495 | pMem->z[pMem->n+1] = 0; |
| 61036 | 61496 | pMem->flags |= MEM_Term; |
| 61037 | 61497 | return SQLITE_OK; |
| 61038 | 61498 | } |
| 61499 | + |
| 61500 | +/* |
| 61501 | +** Make sure the given Mem is \u0000 terminated. |
| 61502 | +*/ |
| 61503 | +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ |
| 61504 | + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 61505 | + testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); |
| 61506 | + testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); |
| 61507 | + if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ |
| 61508 | + return SQLITE_OK; /* Nothing to do */ |
| 61509 | + }else{ |
| 61510 | + return vdbeMemAddTerminator(pMem); |
| 61511 | + } |
| 61512 | +} |
| 61039 | 61513 | |
| 61040 | 61514 | /* |
| 61041 | 61515 | ** Add MEM_Str to the set of representations for the given Mem. Numbers |
| 61042 | 61516 | ** are converted using sqlite3_snprintf(). Converting a BLOB to a string |
| 61043 | 61517 | ** is a no-op. |
| 61044 | 61518 | ** |
| 61045 | | -** Existing representations MEM_Int and MEM_Real are *not* invalidated. |
| 61519 | +** Existing representations MEM_Int and MEM_Real are invalidated if |
| 61520 | +** bForce is true but are retained if bForce is false. |
| 61046 | 61521 | ** |
| 61047 | 61522 | ** A MEM_Null value will never be passed to this function. This function is |
| 61048 | 61523 | ** used for converting values to text for returning to the user (i.e. via |
| 61049 | 61524 | ** sqlite3_value_text()), or for ensuring that values to be used as btree |
| 61050 | 61525 | ** keys are strings. In the former case a NULL pointer is returned the |
| 61051 | 61526 | ** user and the later is an internal programming error. |
| 61052 | 61527 | */ |
| 61053 | | -SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){ |
| 61054 | | - int rc = SQLITE_OK; |
| 61528 | +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ |
| 61055 | 61529 | int fg = pMem->flags; |
| 61056 | 61530 | const int nByte = 32; |
| 61057 | 61531 | |
| 61058 | 61532 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 61059 | 61533 | assert( !(fg&MEM_Zero) ); |
| | @@ -61065,11 +61539,11 @@ |
| 61065 | 61539 | |
| 61066 | 61540 | if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ |
| 61067 | 61541 | return SQLITE_NOMEM; |
| 61068 | 61542 | } |
| 61069 | 61543 | |
| 61070 | | - /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8 |
| 61544 | + /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 |
| 61071 | 61545 | ** string representation of the value. Then, if the required encoding |
| 61072 | 61546 | ** is UTF-16le or UTF-16be do a translation. |
| 61073 | 61547 | ** |
| 61074 | 61548 | ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. |
| 61075 | 61549 | */ |
| | @@ -61080,12 +61554,13 @@ |
| 61080 | 61554 | sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r); |
| 61081 | 61555 | } |
| 61082 | 61556 | pMem->n = sqlite3Strlen30(pMem->z); |
| 61083 | 61557 | pMem->enc = SQLITE_UTF8; |
| 61084 | 61558 | pMem->flags |= MEM_Str|MEM_Term; |
| 61559 | + if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); |
| 61085 | 61560 | sqlite3VdbeChangeEncoding(pMem, enc); |
| 61086 | | - return rc; |
| 61561 | + return SQLITE_OK; |
| 61087 | 61562 | } |
| 61088 | 61563 | |
| 61089 | 61564 | /* |
| 61090 | 61565 | ** Memory cell pMem contains the context of an aggregate function. |
| 61091 | 61566 | ** This routine calls the finalize method for that function. The |
| | @@ -61096,30 +61571,36 @@ |
| 61096 | 61571 | */ |
| 61097 | 61572 | SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ |
| 61098 | 61573 | int rc = SQLITE_OK; |
| 61099 | 61574 | if( ALWAYS(pFunc && pFunc->xFinalize) ){ |
| 61100 | 61575 | sqlite3_context ctx; |
| 61576 | + Mem t; |
| 61101 | 61577 | assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); |
| 61102 | 61578 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 61103 | 61579 | memset(&ctx, 0, sizeof(ctx)); |
| 61104 | | - ctx.s.flags = MEM_Null; |
| 61105 | | - ctx.s.db = pMem->db; |
| 61580 | + memset(&t, 0, sizeof(t)); |
| 61581 | + t.flags = MEM_Null; |
| 61582 | + t.db = pMem->db; |
| 61583 | + ctx.pOut = &t; |
| 61106 | 61584 | ctx.pMem = pMem; |
| 61107 | 61585 | ctx.pFunc = pFunc; |
| 61108 | 61586 | pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ |
| 61109 | 61587 | assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); |
| 61110 | 61588 | sqlite3DbFree(pMem->db, pMem->zMalloc); |
| 61111 | | - memcpy(pMem, &ctx.s, sizeof(ctx.s)); |
| 61589 | + memcpy(pMem, &t, sizeof(t)); |
| 61112 | 61590 | rc = ctx.isError; |
| 61113 | 61591 | } |
| 61114 | 61592 | return rc; |
| 61115 | 61593 | } |
| 61116 | 61594 | |
| 61117 | 61595 | /* |
| 61118 | 61596 | ** If the memory cell contains a string value that must be freed by |
| 61119 | 61597 | ** invoking an external callback, free it now. Calling this function |
| 61120 | 61598 | ** does not free any Mem.zMalloc buffer. |
| 61599 | +** |
| 61600 | +** The VdbeMemReleaseExtern() macro invokes this routine if only if there |
| 61601 | +** is work for this routine to do. |
| 61121 | 61602 | */ |
| 61122 | 61603 | SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ |
| 61123 | 61604 | assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); |
| 61124 | 61605 | if( p->flags&MEM_Agg ){ |
| 61125 | 61606 | sqlite3VdbeMemFinalize(p, p->u.pDef); |
| | @@ -61134,25 +61615,43 @@ |
| 61134 | 61615 | sqlite3RowSetClear(p->u.pRowSet); |
| 61135 | 61616 | }else if( p->flags&MEM_Frame ){ |
| 61136 | 61617 | sqlite3VdbeMemSetNull(p); |
| 61137 | 61618 | } |
| 61138 | 61619 | } |
| 61620 | + |
| 61621 | +/* |
| 61622 | +** Release memory held by the Mem p, both external memory cleared |
| 61623 | +** by p->xDel and memory in p->zMalloc. |
| 61624 | +** |
| 61625 | +** This is a helper routine invoked by sqlite3VdbeMemRelease() in |
| 61626 | +** the uncommon case when there really is memory in p that is |
| 61627 | +** need of freeing. |
| 61628 | +*/ |
| 61629 | +static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ |
| 61630 | + if( VdbeMemDynamic(p) ){ |
| 61631 | + sqlite3VdbeMemReleaseExternal(p); |
| 61632 | + } |
| 61633 | + if( p->zMalloc ){ |
| 61634 | + sqlite3DbFree(p->db, p->zMalloc); |
| 61635 | + p->zMalloc = 0; |
| 61636 | + } |
| 61637 | + p->z = 0; |
| 61638 | +} |
| 61139 | 61639 | |
| 61140 | 61640 | /* |
| 61141 | 61641 | ** Release any memory held by the Mem. This may leave the Mem in an |
| 61142 | 61642 | ** inconsistent state, for example with (Mem.z==0) and |
| 61143 | 61643 | ** (Mem.flags==MEM_Str). |
| 61144 | 61644 | */ |
| 61145 | 61645 | SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ |
| 61146 | 61646 | assert( sqlite3VdbeCheckMemInvariants(p) ); |
| 61147 | | - VdbeMemRelease(p); |
| 61148 | | - if( p->zMalloc ){ |
| 61149 | | - sqlite3DbFree(p->db, p->zMalloc); |
| 61150 | | - p->zMalloc = 0; |
| 61647 | + if( VdbeMemDynamic(p) || p->zMalloc ){ |
| 61648 | + vdbeMemRelease(p); |
| 61649 | + }else{ |
| 61650 | + p->z = 0; |
| 61151 | 61651 | } |
| 61152 | | - p->z = 0; |
| 61153 | | - assert( p->xDel==0 ); /* Zeroed by VdbeMemRelease() above */ |
| 61652 | + assert( p->xDel==0 ); |
| 61154 | 61653 | } |
| 61155 | 61654 | |
| 61156 | 61655 | /* |
| 61157 | 61656 | ** Convert a 64-bit IEEE double into a 64-bit signed integer. |
| 61158 | 61657 | ** If the double is out of range of a 64-bit signed integer then |
| | @@ -61204,11 +61703,10 @@ |
| 61204 | 61703 | }else if( flags & MEM_Real ){ |
| 61205 | 61704 | return doubleToInt64(pMem->r); |
| 61206 | 61705 | }else if( flags & (MEM_Str|MEM_Blob) ){ |
| 61207 | 61706 | i64 value = 0; |
| 61208 | 61707 | assert( pMem->z || pMem->n==0 ); |
| 61209 | | - testcase( pMem->z==0 ); |
| 61210 | 61708 | sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); |
| 61211 | 61709 | return value; |
| 61212 | 61710 | }else{ |
| 61213 | 61711 | return 0; |
| 61214 | 61712 | } |
| | @@ -61316,10 +61814,55 @@ |
| 61316 | 61814 | } |
| 61317 | 61815 | assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); |
| 61318 | 61816 | pMem->flags &= ~(MEM_Str|MEM_Blob); |
| 61319 | 61817 | return SQLITE_OK; |
| 61320 | 61818 | } |
| 61819 | + |
| 61820 | +/* |
| 61821 | +** Cast the datatype of the value in pMem according to the affinity |
| 61822 | +** "aff". Casting is different from applying affinity in that a cast |
| 61823 | +** is forced. In other words, the value is converted into the desired |
| 61824 | +** affinity even if that results in loss of data. This routine is |
| 61825 | +** used (for example) to implement the SQL "cast()" operator. |
| 61826 | +*/ |
| 61827 | +SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ |
| 61828 | + if( pMem->flags & MEM_Null ) return; |
| 61829 | + switch( aff ){ |
| 61830 | + case SQLITE_AFF_NONE: { /* Really a cast to BLOB */ |
| 61831 | + if( (pMem->flags & MEM_Blob)==0 ){ |
| 61832 | + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); |
| 61833 | + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); |
| 61834 | + MemSetTypeFlag(pMem, MEM_Blob); |
| 61835 | + }else{ |
| 61836 | + pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); |
| 61837 | + } |
| 61838 | + break; |
| 61839 | + } |
| 61840 | + case SQLITE_AFF_NUMERIC: { |
| 61841 | + sqlite3VdbeMemNumerify(pMem); |
| 61842 | + break; |
| 61843 | + } |
| 61844 | + case SQLITE_AFF_INTEGER: { |
| 61845 | + sqlite3VdbeMemIntegerify(pMem); |
| 61846 | + break; |
| 61847 | + } |
| 61848 | + case SQLITE_AFF_REAL: { |
| 61849 | + sqlite3VdbeMemRealify(pMem); |
| 61850 | + break; |
| 61851 | + } |
| 61852 | + default: { |
| 61853 | + assert( aff==SQLITE_AFF_TEXT ); |
| 61854 | + assert( MEM_Str==(MEM_Blob>>3) ); |
| 61855 | + pMem->flags |= (pMem->flags&MEM_Blob)>>3; |
| 61856 | + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); |
| 61857 | + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); |
| 61858 | + pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); |
| 61859 | + break; |
| 61860 | + } |
| 61861 | + } |
| 61862 | +} |
| 61863 | + |
| 61321 | 61864 | |
| 61322 | 61865 | /* |
| 61323 | 61866 | ** Delete any previous value and set the value stored in *pMem to NULL. |
| 61324 | 61867 | */ |
| 61325 | 61868 | SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ |
| | @@ -61355,19 +61898,33 @@ |
| 61355 | 61898 | pMem->n = n; |
| 61356 | 61899 | memset(pMem->z, 0, n); |
| 61357 | 61900 | } |
| 61358 | 61901 | #endif |
| 61359 | 61902 | } |
| 61903 | + |
| 61904 | +/* |
| 61905 | +** The pMem is known to contain content that needs to be destroyed prior |
| 61906 | +** to a value change. So invoke the destructor, then set the value to |
| 61907 | +** a 64-bit integer. |
| 61908 | +*/ |
| 61909 | +static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ |
| 61910 | + sqlite3VdbeMemReleaseExternal(pMem); |
| 61911 | + pMem->u.i = val; |
| 61912 | + pMem->flags = MEM_Int; |
| 61913 | +} |
| 61360 | 61914 | |
| 61361 | 61915 | /* |
| 61362 | 61916 | ** Delete any previous value and set the value stored in *pMem to val, |
| 61363 | 61917 | ** manifest type INTEGER. |
| 61364 | 61918 | */ |
| 61365 | 61919 | SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ |
| 61366 | | - sqlite3VdbeMemRelease(pMem); |
| 61367 | | - pMem->u.i = val; |
| 61368 | | - pMem->flags = MEM_Int; |
| 61920 | + if( VdbeMemDynamic(pMem) ){ |
| 61921 | + vdbeReleaseAndSetInt64(pMem, val); |
| 61922 | + }else{ |
| 61923 | + pMem->u.i = val; |
| 61924 | + pMem->flags = MEM_Int; |
| 61925 | + } |
| 61369 | 61926 | } |
| 61370 | 61927 | |
| 61371 | 61928 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 61372 | 61929 | /* |
| 61373 | 61930 | ** Delete any previous value and set the value stored in *pMem to val, |
| | @@ -61454,11 +62011,11 @@ |
| 61454 | 62011 | ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z |
| 61455 | 62012 | ** and flags gets srcType (either MEM_Ephem or MEM_Static). |
| 61456 | 62013 | */ |
| 61457 | 62014 | SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ |
| 61458 | 62015 | assert( (pFrom->flags & MEM_RowSet)==0 ); |
| 61459 | | - VdbeMemRelease(pTo); |
| 62016 | + VdbeMemReleaseExtern(pTo); |
| 61460 | 62017 | memcpy(pTo, pFrom, MEMCELLSIZE); |
| 61461 | 62018 | pTo->xDel = 0; |
| 61462 | 62019 | if( (pFrom->flags&MEM_Static)==0 ){ |
| 61463 | 62020 | pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); |
| 61464 | 62021 | assert( srcType==MEM_Ephem || srcType==MEM_Static ); |
| | @@ -61472,11 +62029,11 @@ |
| 61472 | 62029 | */ |
| 61473 | 62030 | SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ |
| 61474 | 62031 | int rc = SQLITE_OK; |
| 61475 | 62032 | |
| 61476 | 62033 | assert( (pFrom->flags & MEM_RowSet)==0 ); |
| 61477 | | - VdbeMemRelease(pTo); |
| 62034 | + VdbeMemReleaseExtern(pTo); |
| 61478 | 62035 | memcpy(pTo, pFrom, MEMCELLSIZE); |
| 61479 | 62036 | pTo->flags &= ~MEM_Dyn; |
| 61480 | 62037 | pTo->xDel = 0; |
| 61481 | 62038 | |
| 61482 | 62039 | if( pTo->flags&(MEM_Str|MEM_Blob) ){ |
| | @@ -61659,10 +62216,49 @@ |
| 61659 | 62216 | } |
| 61660 | 62217 | } |
| 61661 | 62218 | |
| 61662 | 62219 | return rc; |
| 61663 | 62220 | } |
| 62221 | + |
| 62222 | +/* |
| 62223 | +** The pVal argument is known to be a value other than NULL. |
| 62224 | +** Convert it into a string with encoding enc and return a pointer |
| 62225 | +** to a zero-terminated version of that string. |
| 62226 | +*/ |
| 62227 | +SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ |
| 62228 | + assert( pVal!=0 ); |
| 62229 | + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 62230 | + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 62231 | + assert( (pVal->flags & MEM_RowSet)==0 ); |
| 62232 | + assert( (pVal->flags & (MEM_Null))==0 ); |
| 62233 | + if( pVal->flags & (MEM_Blob|MEM_Str) ){ |
| 62234 | + pVal->flags |= MEM_Str; |
| 62235 | + if( pVal->flags & MEM_Zero ){ |
| 62236 | + sqlite3VdbeMemExpandBlob(pVal); |
| 62237 | + } |
| 62238 | + if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ |
| 62239 | + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); |
| 62240 | + } |
| 62241 | + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ |
| 62242 | + assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); |
| 62243 | + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ |
| 62244 | + return 0; |
| 62245 | + } |
| 62246 | + } |
| 62247 | + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ |
| 62248 | + }else{ |
| 62249 | + sqlite3VdbeMemStringify(pVal, enc, 0); |
| 62250 | + assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); |
| 62251 | + } |
| 62252 | + assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 |
| 62253 | + || pVal->db->mallocFailed ); |
| 62254 | + if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ |
| 62255 | + return pVal->z; |
| 62256 | + }else{ |
| 62257 | + return 0; |
| 62258 | + } |
| 62259 | +} |
| 61664 | 62260 | |
| 61665 | 62261 | /* This function is only available internally, it is not part of the |
| 61666 | 62262 | ** external API. It works in a similar way to sqlite3_value_text(), |
| 61667 | 62263 | ** except the data returned is in the encoding specified by the second |
| 61668 | 62264 | ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or |
| | @@ -61672,42 +62268,20 @@ |
| 61672 | 62268 | ** If that is the case, then the result must be aligned on an even byte |
| 61673 | 62269 | ** boundary. |
| 61674 | 62270 | */ |
| 61675 | 62271 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ |
| 61676 | 62272 | if( !pVal ) return 0; |
| 61677 | | - |
| 61678 | 62273 | assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); |
| 61679 | 62274 | assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); |
| 61680 | 62275 | assert( (pVal->flags & MEM_RowSet)==0 ); |
| 61681 | | - |
| 62276 | + if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ |
| 62277 | + return pVal->z; |
| 62278 | + } |
| 61682 | 62279 | if( pVal->flags&MEM_Null ){ |
| 61683 | 62280 | return 0; |
| 61684 | 62281 | } |
| 61685 | | - assert( (MEM_Blob>>3) == MEM_Str ); |
| 61686 | | - pVal->flags |= (pVal->flags & MEM_Blob)>>3; |
| 61687 | | - ExpandBlob(pVal); |
| 61688 | | - if( pVal->flags&MEM_Str ){ |
| 61689 | | - sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); |
| 61690 | | - if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ |
| 61691 | | - assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); |
| 61692 | | - if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ |
| 61693 | | - return 0; |
| 61694 | | - } |
| 61695 | | - } |
| 61696 | | - sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ |
| 61697 | | - }else{ |
| 61698 | | - assert( (pVal->flags&MEM_Blob)==0 ); |
| 61699 | | - sqlite3VdbeMemStringify(pVal, enc); |
| 61700 | | - assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); |
| 61701 | | - } |
| 61702 | | - assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 |
| 61703 | | - || pVal->db->mallocFailed ); |
| 61704 | | - if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ |
| 61705 | | - return pVal->z; |
| 61706 | | - }else{ |
| 61707 | | - return 0; |
| 61708 | | - } |
| 62282 | + return valueToText(pVal, enc); |
| 61709 | 62283 | } |
| 61710 | 62284 | |
| 61711 | 62285 | /* |
| 61712 | 62286 | ** Create a new sqlite3_value object. |
| 61713 | 62287 | */ |
| | @@ -61810,12 +62384,23 @@ |
| 61810 | 62384 | |
| 61811 | 62385 | if( !pExpr ){ |
| 61812 | 62386 | *ppVal = 0; |
| 61813 | 62387 | return SQLITE_OK; |
| 61814 | 62388 | } |
| 61815 | | - op = pExpr->op; |
| 62389 | + while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft; |
| 61816 | 62390 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 62391 | + |
| 62392 | + if( op==TK_CAST ){ |
| 62393 | + u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); |
| 62394 | + rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); |
| 62395 | + testcase( rc!=SQLITE_OK ); |
| 62396 | + if( *ppVal ){ |
| 62397 | + sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); |
| 62398 | + sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); |
| 62399 | + } |
| 62400 | + return rc; |
| 62401 | + } |
| 61817 | 62402 | |
| 61818 | 62403 | /* Handle negative integers in a single step. This is needed in the |
| 61819 | 62404 | ** case when the value is -9223372036854775808. |
| 61820 | 62405 | */ |
| 61821 | 62406 | if( op==TK_UMINUS |
| | @@ -61947,11 +62532,11 @@ |
| 61947 | 62532 | aRet = sqlite3DbMallocRaw(db, nRet); |
| 61948 | 62533 | if( aRet==0 ){ |
| 61949 | 62534 | sqlite3_result_error_nomem(context); |
| 61950 | 62535 | }else{ |
| 61951 | 62536 | aRet[0] = nSerial+1; |
| 61952 | | - sqlite3PutVarint(&aRet[1], iSerial); |
| 62537 | + putVarint32(&aRet[1], iSerial); |
| 61953 | 62538 | sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); |
| 61954 | 62539 | sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
| 61955 | 62540 | sqlite3DbFree(db, aRet); |
| 61956 | 62541 | } |
| 61957 | 62542 | } |
| | @@ -64709,11 +65294,11 @@ |
| 64709 | 65294 | sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); |
| 64710 | 65295 | sqlite3EndBenignMalloc(); |
| 64711 | 65296 | db->mallocFailed = mallocFailed; |
| 64712 | 65297 | db->errCode = rc; |
| 64713 | 65298 | }else{ |
| 64714 | | - sqlite3Error(db, rc, 0); |
| 65299 | + sqlite3Error(db, rc); |
| 64715 | 65300 | } |
| 64716 | 65301 | return rc; |
| 64717 | 65302 | } |
| 64718 | 65303 | |
| 64719 | 65304 | #ifdef SQLITE_ENABLE_SQLLOG |
| | @@ -64772,11 +65357,11 @@ |
| 64772 | 65357 | }else if( p->rc && p->expired ){ |
| 64773 | 65358 | /* The expired flag was set on the VDBE before the first call |
| 64774 | 65359 | ** to sqlite3_step(). For consistency (since sqlite3_step() was |
| 64775 | 65360 | ** called), set the database error in this case as well. |
| 64776 | 65361 | */ |
| 64777 | | - sqlite3Error(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); |
| 65362 | + sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); |
| 64778 | 65363 | sqlite3DbFree(db, p->zErrMsg); |
| 64779 | 65364 | p->zErrMsg = 0; |
| 64780 | 65365 | } |
| 64781 | 65366 | |
| 64782 | 65367 | /* Reclaim all memory used by the VDBE |
| | @@ -64924,10 +65509,52 @@ |
| 64924 | 65509 | } |
| 64925 | 65510 | p->magic = VDBE_MAGIC_DEAD; |
| 64926 | 65511 | p->db = 0; |
| 64927 | 65512 | sqlite3DbFree(db, p); |
| 64928 | 65513 | } |
| 65514 | + |
| 65515 | +/* |
| 65516 | +** The cursor "p" has a pending seek operation that has not yet been |
| 65517 | +** carried out. Seek the cursor now. If an error occurs, return |
| 65518 | +** the appropriate error code. |
| 65519 | +*/ |
| 65520 | +static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ |
| 65521 | + int res, rc; |
| 65522 | +#ifdef SQLITE_TEST |
| 65523 | + extern int sqlite3_search_count; |
| 65524 | +#endif |
| 65525 | + assert( p->deferredMoveto ); |
| 65526 | + assert( p->isTable ); |
| 65527 | + rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
| 65528 | + if( rc ) return rc; |
| 65529 | + p->lastRowid = p->movetoTarget; |
| 65530 | + if( res!=0 ) return SQLITE_CORRUPT_BKPT; |
| 65531 | + p->rowidIsValid = 1; |
| 65532 | +#ifdef SQLITE_TEST |
| 65533 | + sqlite3_search_count++; |
| 65534 | +#endif |
| 65535 | + p->deferredMoveto = 0; |
| 65536 | + p->cacheStatus = CACHE_STALE; |
| 65537 | + return SQLITE_OK; |
| 65538 | +} |
| 65539 | + |
| 65540 | +/* |
| 65541 | +** Something has moved cursor "p" out of place. Maybe the row it was |
| 65542 | +** pointed to was deleted out from under it. Or maybe the btree was |
| 65543 | +** rebalanced. Whatever the cause, try to restore "p" to the place it |
| 65544 | +** is suppose to be pointing. If the row was deleted out from under the |
| 65545 | +** cursor, set the cursor to point to a NULL row. |
| 65546 | +*/ |
| 65547 | +static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ |
| 65548 | + int isDifferentRow, rc; |
| 65549 | + assert( p->pCursor!=0 ); |
| 65550 | + assert( sqlite3BtreeCursorHasMoved(p->pCursor) ); |
| 65551 | + rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); |
| 65552 | + p->cacheStatus = CACHE_STALE; |
| 65553 | + if( isDifferentRow ) p->nullRow = 1; |
| 65554 | + return rc; |
| 65555 | +} |
| 64929 | 65556 | |
| 64930 | 65557 | /* |
| 64931 | 65558 | ** Make sure the cursor p is ready to read or write the row to which it |
| 64932 | 65559 | ** was last positioned. Return an error code if an OOM fault or I/O error |
| 64933 | 65560 | ** prevents us from positioning the cursor to its correct position. |
| | @@ -64940,33 +65567,14 @@ |
| 64940 | 65567 | ** If the cursor is already pointing to the correct row and that row has |
| 64941 | 65568 | ** not been deleted out from under the cursor, then this routine is a no-op. |
| 64942 | 65569 | */ |
| 64943 | 65570 | SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ |
| 64944 | 65571 | if( p->deferredMoveto ){ |
| 64945 | | - int res, rc; |
| 64946 | | -#ifdef SQLITE_TEST |
| 64947 | | - extern int sqlite3_search_count; |
| 64948 | | -#endif |
| 64949 | | - assert( p->isTable ); |
| 64950 | | - rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); |
| 64951 | | - if( rc ) return rc; |
| 64952 | | - p->lastRowid = p->movetoTarget; |
| 64953 | | - if( res!=0 ) return SQLITE_CORRUPT_BKPT; |
| 64954 | | - p->rowidIsValid = 1; |
| 64955 | | -#ifdef SQLITE_TEST |
| 64956 | | - sqlite3_search_count++; |
| 64957 | | -#endif |
| 64958 | | - p->deferredMoveto = 0; |
| 64959 | | - p->cacheStatus = CACHE_STALE; |
| 64960 | | - }else if( p->pCursor ){ |
| 64961 | | - int hasMoved; |
| 64962 | | - int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); |
| 64963 | | - if( rc ) return rc; |
| 64964 | | - if( hasMoved ){ |
| 64965 | | - p->cacheStatus = CACHE_STALE; |
| 64966 | | - if( hasMoved==2 ) p->nullRow = 1; |
| 64967 | | - } |
| 65572 | + return handleDeferredMoveto(p); |
| 65573 | + } |
| 65574 | + if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ |
| 65575 | + return handleMovedCursor(p); |
| 64968 | 65576 | } |
| 64969 | 65577 | return SQLITE_OK; |
| 64970 | 65578 | } |
| 64971 | 65579 | |
| 64972 | 65580 | /* |
| | @@ -65145,14 +65753,15 @@ |
| 65145 | 65753 | swapMixedEndianFloat(v); |
| 65146 | 65754 | }else{ |
| 65147 | 65755 | v = pMem->u.i; |
| 65148 | 65756 | } |
| 65149 | 65757 | len = i = sqlite3VdbeSerialTypeLen(serial_type); |
| 65150 | | - while( i-- ){ |
| 65151 | | - buf[i] = (u8)(v&0xFF); |
| 65758 | + assert( i>0 ); |
| 65759 | + do{ |
| 65760 | + buf[--i] = (u8)(v&0xFF); |
| 65152 | 65761 | v >>= 8; |
| 65153 | | - } |
| 65762 | + }while( i ); |
| 65154 | 65763 | return len; |
| 65155 | 65764 | } |
| 65156 | 65765 | |
| 65157 | 65766 | /* String or blob */ |
| 65158 | 65767 | if( serial_type>=12 ){ |
| | @@ -65172,22 +65781,58 @@ |
| 65172 | 65781 | */ |
| 65173 | 65782 | #define ONE_BYTE_INT(x) ((i8)(x)[0]) |
| 65174 | 65783 | #define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) |
| 65175 | 65784 | #define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) |
| 65176 | 65785 | #define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) |
| 65786 | +#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) |
| 65177 | 65787 | |
| 65178 | 65788 | /* |
| 65179 | 65789 | ** Deserialize the data blob pointed to by buf as serial type serial_type |
| 65180 | 65790 | ** and store the result in pMem. Return the number of bytes read. |
| 65791 | +** |
| 65792 | +** This function is implemented as two separate routines for performance. |
| 65793 | +** The few cases that require local variables are broken out into a separate |
| 65794 | +** routine so that in most cases the overhead of moving the stack pointer |
| 65795 | +** is avoided. |
| 65181 | 65796 | */ |
| 65797 | +static u32 SQLITE_NOINLINE serialGet( |
| 65798 | + const unsigned char *buf, /* Buffer to deserialize from */ |
| 65799 | + u32 serial_type, /* Serial type to deserialize */ |
| 65800 | + Mem *pMem /* Memory cell to write value into */ |
| 65801 | +){ |
| 65802 | + u64 x = FOUR_BYTE_UINT(buf); |
| 65803 | + u32 y = FOUR_BYTE_UINT(buf+4); |
| 65804 | + x = (x<<32) + y; |
| 65805 | + if( serial_type==6 ){ |
| 65806 | + pMem->u.i = *(i64*)&x; |
| 65807 | + pMem->flags = MEM_Int; |
| 65808 | + testcase( pMem->u.i<0 ); |
| 65809 | + }else{ |
| 65810 | +#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) |
| 65811 | + /* Verify that integers and floating point values use the same |
| 65812 | + ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is |
| 65813 | + ** defined that 64-bit floating point values really are mixed |
| 65814 | + ** endian. |
| 65815 | + */ |
| 65816 | + static const u64 t1 = ((u64)0x3ff00000)<<32; |
| 65817 | + static const double r1 = 1.0; |
| 65818 | + u64 t2 = t1; |
| 65819 | + swapMixedEndianFloat(t2); |
| 65820 | + assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); |
| 65821 | +#endif |
| 65822 | + assert( sizeof(x)==8 && sizeof(pMem->r)==8 ); |
| 65823 | + swapMixedEndianFloat(x); |
| 65824 | + memcpy(&pMem->r, &x, sizeof(x)); |
| 65825 | + pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real; |
| 65826 | + } |
| 65827 | + return 8; |
| 65828 | +} |
| 65182 | 65829 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( |
| 65183 | 65830 | const unsigned char *buf, /* Buffer to deserialize from */ |
| 65184 | 65831 | u32 serial_type, /* Serial type to deserialize */ |
| 65185 | 65832 | Mem *pMem /* Memory cell to write value into */ |
| 65186 | 65833 | ){ |
| 65187 | | - u64 x; |
| 65188 | | - u32 y; |
| 65189 | 65834 | switch( serial_type ){ |
| 65190 | 65835 | case 10: /* Reserved for future use */ |
| 65191 | 65836 | case 11: /* Reserved for future use */ |
| 65192 | 65837 | case 0: { /* NULL */ |
| 65193 | 65838 | pMem->flags = MEM_Null; |
| | @@ -65210,12 +65855,11 @@ |
| 65210 | 65855 | pMem->flags = MEM_Int; |
| 65211 | 65856 | testcase( pMem->u.i<0 ); |
| 65212 | 65857 | return 3; |
| 65213 | 65858 | } |
| 65214 | 65859 | case 4: { /* 4-byte signed integer */ |
| 65215 | | - y = FOUR_BYTE_UINT(buf); |
| 65216 | | - pMem->u.i = (i64)*(int*)&y; |
| 65860 | + pMem->u.i = FOUR_BYTE_INT(buf); |
| 65217 | 65861 | pMem->flags = MEM_Int; |
| 65218 | 65862 | testcase( pMem->u.i<0 ); |
| 65219 | 65863 | return 4; |
| 65220 | 65864 | } |
| 65221 | 65865 | case 5: { /* 6-byte signed integer */ |
| | @@ -65224,56 +65868,31 @@ |
| 65224 | 65868 | testcase( pMem->u.i<0 ); |
| 65225 | 65869 | return 6; |
| 65226 | 65870 | } |
| 65227 | 65871 | case 6: /* 8-byte signed integer */ |
| 65228 | 65872 | case 7: { /* IEEE floating point */ |
| 65229 | | -#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) |
| 65230 | | - /* Verify that integers and floating point values use the same |
| 65231 | | - ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is |
| 65232 | | - ** defined that 64-bit floating point values really are mixed |
| 65233 | | - ** endian. |
| 65234 | | - */ |
| 65235 | | - static const u64 t1 = ((u64)0x3ff00000)<<32; |
| 65236 | | - static const double r1 = 1.0; |
| 65237 | | - u64 t2 = t1; |
| 65238 | | - swapMixedEndianFloat(t2); |
| 65239 | | - assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); |
| 65240 | | -#endif |
| 65241 | | - x = FOUR_BYTE_UINT(buf); |
| 65242 | | - y = FOUR_BYTE_UINT(buf+4); |
| 65243 | | - x = (x<<32) | y; |
| 65244 | | - if( serial_type==6 ){ |
| 65245 | | - pMem->u.i = *(i64*)&x; |
| 65246 | | - pMem->flags = MEM_Int; |
| 65247 | | - testcase( pMem->u.i<0 ); |
| 65248 | | - }else{ |
| 65249 | | - assert( sizeof(x)==8 && sizeof(pMem->r)==8 ); |
| 65250 | | - swapMixedEndianFloat(x); |
| 65251 | | - memcpy(&pMem->r, &x, sizeof(x)); |
| 65252 | | - pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real; |
| 65253 | | - } |
| 65254 | | - return 8; |
| 65873 | + /* These use local variables, so do them in a separate routine |
| 65874 | + ** to avoid having to move the frame pointer in the common case */ |
| 65875 | + return serialGet(buf,serial_type,pMem); |
| 65255 | 65876 | } |
| 65256 | 65877 | case 8: /* Integer 0 */ |
| 65257 | 65878 | case 9: { /* Integer 1 */ |
| 65258 | 65879 | pMem->u.i = serial_type-8; |
| 65259 | 65880 | pMem->flags = MEM_Int; |
| 65260 | 65881 | return 0; |
| 65261 | 65882 | } |
| 65262 | 65883 | default: { |
| 65263 | 65884 | static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; |
| 65264 | | - u32 len = (serial_type-12)/2; |
| 65265 | 65885 | pMem->z = (char *)buf; |
| 65266 | | - pMem->n = len; |
| 65886 | + pMem->n = (serial_type-12)/2; |
| 65267 | 65887 | pMem->xDel = 0; |
| 65268 | 65888 | pMem->flags = aFlag[serial_type&1]; |
| 65269 | | - return len; |
| 65889 | + return pMem->n; |
| 65270 | 65890 | } |
| 65271 | 65891 | } |
| 65272 | 65892 | return 0; |
| 65273 | 65893 | } |
| 65274 | | - |
| 65275 | 65894 | /* |
| 65276 | 65895 | ** This routine is used to allocate sufficient space for an UnpackedRecord |
| 65277 | 65896 | ** structure large enough to be used with sqlite3VdbeRecordUnpack() if |
| 65278 | 65897 | ** the first argument is a pointer to KeyInfo structure pKeyInfo. |
| 65279 | 65898 | ** |
| | @@ -65363,14 +65982,18 @@ |
| 65363 | 65982 | ** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), |
| 65364 | 65983 | ** this function deserializes and compares values using the |
| 65365 | 65984 | ** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used |
| 65366 | 65985 | ** in assert() statements to ensure that the optimized code in |
| 65367 | 65986 | ** sqlite3VdbeRecordCompare() returns results with these two primitives. |
| 65987 | +** |
| 65988 | +** Return true if the result of comparison is equivalent to desiredResult. |
| 65989 | +** Return false if there is a disagreement. |
| 65368 | 65990 | */ |
| 65369 | 65991 | static int vdbeRecordCompareDebug( |
| 65370 | 65992 | int nKey1, const void *pKey1, /* Left key */ |
| 65371 | | - const UnpackedRecord *pPKey2 /* Right key */ |
| 65993 | + const UnpackedRecord *pPKey2, /* Right key */ |
| 65994 | + int desiredResult /* Correct answer */ |
| 65372 | 65995 | ){ |
| 65373 | 65996 | u32 d1; /* Offset into aKey[] of next data element */ |
| 65374 | 65997 | u32 idx1; /* Offset into aKey[] of next header element */ |
| 65375 | 65998 | u32 szHdr1; /* Number of bytes in header */ |
| 65376 | 65999 | int i = 0; |
| | @@ -65378,10 +66001,11 @@ |
| 65378 | 66001 | const unsigned char *aKey1 = (const unsigned char *)pKey1; |
| 65379 | 66002 | KeyInfo *pKeyInfo; |
| 65380 | 66003 | Mem mem1; |
| 65381 | 66004 | |
| 65382 | 66005 | pKeyInfo = pPKey2->pKeyInfo; |
| 66006 | + if( pKeyInfo->db==0 ) return 1; |
| 65383 | 66007 | mem1.enc = pKeyInfo->enc; |
| 65384 | 66008 | mem1.db = pKeyInfo->db; |
| 65385 | 66009 | /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ |
| 65386 | 66010 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 65387 | 66011 | |
| | @@ -65428,11 +66052,11 @@ |
| 65428 | 66052 | if( rc!=0 ){ |
| 65429 | 66053 | assert( mem1.zMalloc==0 ); /* See comment below */ |
| 65430 | 66054 | if( pKeyInfo->aSortOrder[i] ){ |
| 65431 | 66055 | rc = -rc; /* Invert the result for DESC sort order. */ |
| 65432 | 66056 | } |
| 65433 | | - return rc; |
| 66057 | + goto debugCompareEnd; |
| 65434 | 66058 | } |
| 65435 | 66059 | i++; |
| 65436 | 66060 | }while( idx1<szHdr1 && i<pPKey2->nField ); |
| 65437 | 66061 | |
| 65438 | 66062 | /* No memory allocation is ever used on mem1. Prove this using |
| | @@ -65442,11 +66066,19 @@ |
| 65442 | 66066 | assert( mem1.zMalloc==0 ); |
| 65443 | 66067 | |
| 65444 | 66068 | /* rc==0 here means that one of the keys ran out of fields and |
| 65445 | 66069 | ** all the fields up to that point were equal. Return the the default_rc |
| 65446 | 66070 | ** value. */ |
| 65447 | | - return pPKey2->default_rc; |
| 66071 | + rc = pPKey2->default_rc; |
| 66072 | + |
| 66073 | +debugCompareEnd: |
| 66074 | + if( desiredResult==0 && rc==0 ) return 1; |
| 66075 | + if( desiredResult<0 && rc<0 ) return 1; |
| 66076 | + if( desiredResult>0 && rc>0 ) return 1; |
| 66077 | + if( CORRUPT_DB ) return 1; |
| 66078 | + if( pKeyInfo->db->mallocFailed ) return 1; |
| 66079 | + return 0; |
| 65448 | 66080 | } |
| 65449 | 66081 | #endif |
| 65450 | 66082 | |
| 65451 | 66083 | /* |
| 65452 | 66084 | ** Both *pMem1 and *pMem2 contain string values. Compare the two values |
| | @@ -65455,11 +66087,12 @@ |
| 65455 | 66087 | ** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". |
| 65456 | 66088 | */ |
| 65457 | 66089 | static int vdbeCompareMemString( |
| 65458 | 66090 | const Mem *pMem1, |
| 65459 | 66091 | const Mem *pMem2, |
| 65460 | | - const CollSeq *pColl |
| 66092 | + const CollSeq *pColl, |
| 66093 | + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ |
| 65461 | 66094 | ){ |
| 65462 | 66095 | if( pMem1->enc==pColl->enc ){ |
| 65463 | 66096 | /* The strings are already in the correct encoding. Call the |
| 65464 | 66097 | ** comparison function directly */ |
| 65465 | 66098 | return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); |
| | @@ -65478,10 +66111,11 @@ |
| 65478 | 66111 | v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); |
| 65479 | 66112 | n2 = v2==0 ? 0 : c2.n; |
| 65480 | 66113 | rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); |
| 65481 | 66114 | sqlite3VdbeMemRelease(&c1); |
| 65482 | 66115 | sqlite3VdbeMemRelease(&c2); |
| 66116 | + if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM; |
| 65483 | 66117 | return rc; |
| 65484 | 66118 | } |
| 65485 | 66119 | } |
| 65486 | 66120 | |
| 65487 | 66121 | /* |
| | @@ -65560,11 +66194,11 @@ |
| 65560 | 66194 | ** compiled (this was not always the case). |
| 65561 | 66195 | */ |
| 65562 | 66196 | assert( !pColl || pColl->xCmp ); |
| 65563 | 66197 | |
| 65564 | 66198 | if( pColl ){ |
| 65565 | | - return vdbeCompareMemString(pMem1, pMem2, pColl); |
| 66199 | + return vdbeCompareMemString(pMem1, pMem2, pColl, 0); |
| 65566 | 66200 | } |
| 65567 | 66201 | /* If a NULL pointer was passed as the collate function, fall through |
| 65568 | 66202 | ** to the blob case and use memcmp(). */ |
| 65569 | 66203 | } |
| 65570 | 66204 | |
| | @@ -65632,12 +66266,14 @@ |
| 65632 | 66266 | ** |
| 65633 | 66267 | ** Key1 and Key2 do not have to contain the same number of fields. If all |
| 65634 | 66268 | ** fields that appear in both keys are equal, then pPKey2->default_rc is |
| 65635 | 66269 | ** returned. |
| 65636 | 66270 | ** |
| 65637 | | -** If database corruption is discovered, set pPKey2->isCorrupt to non-zero |
| 65638 | | -** and return 0. |
| 66271 | +** If database corruption is discovered, set pPKey2->errCode to |
| 66272 | +** SQLITE_CORRUPT and return 0. If an OOM error is encountered, |
| 66273 | +** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the |
| 66274 | +** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). |
| 65639 | 66275 | */ |
| 65640 | 66276 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare( |
| 65641 | 66277 | int nKey1, const void *pKey1, /* Left key */ |
| 65642 | 66278 | UnpackedRecord *pPKey2, /* Right key */ |
| 65643 | 66279 | int bSkip /* If true, skip the first field */ |
| | @@ -65664,11 +66300,11 @@ |
| 65664 | 66300 | pRhs++; |
| 65665 | 66301 | }else{ |
| 65666 | 66302 | idx1 = getVarint32(aKey1, szHdr1); |
| 65667 | 66303 | d1 = szHdr1; |
| 65668 | 66304 | if( d1>(unsigned)nKey1 ){ |
| 65669 | | - pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 66305 | + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; |
| 65670 | 66306 | return 0; /* Corruption */ |
| 65671 | 66307 | } |
| 65672 | 66308 | i = 0; |
| 65673 | 66309 | } |
| 65674 | 66310 | |
| | @@ -65743,18 +66379,20 @@ |
| 65743 | 66379 | }else{ |
| 65744 | 66380 | mem1.n = (serial_type - 12) / 2; |
| 65745 | 66381 | testcase( (d1+mem1.n)==(unsigned)nKey1 ); |
| 65746 | 66382 | testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); |
| 65747 | 66383 | if( (d1+mem1.n) > (unsigned)nKey1 ){ |
| 65748 | | - pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 66384 | + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; |
| 65749 | 66385 | return 0; /* Corruption */ |
| 65750 | 66386 | }else if( pKeyInfo->aColl[i] ){ |
| 65751 | 66387 | mem1.enc = pKeyInfo->enc; |
| 65752 | 66388 | mem1.db = pKeyInfo->db; |
| 65753 | 66389 | mem1.flags = MEM_Str; |
| 65754 | 66390 | mem1.z = (char*)&aKey1[d1]; |
| 65755 | | - rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]); |
| 66391 | + rc = vdbeCompareMemString( |
| 66392 | + &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode |
| 66393 | + ); |
| 65756 | 66394 | }else{ |
| 65757 | 66395 | int nCmp = MIN(mem1.n, pRhs->n); |
| 65758 | 66396 | rc = memcmp(&aKey1[d1], pRhs->z, nCmp); |
| 65759 | 66397 | if( rc==0 ) rc = mem1.n - pRhs->n; |
| 65760 | 66398 | } |
| | @@ -65770,11 +66408,11 @@ |
| 65770 | 66408 | }else{ |
| 65771 | 66409 | int nStr = (serial_type - 12) / 2; |
| 65772 | 66410 | testcase( (d1+nStr)==(unsigned)nKey1 ); |
| 65773 | 66411 | testcase( (d1+nStr+1)==(unsigned)nKey1 ); |
| 65774 | 66412 | if( (d1+nStr) > (unsigned)nKey1 ){ |
| 65775 | | - pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 66413 | + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; |
| 65776 | 66414 | return 0; /* Corruption */ |
| 65777 | 66415 | }else{ |
| 65778 | 66416 | int nCmp = MIN(nStr, pRhs->n); |
| 65779 | 66417 | rc = memcmp(&aKey1[d1], pRhs->z, nCmp); |
| 65780 | 66418 | if( rc==0 ) rc = nStr - pRhs->n; |
| | @@ -65790,15 +66428,11 @@ |
| 65790 | 66428 | |
| 65791 | 66429 | if( rc!=0 ){ |
| 65792 | 66430 | if( pKeyInfo->aSortOrder[i] ){ |
| 65793 | 66431 | rc = -rc; |
| 65794 | 66432 | } |
| 65795 | | - assert( CORRUPT_DB |
| 65796 | | - || (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0) |
| 65797 | | - || (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0) |
| 65798 | | - || pKeyInfo->db->mallocFailed |
| 65799 | | - ); |
| 66433 | + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); |
| 65800 | 66434 | assert( mem1.zMalloc==0 ); /* See comment below */ |
| 65801 | 66435 | return rc; |
| 65802 | 66436 | } |
| 65803 | 66437 | |
| 65804 | 66438 | i++; |
| | @@ -65814,11 +66448,11 @@ |
| 65814 | 66448 | |
| 65815 | 66449 | /* rc==0 here means that one or both of the keys ran out of fields and |
| 65816 | 66450 | ** all the fields up to that point were equal. Return the the default_rc |
| 65817 | 66451 | ** value. */ |
| 65818 | 66452 | assert( CORRUPT_DB |
| 65819 | | - || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2) |
| 66453 | + || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) |
| 65820 | 66454 | || pKeyInfo->db->mallocFailed |
| 65821 | 66455 | ); |
| 65822 | 66456 | return pPKey2->default_rc; |
| 65823 | 66457 | } |
| 65824 | 66458 | |
| | @@ -65913,15 +66547,11 @@ |
| 65913 | 66547 | /* The first fields of the two keys are equal and there are no trailing |
| 65914 | 66548 | ** fields. Return pPKey2->default_rc in this case. */ |
| 65915 | 66549 | res = pPKey2->default_rc; |
| 65916 | 66550 | } |
| 65917 | 66551 | |
| 65918 | | - assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0) |
| 65919 | | - || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0) |
| 65920 | | - || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0) |
| 65921 | | - || CORRUPT_DB |
| 65922 | | - ); |
| 66552 | + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) ); |
| 65923 | 66553 | return res; |
| 65924 | 66554 | } |
| 65925 | 66555 | |
| 65926 | 66556 | /* |
| 65927 | 66557 | ** This function is an optimized version of sqlite3VdbeRecordCompare() |
| | @@ -65951,11 +66581,11 @@ |
| 65951 | 66581 | int nStr; |
| 65952 | 66582 | int szHdr = aKey1[0]; |
| 65953 | 66583 | |
| 65954 | 66584 | nStr = (serial_type-12) / 2; |
| 65955 | 66585 | if( (szHdr + nStr) > nKey1 ){ |
| 65956 | | - pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 66586 | + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; |
| 65957 | 66587 | return 0; /* Corruption */ |
| 65958 | 66588 | } |
| 65959 | 66589 | nCmp = MIN( pPKey2->aMem[0].n, nStr ); |
| 65960 | 66590 | res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); |
| 65961 | 66591 | |
| | @@ -65977,13 +66607,11 @@ |
| 65977 | 66607 | }else{ |
| 65978 | 66608 | res = pPKey2->r1; |
| 65979 | 66609 | } |
| 65980 | 66610 | } |
| 65981 | 66611 | |
| 65982 | | - assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0) |
| 65983 | | - || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0) |
| 65984 | | - || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0) |
| 66612 | + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) |
| 65985 | 66613 | || CORRUPT_DB |
| 65986 | 66614 | || pPKey2->pKeyInfo->db->mallocFailed |
| 65987 | 66615 | ); |
| 65988 | 66616 | return res; |
| 65989 | 66617 | } |
| | @@ -66466,11 +67094,11 @@ |
| 66466 | 67094 | const char *z, /* String pointer */ |
| 66467 | 67095 | int n, /* Bytes in string, or negative */ |
| 66468 | 67096 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
| 66469 | 67097 | void (*xDel)(void*) /* Destructor function */ |
| 66470 | 67098 | ){ |
| 66471 | | - if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){ |
| 67099 | + if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ |
| 66472 | 67100 | sqlite3_result_error_toobig(pCtx); |
| 66473 | 67101 | } |
| 66474 | 67102 | } |
| 66475 | 67103 | SQLITE_API void sqlite3_result_blob( |
| 66476 | 67104 | sqlite3_context *pCtx, |
| | @@ -66477,114 +67105,114 @@ |
| 66477 | 67105 | const void *z, |
| 66478 | 67106 | int n, |
| 66479 | 67107 | void (*xDel)(void *) |
| 66480 | 67108 | ){ |
| 66481 | 67109 | assert( n>=0 ); |
| 66482 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67110 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66483 | 67111 | setResultStrOrError(pCtx, z, n, 0, xDel); |
| 66484 | 67112 | } |
| 66485 | 67113 | SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ |
| 66486 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66487 | | - sqlite3VdbeMemSetDouble(&pCtx->s, rVal); |
| 67114 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67115 | + sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); |
| 66488 | 67116 | } |
| 66489 | 67117 | SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ |
| 66490 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67118 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66491 | 67119 | pCtx->isError = SQLITE_ERROR; |
| 66492 | 67120 | pCtx->fErrorOrAux = 1; |
| 66493 | | - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); |
| 67121 | + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); |
| 66494 | 67122 | } |
| 66495 | 67123 | #ifndef SQLITE_OMIT_UTF16 |
| 66496 | 67124 | SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ |
| 66497 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67125 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66498 | 67126 | pCtx->isError = SQLITE_ERROR; |
| 66499 | 67127 | pCtx->fErrorOrAux = 1; |
| 66500 | | - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); |
| 67128 | + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); |
| 66501 | 67129 | } |
| 66502 | 67130 | #endif |
| 66503 | 67131 | SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ |
| 66504 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66505 | | - sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal); |
| 67132 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67133 | + sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); |
| 66506 | 67134 | } |
| 66507 | 67135 | SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ |
| 66508 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66509 | | - sqlite3VdbeMemSetInt64(&pCtx->s, iVal); |
| 67136 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67137 | + sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); |
| 66510 | 67138 | } |
| 66511 | 67139 | SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ |
| 66512 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66513 | | - sqlite3VdbeMemSetNull(&pCtx->s); |
| 67140 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67141 | + sqlite3VdbeMemSetNull(pCtx->pOut); |
| 66514 | 67142 | } |
| 66515 | 67143 | SQLITE_API void sqlite3_result_text( |
| 66516 | 67144 | sqlite3_context *pCtx, |
| 66517 | 67145 | const char *z, |
| 66518 | 67146 | int n, |
| 66519 | 67147 | void (*xDel)(void *) |
| 66520 | 67148 | ){ |
| 66521 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67149 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66522 | 67150 | setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); |
| 66523 | 67151 | } |
| 66524 | 67152 | #ifndef SQLITE_OMIT_UTF16 |
| 66525 | 67153 | SQLITE_API void sqlite3_result_text16( |
| 66526 | 67154 | sqlite3_context *pCtx, |
| 66527 | 67155 | const void *z, |
| 66528 | 67156 | int n, |
| 66529 | 67157 | void (*xDel)(void *) |
| 66530 | 67158 | ){ |
| 66531 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67159 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66532 | 67160 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); |
| 66533 | 67161 | } |
| 66534 | 67162 | SQLITE_API void sqlite3_result_text16be( |
| 66535 | 67163 | sqlite3_context *pCtx, |
| 66536 | 67164 | const void *z, |
| 66537 | 67165 | int n, |
| 66538 | 67166 | void (*xDel)(void *) |
| 66539 | 67167 | ){ |
| 66540 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67168 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66541 | 67169 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); |
| 66542 | 67170 | } |
| 66543 | 67171 | SQLITE_API void sqlite3_result_text16le( |
| 66544 | 67172 | sqlite3_context *pCtx, |
| 66545 | 67173 | const void *z, |
| 66546 | 67174 | int n, |
| 66547 | 67175 | void (*xDel)(void *) |
| 66548 | 67176 | ){ |
| 66549 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67177 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66550 | 67178 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); |
| 66551 | 67179 | } |
| 66552 | 67180 | #endif /* SQLITE_OMIT_UTF16 */ |
| 66553 | 67181 | SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ |
| 66554 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66555 | | - sqlite3VdbeMemCopy(&pCtx->s, pValue); |
| 67182 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67183 | + sqlite3VdbeMemCopy(pCtx->pOut, pValue); |
| 66556 | 67184 | } |
| 66557 | 67185 | SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ |
| 66558 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66559 | | - sqlite3VdbeMemSetZeroBlob(&pCtx->s, n); |
| 67186 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67187 | + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); |
| 66560 | 67188 | } |
| 66561 | 67189 | SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ |
| 66562 | 67190 | pCtx->isError = errCode; |
| 66563 | 67191 | pCtx->fErrorOrAux = 1; |
| 66564 | | - if( pCtx->s.flags & MEM_Null ){ |
| 66565 | | - sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, |
| 67192 | + if( pCtx->pOut->flags & MEM_Null ){ |
| 67193 | + sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, |
| 66566 | 67194 | SQLITE_UTF8, SQLITE_STATIC); |
| 66567 | 67195 | } |
| 66568 | 67196 | } |
| 66569 | 67197 | |
| 66570 | 67198 | /* Force an SQLITE_TOOBIG error. */ |
| 66571 | 67199 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ |
| 66572 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67200 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66573 | 67201 | pCtx->isError = SQLITE_TOOBIG; |
| 66574 | 67202 | pCtx->fErrorOrAux = 1; |
| 66575 | | - sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, |
| 67203 | + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, |
| 66576 | 67204 | SQLITE_UTF8, SQLITE_STATIC); |
| 66577 | 67205 | } |
| 66578 | 67206 | |
| 66579 | 67207 | /* An SQLITE_NOMEM error. */ |
| 66580 | 67208 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ |
| 66581 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 66582 | | - sqlite3VdbeMemSetNull(&pCtx->s); |
| 67209 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 67210 | + sqlite3VdbeMemSetNull(pCtx->pOut); |
| 66583 | 67211 | pCtx->isError = SQLITE_NOMEM; |
| 66584 | 67212 | pCtx->fErrorOrAux = 1; |
| 66585 | | - pCtx->s.db->mallocFailed = 1; |
| 67213 | + pCtx->pOut->db->mallocFailed = 1; |
| 66586 | 67214 | } |
| 66587 | 67215 | |
| 66588 | 67216 | /* |
| 66589 | 67217 | ** This function is called after a transaction has been committed. It |
| 66590 | 67218 | ** invokes callbacks registered with sqlite3_wal_hook() as required. |
| | @@ -66756,14 +67384,16 @@ |
| 66756 | 67384 | } |
| 66757 | 67385 | db = v->db; |
| 66758 | 67386 | sqlite3_mutex_enter(db->mutex); |
| 66759 | 67387 | v->doingRerun = 0; |
| 66760 | 67388 | while( (rc = sqlite3Step(v))==SQLITE_SCHEMA |
| 66761 | | - && cnt++ < SQLITE_MAX_SCHEMA_RETRY |
| 66762 | | - && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ |
| 67389 | + && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ |
| 67390 | + int savedPc = v->pc; |
| 67391 | + rc2 = rc = sqlite3Reprepare(v); |
| 67392 | + if( rc!=SQLITE_OK) break; |
| 66763 | 67393 | sqlite3_reset(pStmt); |
| 66764 | | - v->doingRerun = 1; |
| 67394 | + if( savedPc>=0 ) v->doingRerun = 1; |
| 66765 | 67395 | assert( v->expired==0 ); |
| 66766 | 67396 | } |
| 66767 | 67397 | if( rc2!=SQLITE_OK ){ |
| 66768 | 67398 | /* This case occurs after failing to recompile an sql statement. |
| 66769 | 67399 | ** The error message from the SQL compiler has already been loaded |
| | @@ -66809,21 +67439,21 @@ |
| 66809 | 67439 | ** sqlite3_create_function16() routines that originally registered the |
| 66810 | 67440 | ** application defined function. |
| 66811 | 67441 | */ |
| 66812 | 67442 | SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ |
| 66813 | 67443 | assert( p && p->pFunc ); |
| 66814 | | - return p->s.db; |
| 67444 | + return p->pOut->db; |
| 66815 | 67445 | } |
| 66816 | 67446 | |
| 66817 | 67447 | /* |
| 66818 | 67448 | ** Return the current time for a statement |
| 66819 | 67449 | */ |
| 66820 | 67450 | SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ |
| 66821 | 67451 | Vdbe *v = p->pVdbe; |
| 66822 | 67452 | int rc; |
| 66823 | 67453 | if( v->iCurrentTime==0 ){ |
| 66824 | | - rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime); |
| 67454 | + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime); |
| 66825 | 67455 | if( rc ) v->iCurrentTime = 0; |
| 66826 | 67456 | } |
| 66827 | 67457 | return v->iCurrentTime; |
| 66828 | 67458 | } |
| 66829 | 67459 | |
| | @@ -66846,47 +67476,57 @@ |
| 66846 | 67476 | zErr = sqlite3_mprintf( |
| 66847 | 67477 | "unable to use function %s in the requested context", zName); |
| 66848 | 67478 | sqlite3_result_error(context, zErr, -1); |
| 66849 | 67479 | sqlite3_free(zErr); |
| 66850 | 67480 | } |
| 67481 | + |
| 67482 | +/* |
| 67483 | +** Create a new aggregate context for p and return a pointer to |
| 67484 | +** its pMem->z element. |
| 67485 | +*/ |
| 67486 | +static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ |
| 67487 | + Mem *pMem = p->pMem; |
| 67488 | + assert( (pMem->flags & MEM_Agg)==0 ); |
| 67489 | + if( nByte<=0 ){ |
| 67490 | + sqlite3VdbeMemReleaseExternal(pMem); |
| 67491 | + pMem->flags = MEM_Null; |
| 67492 | + pMem->z = 0; |
| 67493 | + }else{ |
| 67494 | + sqlite3VdbeMemGrow(pMem, nByte, 0); |
| 67495 | + pMem->flags = MEM_Agg; |
| 67496 | + pMem->u.pDef = p->pFunc; |
| 67497 | + if( pMem->z ){ |
| 67498 | + memset(pMem->z, 0, nByte); |
| 67499 | + } |
| 67500 | + } |
| 67501 | + return (void*)pMem->z; |
| 67502 | +} |
| 66851 | 67503 | |
| 66852 | 67504 | /* |
| 66853 | 67505 | ** Allocate or return the aggregate context for a user function. A new |
| 66854 | 67506 | ** context is allocated on the first call. Subsequent calls return the |
| 66855 | 67507 | ** same context that was returned on prior calls. |
| 66856 | 67508 | */ |
| 66857 | 67509 | SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ |
| 66858 | | - Mem *pMem; |
| 66859 | 67510 | assert( p && p->pFunc && p->pFunc->xStep ); |
| 66860 | | - assert( sqlite3_mutex_held(p->s.db->mutex) ); |
| 66861 | | - pMem = p->pMem; |
| 67511 | + assert( sqlite3_mutex_held(p->pOut->db->mutex) ); |
| 66862 | 67512 | testcase( nByte<0 ); |
| 66863 | | - if( (pMem->flags & MEM_Agg)==0 ){ |
| 66864 | | - if( nByte<=0 ){ |
| 66865 | | - sqlite3VdbeMemReleaseExternal(pMem); |
| 66866 | | - pMem->flags = MEM_Null; |
| 66867 | | - pMem->z = 0; |
| 66868 | | - }else{ |
| 66869 | | - sqlite3VdbeMemGrow(pMem, nByte, 0); |
| 66870 | | - pMem->flags = MEM_Agg; |
| 66871 | | - pMem->u.pDef = p->pFunc; |
| 66872 | | - if( pMem->z ){ |
| 66873 | | - memset(pMem->z, 0, nByte); |
| 66874 | | - } |
| 66875 | | - } |
| 66876 | | - } |
| 66877 | | - return (void*)pMem->z; |
| 67513 | + if( (p->pMem->flags & MEM_Agg)==0 ){ |
| 67514 | + return createAggContext(p, nByte); |
| 67515 | + }else{ |
| 67516 | + return (void*)p->pMem->z; |
| 67517 | + } |
| 66878 | 67518 | } |
| 66879 | 67519 | |
| 66880 | 67520 | /* |
| 66881 | 67521 | ** Return the auxilary data pointer, if any, for the iArg'th argument to |
| 66882 | 67522 | ** the user-function defined by pCtx. |
| 66883 | 67523 | */ |
| 66884 | 67524 | SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ |
| 66885 | 67525 | AuxData *pAuxData; |
| 66886 | 67526 | |
| 66887 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67527 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66888 | 67528 | for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ |
| 66889 | 67529 | if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; |
| 66890 | 67530 | } |
| 66891 | 67531 | |
| 66892 | 67532 | return (pAuxData ? pAuxData->pAux : 0); |
| | @@ -66904,11 +67544,11 @@ |
| 66904 | 67544 | void (*xDelete)(void*) |
| 66905 | 67545 | ){ |
| 66906 | 67546 | AuxData *pAuxData; |
| 66907 | 67547 | Vdbe *pVdbe = pCtx->pVdbe; |
| 66908 | 67548 | |
| 66909 | | - assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 67549 | + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 66910 | 67550 | if( iArg<0 ) goto failed; |
| 66911 | 67551 | |
| 66912 | 67552 | for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ |
| 66913 | 67553 | if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; |
| 66914 | 67554 | } |
| | @@ -67011,11 +67651,11 @@ |
| 67011 | 67651 | sqlite3_mutex_enter(pVm->db->mutex); |
| 67012 | 67652 | pOut = &pVm->pResultSet[i]; |
| 67013 | 67653 | }else{ |
| 67014 | 67654 | if( pVm && ALWAYS(pVm->db) ){ |
| 67015 | 67655 | sqlite3_mutex_enter(pVm->db->mutex); |
| 67016 | | - sqlite3Error(pVm->db, SQLITE_RANGE, 0); |
| 67656 | + sqlite3Error(pVm->db, SQLITE_RANGE); |
| 67017 | 67657 | } |
| 67018 | 67658 | pOut = (Mem*)columnNullValue(); |
| 67019 | 67659 | } |
| 67020 | 67660 | return pOut; |
| 67021 | 67661 | } |
| | @@ -67276,26 +67916,26 @@ |
| 67276 | 67916 | if( vdbeSafetyNotNull(p) ){ |
| 67277 | 67917 | return SQLITE_MISUSE_BKPT; |
| 67278 | 67918 | } |
| 67279 | 67919 | sqlite3_mutex_enter(p->db->mutex); |
| 67280 | 67920 | if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ |
| 67281 | | - sqlite3Error(p->db, SQLITE_MISUSE, 0); |
| 67921 | + sqlite3Error(p->db, SQLITE_MISUSE); |
| 67282 | 67922 | sqlite3_mutex_leave(p->db->mutex); |
| 67283 | 67923 | sqlite3_log(SQLITE_MISUSE, |
| 67284 | 67924 | "bind on a busy prepared statement: [%s]", p->zSql); |
| 67285 | 67925 | return SQLITE_MISUSE_BKPT; |
| 67286 | 67926 | } |
| 67287 | 67927 | if( i<1 || i>p->nVar ){ |
| 67288 | | - sqlite3Error(p->db, SQLITE_RANGE, 0); |
| 67928 | + sqlite3Error(p->db, SQLITE_RANGE); |
| 67289 | 67929 | sqlite3_mutex_leave(p->db->mutex); |
| 67290 | 67930 | return SQLITE_RANGE; |
| 67291 | 67931 | } |
| 67292 | 67932 | i--; |
| 67293 | 67933 | pVar = &p->aVar[i]; |
| 67294 | 67934 | sqlite3VdbeMemRelease(pVar); |
| 67295 | 67935 | pVar->flags = MEM_Null; |
| 67296 | | - sqlite3Error(p->db, SQLITE_OK, 0); |
| 67936 | + sqlite3Error(p->db, SQLITE_OK); |
| 67297 | 67937 | |
| 67298 | 67938 | /* If the bit corresponding to this variable in Vdbe.expmask is set, then |
| 67299 | 67939 | ** binding a new value to this variable invalidates the current query plan. |
| 67300 | 67940 | ** |
| 67301 | 67941 | ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host |
| | @@ -67333,11 +67973,11 @@ |
| 67333 | 67973 | pVar = &p->aVar[i-1]; |
| 67334 | 67974 | rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); |
| 67335 | 67975 | if( rc==SQLITE_OK && encoding!=0 ){ |
| 67336 | 67976 | rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); |
| 67337 | 67977 | } |
| 67338 | | - sqlite3Error(p->db, rc, 0); |
| 67978 | + sqlite3Error(p->db, rc); |
| 67339 | 67979 | rc = sqlite3ApiExit(p->db, rc); |
| 67340 | 67980 | } |
| 67341 | 67981 | sqlite3_mutex_leave(p->db->mutex); |
| 67342 | 67982 | }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ |
| 67343 | 67983 | xDel((void*)zData); |
| | @@ -68046,11 +68686,11 @@ |
| 68046 | 68686 | /* |
| 68047 | 68687 | ** Convert the given register into a string if it isn't one |
| 68048 | 68688 | ** already. Return non-zero if a malloc() fails. |
| 68049 | 68689 | */ |
| 68050 | 68690 | #define Stringify(P, enc) \ |
| 68051 | | - if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ |
| 68691 | + if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \ |
| 68052 | 68692 | { goto no_mem; } |
| 68053 | 68693 | |
| 68054 | 68694 | /* |
| 68055 | 68695 | ** An ephemeral string value (signified by the MEM_Ephem flag) contains |
| 68056 | 68696 | ** a pointer to a dynamically allocated string where some other entity |
| | @@ -68128,12 +68768,21 @@ |
| 68128 | 68768 | /* |
| 68129 | 68769 | ** Try to convert a value into a numeric representation if we can |
| 68130 | 68770 | ** do so without loss of information. In other words, if the string |
| 68131 | 68771 | ** looks like a number, convert it into a number. If it does not |
| 68132 | 68772 | ** look like a number, leave it alone. |
| 68773 | +** |
| 68774 | +** If the bTryForInt flag is true, then extra effort is made to give |
| 68775 | +** an integer representation. Strings that look like floating point |
| 68776 | +** values but which have no fractional component (example: '48.00') |
| 68777 | +** will have a MEM_Int representation when bTryForInt is true. |
| 68778 | +** |
| 68779 | +** If bTryForInt is false, then if the input string contains a decimal |
| 68780 | +** point or exponential notation, the result is only MEM_Real, even |
| 68781 | +** if there is an exact integer representation of the quantity. |
| 68133 | 68782 | */ |
| 68134 | | -static void applyNumericAffinity(Mem *pRec){ |
| 68783 | +static void applyNumericAffinity(Mem *pRec, int bTryForInt){ |
| 68135 | 68784 | double rValue; |
| 68136 | 68785 | i64 iValue; |
| 68137 | 68786 | u8 enc = pRec->enc; |
| 68138 | 68787 | if( (pRec->flags&MEM_Str)==0 ) return; |
| 68139 | 68788 | if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; |
| | @@ -68141,14 +68790,13 @@ |
| 68141 | 68790 | pRec->u.i = iValue; |
| 68142 | 68791 | pRec->flags |= MEM_Int; |
| 68143 | 68792 | }else{ |
| 68144 | 68793 | pRec->r = rValue; |
| 68145 | 68794 | pRec->flags |= MEM_Real; |
| 68795 | + if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); |
| 68146 | 68796 | } |
| 68147 | 68797 | } |
| 68148 | | -#define ApplyNumericAffinity(X) \ |
| 68149 | | - if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} |
| 68150 | 68798 | |
| 68151 | 68799 | /* |
| 68152 | 68800 | ** Processing is determine by the affinity parameter: |
| 68153 | 68801 | ** |
| 68154 | 68802 | ** SQLITE_AFF_INTEGER: |
| | @@ -68175,19 +68823,21 @@ |
| 68175 | 68823 | /* Only attempt the conversion to TEXT if there is an integer or real |
| 68176 | 68824 | ** representation (blob and NULL do not get converted) but no string |
| 68177 | 68825 | ** representation. |
| 68178 | 68826 | */ |
| 68179 | 68827 | if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ |
| 68180 | | - sqlite3VdbeMemStringify(pRec, enc); |
| 68828 | + sqlite3VdbeMemStringify(pRec, enc, 1); |
| 68181 | 68829 | } |
| 68182 | | - pRec->flags &= ~(MEM_Real|MEM_Int); |
| 68183 | 68830 | }else if( affinity!=SQLITE_AFF_NONE ){ |
| 68184 | 68831 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 68185 | 68832 | || affinity==SQLITE_AFF_NUMERIC ); |
| 68186 | | - ApplyNumericAffinity(pRec); |
| 68187 | | - if( pRec->flags & MEM_Real ){ |
| 68188 | | - sqlite3VdbeIntegerAffinity(pRec); |
| 68833 | + if( (pRec->flags & MEM_Int)==0 ){ |
| 68834 | + if( (pRec->flags & MEM_Real)==0 ){ |
| 68835 | + applyNumericAffinity(pRec,1); |
| 68836 | + }else{ |
| 68837 | + sqlite3VdbeIntegerAffinity(pRec); |
| 68838 | + } |
| 68189 | 68839 | } |
| 68190 | 68840 | } |
| 68191 | 68841 | } |
| 68192 | 68842 | |
| 68193 | 68843 | /* |
| | @@ -68198,11 +68848,11 @@ |
| 68198 | 68848 | */ |
| 68199 | 68849 | SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ |
| 68200 | 68850 | int eType = sqlite3_value_type(pVal); |
| 68201 | 68851 | if( eType==SQLITE_TEXT ){ |
| 68202 | 68852 | Mem *pMem = (Mem*)pVal; |
| 68203 | | - applyNumericAffinity(pMem); |
| 68853 | + applyNumericAffinity(pMem, 0); |
| 68204 | 68854 | eType = sqlite3_value_type(pVal); |
| 68205 | 68855 | } |
| 68206 | 68856 | return eType; |
| 68207 | 68857 | } |
| 68208 | 68858 | |
| | @@ -68215,10 +68865,28 @@ |
| 68215 | 68865 | u8 affinity, |
| 68216 | 68866 | u8 enc |
| 68217 | 68867 | ){ |
| 68218 | 68868 | applyAffinity((Mem *)pVal, affinity, enc); |
| 68219 | 68869 | } |
| 68870 | + |
| 68871 | +/* |
| 68872 | +** pMem currently only holds a string type (or maybe a BLOB that we can |
| 68873 | +** interpret as a string if we want to). Compute its corresponding |
| 68874 | +** numeric type, if has one. Set the pMem->r and pMem->u.i fields |
| 68875 | +** accordingly. |
| 68876 | +*/ |
| 68877 | +static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ |
| 68878 | + assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); |
| 68879 | + assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); |
| 68880 | + if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){ |
| 68881 | + return 0; |
| 68882 | + } |
| 68883 | + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ |
| 68884 | + return MEM_Int; |
| 68885 | + } |
| 68886 | + return MEM_Real; |
| 68887 | +} |
| 68220 | 68888 | |
| 68221 | 68889 | /* |
| 68222 | 68890 | ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or |
| 68223 | 68891 | ** none. |
| 68224 | 68892 | ** |
| | @@ -68228,17 +68896,11 @@ |
| 68228 | 68896 | static u16 numericType(Mem *pMem){ |
| 68229 | 68897 | if( pMem->flags & (MEM_Int|MEM_Real) ){ |
| 68230 | 68898 | return pMem->flags & (MEM_Int|MEM_Real); |
| 68231 | 68899 | } |
| 68232 | 68900 | if( pMem->flags & (MEM_Str|MEM_Blob) ){ |
| 68233 | | - if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){ |
| 68234 | | - return 0; |
| 68235 | | - } |
| 68236 | | - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ |
| 68237 | | - return MEM_Int; |
| 68238 | | - } |
| 68239 | | - return MEM_Real; |
| 68901 | + return computeNumericType(pMem); |
| 68240 | 68902 | } |
| 68241 | 68903 | return 0; |
| 68242 | 68904 | } |
| 68243 | 68905 | |
| 68244 | 68906 | #ifdef SQLITE_DEBUG |
| | @@ -68607,11 +69269,11 @@ |
| 68607 | 69269 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 68608 | 69270 | assert( pOp->p2>0 ); |
| 68609 | 69271 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 68610 | 69272 | pOut = &aMem[pOp->p2]; |
| 68611 | 69273 | memAboutToChange(p, pOut); |
| 68612 | | - VdbeMemRelease(pOut); |
| 69274 | + VdbeMemReleaseExtern(pOut); |
| 68613 | 69275 | pOut->flags = MEM_Int; |
| 68614 | 69276 | } |
| 68615 | 69277 | |
| 68616 | 69278 | /* Sanity checking on other operands */ |
| 68617 | 69279 | #ifdef SQLITE_DEBUG |
| | @@ -69046,11 +69708,11 @@ |
| 69046 | 69708 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 69047 | 69709 | pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 69048 | 69710 | while( cnt>0 ){ |
| 69049 | 69711 | pOut++; |
| 69050 | 69712 | memAboutToChange(p, pOut); |
| 69051 | | - VdbeMemRelease(pOut); |
| 69713 | + VdbeMemReleaseExtern(pOut); |
| 69052 | 69714 | pOut->flags = nullFlag; |
| 69053 | 69715 | cnt--; |
| 69054 | 69716 | } |
| 69055 | 69717 | break; |
| 69056 | 69718 | } |
| | @@ -69132,11 +69794,11 @@ |
| 69132 | 69794 | do{ |
| 69133 | 69795 | assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 69134 | 69796 | assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 69135 | 69797 | assert( memIsValid(pIn1) ); |
| 69136 | 69798 | memAboutToChange(p, pOut); |
| 69137 | | - VdbeMemRelease(pOut); |
| 69799 | + sqlite3VdbeMemRelease(pOut); |
| 69138 | 69800 | zMalloc = pOut->zMalloc; |
| 69139 | 69801 | memcpy(pOut, pIn1, sizeof(Mem)); |
| 69140 | 69802 | #ifdef SQLITE_DEBUG |
| 69141 | 69803 | if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ |
| 69142 | 69804 | pOut->pScopyFrom += p1 - pOp->p2; |
| | @@ -69512,12 +70174,12 @@ |
| 69512 | 70174 | |
| 69513 | 70175 | n = pOp->p5; |
| 69514 | 70176 | apVal = p->apArg; |
| 69515 | 70177 | assert( apVal || n==0 ); |
| 69516 | 70178 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 69517 | | - pOut = &aMem[pOp->p3]; |
| 69518 | | - memAboutToChange(p, pOut); |
| 70179 | + ctx.pOut = &aMem[pOp->p3]; |
| 70180 | + memAboutToChange(p, ctx.pOut); |
| 69519 | 70181 | |
| 69520 | 70182 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); |
| 69521 | 70183 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 69522 | 70184 | pArg = &aMem[pOp->p2]; |
| 69523 | 70185 | for(i=0; i<n; i++, pArg++){ |
| | @@ -69529,20 +70191,11 @@ |
| 69529 | 70191 | |
| 69530 | 70192 | assert( pOp->p4type==P4_FUNCDEF ); |
| 69531 | 70193 | ctx.pFunc = pOp->p4.pFunc; |
| 69532 | 70194 | ctx.iOp = pc; |
| 69533 | 70195 | ctx.pVdbe = p; |
| 69534 | | - |
| 69535 | | - /* The output cell may already have a buffer allocated. Move |
| 69536 | | - ** the pointer to ctx.s so in case the user-function can use |
| 69537 | | - ** the already allocated buffer instead of allocating a new one. |
| 69538 | | - */ |
| 69539 | | - memcpy(&ctx.s, pOut, sizeof(Mem)); |
| 69540 | | - pOut->flags = MEM_Null; |
| 69541 | | - pOut->xDel = 0; |
| 69542 | | - pOut->zMalloc = 0; |
| 69543 | | - MemSetTypeFlag(&ctx.s, MEM_Null); |
| 70196 | + MemSetTypeFlag(ctx.pOut, MEM_Null); |
| 69544 | 70197 | |
| 69545 | 70198 | ctx.fErrorOrAux = 0; |
| 69546 | 70199 | if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 69547 | 70200 | assert( pOp>aOp ); |
| 69548 | 70201 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| | @@ -69551,47 +70204,27 @@ |
| 69551 | 70204 | } |
| 69552 | 70205 | db->lastRowid = lastRowid; |
| 69553 | 70206 | (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 69554 | 70207 | lastRowid = db->lastRowid; |
| 69555 | 70208 | |
| 69556 | | - if( db->mallocFailed ){ |
| 69557 | | - /* Even though a malloc() has failed, the implementation of the |
| 69558 | | - ** user function may have called an sqlite3_result_XXX() function |
| 69559 | | - ** to return a value. The following call releases any resources |
| 69560 | | - ** associated with such a value. |
| 69561 | | - */ |
| 69562 | | - sqlite3VdbeMemRelease(&ctx.s); |
| 69563 | | - goto no_mem; |
| 69564 | | - } |
| 69565 | | - |
| 69566 | 70209 | /* If the function returned an error, throw an exception */ |
| 69567 | 70210 | if( ctx.fErrorOrAux ){ |
| 69568 | 70211 | if( ctx.isError ){ |
| 69569 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); |
| 70212 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut)); |
| 69570 | 70213 | rc = ctx.isError; |
| 69571 | 70214 | } |
| 69572 | 70215 | sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); |
| 69573 | 70216 | } |
| 69574 | 70217 | |
| 69575 | 70218 | /* Copy the result of the function into register P3 */ |
| 69576 | | - sqlite3VdbeChangeEncoding(&ctx.s, encoding); |
| 69577 | | - assert( pOut->flags==MEM_Null ); |
| 69578 | | - memcpy(pOut, &ctx.s, sizeof(Mem)); |
| 69579 | | - if( sqlite3VdbeMemTooBig(pOut) ){ |
| 70219 | + sqlite3VdbeChangeEncoding(ctx.pOut, encoding); |
| 70220 | + if( sqlite3VdbeMemTooBig(ctx.pOut) ){ |
| 69580 | 70221 | goto too_big; |
| 69581 | 70222 | } |
| 69582 | 70223 | |
| 69583 | | -#if 0 |
| 69584 | | - /* The app-defined function has done something that as caused this |
| 69585 | | - ** statement to expire. (Perhaps the function called sqlite3_exec() |
| 69586 | | - ** with a CREATE TABLE statement.) |
| 69587 | | - */ |
| 69588 | | - if( p->expired ) rc = SQLITE_ABORT; |
| 69589 | | -#endif |
| 69590 | | - |
| 69591 | | - REGISTER_TRACE(pOp->p3, pOut); |
| 69592 | | - UPDATE_MAX_BLOBSIZE(pOut); |
| 70224 | + REGISTER_TRACE(pOp->p3, ctx.pOut); |
| 70225 | + UPDATE_MAX_BLOBSIZE(ctx.pOut); |
| 69593 | 70226 | break; |
| 69594 | 70227 | } |
| 69595 | 70228 | |
| 69596 | 70229 | /* Opcode: BitAnd P1 P2 P3 * * |
| 69597 | 70230 | ** Synopsis: r[P3]=r[P1]&r[P2] |
| | @@ -69735,109 +70368,40 @@ |
| 69735 | 70368 | break; |
| 69736 | 70369 | } |
| 69737 | 70370 | #endif |
| 69738 | 70371 | |
| 69739 | 70372 | #ifndef SQLITE_OMIT_CAST |
| 69740 | | -/* Opcode: ToText P1 * * * * |
| 69741 | | -** |
| 69742 | | -** Force the value in register P1 to be text. |
| 69743 | | -** If the value is numeric, convert it to a string using the |
| 69744 | | -** equivalent of sprintf(). Blob values are unchanged and |
| 69745 | | -** are afterwards simply interpreted as text. |
| 69746 | | -** |
| 69747 | | -** A NULL value is not changed by this routine. It remains NULL. |
| 69748 | | -*/ |
| 69749 | | -case OP_ToText: { /* same as TK_TO_TEXT, in1 */ |
| 69750 | | - pIn1 = &aMem[pOp->p1]; |
| 69751 | | - memAboutToChange(p, pIn1); |
| 69752 | | - if( pIn1->flags & MEM_Null ) break; |
| 69753 | | - assert( MEM_Str==(MEM_Blob>>3) ); |
| 69754 | | - pIn1->flags |= (pIn1->flags&MEM_Blob)>>3; |
| 69755 | | - applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); |
| 69756 | | - rc = ExpandBlob(pIn1); |
| 69757 | | - assert( pIn1->flags & MEM_Str || db->mallocFailed ); |
| 69758 | | - pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); |
| 69759 | | - UPDATE_MAX_BLOBSIZE(pIn1); |
| 69760 | | - break; |
| 69761 | | -} |
| 69762 | | - |
| 69763 | | -/* Opcode: ToBlob P1 * * * * |
| 69764 | | -** |
| 69765 | | -** Force the value in register P1 to be a BLOB. |
| 69766 | | -** If the value is numeric, convert it to a string first. |
| 69767 | | -** Strings are simply reinterpreted as blobs with no change |
| 69768 | | -** to the underlying data. |
| 69769 | | -** |
| 69770 | | -** A NULL value is not changed by this routine. It remains NULL. |
| 69771 | | -*/ |
| 69772 | | -case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ |
| 69773 | | - pIn1 = &aMem[pOp->p1]; |
| 69774 | | - if( pIn1->flags & MEM_Null ) break; |
| 69775 | | - if( (pIn1->flags & MEM_Blob)==0 ){ |
| 69776 | | - applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); |
| 69777 | | - assert( pIn1->flags & MEM_Str || db->mallocFailed ); |
| 69778 | | - MemSetTypeFlag(pIn1, MEM_Blob); |
| 69779 | | - }else{ |
| 69780 | | - pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob); |
| 69781 | | - } |
| 69782 | | - UPDATE_MAX_BLOBSIZE(pIn1); |
| 69783 | | - break; |
| 69784 | | -} |
| 69785 | | - |
| 69786 | | -/* Opcode: ToNumeric P1 * * * * |
| 69787 | | -** |
| 69788 | | -** Force the value in register P1 to be numeric (either an |
| 69789 | | -** integer or a floating-point number.) |
| 69790 | | -** If the value is text or blob, try to convert it to an using the |
| 69791 | | -** equivalent of atoi() or atof() and store 0 if no such conversion |
| 69792 | | -** is possible. |
| 69793 | | -** |
| 69794 | | -** A NULL value is not changed by this routine. It remains NULL. |
| 69795 | | -*/ |
| 69796 | | -case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ |
| 69797 | | - pIn1 = &aMem[pOp->p1]; |
| 69798 | | - sqlite3VdbeMemNumerify(pIn1); |
| 69799 | | - break; |
| 69800 | | -} |
| 69801 | | -#endif /* SQLITE_OMIT_CAST */ |
| 69802 | | - |
| 69803 | | -/* Opcode: ToInt P1 * * * * |
| 69804 | | -** |
| 69805 | | -** Force the value in register P1 to be an integer. If |
| 69806 | | -** The value is currently a real number, drop its fractional part. |
| 69807 | | -** If the value is text or blob, try to convert it to an integer using the |
| 69808 | | -** equivalent of atoi() and store 0 if no such conversion is possible. |
| 69809 | | -** |
| 69810 | | -** A NULL value is not changed by this routine. It remains NULL. |
| 69811 | | -*/ |
| 69812 | | -case OP_ToInt: { /* same as TK_TO_INT, in1 */ |
| 69813 | | - pIn1 = &aMem[pOp->p1]; |
| 69814 | | - if( (pIn1->flags & MEM_Null)==0 ){ |
| 69815 | | - sqlite3VdbeMemIntegerify(pIn1); |
| 69816 | | - } |
| 69817 | | - break; |
| 69818 | | -} |
| 69819 | | - |
| 69820 | | -#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) |
| 69821 | | -/* Opcode: ToReal P1 * * * * |
| 69822 | | -** |
| 69823 | | -** Force the value in register P1 to be a floating point number. |
| 69824 | | -** If The value is currently an integer, convert it. |
| 69825 | | -** If the value is text or blob, try to convert it to an integer using the |
| 69826 | | -** equivalent of atoi() and store 0.0 if no such conversion is possible. |
| 69827 | | -** |
| 69828 | | -** A NULL value is not changed by this routine. It remains NULL. |
| 69829 | | -*/ |
| 69830 | | -case OP_ToReal: { /* same as TK_TO_REAL, in1 */ |
| 69831 | | - pIn1 = &aMem[pOp->p1]; |
| 69832 | | - memAboutToChange(p, pIn1); |
| 69833 | | - if( (pIn1->flags & MEM_Null)==0 ){ |
| 69834 | | - sqlite3VdbeMemRealify(pIn1); |
| 69835 | | - } |
| 69836 | | - break; |
| 69837 | | -} |
| 69838 | | -#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */ |
| 70373 | +/* Opcode: Cast P1 P2 * * * |
| 70374 | +** Synopsis: affinity(r[P1]) |
| 70375 | +** |
| 70376 | +** Force the value in register P1 to be the type defined by P2. |
| 70377 | +** |
| 70378 | +** <ul> |
| 70379 | +** <li value="97"> TEXT |
| 70380 | +** <li value="98"> BLOB |
| 70381 | +** <li value="99"> NUMERIC |
| 70382 | +** <li value="100"> INTEGER |
| 70383 | +** <li value="101"> REAL |
| 70384 | +** </ul> |
| 70385 | +** |
| 70386 | +** A NULL value is not changed by this routine. It remains NULL. |
| 70387 | +*/ |
| 70388 | +case OP_Cast: { /* in1 */ |
| 70389 | + assert( pOp->p2>=SQLITE_AFF_TEXT && pOp->p2<=SQLITE_AFF_REAL ); |
| 70390 | + testcase( pOp->p2==SQLITE_AFF_TEXT ); |
| 70391 | + testcase( pOp->p2==SQLITE_AFF_NONE ); |
| 70392 | + testcase( pOp->p2==SQLITE_AFF_NUMERIC ); |
| 70393 | + testcase( pOp->p2==SQLITE_AFF_INTEGER ); |
| 70394 | + testcase( pOp->p2==SQLITE_AFF_REAL ); |
| 70395 | + pIn1 = &aMem[pOp->p1]; |
| 70396 | + memAboutToChange(p, pIn1); |
| 70397 | + rc = ExpandBlob(pIn1); |
| 70398 | + sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); |
| 70399 | + UPDATE_MAX_BLOBSIZE(pIn1); |
| 70400 | + break; |
| 70401 | +} |
| 70402 | +#endif /* SQLITE_OMIT_CAST */ |
| 69839 | 70403 | |
| 69840 | 70404 | /* Opcode: Lt P1 P2 P3 P4 P5 |
| 69841 | 70405 | ** Synopsis: if r[P1]<r[P3] goto P2 |
| 69842 | 70406 | ** |
| 69843 | 70407 | ** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then |
| | @@ -70505,11 +71069,11 @@ |
| 70505 | 71069 | assert( rc==SQLITE_OK ); |
| 70506 | 71070 | assert( sqlite3VdbeCheckMemInvariants(pDest) ); |
| 70507 | 71071 | if( pC->szRow>=aOffset[p2+1] ){ |
| 70508 | 71072 | /* This is the common case where the desired content fits on the original |
| 70509 | 71073 | ** page - where the content is not on an overflow page */ |
| 70510 | | - VdbeMemRelease(pDest); |
| 71074 | + VdbeMemReleaseExtern(pDest); |
| 70511 | 71075 | sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); |
| 70512 | 71076 | }else{ |
| 70513 | 71077 | /* This branch happens only when content is on overflow pages */ |
| 70514 | 71078 | t = aType[p2]; |
| 70515 | 71079 | if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 |
| | @@ -71427,15 +71991,19 @@ |
| 71427 | 71991 | } |
| 71428 | 71992 | pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 71429 | 71993 | break; |
| 71430 | 71994 | } |
| 71431 | 71995 | |
| 71432 | | -/* Opcode: SorterOpen P1 P2 * P4 * |
| 71996 | +/* Opcode: SorterOpen P1 P2 P3 P4 * |
| 71433 | 71997 | ** |
| 71434 | 71998 | ** This opcode works like OP_OpenEphemeral except that it opens |
| 71435 | 71999 | ** a transient index that is specifically designed to sort large |
| 71436 | 72000 | ** tables using an external merge-sort algorithm. |
| 72001 | +** |
| 72002 | +** If argument P3 is non-zero, then it indicates that the sorter may |
| 72003 | +** assume that a stable sort considering the first P3 fields of each |
| 72004 | +** key is sufficient to produce the required results. |
| 71437 | 72005 | */ |
| 71438 | 72006 | case OP_SorterOpen: { |
| 71439 | 72007 | VdbeCursor *pCx; |
| 71440 | 72008 | |
| 71441 | 72009 | assert( pOp->p1>=0 ); |
| | @@ -71443,11 +72011,29 @@ |
| 71443 | 72011 | pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 71444 | 72012 | if( pCx==0 ) goto no_mem; |
| 71445 | 72013 | pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 71446 | 72014 | assert( pCx->pKeyInfo->db==db ); |
| 71447 | 72015 | assert( pCx->pKeyInfo->enc==ENC(db) ); |
| 71448 | | - rc = sqlite3VdbeSorterInit(db, pCx); |
| 72016 | + rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); |
| 72017 | + break; |
| 72018 | +} |
| 72019 | + |
| 72020 | +/* Opcode: SequenceTest P1 P2 * * * |
| 72021 | +** Synopsis: if( cursor[P1].ctr++ ) pc = P2 |
| 72022 | +** |
| 72023 | +** P1 is a sorter cursor. If the sequence counter is currently zero, jump |
| 72024 | +** to P2. Regardless of whether or not the jump is taken, increment the |
| 72025 | +** the sequence value. |
| 72026 | +*/ |
| 72027 | +case OP_SequenceTest: { |
| 72028 | + VdbeCursor *pC; |
| 72029 | + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72030 | + pC = p->apCsr[pOp->p1]; |
| 72031 | + assert( pC->pSorter ); |
| 72032 | + if( (pC->seqCount++)==0 ){ |
| 72033 | + pc = pOp->p2 - 1; |
| 72034 | + } |
| 71449 | 72035 | break; |
| 71450 | 72036 | } |
| 71451 | 72037 | |
| 71452 | 72038 | /* Opcode: OpenPseudo P1 P2 P3 * * |
| 71453 | 72039 | ** Synopsis: P3 columns in r[P2] |
| | @@ -71592,11 +72178,13 @@ |
| 71592 | 72178 | if( pC->isTable ){ |
| 71593 | 72179 | /* The input value in P3 might be of any type: integer, real, string, |
| 71594 | 72180 | ** blob, or NULL. But it needs to be an integer before we can do |
| 71595 | 72181 | ** the seek, so covert it. */ |
| 71596 | 72182 | pIn3 = &aMem[pOp->p3]; |
| 71597 | | - ApplyNumericAffinity(pIn3); |
| 72183 | + if( (pIn3->flags & (MEM_Int|MEM_Real))==0 ){ |
| 72184 | + applyNumericAffinity(pIn3, 0); |
| 72185 | + } |
| 71598 | 72186 | iKey = sqlite3VdbeIntValue(pIn3); |
| 71599 | 72187 | pC->rowidIsValid = 0; |
| 71600 | 72188 | |
| 71601 | 72189 | /* If the P3 value could not be converted into an integer without |
| 71602 | 72190 | ** loss of information, then special processing is required... */ |
| | @@ -72290,10 +72878,11 @@ |
| 72290 | 72878 | pC = p->apCsr[pOp->p1]; |
| 72291 | 72879 | assert( isSorter(pC) ); |
| 72292 | 72880 | assert( pOp->p4type==P4_INT32 ); |
| 72293 | 72881 | pIn3 = &aMem[pOp->p3]; |
| 72294 | 72882 | nKeyCol = pOp->p4.i; |
| 72883 | + res = 0; |
| 72295 | 72884 | rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); |
| 72296 | 72885 | VdbeBranchTaken(res!=0,2); |
| 72297 | 72886 | if( res ){ |
| 72298 | 72887 | pc = pOp->p2-1; |
| 72299 | 72888 | } |
| | @@ -72554,11 +73143,11 @@ |
| 72554 | 73143 | res = 1; |
| 72555 | 73144 | #ifdef SQLITE_DEBUG |
| 72556 | 73145 | pC->seekOp = OP_Rewind; |
| 72557 | 73146 | #endif |
| 72558 | 73147 | if( isSorter(pC) ){ |
| 72559 | | - rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 73148 | + rc = sqlite3VdbeSorterRewind(pC, &res); |
| 72560 | 73149 | }else{ |
| 72561 | 73150 | pCrsr = pC->pCursor; |
| 72562 | 73151 | assert( pCrsr ); |
| 72563 | 73152 | rc = sqlite3BtreeFirst(pCrsr, &res); |
| 72564 | 73153 | pC->deferredMoveto = 0; |
| | @@ -72732,11 +73321,11 @@ |
| 72732 | 73321 | assert( pCrsr!=0 ); |
| 72733 | 73322 | assert( pC->isTable==0 ); |
| 72734 | 73323 | rc = ExpandBlob(pIn2); |
| 72735 | 73324 | if( rc==SQLITE_OK ){ |
| 72736 | 73325 | if( isSorter(pC) ){ |
| 72737 | | - rc = sqlite3VdbeSorterWrite(db, pC, pIn2); |
| 73326 | + rc = sqlite3VdbeSorterWrite(pC, pIn2); |
| 72738 | 73327 | }else{ |
| 72739 | 73328 | nKey = pIn2->n; |
| 72740 | 73329 | zKey = pIn2->z; |
| 72741 | 73330 | rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, |
| 72742 | 73331 | ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) |
| | @@ -73645,10 +74234,11 @@ |
| 73645 | 74234 | case OP_AggStep: { |
| 73646 | 74235 | int n; |
| 73647 | 74236 | int i; |
| 73648 | 74237 | Mem *pMem; |
| 73649 | 74238 | Mem *pRec; |
| 74239 | + Mem t; |
| 73650 | 74240 | sqlite3_context ctx; |
| 73651 | 74241 | sqlite3_value **apVal; |
| 73652 | 74242 | |
| 73653 | 74243 | n = pOp->p5; |
| 73654 | 74244 | assert( n>=0 ); |
| | @@ -73662,15 +74252,16 @@ |
| 73662 | 74252 | } |
| 73663 | 74253 | ctx.pFunc = pOp->p4.pFunc; |
| 73664 | 74254 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 73665 | 74255 | ctx.pMem = pMem = &aMem[pOp->p3]; |
| 73666 | 74256 | pMem->n++; |
| 73667 | | - ctx.s.flags = MEM_Null; |
| 73668 | | - ctx.s.z = 0; |
| 73669 | | - ctx.s.zMalloc = 0; |
| 73670 | | - ctx.s.xDel = 0; |
| 73671 | | - ctx.s.db = db; |
| 74257 | + t.flags = MEM_Null; |
| 74258 | + t.z = 0; |
| 74259 | + t.zMalloc = 0; |
| 74260 | + t.xDel = 0; |
| 74261 | + t.db = db; |
| 74262 | + ctx.pOut = &t; |
| 73672 | 74263 | ctx.isError = 0; |
| 73673 | 74264 | ctx.pColl = 0; |
| 73674 | 74265 | ctx.skipFlag = 0; |
| 73675 | 74266 | if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 73676 | 74267 | assert( pOp>p->aOp ); |
| | @@ -73678,21 +74269,19 @@ |
| 73678 | 74269 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 73679 | 74270 | ctx.pColl = pOp[-1].p4.pColl; |
| 73680 | 74271 | } |
| 73681 | 74272 | (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 73682 | 74273 | if( ctx.isError ){ |
| 73683 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); |
| 74274 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t)); |
| 73684 | 74275 | rc = ctx.isError; |
| 73685 | 74276 | } |
| 73686 | 74277 | if( ctx.skipFlag ){ |
| 73687 | 74278 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 73688 | 74279 | i = pOp[-1].p1; |
| 73689 | 74280 | if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); |
| 73690 | 74281 | } |
| 73691 | | - |
| 73692 | | - sqlite3VdbeMemRelease(&ctx.s); |
| 73693 | | - |
| 74282 | + sqlite3VdbeMemRelease(&t); |
| 73694 | 74283 | break; |
| 73695 | 74284 | } |
| 73696 | 74285 | |
| 73697 | 74286 | /* Opcode: AggFinal P1 P2 * P4 * |
| 73698 | 74287 | ** Synopsis: accum=r[P1] N=P2 |
| | @@ -74138,31 +74727,18 @@ |
| 74138 | 74727 | } |
| 74139 | 74728 | pVtab = pCur->pVtabCursor->pVtab; |
| 74140 | 74729 | pModule = pVtab->pModule; |
| 74141 | 74730 | assert( pModule->xColumn ); |
| 74142 | 74731 | memset(&sContext, 0, sizeof(sContext)); |
| 74143 | | - |
| 74144 | | - /* The output cell may already have a buffer allocated. Move |
| 74145 | | - ** the current contents to sContext.s so in case the user-function |
| 74146 | | - ** can use the already allocated buffer instead of allocating a |
| 74147 | | - ** new one. |
| 74148 | | - */ |
| 74149 | | - sqlite3VdbeMemMove(&sContext.s, pDest); |
| 74150 | | - MemSetTypeFlag(&sContext.s, MEM_Null); |
| 74151 | | - |
| 74732 | + sContext.pOut = pDest; |
| 74733 | + MemSetTypeFlag(pDest, MEM_Null); |
| 74152 | 74734 | rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); |
| 74153 | 74735 | sqlite3VtabImportErrmsg(p, pVtab); |
| 74154 | 74736 | if( sContext.isError ){ |
| 74155 | 74737 | rc = sContext.isError; |
| 74156 | 74738 | } |
| 74157 | | - |
| 74158 | | - /* Copy the result of the function to the P3 register. We |
| 74159 | | - ** do this regardless of whether or not an error occurred to ensure any |
| 74160 | | - ** dynamic allocation in sContext.s (a Mem struct) is released. |
| 74161 | | - */ |
| 74162 | | - sqlite3VdbeChangeEncoding(&sContext.s, encoding); |
| 74163 | | - sqlite3VdbeMemMove(pDest, &sContext.s); |
| 74739 | + sqlite3VdbeChangeEncoding(pDest, encoding); |
| 74164 | 74740 | REGISTER_TRACE(pOp->p3, pDest); |
| 74165 | 74741 | UPDATE_MAX_BLOBSIZE(pDest); |
| 74166 | 74742 | |
| 74167 | 74743 | if( sqlite3VdbeMemTooBig(pDest) ){ |
| 74168 | 74744 | goto too_big; |
| | @@ -74848,11 +75424,11 @@ |
| 74848 | 75424 | *ppBlob = (sqlite3_blob *)pBlob; |
| 74849 | 75425 | }else{ |
| 74850 | 75426 | if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); |
| 74851 | 75427 | sqlite3DbFree(db, pBlob); |
| 74852 | 75428 | } |
| 74853 | | - sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); |
| 75429 | + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); |
| 74854 | 75430 | sqlite3DbFree(db, zErr); |
| 74855 | 75431 | sqlite3ParserReset(pParse); |
| 74856 | 75432 | sqlite3StackFree(db, pParse); |
| 74857 | 75433 | rc = sqlite3ApiExit(db, rc); |
| 74858 | 75434 | sqlite3_mutex_leave(db->mutex); |
| | @@ -74901,11 +75477,11 @@ |
| 74901 | 75477 | v = (Vdbe*)p->pStmt; |
| 74902 | 75478 | |
| 74903 | 75479 | if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){ |
| 74904 | 75480 | /* Request is out of range. Return a transient error. */ |
| 74905 | 75481 | rc = SQLITE_ERROR; |
| 74906 | | - sqlite3Error(db, SQLITE_ERROR, 0); |
| 75482 | + sqlite3Error(db, SQLITE_ERROR); |
| 74907 | 75483 | }else if( v==0 ){ |
| 74908 | 75484 | /* If there is no statement handle, then the blob-handle has |
| 74909 | 75485 | ** already been invalidated. Return SQLITE_ABORT in this case. |
| 74910 | 75486 | */ |
| 74911 | 75487 | rc = SQLITE_ABORT; |
| | @@ -74981,11 +75557,11 @@ |
| 74981 | 75557 | rc = SQLITE_ABORT; |
| 74982 | 75558 | }else{ |
| 74983 | 75559 | char *zErr; |
| 74984 | 75560 | rc = blobSeekToRow(p, iRow, &zErr); |
| 74985 | 75561 | if( rc!=SQLITE_OK ){ |
| 74986 | | - sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); |
| 75562 | + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); |
| 74987 | 75563 | sqlite3DbFree(db, zErr); |
| 74988 | 75564 | } |
| 74989 | 75565 | assert( rc!=SQLITE_SCHEMA ); |
| 74990 | 75566 | } |
| 74991 | 75567 | |
| | @@ -74998,11 +75574,11 @@ |
| 74998 | 75574 | #endif /* #ifndef SQLITE_OMIT_INCRBLOB */ |
| 74999 | 75575 | |
| 75000 | 75576 | /************** End of vdbeblob.c ********************************************/ |
| 75001 | 75577 | /************** Begin file vdbesort.c ****************************************/ |
| 75002 | 75578 | /* |
| 75003 | | -** 2011 July 9 |
| 75579 | +** 2011-07-09 |
| 75004 | 75580 | ** |
| 75005 | 75581 | ** The author disclaims copyright to this source code. In place of |
| 75006 | 75582 | ** a legal notice, here is a blessing: |
| 75007 | 75583 | ** |
| 75008 | 75584 | ** May you do good and not evil. |
| | @@ -75009,181 +75585,484 @@ |
| 75009 | 75585 | ** May you find forgiveness for yourself and forgive others. |
| 75010 | 75586 | ** May you share freely, never taking more than you give. |
| 75011 | 75587 | ** |
| 75012 | 75588 | ************************************************************************* |
| 75013 | 75589 | ** This file contains code for the VdbeSorter object, used in concert with |
| 75014 | | -** a VdbeCursor to sort large numbers of keys (as may be required, for |
| 75015 | | -** example, by CREATE INDEX statements on tables too large to fit in main |
| 75016 | | -** memory). |
| 75017 | | -*/ |
| 75018 | | - |
| 75019 | | - |
| 75020 | | - |
| 75021 | | -typedef struct VdbeSorterIter VdbeSorterIter; |
| 75022 | | -typedef struct SorterRecord SorterRecord; |
| 75023 | | -typedef struct FileWriter FileWriter; |
| 75024 | | - |
| 75025 | | -/* |
| 75026 | | -** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 75027 | | -** |
| 75028 | | -** As keys are added to the sorter, they are written to disk in a series |
| 75029 | | -** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly |
| 75030 | | -** the same as the cache-size allowed for temporary databases. In order |
| 75031 | | -** to allow the caller to extract keys from the sorter in sorted order, |
| 75032 | | -** all PMAs currently stored on disk must be merged together. This comment |
| 75033 | | -** describes the data structure used to do so. The structure supports |
| 75034 | | -** merging any number of arrays in a single pass with no redundant comparison |
| 75035 | | -** operations. |
| 75036 | | -** |
| 75037 | | -** The aIter[] array contains an iterator for each of the PMAs being merged. |
| 75038 | | -** An aIter[] iterator either points to a valid key or else is at EOF. For |
| 75039 | | -** the purposes of the paragraphs below, we assume that the array is actually |
| 75040 | | -** N elements in size, where N is the smallest power of 2 greater to or equal |
| 75041 | | -** to the number of iterators being merged. The extra aIter[] elements are |
| 75042 | | -** treated as if they are empty (always at EOF). |
| 75590 | +** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements |
| 75591 | +** or by SELECT statements with ORDER BY clauses that cannot be satisfied |
| 75592 | +** using indexes and without LIMIT clauses. |
| 75593 | +** |
| 75594 | +** The VdbeSorter object implements a multi-threaded external merge sort |
| 75595 | +** algorithm that is efficient even if the number of elements being sorted |
| 75596 | +** exceeds the available memory. |
| 75597 | +** |
| 75598 | +** Here is the (internal, non-API) interface between this module and the |
| 75599 | +** rest of the SQLite system: |
| 75600 | +** |
| 75601 | +** sqlite3VdbeSorterInit() Create a new VdbeSorter object. |
| 75602 | +** |
| 75603 | +** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter |
| 75604 | +** object. The row is a binary blob in the |
| 75605 | +** OP_MakeRecord format that contains both |
| 75606 | +** the ORDER BY key columns and result columns |
| 75607 | +** in the case of a SELECT w/ ORDER BY, or |
| 75608 | +** the complete record for an index entry |
| 75609 | +** in the case of a CREATE INDEX. |
| 75610 | +** |
| 75611 | +** sqlite3VdbeSorterRewind() Sort all content previously added. |
| 75612 | +** Position the read cursor on the |
| 75613 | +** first sorted element. |
| 75614 | +** |
| 75615 | +** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted |
| 75616 | +** element. |
| 75617 | +** |
| 75618 | +** sqlite3VdbeSorterRowkey() Return the complete binary blob for the |
| 75619 | +** row currently under the read cursor. |
| 75620 | +** |
| 75621 | +** sqlite3VdbeSorterCompare() Compare the binary blob for the row |
| 75622 | +** currently under the read cursor against |
| 75623 | +** another binary blob X and report if |
| 75624 | +** X is strictly less than the read cursor. |
| 75625 | +** Used to enforce uniqueness in a |
| 75626 | +** CREATE UNIQUE INDEX statement. |
| 75627 | +** |
| 75628 | +** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim |
| 75629 | +** all resources. |
| 75630 | +** |
| 75631 | +** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This |
| 75632 | +** is like Close() followed by Init() only |
| 75633 | +** much faster. |
| 75634 | +** |
| 75635 | +** The interfaces above must be called in a particular order. Write() can |
| 75636 | +** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and |
| 75637 | +** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. |
| 75638 | +** |
| 75639 | +** Init() |
| 75640 | +** for each record: Write() |
| 75641 | +** Rewind() |
| 75642 | +** Rowkey()/Compare() |
| 75643 | +** Next() |
| 75644 | +** Close() |
| 75645 | +** |
| 75646 | +** Algorithm: |
| 75647 | +** |
| 75648 | +** Records passed to the sorter via calls to Write() are initially held |
| 75649 | +** unsorted in main memory. Assuming the amount of memory used never exceeds |
| 75650 | +** a threshold, when Rewind() is called the set of records is sorted using |
| 75651 | +** an in-memory merge sort. In this case, no temporary files are required |
| 75652 | +** and subsequent calls to Rowkey(), Next() and Compare() read records |
| 75653 | +** directly from main memory. |
| 75654 | +** |
| 75655 | +** If the amount of space used to store records in main memory exceeds the |
| 75656 | +** threshold, then the set of records currently in memory are sorted and |
| 75657 | +** written to a temporary file in "Packed Memory Array" (PMA) format. |
| 75658 | +** A PMA created at this point is known as a "level-0 PMA". Higher levels |
| 75659 | +** of PMAs may be created by merging existing PMAs together - for example |
| 75660 | +** merging two or more level-0 PMAs together creates a level-1 PMA. |
| 75661 | +** |
| 75662 | +** The threshold for the amount of main memory to use before flushing |
| 75663 | +** records to a PMA is roughly the same as the limit configured for the |
| 75664 | +** page-cache of the main database. Specifically, the threshold is set to |
| 75665 | +** the value returned by "PRAGMA main.page_size" multipled by |
| 75666 | +** that returned by "PRAGMA main.cache_size", in bytes. |
| 75667 | +** |
| 75668 | +** If the sorter is running in single-threaded mode, then all PMAs generated |
| 75669 | +** are appended to a single temporary file. Or, if the sorter is running in |
| 75670 | +** multi-threaded mode then up to (N+1) temporary files may be opened, where |
| 75671 | +** N is the configured number of worker threads. In this case, instead of |
| 75672 | +** sorting the records and writing the PMA to a temporary file itself, the |
| 75673 | +** calling thread usually launches a worker thread to do so. Except, if |
| 75674 | +** there are already N worker threads running, the main thread does the work |
| 75675 | +** itself. |
| 75676 | +** |
| 75677 | +** The sorter is running in multi-threaded mode if (a) the library was built |
| 75678 | +** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater |
| 75679 | +** than zero, and (b) worker threads have been enabled at runtime by calling |
| 75680 | +** sqlite3_config(SQLITE_CONFIG_WORKER_THREADS, ...). |
| 75681 | +** |
| 75682 | +** When Rewind() is called, any data remaining in memory is flushed to a |
| 75683 | +** final PMA. So at this point the data is stored in some number of sorted |
| 75684 | +** PMAs within temporary files on disk. |
| 75685 | +** |
| 75686 | +** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the |
| 75687 | +** sorter is running in single-threaded mode, then these PMAs are merged |
| 75688 | +** incrementally as keys are retreived from the sorter by the VDBE. The |
| 75689 | +** MergeEngine object, described in further detail below, performs this |
| 75690 | +** merge. |
| 75691 | +** |
| 75692 | +** Or, if running in multi-threaded mode, then a background thread is |
| 75693 | +** launched to merge the existing PMAs. Once the background thread has |
| 75694 | +** merged T bytes of data into a single sorted PMA, the main thread |
| 75695 | +** begins reading keys from that PMA while the background thread proceeds |
| 75696 | +** with merging the next T bytes of data. And so on. |
| 75697 | +** |
| 75698 | +** Parameter T is set to half the value of the memory threshold used |
| 75699 | +** by Write() above to determine when to create a new PMA. |
| 75700 | +** |
| 75701 | +** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when |
| 75702 | +** Rewind() is called, then a hierarchy of incremental-merges is used. |
| 75703 | +** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on |
| 75704 | +** disk are merged together. Then T bytes of data from the second set, and |
| 75705 | +** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT |
| 75706 | +** PMAs at a time. This done is to improve locality. |
| 75707 | +** |
| 75708 | +** If running in multi-threaded mode and there are more than |
| 75709 | +** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more |
| 75710 | +** than one background thread may be created. Specifically, there may be |
| 75711 | +** one background thread for each temporary file on disk, and one background |
| 75712 | +** thread to merge the output of each of the others to a single PMA for |
| 75713 | +** the main thread to read from. |
| 75714 | +*/ |
| 75715 | + |
| 75716 | +/* |
| 75717 | +** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various |
| 75718 | +** messages to stderr that may be helpful in understanding the performance |
| 75719 | +** characteristics of the sorter in multi-threaded mode. |
| 75720 | +*/ |
| 75721 | +#if 0 |
| 75722 | +# define SQLITE_DEBUG_SORTER_THREADS 1 |
| 75723 | +#endif |
| 75724 | + |
| 75725 | +/* |
| 75726 | +** Private objects used by the sorter |
| 75727 | +*/ |
| 75728 | +typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ |
| 75729 | +typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ |
| 75730 | +typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ |
| 75731 | +typedef struct SorterRecord SorterRecord; /* A record being sorted */ |
| 75732 | +typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ |
| 75733 | +typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ |
| 75734 | +typedef struct SorterList SorterList; /* In-memory list of records */ |
| 75735 | +typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ |
| 75736 | + |
| 75737 | +/* |
| 75738 | +** A container for a temp file handle and the current amount of data |
| 75739 | +** stored in the file. |
| 75740 | +*/ |
| 75741 | +struct SorterFile { |
| 75742 | + sqlite3_file *pFd; /* File handle */ |
| 75743 | + i64 iEof; /* Bytes of data stored in pFd */ |
| 75744 | +}; |
| 75745 | + |
| 75746 | +/* |
| 75747 | +** An in-memory list of objects to be sorted. |
| 75748 | +** |
| 75749 | +** If aMemory==0 then each object is allocated separately and the objects |
| 75750 | +** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects |
| 75751 | +** are stored in the aMemory[] bulk memory, one right after the other, and |
| 75752 | +** are connected using SorterRecord.u.iNext. |
| 75753 | +*/ |
| 75754 | +struct SorterList { |
| 75755 | + SorterRecord *pList; /* Linked list of records */ |
| 75756 | + u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ |
| 75757 | + int szPMA; /* Size of pList as PMA in bytes */ |
| 75758 | +}; |
| 75759 | + |
| 75760 | +/* |
| 75761 | +** The MergeEngine object is used to combine two or more smaller PMAs into |
| 75762 | +** one big PMA using a merge operation. Separate PMAs all need to be |
| 75763 | +** combined into one big PMA in order to be able to step through the sorted |
| 75764 | +** records in order. |
| 75765 | +** |
| 75766 | +** The aReadr[] array contains a PmaReader object for each of the PMAs being |
| 75767 | +** merged. An aReadr[] object either points to a valid key or else is at EOF. |
| 75768 | +** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.) |
| 75769 | +** For the purposes of the paragraphs below, we assume that the array is |
| 75770 | +** actually N elements in size, where N is the smallest power of 2 greater |
| 75771 | +** to or equal to the number of PMAs being merged. The extra aReadr[] elements |
| 75772 | +** are treated as if they are empty (always at EOF). |
| 75043 | 75773 | ** |
| 75044 | 75774 | ** The aTree[] array is also N elements in size. The value of N is stored in |
| 75045 | | -** the VdbeSorter.nTree variable. |
| 75775 | +** the MergeEngine.nTree variable. |
| 75046 | 75776 | ** |
| 75047 | 75777 | ** The final (N/2) elements of aTree[] contain the results of comparing |
| 75048 | | -** pairs of iterator keys together. Element i contains the result of |
| 75049 | | -** comparing aIter[2*i-N] and aIter[2*i-N+1]. Whichever key is smaller, the |
| 75778 | +** pairs of PMA keys together. Element i contains the result of |
| 75779 | +** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the |
| 75050 | 75780 | ** aTree element is set to the index of it. |
| 75051 | 75781 | ** |
| 75052 | 75782 | ** For the purposes of this comparison, EOF is considered greater than any |
| 75053 | 75783 | ** other key value. If the keys are equal (only possible with two EOF |
| 75054 | 75784 | ** values), it doesn't matter which index is stored. |
| 75055 | 75785 | ** |
| 75056 | 75786 | ** The (N/4) elements of aTree[] that precede the final (N/2) described |
| 75057 | | -** above contains the index of the smallest of each block of 4 iterators. |
| 75058 | | -** And so on. So that aTree[1] contains the index of the iterator that |
| 75787 | +** above contains the index of the smallest of each block of 4 PmaReaders |
| 75788 | +** And so on. So that aTree[1] contains the index of the PmaReader that |
| 75059 | 75789 | ** currently points to the smallest key value. aTree[0] is unused. |
| 75060 | 75790 | ** |
| 75061 | 75791 | ** Example: |
| 75062 | 75792 | ** |
| 75063 | | -** aIter[0] -> Banana |
| 75064 | | -** aIter[1] -> Feijoa |
| 75065 | | -** aIter[2] -> Elderberry |
| 75066 | | -** aIter[3] -> Currant |
| 75067 | | -** aIter[4] -> Grapefruit |
| 75068 | | -** aIter[5] -> Apple |
| 75069 | | -** aIter[6] -> Durian |
| 75070 | | -** aIter[7] -> EOF |
| 75793 | +** aReadr[0] -> Banana |
| 75794 | +** aReadr[1] -> Feijoa |
| 75795 | +** aReadr[2] -> Elderberry |
| 75796 | +** aReadr[3] -> Currant |
| 75797 | +** aReadr[4] -> Grapefruit |
| 75798 | +** aReadr[5] -> Apple |
| 75799 | +** aReadr[6] -> Durian |
| 75800 | +** aReadr[7] -> EOF |
| 75071 | 75801 | ** |
| 75072 | 75802 | ** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } |
| 75073 | 75803 | ** |
| 75074 | 75804 | ** The current element is "Apple" (the value of the key indicated by |
| 75075 | | -** iterator 5). When the Next() operation is invoked, iterator 5 will |
| 75805 | +** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will |
| 75076 | 75806 | ** be advanced to the next key in its segment. Say the next key is |
| 75077 | 75807 | ** "Eggplant": |
| 75078 | 75808 | ** |
| 75079 | | -** aIter[5] -> Eggplant |
| 75809 | +** aReadr[5] -> Eggplant |
| 75080 | 75810 | ** |
| 75081 | | -** The contents of aTree[] are updated first by comparing the new iterator |
| 75082 | | -** 5 key to the current key of iterator 4 (still "Grapefruit"). The iterator |
| 75811 | +** The contents of aTree[] are updated first by comparing the new PmaReader |
| 75812 | +** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader |
| 75083 | 75813 | ** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. |
| 75084 | | -** The value of iterator 6 - "Durian" - is now smaller than that of iterator |
| 75814 | +** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader |
| 75085 | 75815 | ** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Banana<Durian), |
| 75086 | 75816 | ** so the value written into element 1 of the array is 0. As follows: |
| 75087 | 75817 | ** |
| 75088 | 75818 | ** aTree[] = { X, 0 0, 6 0, 3, 5, 6 } |
| 75089 | 75819 | ** |
| 75090 | 75820 | ** In other words, each time we advance to the next sorter element, log2(N) |
| 75091 | 75821 | ** key comparison operations are required, where N is the number of segments |
| 75092 | 75822 | ** being merged (rounded up to the next power of 2). |
| 75093 | 75823 | */ |
| 75824 | +struct MergeEngine { |
| 75825 | + int nTree; /* Used size of aTree/aReadr (power of 2) */ |
| 75826 | + SortSubtask *pTask; /* Used by this thread only */ |
| 75827 | + int *aTree; /* Current state of incremental merge */ |
| 75828 | + PmaReader *aReadr; /* Array of PmaReaders to merge data from */ |
| 75829 | +}; |
| 75830 | + |
| 75831 | +/* |
| 75832 | +** This object represents a single thread of control in a sort operation. |
| 75833 | +** Exactly VdbeSorter.nTask instances of this object are allocated |
| 75834 | +** as part of each VdbeSorter object. Instances are never allocated any |
| 75835 | +** other way. VdbeSorter.nTask is set to the number of worker threads allowed |
| 75836 | +** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread). Thus for |
| 75837 | +** single-threaded operation, there is exactly one instance of this object |
| 75838 | +** and for multi-threaded operation there are two or more instances. |
| 75839 | +** |
| 75840 | +** Essentially, this structure contains all those fields of the VdbeSorter |
| 75841 | +** structure for which each thread requires a separate instance. For example, |
| 75842 | +** each thread requries its own UnpackedRecord object to unpack records in |
| 75843 | +** as part of comparison operations. |
| 75844 | +** |
| 75845 | +** Before a background thread is launched, variable bDone is set to 0. Then, |
| 75846 | +** right before it exits, the thread itself sets bDone to 1. This is used for |
| 75847 | +** two purposes: |
| 75848 | +** |
| 75849 | +** 1. When flushing the contents of memory to a level-0 PMA on disk, to |
| 75850 | +** attempt to select a SortSubtask for which there is not already an |
| 75851 | +** active background thread (since doing so causes the main thread |
| 75852 | +** to block until it finishes). |
| 75853 | +** |
| 75854 | +** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call |
| 75855 | +** to sqlite3ThreadJoin() is likely to block. Cases that are likely to |
| 75856 | +** block provoke debugging output. |
| 75857 | +** |
| 75858 | +** In both cases, the effects of the main thread seeing (bDone==0) even |
| 75859 | +** after the thread has finished are not dire. So we don't worry about |
| 75860 | +** memory barriers and such here. |
| 75861 | +*/ |
| 75862 | +struct SortSubtask { |
| 75863 | + SQLiteThread *pThread; /* Background thread, if any */ |
| 75864 | + int bDone; /* Set if thread is finished but not joined */ |
| 75865 | + VdbeSorter *pSorter; /* Sorter that owns this sub-task */ |
| 75866 | + UnpackedRecord *pUnpacked; /* Space to unpack a record */ |
| 75867 | + SorterList list; /* List for thread to write to a PMA */ |
| 75868 | + int nPMA; /* Number of PMAs currently in file */ |
| 75869 | + SorterFile file; /* Temp file for level-0 PMAs */ |
| 75870 | + SorterFile file2; /* Space for other PMAs */ |
| 75871 | +}; |
| 75872 | + |
| 75873 | +/* |
| 75874 | +** Main sorter structure. A single instance of this is allocated for each |
| 75875 | +** sorter cursor created by the VDBE. |
| 75876 | +** |
| 75877 | +** mxKeysize: |
| 75878 | +** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(), |
| 75879 | +** this variable is updated so as to be set to the size on disk of the |
| 75880 | +** largest record in the sorter. |
| 75881 | +*/ |
| 75094 | 75882 | struct VdbeSorter { |
| 75095 | | - i64 iWriteOff; /* Current write offset within file pTemp1 */ |
| 75096 | | - i64 iReadOff; /* Current read offset within file pTemp1 */ |
| 75097 | | - int nInMemory; /* Current size of pRecord list as PMA */ |
| 75098 | | - int nTree; /* Used size of aTree/aIter (power of 2) */ |
| 75099 | | - int nPMA; /* Number of PMAs stored in pTemp1 */ |
| 75100 | 75883 | int mnPmaSize; /* Minimum PMA size, in bytes */ |
| 75101 | 75884 | int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ |
| 75102 | | - VdbeSorterIter *aIter; /* Array of iterators to merge */ |
| 75103 | | - int *aTree; /* Current state of incremental merge */ |
| 75104 | | - sqlite3_file *pTemp1; /* PMA file 1 */ |
| 75105 | | - SorterRecord *pRecord; /* Head of in-memory record list */ |
| 75106 | | - UnpackedRecord *pUnpacked; /* Used to unpack keys */ |
| 75107 | | -}; |
| 75108 | | - |
| 75109 | | -/* |
| 75110 | | -** The following type is an iterator for a PMA. It caches the current key in |
| 75111 | | -** variables nKey/aKey. If the iterator is at EOF, pFile==0. |
| 75112 | | -*/ |
| 75113 | | -struct VdbeSorterIter { |
| 75114 | | - i64 iReadOff; /* Current read offset */ |
| 75115 | | - i64 iEof; /* 1 byte past EOF for this iterator */ |
| 75116 | | - int nAlloc; /* Bytes of space at aAlloc */ |
| 75117 | | - int nKey; /* Number of bytes in key */ |
| 75118 | | - sqlite3_file *pFile; /* File iterator is reading from */ |
| 75119 | | - u8 *aAlloc; /* Allocated space */ |
| 75120 | | - u8 *aKey; /* Pointer to current key */ |
| 75121 | | - u8 *aBuffer; /* Current read buffer */ |
| 75122 | | - int nBuffer; /* Size of read buffer in bytes */ |
| 75123 | | -}; |
| 75124 | | - |
| 75125 | | -/* |
| 75126 | | -** An instance of this structure is used to organize the stream of records |
| 75127 | | -** being written to files by the merge-sort code into aligned, page-sized |
| 75128 | | -** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go |
| 75129 | | -** faster on many operating systems. |
| 75130 | | -*/ |
| 75131 | | -struct FileWriter { |
| 75885 | + int mxKeysize; /* Largest serialized key seen so far */ |
| 75886 | + int pgsz; /* Main database page size */ |
| 75887 | + PmaReader *pReader; /* Readr data from here after Rewind() */ |
| 75888 | + MergeEngine *pMerger; /* Or here, if bUseThreads==0 */ |
| 75889 | + sqlite3 *db; /* Database connection */ |
| 75890 | + KeyInfo *pKeyInfo; /* How to compare records */ |
| 75891 | + UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */ |
| 75892 | + SorterList list; /* List of in-memory records */ |
| 75893 | + int iMemory; /* Offset of free space in list.aMemory */ |
| 75894 | + int nMemory; /* Size of list.aMemory allocation in bytes */ |
| 75895 | + u8 bUsePMA; /* True if one or more PMAs created */ |
| 75896 | + u8 bUseThreads; /* True to use background threads */ |
| 75897 | + u8 iPrev; /* Previous thread used to flush PMA */ |
| 75898 | + u8 nTask; /* Size of aTask[] array */ |
| 75899 | + SortSubtask aTask[1]; /* One or more subtasks */ |
| 75900 | +}; |
| 75901 | + |
| 75902 | +/* |
| 75903 | +** An instance of the following object is used to read records out of a |
| 75904 | +** PMA, in sorted order. The next key to be read is cached in nKey/aKey. |
| 75905 | +** aKey might point into aMap or into aBuffer. If neither of those locations |
| 75906 | +** contain a contiguous representation of the key, then aAlloc is allocated |
| 75907 | +** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. |
| 75908 | +** |
| 75909 | +** pFd==0 at EOF. |
| 75910 | +*/ |
| 75911 | +struct PmaReader { |
| 75912 | + i64 iReadOff; /* Current read offset */ |
| 75913 | + i64 iEof; /* 1 byte past EOF for this PmaReader */ |
| 75914 | + int nAlloc; /* Bytes of space at aAlloc */ |
| 75915 | + int nKey; /* Number of bytes in key */ |
| 75916 | + sqlite3_file *pFd; /* File handle we are reading from */ |
| 75917 | + u8 *aAlloc; /* Space for aKey if aBuffer and pMap wont work */ |
| 75918 | + u8 *aKey; /* Pointer to current key */ |
| 75919 | + u8 *aBuffer; /* Current read buffer */ |
| 75920 | + int nBuffer; /* Size of read buffer in bytes */ |
| 75921 | + u8 *aMap; /* Pointer to mapping of entire file */ |
| 75922 | + IncrMerger *pIncr; /* Incremental merger */ |
| 75923 | +}; |
| 75924 | + |
| 75925 | +/* |
| 75926 | +** Normally, a PmaReader object iterates through an existing PMA stored |
| 75927 | +** within a temp file. However, if the PmaReader.pIncr variable points to |
| 75928 | +** an object of the following type, it may be used to iterate/merge through |
| 75929 | +** multiple PMAs simultaneously. |
| 75930 | +** |
| 75931 | +** There are two types of IncrMerger object - single (bUseThread==0) and |
| 75932 | +** multi-threaded (bUseThread==1). |
| 75933 | +** |
| 75934 | +** A multi-threaded IncrMerger object uses two temporary files - aFile[0] |
| 75935 | +** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in |
| 75936 | +** size. When the IncrMerger is initialized, it reads enough data from |
| 75937 | +** pMerger to populate aFile[0]. It then sets variables within the |
| 75938 | +** corresponding PmaReader object to read from that file and kicks off |
| 75939 | +** a background thread to populate aFile[1] with the next mxSz bytes of |
| 75940 | +** sorted record data from pMerger. |
| 75941 | +** |
| 75942 | +** When the PmaReader reaches the end of aFile[0], it blocks until the |
| 75943 | +** background thread has finished populating aFile[1]. It then exchanges |
| 75944 | +** the contents of the aFile[0] and aFile[1] variables within this structure, |
| 75945 | +** sets the PmaReader fields to read from the new aFile[0] and kicks off |
| 75946 | +** another background thread to populate the new aFile[1]. And so on, until |
| 75947 | +** the contents of pMerger are exhausted. |
| 75948 | +** |
| 75949 | +** A single-threaded IncrMerger does not open any temporary files of its |
| 75950 | +** own. Instead, it has exclusive access to mxSz bytes of space beginning |
| 75951 | +** at offset iStartOff of file pTask->file2. And instead of using a |
| 75952 | +** background thread to prepare data for the PmaReader, with a single |
| 75953 | +** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with |
| 75954 | +** keys from pMerger by the calling thread whenever the PmaReader runs out |
| 75955 | +** of data. |
| 75956 | +*/ |
| 75957 | +struct IncrMerger { |
| 75958 | + SortSubtask *pTask; /* Task that owns this merger */ |
| 75959 | + MergeEngine *pMerger; /* Merge engine thread reads data from */ |
| 75960 | + i64 iStartOff; /* Offset to start writing file at */ |
| 75961 | + int mxSz; /* Maximum bytes of data to store */ |
| 75962 | + int bEof; /* Set to true when merge is finished */ |
| 75963 | + int bUseThread; /* True to use a bg thread for this object */ |
| 75964 | + SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */ |
| 75965 | +}; |
| 75966 | + |
| 75967 | +/* |
| 75968 | +** An instance of this object is used for writing a PMA. |
| 75969 | +** |
| 75970 | +** The PMA is written one record at a time. Each record is of an arbitrary |
| 75971 | +** size. But I/O is more efficient if it occurs in page-sized blocks where |
| 75972 | +** each block is aligned on a page boundary. This object caches writes to |
| 75973 | +** the PMA so that aligned, page-size blocks are written. |
| 75974 | +*/ |
| 75975 | +struct PmaWriter { |
| 75132 | 75976 | int eFWErr; /* Non-zero if in an error state */ |
| 75133 | 75977 | u8 *aBuffer; /* Pointer to write buffer */ |
| 75134 | 75978 | int nBuffer; /* Size of write buffer in bytes */ |
| 75135 | 75979 | int iBufStart; /* First byte of buffer to write */ |
| 75136 | 75980 | int iBufEnd; /* Last byte of buffer to write */ |
| 75137 | 75981 | i64 iWriteOff; /* Offset of start of buffer in file */ |
| 75138 | | - sqlite3_file *pFile; /* File to write to */ |
| 75982 | + sqlite3_file *pFd; /* File handle to write to */ |
| 75139 | 75983 | }; |
| 75140 | 75984 | |
| 75141 | 75985 | /* |
| 75142 | | -** A structure to store a single record. All in-memory records are connected |
| 75143 | | -** together into a linked list headed at VdbeSorter.pRecord using the |
| 75144 | | -** SorterRecord.pNext pointer. |
| 75986 | +** This object is the header on a single record while that record is being |
| 75987 | +** held in memory and prior to being written out as part of a PMA. |
| 75988 | +** |
| 75989 | +** How the linked list is connected depends on how memory is being managed |
| 75990 | +** by this module. If using a separate allocation for each in-memory record |
| 75991 | +** (VdbeSorter.list.aMemory==0), then the list is always connected using the |
| 75992 | +** SorterRecord.u.pNext pointers. |
| 75993 | +** |
| 75994 | +** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), |
| 75995 | +** then while records are being accumulated the list is linked using the |
| 75996 | +** SorterRecord.u.iNext offset. This is because the aMemory[] array may |
| 75997 | +** be sqlite3Realloc()ed while records are being accumulated. Once the VM |
| 75998 | +** has finished passing records to the sorter, or when the in-memory buffer |
| 75999 | +** is full, the list is sorted. As part of the sorting process, it is |
| 76000 | +** converted to use the SorterRecord.u.pNext pointers. See function |
| 76001 | +** vdbeSorterSort() for details. |
| 75145 | 76002 | */ |
| 75146 | 76003 | struct SorterRecord { |
| 75147 | | - void *pVal; |
| 75148 | | - int nVal; |
| 75149 | | - SorterRecord *pNext; |
| 76004 | + int nVal; /* Size of the record in bytes */ |
| 76005 | + union { |
| 76006 | + SorterRecord *pNext; /* Pointer to next record in list */ |
| 76007 | + int iNext; /* Offset within aMemory of next record */ |
| 76008 | + } u; |
| 76009 | + /* The data for the record immediately follows this header */ |
| 75150 | 76010 | }; |
| 75151 | 76011 | |
| 75152 | | -/* Minimum allowable value for the VdbeSorter.nWorking variable */ |
| 76012 | +/* Return a pointer to the buffer containing the record data for SorterRecord |
| 76013 | +** object p. Should be used as if: |
| 76014 | +** |
| 76015 | +** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } |
| 76016 | +*/ |
| 76017 | +#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) |
| 76018 | + |
| 76019 | +/* The minimum PMA size is set to this value multiplied by the database |
| 76020 | +** page size in bytes. */ |
| 75153 | 76021 | #define SORTER_MIN_WORKING 10 |
| 75154 | 76022 | |
| 75155 | | -/* Maximum number of segments to merge in a single pass. */ |
| 76023 | +/* Maximum number of PMAs that a single MergeEngine can merge */ |
| 75156 | 76024 | #define SORTER_MAX_MERGE_COUNT 16 |
| 75157 | 76025 | |
| 76026 | +static int vdbeIncrSwap(IncrMerger*); |
| 76027 | +static void vdbeIncrFree(IncrMerger *); |
| 76028 | + |
| 75158 | 76029 | /* |
| 75159 | | -** Free all memory belonging to the VdbeSorterIter object passed as the second |
| 76030 | +** Free all memory belonging to the PmaReader object passed as the |
| 75160 | 76031 | ** argument. All structure fields are set to zero before returning. |
| 75161 | 76032 | */ |
| 75162 | | -static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ |
| 75163 | | - sqlite3DbFree(db, pIter->aAlloc); |
| 75164 | | - sqlite3DbFree(db, pIter->aBuffer); |
| 75165 | | - memset(pIter, 0, sizeof(VdbeSorterIter)); |
| 76033 | +static void vdbePmaReaderClear(PmaReader *pReadr){ |
| 76034 | + sqlite3_free(pReadr->aAlloc); |
| 76035 | + sqlite3_free(pReadr->aBuffer); |
| 76036 | + if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); |
| 76037 | + vdbeIncrFree(pReadr->pIncr); |
| 76038 | + memset(pReadr, 0, sizeof(PmaReader)); |
| 75166 | 76039 | } |
| 75167 | 76040 | |
| 75168 | 76041 | /* |
| 75169 | | -** Read nByte bytes of data from the stream of data iterated by object p. |
| 76042 | +** Read the next nByte bytes of data from the PMA p. |
| 75170 | 76043 | ** If successful, set *ppOut to point to a buffer containing the data |
| 75171 | 76044 | ** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite |
| 75172 | 76045 | ** error code. |
| 75173 | 76046 | ** |
| 75174 | | -** The buffer indicated by *ppOut may only be considered valid until the |
| 76047 | +** The buffer returned in *ppOut is only valid until the |
| 75175 | 76048 | ** next call to this function. |
| 75176 | 76049 | */ |
| 75177 | | -static int vdbeSorterIterRead( |
| 75178 | | - sqlite3 *db, /* Database handle (for malloc) */ |
| 75179 | | - VdbeSorterIter *p, /* Iterator */ |
| 76050 | +static int vdbePmaReadBlob( |
| 76051 | + PmaReader *p, /* PmaReader from which to take the blob */ |
| 75180 | 76052 | int nByte, /* Bytes of data to read */ |
| 75181 | 76053 | u8 **ppOut /* OUT: Pointer to buffer containing data */ |
| 75182 | 76054 | ){ |
| 75183 | 76055 | int iBuf; /* Offset within buffer to read from */ |
| 75184 | 76056 | int nAvail; /* Bytes of data available in buffer */ |
| 76057 | + |
| 76058 | + if( p->aMap ){ |
| 76059 | + *ppOut = &p->aMap[p->iReadOff]; |
| 76060 | + p->iReadOff += nByte; |
| 76061 | + return SQLITE_OK; |
| 76062 | + } |
| 76063 | + |
| 75185 | 76064 | assert( p->aBuffer ); |
| 75186 | 76065 | |
| 75187 | 76066 | /* If there is no more data to be read from the buffer, read the next |
| 75188 | 76067 | ** p->nBuffer bytes of data from the file into it. Or, if there are less |
| 75189 | 76068 | ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ |
| | @@ -75198,12 +76077,12 @@ |
| 75198 | 76077 | }else{ |
| 75199 | 76078 | nRead = (int)(p->iEof - p->iReadOff); |
| 75200 | 76079 | } |
| 75201 | 76080 | assert( nRead>0 ); |
| 75202 | 76081 | |
| 75203 | | - /* Read data from the file. Return early if an error occurs. */ |
| 75204 | | - rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff); |
| 76082 | + /* Readr data from the file. Return early if an error occurs. */ |
| 76083 | + rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); |
| 75205 | 76084 | assert( rc!=SQLITE_IOERR_SHORT_READ ); |
| 75206 | 76085 | if( rc!=SQLITE_OK ) return rc; |
| 75207 | 76086 | } |
| 75208 | 76087 | nAvail = p->nBuffer - iBuf; |
| 75209 | 76088 | |
| | @@ -75219,15 +76098,17 @@ |
| 75219 | 76098 | ** range into. Then return a copy of pointer p->aAlloc to the caller. */ |
| 75220 | 76099 | int nRem; /* Bytes remaining to copy */ |
| 75221 | 76100 | |
| 75222 | 76101 | /* Extend the p->aAlloc[] allocation if required. */ |
| 75223 | 76102 | if( p->nAlloc<nByte ){ |
| 75224 | | - int nNew = p->nAlloc*2; |
| 76103 | + u8 *aNew; |
| 76104 | + int nNew = MAX(128, p->nAlloc*2); |
| 75225 | 76105 | while( nByte>nNew ) nNew = nNew*2; |
| 75226 | | - p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew); |
| 75227 | | - if( !p->aAlloc ) return SQLITE_NOMEM; |
| 76106 | + aNew = sqlite3Realloc(p->aAlloc, nNew); |
| 76107 | + if( !aNew ) return SQLITE_NOMEM; |
| 75228 | 76108 | p->nAlloc = nNew; |
| 76109 | + p->aAlloc = aNew; |
| 75229 | 76110 | } |
| 75230 | 76111 | |
| 75231 | 76112 | /* Copy as much data as is available in the buffer into the start of |
| 75232 | 76113 | ** p->aAlloc[]. */ |
| 75233 | 76114 | memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); |
| | @@ -75235,17 +76116,17 @@ |
| 75235 | 76116 | nRem = nByte - nAvail; |
| 75236 | 76117 | |
| 75237 | 76118 | /* The following loop copies up to p->nBuffer bytes per iteration into |
| 75238 | 76119 | ** the p->aAlloc[] buffer. */ |
| 75239 | 76120 | while( nRem>0 ){ |
| 75240 | | - int rc; /* vdbeSorterIterRead() return code */ |
| 76121 | + int rc; /* vdbePmaReadBlob() return code */ |
| 75241 | 76122 | int nCopy; /* Number of bytes to copy */ |
| 75242 | 76123 | u8 *aNext; /* Pointer to buffer to copy data from */ |
| 75243 | 76124 | |
| 75244 | 76125 | nCopy = nRem; |
| 75245 | 76126 | if( nRem>p->nBuffer ) nCopy = p->nBuffer; |
| 75246 | | - rc = vdbeSorterIterRead(db, p, nCopy, &aNext); |
| 76127 | + rc = vdbePmaReadBlob(p, nCopy, &aNext); |
| 75247 | 76128 | if( rc!=SQLITE_OK ) return rc; |
| 75248 | 76129 | assert( aNext!=p->aAlloc ); |
| 75249 | 76130 | memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); |
| 75250 | 76131 | nRem -= nCopy; |
| 75251 | 76132 | } |
| | @@ -75258,405 +76139,739 @@ |
| 75258 | 76139 | |
| 75259 | 76140 | /* |
| 75260 | 76141 | ** Read a varint from the stream of data accessed by p. Set *pnOut to |
| 75261 | 76142 | ** the value read. |
| 75262 | 76143 | */ |
| 75263 | | -static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){ |
| 75264 | | - int iBuf; |
| 75265 | | - |
| 75266 | | - iBuf = p->iReadOff % p->nBuffer; |
| 75267 | | - if( iBuf && (p->nBuffer-iBuf)>=9 ){ |
| 75268 | | - p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); |
| 75269 | | - }else{ |
| 75270 | | - u8 aVarint[16], *a; |
| 75271 | | - int i = 0, rc; |
| 75272 | | - do{ |
| 75273 | | - rc = vdbeSorterIterRead(db, p, 1, &a); |
| 75274 | | - if( rc ) return rc; |
| 75275 | | - aVarint[(i++)&0xf] = a[0]; |
| 75276 | | - }while( (a[0]&0x80)!=0 ); |
| 75277 | | - sqlite3GetVarint(aVarint, pnOut); |
| 75278 | | - } |
| 75279 | | - |
| 75280 | | - return SQLITE_OK; |
| 75281 | | -} |
| 75282 | | - |
| 75283 | | - |
| 75284 | | -/* |
| 75285 | | -** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if |
| 75286 | | -** no error occurs, or an SQLite error code if one does. |
| 75287 | | -*/ |
| 75288 | | -static int vdbeSorterIterNext( |
| 75289 | | - sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 75290 | | - VdbeSorterIter *pIter /* Iterator to advance */ |
| 75291 | | -){ |
| 75292 | | - int rc; /* Return Code */ |
| 75293 | | - u64 nRec = 0; /* Size of record in bytes */ |
| 75294 | | - |
| 75295 | | - if( pIter->iReadOff>=pIter->iEof ){ |
| 75296 | | - /* This is an EOF condition */ |
| 75297 | | - vdbeSorterIterZero(db, pIter); |
| 75298 | | - return SQLITE_OK; |
| 75299 | | - } |
| 75300 | | - |
| 75301 | | - rc = vdbeSorterIterVarint(db, pIter, &nRec); |
| 75302 | | - if( rc==SQLITE_OK ){ |
| 75303 | | - pIter->nKey = (int)nRec; |
| 75304 | | - rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey); |
| 75305 | | - } |
| 75306 | | - |
| 75307 | | - return rc; |
| 75308 | | -} |
| 75309 | | - |
| 75310 | | -/* |
| 75311 | | -** Initialize iterator pIter to scan through the PMA stored in file pFile |
| 75312 | | -** starting at offset iStart and ending at offset iEof-1. This function |
| 75313 | | -** leaves the iterator pointing to the first key in the PMA (or EOF if the |
| 75314 | | -** PMA is empty). |
| 75315 | | -*/ |
| 75316 | | -static int vdbeSorterIterInit( |
| 75317 | | - sqlite3 *db, /* Database handle */ |
| 75318 | | - const VdbeSorter *pSorter, /* Sorter object */ |
| 75319 | | - i64 iStart, /* Start offset in pFile */ |
| 75320 | | - VdbeSorterIter *pIter, /* Iterator to populate */ |
| 75321 | | - i64 *pnByte /* IN/OUT: Increment this value by PMA size */ |
| 75322 | | -){ |
| 75323 | | - int rc = SQLITE_OK; |
| 75324 | | - int nBuf; |
| 75325 | | - |
| 75326 | | - nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 75327 | | - |
| 75328 | | - assert( pSorter->iWriteOff>iStart ); |
| 75329 | | - assert( pIter->aAlloc==0 ); |
| 75330 | | - assert( pIter->aBuffer==0 ); |
| 75331 | | - pIter->pFile = pSorter->pTemp1; |
| 75332 | | - pIter->iReadOff = iStart; |
| 75333 | | - pIter->nAlloc = 128; |
| 75334 | | - pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 75335 | | - pIter->nBuffer = nBuf; |
| 75336 | | - pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); |
| 75337 | | - |
| 75338 | | - if( !pIter->aBuffer ){ |
| 75339 | | - rc = SQLITE_NOMEM; |
| 75340 | | - }else{ |
| 75341 | | - int iBuf; |
| 75342 | | - |
| 75343 | | - iBuf = iStart % nBuf; |
| 75344 | | - if( iBuf ){ |
| 75345 | | - int nRead = nBuf - iBuf; |
| 75346 | | - if( (iStart + nRead) > pSorter->iWriteOff ){ |
| 75347 | | - nRead = (int)(pSorter->iWriteOff - iStart); |
| 76144 | +static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ |
| 76145 | + int iBuf; |
| 76146 | + |
| 76147 | + if( p->aMap ){ |
| 76148 | + p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); |
| 76149 | + }else{ |
| 76150 | + iBuf = p->iReadOff % p->nBuffer; |
| 76151 | + if( iBuf && (p->nBuffer-iBuf)>=9 ){ |
| 76152 | + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); |
| 76153 | + }else{ |
| 76154 | + u8 aVarint[16], *a; |
| 76155 | + int i = 0, rc; |
| 76156 | + do{ |
| 76157 | + rc = vdbePmaReadBlob(p, 1, &a); |
| 76158 | + if( rc ) return rc; |
| 76159 | + aVarint[(i++)&0xf] = a[0]; |
| 76160 | + }while( (a[0]&0x80)!=0 ); |
| 76161 | + sqlite3GetVarint(aVarint, pnOut); |
| 76162 | + } |
| 76163 | + } |
| 76164 | + |
| 76165 | + return SQLITE_OK; |
| 76166 | +} |
| 76167 | + |
| 76168 | +/* |
| 76169 | +** Attempt to memory map file pFile. If successful, set *pp to point to the |
| 76170 | +** new mapping and return SQLITE_OK. If the mapping is not attempted |
| 76171 | +** (because the file is too large or the VFS layer is configured not to use |
| 76172 | +** mmap), return SQLITE_OK and set *pp to NULL. |
| 76173 | +** |
| 76174 | +** Or, if an error occurs, return an SQLite error code. The final value of |
| 76175 | +** *pp is undefined in this case. |
| 76176 | +*/ |
| 76177 | +static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ |
| 76178 | + int rc = SQLITE_OK; |
| 76179 | + if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ |
| 76180 | + rc = sqlite3OsFetch(pFile->pFd, 0, (int)pFile->iEof, (void**)pp); |
| 76181 | + testcase( rc!=SQLITE_OK ); |
| 76182 | + } |
| 76183 | + return rc; |
| 76184 | +} |
| 76185 | + |
| 76186 | +/* |
| 76187 | +** Attach PmaReader pReadr to file pFile (if it is not already attached to |
| 76188 | +** that file) and seek it to offset iOff within the file. Return SQLITE_OK |
| 76189 | +** if successful, or an SQLite error code if an error occurs. |
| 76190 | +*/ |
| 76191 | +static int vdbePmaReaderSeek( |
| 76192 | + SortSubtask *pTask, /* Task context */ |
| 76193 | + PmaReader *pReadr, /* Reader whose cursor is to be moved */ |
| 76194 | + SorterFile *pFile, /* Sorter file to read from */ |
| 76195 | + i64 iOff /* Offset in pFile */ |
| 76196 | +){ |
| 76197 | + int rc = SQLITE_OK; |
| 76198 | + |
| 76199 | + assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); |
| 76200 | + |
| 76201 | + if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; |
| 76202 | + if( pReadr->aMap ){ |
| 76203 | + sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); |
| 76204 | + pReadr->aMap = 0; |
| 76205 | + } |
| 76206 | + pReadr->iReadOff = iOff; |
| 76207 | + pReadr->iEof = pFile->iEof; |
| 76208 | + pReadr->pFd = pFile->pFd; |
| 76209 | + |
| 76210 | + rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap); |
| 76211 | + if( rc==SQLITE_OK && pReadr->aMap==0 ){ |
| 76212 | + int pgsz = pTask->pSorter->pgsz; |
| 76213 | + int iBuf = pReadr->iReadOff % pgsz; |
| 76214 | + if( pReadr->aBuffer==0 ){ |
| 76215 | + pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); |
| 76216 | + if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM; |
| 76217 | + pReadr->nBuffer = pgsz; |
| 76218 | + } |
| 76219 | + if( rc==SQLITE_OK && iBuf ){ |
| 76220 | + int nRead = pgsz - iBuf; |
| 76221 | + if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ |
| 76222 | + nRead = (int)(pReadr->iEof - pReadr->iReadOff); |
| 75348 | 76223 | } |
| 75349 | 76224 | rc = sqlite3OsRead( |
| 75350 | | - pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart |
| 76225 | + pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff |
| 75351 | 76226 | ); |
| 76227 | + testcase( rc!=SQLITE_OK ); |
| 76228 | + } |
| 76229 | + } |
| 76230 | + |
| 76231 | + return rc; |
| 76232 | +} |
| 76233 | + |
| 76234 | +/* |
| 76235 | +** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if |
| 76236 | +** no error occurs, or an SQLite error code if one does. |
| 76237 | +*/ |
| 76238 | +static int vdbePmaReaderNext(PmaReader *pReadr){ |
| 76239 | + int rc = SQLITE_OK; /* Return Code */ |
| 76240 | + u64 nRec = 0; /* Size of record in bytes */ |
| 76241 | + |
| 76242 | + |
| 76243 | + if( pReadr->iReadOff>=pReadr->iEof ){ |
| 76244 | + IncrMerger *pIncr = pReadr->pIncr; |
| 76245 | + int bEof = 1; |
| 76246 | + if( pIncr ){ |
| 76247 | + rc = vdbeIncrSwap(pIncr); |
| 76248 | + if( rc==SQLITE_OK && pIncr->bEof==0 ){ |
| 76249 | + rc = vdbePmaReaderSeek( |
| 76250 | + pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff |
| 76251 | + ); |
| 76252 | + bEof = 0; |
| 76253 | + } |
| 75352 | 76254 | } |
| 75353 | 76255 | |
| 75354 | | - if( rc==SQLITE_OK ){ |
| 75355 | | - u64 nByte; /* Size of PMA in bytes */ |
| 75356 | | - pIter->iEof = pSorter->iWriteOff; |
| 75357 | | - rc = vdbeSorterIterVarint(db, pIter, &nByte); |
| 75358 | | - pIter->iEof = pIter->iReadOff + nByte; |
| 75359 | | - *pnByte += nByte; |
| 76256 | + if( bEof ){ |
| 76257 | + /* This is an EOF condition */ |
| 76258 | + vdbePmaReaderClear(pReadr); |
| 76259 | + testcase( rc!=SQLITE_OK ); |
| 76260 | + return rc; |
| 75360 | 76261 | } |
| 75361 | 76262 | } |
| 75362 | 76263 | |
| 75363 | 76264 | if( rc==SQLITE_OK ){ |
| 75364 | | - rc = vdbeSorterIterNext(db, pIter); |
| 76265 | + rc = vdbePmaReadVarint(pReadr, &nRec); |
| 76266 | + } |
| 76267 | + if( rc==SQLITE_OK ){ |
| 76268 | + pReadr->nKey = (int)nRec; |
| 76269 | + rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey); |
| 76270 | + testcase( rc!=SQLITE_OK ); |
| 76271 | + } |
| 76272 | + |
| 76273 | + return rc; |
| 76274 | +} |
| 76275 | + |
| 76276 | +/* |
| 76277 | +** Initialize PmaReader pReadr to scan through the PMA stored in file pFile |
| 76278 | +** starting at offset iStart and ending at offset iEof-1. This function |
| 76279 | +** leaves the PmaReader pointing to the first key in the PMA (or EOF if the |
| 76280 | +** PMA is empty). |
| 76281 | +** |
| 76282 | +** If the pnByte parameter is NULL, then it is assumed that the file |
| 76283 | +** contains a single PMA, and that that PMA omits the initial length varint. |
| 76284 | +*/ |
| 76285 | +static int vdbePmaReaderInit( |
| 76286 | + SortSubtask *pTask, /* Task context */ |
| 76287 | + SorterFile *pFile, /* Sorter file to read from */ |
| 76288 | + i64 iStart, /* Start offset in pFile */ |
| 76289 | + PmaReader *pReadr, /* PmaReader to populate */ |
| 76290 | + i64 *pnByte /* IN/OUT: Increment this value by PMA size */ |
| 76291 | +){ |
| 76292 | + int rc; |
| 76293 | + |
| 76294 | + assert( pFile->iEof>iStart ); |
| 76295 | + assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 ); |
| 76296 | + assert( pReadr->aBuffer==0 ); |
| 76297 | + assert( pReadr->aMap==0 ); |
| 76298 | + |
| 76299 | + rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart); |
| 76300 | + if( rc==SQLITE_OK ){ |
| 76301 | + u64 nByte; /* Size of PMA in bytes */ |
| 76302 | + rc = vdbePmaReadVarint(pReadr, &nByte); |
| 76303 | + pReadr->iEof = pReadr->iReadOff + nByte; |
| 76304 | + *pnByte += nByte; |
| 76305 | + } |
| 76306 | + |
| 76307 | + if( rc==SQLITE_OK ){ |
| 76308 | + rc = vdbePmaReaderNext(pReadr); |
| 75365 | 76309 | } |
| 75366 | 76310 | return rc; |
| 75367 | 76311 | } |
| 75368 | 76312 | |
| 75369 | 76313 | |
| 75370 | 76314 | /* |
| 75371 | 76315 | ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, |
| 75372 | | -** size nKey2 bytes). Argument pKeyInfo supplies the collation functions |
| 75373 | | -** used by the comparison. If an error occurs, return an SQLite error code. |
| 75374 | | -** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive |
| 75375 | | -** value, depending on whether key1 is smaller, equal to or larger than key2. |
| 75376 | | -** |
| 75377 | | -** If the bOmitRowid argument is non-zero, assume both keys end in a rowid |
| 75378 | | -** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid |
| 75379 | | -** is true and key1 contains even a single NULL value, it is considered to |
| 75380 | | -** be less than key2. Even if key2 also contains NULL values. |
| 75381 | | -** |
| 75382 | | -** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 75383 | | -** has been allocated and contains an unpacked record that is used as key2. |
| 75384 | | -*/ |
| 75385 | | -static void vdbeSorterCompare( |
| 75386 | | - const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 75387 | | - int nKeyCol, /* Num of columns. 0 means "all" */ |
| 76316 | +** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences |
| 76317 | +** used by the comparison. Return the result of the comparison. |
| 76318 | +** |
| 76319 | +** Before returning, object (pTask->pUnpacked) is populated with the |
| 76320 | +** unpacked version of key2. Or, if pKey2 is passed a NULL pointer, then it |
| 76321 | +** is assumed that the (pTask->pUnpacked) structure already contains the |
| 76322 | +** unpacked key to use as key2. |
| 76323 | +** |
| 76324 | +** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set |
| 76325 | +** to SQLITE_NOMEM. |
| 76326 | +*/ |
| 76327 | +static int vdbeSorterCompare( |
| 76328 | + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ |
| 75388 | 76329 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 75389 | | - const void *pKey2, int nKey2, /* Right side of comparison */ |
| 75390 | | - int *pRes /* OUT: Result of comparison */ |
| 76330 | + const void *pKey2, int nKey2 /* Right side of comparison */ |
| 75391 | 76331 | ){ |
| 75392 | | - KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 75393 | | - VdbeSorter *pSorter = pCsr->pSorter; |
| 75394 | | - UnpackedRecord *r2 = pSorter->pUnpacked; |
| 75395 | | - int i; |
| 75396 | | - |
| 76332 | + UnpackedRecord *r2 = pTask->pUnpacked; |
| 75397 | 76333 | if( pKey2 ){ |
| 75398 | | - sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 75399 | | - } |
| 75400 | | - |
| 75401 | | - if( nKeyCol ){ |
| 75402 | | - r2->nField = nKeyCol; |
| 75403 | | - for(i=0; i<nKeyCol; i++){ |
| 75404 | | - if( r2->aMem[i].flags & MEM_Null ){ |
| 75405 | | - *pRes = -1; |
| 75406 | | - return; |
| 75407 | | - } |
| 75408 | | - } |
| 75409 | | - assert( r2->default_rc==0 ); |
| 75410 | | - } |
| 75411 | | - |
| 75412 | | - *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0); |
| 75413 | | -} |
| 75414 | | - |
| 75415 | | -/* |
| 75416 | | -** This function is called to compare two iterator keys when merging |
| 75417 | | -** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 75418 | | -** value to recalculate. |
| 75419 | | -*/ |
| 75420 | | -static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){ |
| 75421 | | - VdbeSorter *pSorter = pCsr->pSorter; |
| 75422 | | - int i1; |
| 75423 | | - int i2; |
| 75424 | | - int iRes; |
| 75425 | | - VdbeSorterIter *p1; |
| 75426 | | - VdbeSorterIter *p2; |
| 75427 | | - |
| 75428 | | - assert( iOut<pSorter->nTree && iOut>0 ); |
| 75429 | | - |
| 75430 | | - if( iOut>=(pSorter->nTree/2) ){ |
| 75431 | | - i1 = (iOut - pSorter->nTree/2) * 2; |
| 75432 | | - i2 = i1 + 1; |
| 75433 | | - }else{ |
| 75434 | | - i1 = pSorter->aTree[iOut*2]; |
| 75435 | | - i2 = pSorter->aTree[iOut*2+1]; |
| 75436 | | - } |
| 75437 | | - |
| 75438 | | - p1 = &pSorter->aIter[i1]; |
| 75439 | | - p2 = &pSorter->aIter[i2]; |
| 75440 | | - |
| 75441 | | - if( p1->pFile==0 ){ |
| 75442 | | - iRes = i2; |
| 75443 | | - }else if( p2->pFile==0 ){ |
| 75444 | | - iRes = i1; |
| 75445 | | - }else{ |
| 75446 | | - int res; |
| 75447 | | - assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */ |
| 75448 | | - vdbeSorterCompare( |
| 75449 | | - pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res |
| 75450 | | - ); |
| 75451 | | - if( res<=0 ){ |
| 75452 | | - iRes = i1; |
| 75453 | | - }else{ |
| 75454 | | - iRes = i2; |
| 75455 | | - } |
| 75456 | | - } |
| 75457 | | - |
| 75458 | | - pSorter->aTree[iOut] = iRes; |
| 75459 | | - return SQLITE_OK; |
| 76334 | + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); |
| 76335 | + } |
| 76336 | + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0); |
| 75460 | 76337 | } |
| 75461 | 76338 | |
| 75462 | 76339 | /* |
| 75463 | 76340 | ** Initialize the temporary index cursor just opened as a sorter cursor. |
| 76341 | +** |
| 76342 | +** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField) |
| 76343 | +** to determine the number of fields that should be compared from the |
| 76344 | +** records being sorted. However, if the value passed as argument nField |
| 76345 | +** is non-zero and the sorter is able to guarantee a stable sort, nField |
| 76346 | +** is used instead. This is used when sorting records for a CREATE INDEX |
| 76347 | +** statement. In this case, keys are always delivered to the sorter in |
| 76348 | +** order of the primary key, which happens to be make up the final part |
| 76349 | +** of the records being sorted. So if the sort is stable, there is never |
| 76350 | +** any reason to compare PK fields and they can be ignored for a small |
| 76351 | +** performance boost. |
| 76352 | +** |
| 76353 | +** The sorter can guarantee a stable sort when running in single-threaded |
| 76354 | +** mode, but not in multi-threaded mode. |
| 76355 | +** |
| 76356 | +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 75464 | 76357 | */ |
| 75465 | | -SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ |
| 76358 | +SQLITE_PRIVATE int sqlite3VdbeSorterInit( |
| 76359 | + sqlite3 *db, /* Database connection (for malloc()) */ |
| 76360 | + int nField, /* Number of key fields in each record */ |
| 76361 | + VdbeCursor *pCsr /* Cursor that holds the new sorter */ |
| 76362 | +){ |
| 75466 | 76363 | int pgsz; /* Page size of main database */ |
| 76364 | + int i; /* Used to iterate through aTask[] */ |
| 75467 | 76365 | int mxCache; /* Cache size */ |
| 75468 | 76366 | VdbeSorter *pSorter; /* The new sorter */ |
| 75469 | | - char *d; /* Dummy */ |
| 76367 | + KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ |
| 76368 | + int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ |
| 76369 | + int sz; /* Size of pSorter in bytes */ |
| 76370 | + int rc = SQLITE_OK; |
| 76371 | +#if SQLITE_MAX_WORKER_THREADS==0 |
| 76372 | +# define nWorker 0 |
| 76373 | +#else |
| 76374 | + int nWorker; |
| 76375 | +#endif |
| 76376 | + |
| 76377 | + /* Initialize the upper limit on the number of worker threads */ |
| 76378 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 76379 | + if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ |
| 76380 | + nWorker = 0; |
| 76381 | + }else{ |
| 76382 | + nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; |
| 76383 | + } |
| 76384 | +#endif |
| 76385 | + |
| 76386 | + /* Do not allow the total number of threads (main thread + all workers) |
| 76387 | + ** to exceed the maximum merge count */ |
| 76388 | +#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT |
| 76389 | + if( nWorker>=SORTER_MAX_MERGE_COUNT ){ |
| 76390 | + nWorker = SORTER_MAX_MERGE_COUNT-1; |
| 76391 | + } |
| 76392 | +#endif |
| 75470 | 76393 | |
| 75471 | 76394 | assert( pCsr->pKeyInfo && pCsr->pBt==0 ); |
| 75472 | | - pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); |
| 76395 | + szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); |
| 76396 | + sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); |
| 76397 | + |
| 76398 | + pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 76399 | + pCsr->pSorter = pSorter; |
| 75473 | 76400 | if( pSorter==0 ){ |
| 75474 | | - return SQLITE_NOMEM; |
| 75475 | | - } |
| 75476 | | - |
| 75477 | | - pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d); |
| 75478 | | - if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM; |
| 75479 | | - assert( pSorter->pUnpacked==(UnpackedRecord *)d ); |
| 75480 | | - |
| 75481 | | - if( !sqlite3TempInMemory(db) ){ |
| 75482 | | - pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 75483 | | - pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; |
| 75484 | | - mxCache = db->aDb[0].pSchema->cache_size; |
| 75485 | | - if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; |
| 75486 | | - pSorter->mxPmaSize = mxCache * pgsz; |
| 75487 | | - } |
| 75488 | | - |
| 75489 | | - return SQLITE_OK; |
| 75490 | | -} |
| 76401 | + rc = SQLITE_NOMEM; |
| 76402 | + }else{ |
| 76403 | + pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); |
| 76404 | + memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); |
| 76405 | + pKeyInfo->db = 0; |
| 76406 | + if( nField && nWorker==0 ) pKeyInfo->nField = nField; |
| 76407 | + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 76408 | + pSorter->nTask = nWorker + 1; |
| 76409 | + pSorter->bUseThreads = (pSorter->nTask>1); |
| 76410 | + pSorter->db = db; |
| 76411 | + for(i=0; i<pSorter->nTask; i++){ |
| 76412 | + SortSubtask *pTask = &pSorter->aTask[i]; |
| 76413 | + pTask->pSorter = pSorter; |
| 76414 | + } |
| 76415 | + |
| 76416 | + if( !sqlite3TempInMemory(db) ){ |
| 76417 | + pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; |
| 76418 | + mxCache = db->aDb[0].pSchema->cache_size; |
| 76419 | + if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; |
| 76420 | + pSorter->mxPmaSize = mxCache * pgsz; |
| 76421 | + |
| 76422 | + /* If the application has not configure scratch memory using |
| 76423 | + ** SQLITE_CONFIG_SCRATCH then we assume it is OK to do large memory |
| 76424 | + ** allocations. If scratch memory has been configured, then assume |
| 76425 | + ** large memory allocations should be avoided to prevent heap |
| 76426 | + ** fragmentation. |
| 76427 | + */ |
| 76428 | + if( sqlite3GlobalConfig.pScratch==0 ){ |
| 76429 | + assert( pSorter->iMemory==0 ); |
| 76430 | + pSorter->nMemory = pgsz; |
| 76431 | + pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); |
| 76432 | + if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM; |
| 76433 | + } |
| 76434 | + } |
| 76435 | + } |
| 76436 | + |
| 76437 | + return rc; |
| 76438 | +} |
| 76439 | +#undef nWorker /* Defined at the top of this function */ |
| 75491 | 76440 | |
| 75492 | 76441 | /* |
| 75493 | 76442 | ** Free the list of sorted records starting at pRecord. |
| 75494 | 76443 | */ |
| 75495 | 76444 | static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ |
| 75496 | 76445 | SorterRecord *p; |
| 75497 | 76446 | SorterRecord *pNext; |
| 75498 | 76447 | for(p=pRecord; p; p=pNext){ |
| 75499 | | - pNext = p->pNext; |
| 76448 | + pNext = p->u.pNext; |
| 75500 | 76449 | sqlite3DbFree(db, p); |
| 75501 | 76450 | } |
| 75502 | 76451 | } |
| 76452 | + |
| 76453 | +/* |
| 76454 | +** Free all resources owned by the object indicated by argument pTask. All |
| 76455 | +** fields of *pTask are zeroed before returning. |
| 76456 | +*/ |
| 76457 | +static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ |
| 76458 | + sqlite3DbFree(db, pTask->pUnpacked); |
| 76459 | + pTask->pUnpacked = 0; |
| 76460 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 76461 | + /* pTask->list.aMemory can only be non-zero if it was handed memory |
| 76462 | + ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ |
| 76463 | + if( pTask->list.aMemory ){ |
| 76464 | + sqlite3_free(pTask->list.aMemory); |
| 76465 | + pTask->list.aMemory = 0; |
| 76466 | + }else |
| 76467 | +#endif |
| 76468 | + { |
| 76469 | + assert( pTask->list.aMemory==0 ); |
| 76470 | + vdbeSorterRecordFree(0, pTask->list.pList); |
| 76471 | + } |
| 76472 | + pTask->list.pList = 0; |
| 76473 | + if( pTask->file.pFd ){ |
| 76474 | + sqlite3OsCloseFree(pTask->file.pFd); |
| 76475 | + pTask->file.pFd = 0; |
| 76476 | + pTask->file.iEof = 0; |
| 76477 | + } |
| 76478 | + if( pTask->file2.pFd ){ |
| 76479 | + sqlite3OsCloseFree(pTask->file2.pFd); |
| 76480 | + pTask->file2.pFd = 0; |
| 76481 | + pTask->file2.iEof = 0; |
| 76482 | + } |
| 76483 | +} |
| 76484 | + |
| 76485 | +#ifdef SQLITE_DEBUG_SORTER_THREADS |
| 76486 | +static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ |
| 76487 | + i64 t; |
| 76488 | + int iTask = (pTask - pTask->pSorter->aTask); |
| 76489 | + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); |
| 76490 | + fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); |
| 76491 | +} |
| 76492 | +static void vdbeSorterRewindDebug(const char *zEvent){ |
| 76493 | + i64 t; |
| 76494 | + sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t); |
| 76495 | + fprintf(stderr, "%lld:X %s\n", t, zEvent); |
| 76496 | +} |
| 76497 | +static void vdbeSorterPopulateDebug( |
| 76498 | + SortSubtask *pTask, |
| 76499 | + const char *zEvent |
| 76500 | +){ |
| 76501 | + i64 t; |
| 76502 | + int iTask = (pTask - pTask->pSorter->aTask); |
| 76503 | + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); |
| 76504 | + fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); |
| 76505 | +} |
| 76506 | +static void vdbeSorterBlockDebug( |
| 76507 | + SortSubtask *pTask, |
| 76508 | + int bBlocked, |
| 76509 | + const char *zEvent |
| 76510 | +){ |
| 76511 | + if( bBlocked ){ |
| 76512 | + i64 t; |
| 76513 | + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); |
| 76514 | + fprintf(stderr, "%lld:main %s\n", t, zEvent); |
| 76515 | + } |
| 76516 | +} |
| 76517 | +#else |
| 76518 | +# define vdbeSorterWorkDebug(x,y) |
| 76519 | +# define vdbeSorterRewindDebug(y) |
| 76520 | +# define vdbeSorterPopulateDebug(x,y) |
| 76521 | +# define vdbeSorterBlockDebug(x,y,z) |
| 76522 | +#endif |
| 76523 | + |
| 76524 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 76525 | +/* |
| 76526 | +** Join thread pTask->thread. |
| 76527 | +*/ |
| 76528 | +static int vdbeSorterJoinThread(SortSubtask *pTask){ |
| 76529 | + int rc = SQLITE_OK; |
| 76530 | + if( pTask->pThread ){ |
| 76531 | +#ifdef SQLITE_DEBUG_SORTER_THREADS |
| 76532 | + int bDone = pTask->bDone; |
| 76533 | +#endif |
| 76534 | + void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); |
| 76535 | + vdbeSorterBlockDebug(pTask, !bDone, "enter"); |
| 76536 | + (void)sqlite3ThreadJoin(pTask->pThread, &pRet); |
| 76537 | + vdbeSorterBlockDebug(pTask, !bDone, "exit"); |
| 76538 | + rc = SQLITE_PTR_TO_INT(pRet); |
| 76539 | + assert( pTask->bDone==1 ); |
| 76540 | + pTask->bDone = 0; |
| 76541 | + pTask->pThread = 0; |
| 76542 | + } |
| 76543 | + return rc; |
| 76544 | +} |
| 76545 | + |
| 76546 | +/* |
| 76547 | +** Launch a background thread to run xTask(pIn). |
| 76548 | +*/ |
| 76549 | +static int vdbeSorterCreateThread( |
| 76550 | + SortSubtask *pTask, /* Thread will use this task object */ |
| 76551 | + void *(*xTask)(void*), /* Routine to run in a separate thread */ |
| 76552 | + void *pIn /* Argument passed into xTask() */ |
| 76553 | +){ |
| 76554 | + assert( pTask->pThread==0 && pTask->bDone==0 ); |
| 76555 | + return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); |
| 76556 | +} |
| 76557 | + |
| 76558 | +/* |
| 76559 | +** Join all outstanding threads launched by SorterWrite() to create |
| 76560 | +** level-0 PMAs. |
| 76561 | +*/ |
| 76562 | +static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ |
| 76563 | + int rc = rcin; |
| 76564 | + int i; |
| 76565 | + |
| 76566 | + /* This function is always called by the main user thread. |
| 76567 | + ** |
| 76568 | + ** If this function is being called after SorterRewind() has been called, |
| 76569 | + ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread |
| 76570 | + ** is currently attempt to join one of the other threads. To avoid a race |
| 76571 | + ** condition where this thread also attempts to join the same object, join |
| 76572 | + ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ |
| 76573 | + for(i=pSorter->nTask-1; i>=0; i--){ |
| 76574 | + SortSubtask *pTask = &pSorter->aTask[i]; |
| 76575 | + int rc2 = vdbeSorterJoinThread(pTask); |
| 76576 | + if( rc==SQLITE_OK ) rc = rc2; |
| 76577 | + } |
| 76578 | + return rc; |
| 76579 | +} |
| 76580 | +#else |
| 76581 | +# define vdbeSorterJoinAll(x,rcin) (rcin) |
| 76582 | +# define vdbeSorterJoinThread(pTask) SQLITE_OK |
| 76583 | +#endif |
| 76584 | + |
| 76585 | +/* |
| 76586 | +** Allocate a new MergeEngine object capable of handling up to |
| 76587 | +** nReader PmaReader inputs. |
| 76588 | +** |
| 76589 | +** nReader is automatically rounded up to the next power of two. |
| 76590 | +** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up. |
| 76591 | +*/ |
| 76592 | +static MergeEngine *vdbeMergeEngineNew(int nReader){ |
| 76593 | + int N = 2; /* Smallest power of two >= nReader */ |
| 76594 | + int nByte; /* Total bytes of space to allocate */ |
| 76595 | + MergeEngine *pNew; /* Pointer to allocated object to return */ |
| 76596 | + |
| 76597 | + assert( nReader<=SORTER_MAX_MERGE_COUNT ); |
| 76598 | + |
| 76599 | + while( N<nReader ) N += N; |
| 76600 | + nByte = sizeof(MergeEngine) + N * (sizeof(int) + sizeof(PmaReader)); |
| 76601 | + |
| 76602 | + pNew = sqlite3FaultSim(100) ? 0 : (MergeEngine*)sqlite3MallocZero(nByte); |
| 76603 | + if( pNew ){ |
| 76604 | + pNew->nTree = N; |
| 76605 | + pNew->pTask = 0; |
| 76606 | + pNew->aReadr = (PmaReader*)&pNew[1]; |
| 76607 | + pNew->aTree = (int*)&pNew->aReadr[N]; |
| 76608 | + } |
| 76609 | + return pNew; |
| 76610 | +} |
| 76611 | + |
| 76612 | +/* |
| 76613 | +** Free the MergeEngine object passed as the only argument. |
| 76614 | +*/ |
| 76615 | +static void vdbeMergeEngineFree(MergeEngine *pMerger){ |
| 76616 | + int i; |
| 76617 | + if( pMerger ){ |
| 76618 | + for(i=0; i<pMerger->nTree; i++){ |
| 76619 | + vdbePmaReaderClear(&pMerger->aReadr[i]); |
| 76620 | + } |
| 76621 | + } |
| 76622 | + sqlite3_free(pMerger); |
| 76623 | +} |
| 76624 | + |
| 76625 | +/* |
| 76626 | +** Free all resources associated with the IncrMerger object indicated by |
| 76627 | +** the first argument. |
| 76628 | +*/ |
| 76629 | +static void vdbeIncrFree(IncrMerger *pIncr){ |
| 76630 | + if( pIncr ){ |
| 76631 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 76632 | + if( pIncr->bUseThread ){ |
| 76633 | + vdbeSorterJoinThread(pIncr->pTask); |
| 76634 | + if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); |
| 76635 | + if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); |
| 76636 | + } |
| 76637 | +#endif |
| 76638 | + vdbeMergeEngineFree(pIncr->pMerger); |
| 76639 | + sqlite3_free(pIncr); |
| 76640 | + } |
| 76641 | +} |
| 75503 | 76642 | |
| 75504 | 76643 | /* |
| 75505 | 76644 | ** Reset a sorting cursor back to its original empty state. |
| 75506 | 76645 | */ |
| 75507 | 76646 | SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ |
| 75508 | | - if( pSorter->aIter ){ |
| 75509 | | - int i; |
| 75510 | | - for(i=0; i<pSorter->nTree; i++){ |
| 75511 | | - vdbeSorterIterZero(db, &pSorter->aIter[i]); |
| 75512 | | - } |
| 75513 | | - sqlite3DbFree(db, pSorter->aIter); |
| 75514 | | - pSorter->aIter = 0; |
| 75515 | | - } |
| 75516 | | - if( pSorter->pTemp1 ){ |
| 75517 | | - sqlite3OsCloseFree(pSorter->pTemp1); |
| 75518 | | - pSorter->pTemp1 = 0; |
| 75519 | | - } |
| 75520 | | - vdbeSorterRecordFree(db, pSorter->pRecord); |
| 75521 | | - pSorter->pRecord = 0; |
| 75522 | | - pSorter->iWriteOff = 0; |
| 75523 | | - pSorter->iReadOff = 0; |
| 75524 | | - pSorter->nInMemory = 0; |
| 75525 | | - pSorter->nTree = 0; |
| 75526 | | - pSorter->nPMA = 0; |
| 75527 | | - pSorter->aTree = 0; |
| 75528 | | -} |
| 75529 | | - |
| 76647 | + int i; |
| 76648 | + (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); |
| 76649 | + assert( pSorter->bUseThreads || pSorter->pReader==0 ); |
| 76650 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 76651 | + if( pSorter->pReader ){ |
| 76652 | + vdbePmaReaderClear(pSorter->pReader); |
| 76653 | + sqlite3DbFree(db, pSorter->pReader); |
| 76654 | + pSorter->pReader = 0; |
| 76655 | + } |
| 76656 | +#endif |
| 76657 | + vdbeMergeEngineFree(pSorter->pMerger); |
| 76658 | + pSorter->pMerger = 0; |
| 76659 | + for(i=0; i<pSorter->nTask; i++){ |
| 76660 | + SortSubtask *pTask = &pSorter->aTask[i]; |
| 76661 | + vdbeSortSubtaskCleanup(db, pTask); |
| 76662 | + } |
| 76663 | + if( pSorter->list.aMemory==0 ){ |
| 76664 | + vdbeSorterRecordFree(0, pSorter->list.pList); |
| 76665 | + } |
| 76666 | + pSorter->list.pList = 0; |
| 76667 | + pSorter->list.szPMA = 0; |
| 76668 | + pSorter->bUsePMA = 0; |
| 76669 | + pSorter->iMemory = 0; |
| 76670 | + pSorter->mxKeysize = 0; |
| 76671 | + sqlite3DbFree(db, pSorter->pUnpacked); |
| 76672 | + pSorter->pUnpacked = 0; |
| 76673 | +} |
| 75530 | 76674 | |
| 75531 | 76675 | /* |
| 75532 | 76676 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 75533 | 76677 | */ |
| 75534 | 76678 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ |
| 75535 | 76679 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75536 | 76680 | if( pSorter ){ |
| 75537 | 76681 | sqlite3VdbeSorterReset(db, pSorter); |
| 75538 | | - sqlite3DbFree(db, pSorter->pUnpacked); |
| 76682 | + sqlite3_free(pSorter->list.aMemory); |
| 75539 | 76683 | sqlite3DbFree(db, pSorter); |
| 75540 | 76684 | pCsr->pSorter = 0; |
| 75541 | 76685 | } |
| 75542 | 76686 | } |
| 75543 | 76687 | |
| 76688 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 76689 | +/* |
| 76690 | +** The first argument is a file-handle open on a temporary file. The file |
| 76691 | +** is guaranteed to be nByte bytes or smaller in size. This function |
| 76692 | +** attempts to extend the file to nByte bytes in size and to ensure that |
| 76693 | +** the VFS has memory mapped it. |
| 76694 | +** |
| 76695 | +** Whether or not the file does end up memory mapped of course depends on |
| 76696 | +** the specific VFS implementation. |
| 76697 | +*/ |
| 76698 | +static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ |
| 76699 | + if( nByte<=(i64)(db->nMaxSorterMmap) ){ |
| 76700 | + int rc = sqlite3OsTruncate(pFd, nByte); |
| 76701 | + if( rc==SQLITE_OK ){ |
| 76702 | + void *p = 0; |
| 76703 | + sqlite3OsFetch(pFd, 0, (int)nByte, &p); |
| 76704 | + sqlite3OsUnfetch(pFd, 0, p); |
| 76705 | + } |
| 76706 | + } |
| 76707 | +} |
| 76708 | +#else |
| 76709 | +# define vdbeSorterExtendFile(x,y,z) |
| 76710 | +#endif |
| 76711 | + |
| 75544 | 76712 | /* |
| 75545 | 76713 | ** Allocate space for a file-handle and open a temporary file. If successful, |
| 75546 | | -** set *ppFile to point to the malloc'd file-handle and return SQLITE_OK. |
| 75547 | | -** Otherwise, set *ppFile to 0 and return an SQLite error code. |
| 76714 | +** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. |
| 76715 | +** Otherwise, set *ppFd to 0 and return an SQLite error code. |
| 75548 | 76716 | */ |
| 75549 | | -static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){ |
| 75550 | | - int dummy; |
| 75551 | | - return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile, |
| 76717 | +static int vdbeSorterOpenTempFile( |
| 76718 | + sqlite3 *db, /* Database handle doing sort */ |
| 76719 | + i64 nExtend, /* Attempt to extend file to this size */ |
| 76720 | + sqlite3_file **ppFd |
| 76721 | +){ |
| 76722 | + int rc; |
| 76723 | + rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, |
| 75552 | 76724 | SQLITE_OPEN_TEMP_JOURNAL | |
| 75553 | 76725 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| 75554 | | - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy |
| 76726 | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc |
| 75555 | 76727 | ); |
| 76728 | + if( rc==SQLITE_OK ){ |
| 76729 | + i64 max = SQLITE_MAX_MMAP_SIZE; |
| 76730 | + sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); |
| 76731 | + if( nExtend>0 ){ |
| 76732 | + vdbeSorterExtendFile(db, *ppFd, nExtend); |
| 76733 | + } |
| 76734 | + } |
| 76735 | + return rc; |
| 75556 | 76736 | } |
| 76737 | + |
| 76738 | +/* |
| 76739 | +** If it has not already been allocated, allocate the UnpackedRecord |
| 76740 | +** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or |
| 76741 | +** if no allocation was required), or SQLITE_NOMEM otherwise. |
| 76742 | +*/ |
| 76743 | +static int vdbeSortAllocUnpacked(SortSubtask *pTask){ |
| 76744 | + if( pTask->pUnpacked==0 ){ |
| 76745 | + char *pFree; |
| 76746 | + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord( |
| 76747 | + pTask->pSorter->pKeyInfo, 0, 0, &pFree |
| 76748 | + ); |
| 76749 | + assert( pTask->pUnpacked==(UnpackedRecord*)pFree ); |
| 76750 | + if( pFree==0 ) return SQLITE_NOMEM; |
| 76751 | + pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; |
| 76752 | + pTask->pUnpacked->errCode = 0; |
| 76753 | + } |
| 76754 | + return SQLITE_OK; |
| 76755 | +} |
| 76756 | + |
| 75557 | 76757 | |
| 75558 | 76758 | /* |
| 75559 | 76759 | ** Merge the two sorted lists p1 and p2 into a single list. |
| 75560 | 76760 | ** Set *ppOut to the head of the new list. |
| 75561 | 76761 | */ |
| 75562 | 76762 | static void vdbeSorterMerge( |
| 75563 | | - const VdbeCursor *pCsr, /* For pKeyInfo */ |
| 76763 | + SortSubtask *pTask, /* Calling thread context */ |
| 75564 | 76764 | SorterRecord *p1, /* First list to merge */ |
| 75565 | 76765 | SorterRecord *p2, /* Second list to merge */ |
| 75566 | 76766 | SorterRecord **ppOut /* OUT: Head of merged list */ |
| 75567 | 76767 | ){ |
| 75568 | 76768 | SorterRecord *pFinal = 0; |
| 75569 | 76769 | SorterRecord **pp = &pFinal; |
| 75570 | | - void *pVal2 = p2 ? p2->pVal : 0; |
| 76770 | + void *pVal2 = p2 ? SRVAL(p2) : 0; |
| 75571 | 76771 | |
| 75572 | 76772 | while( p1 && p2 ){ |
| 75573 | 76773 | int res; |
| 75574 | | - vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); |
| 76774 | + res = vdbeSorterCompare(pTask, SRVAL(p1), p1->nVal, pVal2, p2->nVal); |
| 75575 | 76775 | if( res<=0 ){ |
| 75576 | 76776 | *pp = p1; |
| 75577 | | - pp = &p1->pNext; |
| 75578 | | - p1 = p1->pNext; |
| 76777 | + pp = &p1->u.pNext; |
| 76778 | + p1 = p1->u.pNext; |
| 75579 | 76779 | pVal2 = 0; |
| 75580 | 76780 | }else{ |
| 75581 | 76781 | *pp = p2; |
| 75582 | | - pp = &p2->pNext; |
| 75583 | | - p2 = p2->pNext; |
| 76782 | + pp = &p2->u.pNext; |
| 76783 | + p2 = p2->u.pNext; |
| 75584 | 76784 | if( p2==0 ) break; |
| 75585 | | - pVal2 = p2->pVal; |
| 76785 | + pVal2 = SRVAL(p2); |
| 75586 | 76786 | } |
| 75587 | 76787 | } |
| 75588 | 76788 | *pp = p1 ? p1 : p2; |
| 75589 | 76789 | *ppOut = pFinal; |
| 75590 | 76790 | } |
| 75591 | 76791 | |
| 75592 | 76792 | /* |
| 75593 | | -** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 75594 | | -** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 75595 | | -** occurs. |
| 76793 | +** Sort the linked list of records headed at pTask->pList. Return |
| 76794 | +** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if |
| 76795 | +** an error occurs. |
| 75596 | 76796 | */ |
| 75597 | | -static int vdbeSorterSort(const VdbeCursor *pCsr){ |
| 76797 | +static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ |
| 75598 | 76798 | int i; |
| 75599 | 76799 | SorterRecord **aSlot; |
| 75600 | 76800 | SorterRecord *p; |
| 75601 | | - VdbeSorter *pSorter = pCsr->pSorter; |
| 76801 | + int rc; |
| 76802 | + |
| 76803 | + rc = vdbeSortAllocUnpacked(pTask); |
| 76804 | + if( rc!=SQLITE_OK ) return rc; |
| 75602 | 76805 | |
| 75603 | 76806 | aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); |
| 75604 | 76807 | if( !aSlot ){ |
| 75605 | 76808 | return SQLITE_NOMEM; |
| 75606 | 76809 | } |
| 75607 | 76810 | |
| 75608 | | - p = pSorter->pRecord; |
| 76811 | + p = pList->pList; |
| 75609 | 76812 | while( p ){ |
| 75610 | | - SorterRecord *pNext = p->pNext; |
| 75611 | | - p->pNext = 0; |
| 76813 | + SorterRecord *pNext; |
| 76814 | + if( pList->aMemory ){ |
| 76815 | + if( (u8*)p==pList->aMemory ){ |
| 76816 | + pNext = 0; |
| 76817 | + }else{ |
| 76818 | + assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) ); |
| 76819 | + pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; |
| 76820 | + } |
| 76821 | + }else{ |
| 76822 | + pNext = p->u.pNext; |
| 76823 | + } |
| 76824 | + |
| 76825 | + p->u.pNext = 0; |
| 75612 | 76826 | for(i=0; aSlot[i]; i++){ |
| 75613 | | - vdbeSorterMerge(pCsr, p, aSlot[i], &p); |
| 76827 | + vdbeSorterMerge(pTask, p, aSlot[i], &p); |
| 75614 | 76828 | aSlot[i] = 0; |
| 75615 | 76829 | } |
| 75616 | 76830 | aSlot[i] = p; |
| 75617 | 76831 | p = pNext; |
| 75618 | 76832 | } |
| 75619 | 76833 | |
| 75620 | 76834 | p = 0; |
| 75621 | 76835 | for(i=0; i<64; i++){ |
| 75622 | | - vdbeSorterMerge(pCsr, p, aSlot[i], &p); |
| 76836 | + vdbeSorterMerge(pTask, p, aSlot[i], &p); |
| 75623 | 76837 | } |
| 75624 | | - pSorter->pRecord = p; |
| 76838 | + pList->pList = p; |
| 75625 | 76839 | |
| 75626 | 76840 | sqlite3_free(aSlot); |
| 75627 | | - return SQLITE_OK; |
| 76841 | + assert( pTask->pUnpacked->errCode==SQLITE_OK |
| 76842 | + || pTask->pUnpacked->errCode==SQLITE_NOMEM |
| 76843 | + ); |
| 76844 | + return pTask->pUnpacked->errCode; |
| 75628 | 76845 | } |
| 75629 | 76846 | |
| 75630 | 76847 | /* |
| 75631 | | -** Initialize a file-writer object. |
| 76848 | +** Initialize a PMA-writer object. |
| 75632 | 76849 | */ |
| 75633 | | -static void fileWriterInit( |
| 75634 | | - sqlite3 *db, /* Database (for malloc) */ |
| 75635 | | - sqlite3_file *pFile, /* File to write to */ |
| 75636 | | - FileWriter *p, /* Object to populate */ |
| 75637 | | - i64 iStart /* Offset of pFile to begin writing at */ |
| 76850 | +static void vdbePmaWriterInit( |
| 76851 | + sqlite3_file *pFd, /* File handle to write to */ |
| 76852 | + PmaWriter *p, /* Object to populate */ |
| 76853 | + int nBuf, /* Buffer size */ |
| 76854 | + i64 iStart /* Offset of pFd to begin writing at */ |
| 75638 | 76855 | ){ |
| 75639 | | - int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 75640 | | - |
| 75641 | | - memset(p, 0, sizeof(FileWriter)); |
| 75642 | | - p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); |
| 76856 | + memset(p, 0, sizeof(PmaWriter)); |
| 76857 | + p->aBuffer = (u8*)sqlite3Malloc(nBuf); |
| 75643 | 76858 | if( !p->aBuffer ){ |
| 75644 | 76859 | p->eFWErr = SQLITE_NOMEM; |
| 75645 | 76860 | }else{ |
| 75646 | 76861 | p->iBufEnd = p->iBufStart = (iStart % nBuf); |
| 75647 | 76862 | p->iWriteOff = iStart - p->iBufStart; |
| 75648 | 76863 | p->nBuffer = nBuf; |
| 75649 | | - p->pFile = pFile; |
| 76864 | + p->pFd = pFd; |
| 75650 | 76865 | } |
| 75651 | 76866 | } |
| 75652 | 76867 | |
| 75653 | 76868 | /* |
| 75654 | | -** Write nData bytes of data to the file-write object. Return SQLITE_OK |
| 76869 | +** Write nData bytes of data to the PMA. Return SQLITE_OK |
| 75655 | 76870 | ** if successful, or an SQLite error code if an error occurs. |
| 75656 | 76871 | */ |
| 75657 | | -static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){ |
| 76872 | +static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ |
| 75658 | 76873 | int nRem = nData; |
| 75659 | 76874 | while( nRem>0 && p->eFWErr==0 ){ |
| 75660 | 76875 | int nCopy = nRem; |
| 75661 | 76876 | if( nCopy>(p->nBuffer - p->iBufEnd) ){ |
| 75662 | 76877 | nCopy = p->nBuffer - p->iBufEnd; |
| | @@ -75663,11 +76878,11 @@ |
| 75663 | 76878 | } |
| 75664 | 76879 | |
| 75665 | 76880 | memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); |
| 75666 | 76881 | p->iBufEnd += nCopy; |
| 75667 | 76882 | if( p->iBufEnd==p->nBuffer ){ |
| 75668 | | - p->eFWErr = sqlite3OsWrite(p->pFile, |
| 76883 | + p->eFWErr = sqlite3OsWrite(p->pFd, |
| 75669 | 76884 | &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, |
| 75670 | 76885 | p->iWriteOff + p->iBufStart |
| 75671 | 76886 | ); |
| 75672 | 76887 | p->iBufStart = p->iBufEnd = 0; |
| 75673 | 76888 | p->iWriteOff += p->nBuffer; |
| | @@ -75677,47 +76892,48 @@ |
| 75677 | 76892 | nRem -= nCopy; |
| 75678 | 76893 | } |
| 75679 | 76894 | } |
| 75680 | 76895 | |
| 75681 | 76896 | /* |
| 75682 | | -** Flush any buffered data to disk and clean up the file-writer object. |
| 75683 | | -** The results of using the file-writer after this call are undefined. |
| 76897 | +** Flush any buffered data to disk and clean up the PMA-writer object. |
| 76898 | +** The results of using the PMA-writer after this call are undefined. |
| 75684 | 76899 | ** Return SQLITE_OK if flushing the buffered data succeeds or is not |
| 75685 | 76900 | ** required. Otherwise, return an SQLite error code. |
| 75686 | 76901 | ** |
| 75687 | 76902 | ** Before returning, set *piEof to the offset immediately following the |
| 75688 | 76903 | ** last byte written to the file. |
| 75689 | 76904 | */ |
| 75690 | | -static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){ |
| 76905 | +static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ |
| 75691 | 76906 | int rc; |
| 75692 | 76907 | if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ |
| 75693 | | - p->eFWErr = sqlite3OsWrite(p->pFile, |
| 76908 | + p->eFWErr = sqlite3OsWrite(p->pFd, |
| 75694 | 76909 | &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, |
| 75695 | 76910 | p->iWriteOff + p->iBufStart |
| 75696 | 76911 | ); |
| 75697 | 76912 | } |
| 75698 | 76913 | *piEof = (p->iWriteOff + p->iBufEnd); |
| 75699 | | - sqlite3DbFree(db, p->aBuffer); |
| 76914 | + sqlite3_free(p->aBuffer); |
| 75700 | 76915 | rc = p->eFWErr; |
| 75701 | | - memset(p, 0, sizeof(FileWriter)); |
| 76916 | + memset(p, 0, sizeof(PmaWriter)); |
| 75702 | 76917 | return rc; |
| 75703 | 76918 | } |
| 75704 | 76919 | |
| 75705 | 76920 | /* |
| 75706 | | -** Write value iVal encoded as a varint to the file-write object. Return |
| 76921 | +** Write value iVal encoded as a varint to the PMA. Return |
| 75707 | 76922 | ** SQLITE_OK if successful, or an SQLite error code if an error occurs. |
| 75708 | 76923 | */ |
| 75709 | | -static void fileWriterWriteVarint(FileWriter *p, u64 iVal){ |
| 76924 | +static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ |
| 75710 | 76925 | int nByte; |
| 75711 | 76926 | u8 aByte[10]; |
| 75712 | 76927 | nByte = sqlite3PutVarint(aByte, iVal); |
| 75713 | | - fileWriterWrite(p, aByte, nByte); |
| 76928 | + vdbePmaWriteBlob(p, aByte, nByte); |
| 75714 | 76929 | } |
| 75715 | 76930 | |
| 75716 | 76931 | /* |
| 75717 | | -** Write the current contents of the in-memory linked-list to a PMA. Return |
| 75718 | | -** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 76932 | +** Write the current contents of in-memory linked-list pList to a level-0 |
| 76933 | +** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if |
| 76934 | +** successful, or an SQLite error code otherwise. |
| 75719 | 76935 | ** |
| 75720 | 76936 | ** The format of a PMA is: |
| 75721 | 76937 | ** |
| 75722 | 76938 | ** * A varint. This varint contains the total number of bytes of content |
| 75723 | 76939 | ** in the PMA (not including the varint itself). |
| | @@ -75724,242 +76940,1029 @@ |
| 75724 | 76940 | ** |
| 75725 | 76941 | ** * One or more records packed end-to-end in order of ascending keys. |
| 75726 | 76942 | ** Each record consists of a varint followed by a blob of data (the |
| 75727 | 76943 | ** key). The varint is the number of bytes in the blob of data. |
| 75728 | 76944 | */ |
| 75729 | | -static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){ |
| 76945 | +static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ |
| 76946 | + sqlite3 *db = pTask->pSorter->db; |
| 75730 | 76947 | int rc = SQLITE_OK; /* Return code */ |
| 75731 | | - VdbeSorter *pSorter = pCsr->pSorter; |
| 75732 | | - FileWriter writer; |
| 75733 | | - |
| 75734 | | - memset(&writer, 0, sizeof(FileWriter)); |
| 75735 | | - |
| 75736 | | - if( pSorter->nInMemory==0 ){ |
| 75737 | | - assert( pSorter->pRecord==0 ); |
| 75738 | | - return rc; |
| 75739 | | - } |
| 75740 | | - |
| 75741 | | - rc = vdbeSorterSort(pCsr); |
| 76948 | + PmaWriter writer; /* Object used to write to the file */ |
| 76949 | + |
| 76950 | +#ifdef SQLITE_DEBUG |
| 76951 | + /* Set iSz to the expected size of file pTask->file after writing the PMA. |
| 76952 | + ** This is used by an assert() statement at the end of this function. */ |
| 76953 | + i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; |
| 76954 | +#endif |
| 76955 | + |
| 76956 | + vdbeSorterWorkDebug(pTask, "enter"); |
| 76957 | + memset(&writer, 0, sizeof(PmaWriter)); |
| 76958 | + assert( pList->szPMA>0 ); |
| 75742 | 76959 | |
| 75743 | 76960 | /* If the first temporary PMA file has not been opened, open it now. */ |
| 75744 | | - if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ |
| 75745 | | - rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); |
| 75746 | | - assert( rc!=SQLITE_OK || pSorter->pTemp1 ); |
| 75747 | | - assert( pSorter->iWriteOff==0 ); |
| 75748 | | - assert( pSorter->nPMA==0 ); |
| 76961 | + if( pTask->file.pFd==0 ){ |
| 76962 | + rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd); |
| 76963 | + assert( rc!=SQLITE_OK || pTask->file.pFd ); |
| 76964 | + assert( pTask->file.iEof==0 ); |
| 76965 | + assert( pTask->nPMA==0 ); |
| 76966 | + } |
| 76967 | + |
| 76968 | + /* Try to get the file to memory map */ |
| 76969 | + if( rc==SQLITE_OK ){ |
| 76970 | + vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9); |
| 76971 | + } |
| 76972 | + |
| 76973 | + /* Sort the list */ |
| 76974 | + if( rc==SQLITE_OK ){ |
| 76975 | + rc = vdbeSorterSort(pTask, pList); |
| 75749 | 76976 | } |
| 75750 | 76977 | |
| 75751 | 76978 | if( rc==SQLITE_OK ){ |
| 75752 | 76979 | SorterRecord *p; |
| 75753 | 76980 | SorterRecord *pNext = 0; |
| 75754 | 76981 | |
| 75755 | | - fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff); |
| 75756 | | - pSorter->nPMA++; |
| 75757 | | - fileWriterWriteVarint(&writer, pSorter->nInMemory); |
| 75758 | | - for(p=pSorter->pRecord; p; p=pNext){ |
| 75759 | | - pNext = p->pNext; |
| 75760 | | - fileWriterWriteVarint(&writer, p->nVal); |
| 75761 | | - fileWriterWrite(&writer, p->pVal, p->nVal); |
| 75762 | | - sqlite3DbFree(db, p); |
| 75763 | | - } |
| 75764 | | - pSorter->pRecord = p; |
| 75765 | | - rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff); |
| 76982 | + vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz, |
| 76983 | + pTask->file.iEof); |
| 76984 | + pTask->nPMA++; |
| 76985 | + vdbePmaWriteVarint(&writer, pList->szPMA); |
| 76986 | + for(p=pList->pList; p; p=pNext){ |
| 76987 | + pNext = p->u.pNext; |
| 76988 | + vdbePmaWriteVarint(&writer, p->nVal); |
| 76989 | + vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); |
| 76990 | + if( pList->aMemory==0 ) sqlite3_free(p); |
| 76991 | + } |
| 76992 | + pList->pList = p; |
| 76993 | + rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); |
| 76994 | + } |
| 76995 | + |
| 76996 | + vdbeSorterWorkDebug(pTask, "exit"); |
| 76997 | + assert( rc!=SQLITE_OK || pList->pList==0 ); |
| 76998 | + assert( rc!=SQLITE_OK || pTask->file.iEof==iSz ); |
| 76999 | + return rc; |
| 77000 | +} |
| 77001 | + |
| 77002 | +/* |
| 77003 | +** Advance the MergeEngine to its next entry. |
| 77004 | +** Set *pbEof to true there is no next entry because |
| 77005 | +** the MergeEngine has reached the end of all its inputs. |
| 77006 | +** |
| 77007 | +** Return SQLITE_OK if successful or an error code if an error occurs. |
| 77008 | +*/ |
| 77009 | +static int vdbeMergeEngineStep( |
| 77010 | + MergeEngine *pMerger, /* The merge engine to advance to the next row */ |
| 77011 | + int *pbEof /* Set TRUE at EOF. Set false for more content */ |
| 77012 | +){ |
| 77013 | + int rc; |
| 77014 | + int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */ |
| 77015 | + SortSubtask *pTask = pMerger->pTask; |
| 77016 | + |
| 77017 | + /* Advance the current PmaReader */ |
| 77018 | + rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); |
| 77019 | + |
| 77020 | + /* Update contents of aTree[] */ |
| 77021 | + if( rc==SQLITE_OK ){ |
| 77022 | + int i; /* Index of aTree[] to recalculate */ |
| 77023 | + PmaReader *pReadr1; /* First PmaReader to compare */ |
| 77024 | + PmaReader *pReadr2; /* Second PmaReader to compare */ |
| 77025 | + u8 *pKey2; /* To pReadr2->aKey, or 0 if record cached */ |
| 77026 | + |
| 77027 | + /* Find the first two PmaReaders to compare. The one that was just |
| 77028 | + ** advanced (iPrev) and the one next to it in the array. */ |
| 77029 | + pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; |
| 77030 | + pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; |
| 77031 | + pKey2 = pReadr2->aKey; |
| 77032 | + |
| 77033 | + for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ |
| 77034 | + /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ |
| 77035 | + int iRes; |
| 77036 | + if( pReadr1->pFd==0 ){ |
| 77037 | + iRes = +1; |
| 77038 | + }else if( pReadr2->pFd==0 ){ |
| 77039 | + iRes = -1; |
| 77040 | + }else{ |
| 77041 | + iRes = vdbeSorterCompare(pTask, |
| 77042 | + pReadr1->aKey, pReadr1->nKey, pKey2, pReadr2->nKey |
| 77043 | + ); |
| 77044 | + } |
| 77045 | + |
| 77046 | + /* If pReadr1 contained the smaller value, set aTree[i] to its index. |
| 77047 | + ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this |
| 77048 | + ** case there is no cache of pReadr2 in pTask->pUnpacked, so set |
| 77049 | + ** pKey2 to point to the record belonging to pReadr2. |
| 77050 | + ** |
| 77051 | + ** Alternatively, if pReadr2 contains the smaller of the two values, |
| 77052 | + ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() |
| 77053 | + ** was actually called above, then pTask->pUnpacked now contains |
| 77054 | + ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent |
| 77055 | + ** vdbeSorterCompare() from decoding pReadr2 again. |
| 77056 | + ** |
| 77057 | + ** If the two values were equal, then the value from the oldest |
| 77058 | + ** PMA should be considered smaller. The VdbeSorter.aReadr[] array |
| 77059 | + ** is sorted from oldest to newest, so pReadr1 contains older values |
| 77060 | + ** than pReadr2 iff (pReadr1<pReadr2). */ |
| 77061 | + if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){ |
| 77062 | + pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr); |
| 77063 | + pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; |
| 77064 | + pKey2 = pReadr2->aKey; |
| 77065 | + }else{ |
| 77066 | + if( pReadr1->pFd ) pKey2 = 0; |
| 77067 | + pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); |
| 77068 | + pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; |
| 77069 | + } |
| 77070 | + } |
| 77071 | + *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); |
| 77072 | + } |
| 77073 | + |
| 77074 | + return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); |
| 77075 | +} |
| 77076 | + |
| 77077 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77078 | +/* |
| 77079 | +** The main routine for background threads that write level-0 PMAs. |
| 77080 | +*/ |
| 77081 | +static void *vdbeSorterFlushThread(void *pCtx){ |
| 77082 | + SortSubtask *pTask = (SortSubtask*)pCtx; |
| 77083 | + int rc; /* Return code */ |
| 77084 | + assert( pTask->bDone==0 ); |
| 77085 | + rc = vdbeSorterListToPMA(pTask, &pTask->list); |
| 77086 | + pTask->bDone = 1; |
| 77087 | + return SQLITE_INT_TO_PTR(rc); |
| 77088 | +} |
| 77089 | +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ |
| 77090 | + |
| 77091 | +/* |
| 77092 | +** Flush the current contents of VdbeSorter.list to a new PMA, possibly |
| 77093 | +** using a background thread. |
| 77094 | +*/ |
| 77095 | +static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ |
| 77096 | +#if SQLITE_MAX_WORKER_THREADS==0 |
| 77097 | + pSorter->bUsePMA = 1; |
| 77098 | + return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); |
| 77099 | +#else |
| 77100 | + int rc = SQLITE_OK; |
| 77101 | + int i; |
| 77102 | + SortSubtask *pTask = 0; /* Thread context used to create new PMA */ |
| 77103 | + int nWorker = (pSorter->nTask-1); |
| 77104 | + |
| 77105 | + /* Set the flag to indicate that at least one PMA has been written. |
| 77106 | + ** Or will be, anyhow. */ |
| 77107 | + pSorter->bUsePMA = 1; |
| 77108 | + |
| 77109 | + /* Select a sub-task to sort and flush the current list of in-memory |
| 77110 | + ** records to disk. If the sorter is running in multi-threaded mode, |
| 77111 | + ** round-robin between the first (pSorter->nTask-1) tasks. Except, if |
| 77112 | + ** the background thread from a sub-tasks previous turn is still running, |
| 77113 | + ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, |
| 77114 | + ** fall back to using the final sub-task. The first (pSorter->nTask-1) |
| 77115 | + ** sub-tasks are prefered as they use background threads - the final |
| 77116 | + ** sub-task uses the main thread. */ |
| 77117 | + for(i=0; i<nWorker; i++){ |
| 77118 | + int iTest = (pSorter->iPrev + i + 1) % nWorker; |
| 77119 | + pTask = &pSorter->aTask[iTest]; |
| 77120 | + if( pTask->bDone ){ |
| 77121 | + rc = vdbeSorterJoinThread(pTask); |
| 77122 | + } |
| 77123 | + if( rc!=SQLITE_OK || pTask->pThread==0 ) break; |
| 77124 | + } |
| 77125 | + |
| 77126 | + if( rc==SQLITE_OK ){ |
| 77127 | + if( i==nWorker ){ |
| 77128 | + /* Use the foreground thread for this operation */ |
| 77129 | + rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); |
| 77130 | + }else{ |
| 77131 | + /* Launch a background thread for this operation */ |
| 77132 | + u8 *aMem = pTask->list.aMemory; |
| 77133 | + void *pCtx = (void*)pTask; |
| 77134 | + |
| 77135 | + assert( pTask->pThread==0 && pTask->bDone==0 ); |
| 77136 | + assert( pTask->list.pList==0 ); |
| 77137 | + assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); |
| 77138 | + |
| 77139 | + pSorter->iPrev = (u8)(pTask - pSorter->aTask); |
| 77140 | + pTask->list = pSorter->list; |
| 77141 | + pSorter->list.pList = 0; |
| 77142 | + pSorter->list.szPMA = 0; |
| 77143 | + if( aMem ){ |
| 77144 | + pSorter->list.aMemory = aMem; |
| 77145 | + pSorter->nMemory = sqlite3MallocSize(aMem); |
| 77146 | + }else if( pSorter->list.aMemory ){ |
| 77147 | + pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); |
| 77148 | + if( !pSorter->list.aMemory ) return SQLITE_NOMEM; |
| 77149 | + } |
| 77150 | + |
| 77151 | + rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx); |
| 77152 | + } |
| 75766 | 77153 | } |
| 75767 | 77154 | |
| 75768 | 77155 | return rc; |
| 77156 | +#endif /* SQLITE_MAX_WORKER_THREADS!=0 */ |
| 75769 | 77157 | } |
| 75770 | 77158 | |
| 75771 | 77159 | /* |
| 75772 | 77160 | ** Add a record to the sorter. |
| 75773 | 77161 | */ |
| 75774 | 77162 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 75775 | | - sqlite3 *db, /* Database handle */ |
| 75776 | | - const VdbeCursor *pCsr, /* Sorter cursor */ |
| 77163 | + const VdbeCursor *pCsr, /* Sorter cursor */ |
| 75777 | 77164 | Mem *pVal /* Memory cell containing record */ |
| 75778 | 77165 | ){ |
| 75779 | 77166 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75780 | 77167 | int rc = SQLITE_OK; /* Return Code */ |
| 75781 | 77168 | SorterRecord *pNew; /* New list element */ |
| 75782 | 77169 | |
| 77170 | + int bFlush; /* True to flush contents of memory to PMA */ |
| 77171 | + int nReq; /* Bytes of memory required */ |
| 77172 | + int nPMA; /* Bytes of PMA space required */ |
| 77173 | + |
| 75783 | 77174 | assert( pSorter ); |
| 75784 | | - pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; |
| 75785 | | - |
| 75786 | | - pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); |
| 75787 | | - if( pNew==0 ){ |
| 75788 | | - rc = SQLITE_NOMEM; |
| 75789 | | - }else{ |
| 75790 | | - pNew->pVal = (void *)&pNew[1]; |
| 75791 | | - memcpy(pNew->pVal, pVal->z, pVal->n); |
| 75792 | | - pNew->nVal = pVal->n; |
| 75793 | | - pNew->pNext = pSorter->pRecord; |
| 75794 | | - pSorter->pRecord = pNew; |
| 75795 | | - } |
| 75796 | | - |
| 75797 | | - /* See if the contents of the sorter should now be written out. They |
| 75798 | | - ** are written out when either of the following are true: |
| 77175 | + |
| 77176 | + /* Figure out whether or not the current contents of memory should be |
| 77177 | + ** flushed to a PMA before continuing. If so, do so. |
| 77178 | + ** |
| 77179 | + ** If using the single large allocation mode (pSorter->aMemory!=0), then |
| 77180 | + ** flush the contents of memory to a new PMA if (a) at least one value is |
| 77181 | + ** already in memory and (b) the new value will not fit in memory. |
| 77182 | + ** |
| 77183 | + ** Or, if using separate allocations for each record, flush the contents |
| 77184 | + ** of memory to a PMA if either of the following are true: |
| 75799 | 77185 | ** |
| 75800 | 77186 | ** * The total memory allocated for the in-memory list is greater |
| 75801 | 77187 | ** than (page-size * cache-size), or |
| 75802 | 77188 | ** |
| 75803 | 77189 | ** * The total memory allocated for the in-memory list is greater |
| 75804 | 77190 | ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. |
| 75805 | 77191 | */ |
| 75806 | | - if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 75807 | | - (pSorter->nInMemory>pSorter->mxPmaSize) |
| 75808 | | - || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 75809 | | - )){ |
| 75810 | | -#ifdef SQLITE_DEBUG |
| 75811 | | - i64 nExpect = pSorter->iWriteOff |
| 75812 | | - + sqlite3VarintLen(pSorter->nInMemory) |
| 75813 | | - + pSorter->nInMemory; |
| 75814 | | -#endif |
| 75815 | | - rc = vdbeSorterListToPMA(db, pCsr); |
| 75816 | | - pSorter->nInMemory = 0; |
| 75817 | | - assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) ); |
| 75818 | | - } |
| 75819 | | - |
| 75820 | | - return rc; |
| 75821 | | -} |
| 75822 | | - |
| 75823 | | -/* |
| 75824 | | -** Helper function for sqlite3VdbeSorterRewind(). |
| 75825 | | -*/ |
| 75826 | | -static int vdbeSorterInitMerge( |
| 75827 | | - sqlite3 *db, /* Database handle */ |
| 75828 | | - const VdbeCursor *pCsr, /* Cursor handle for this sorter */ |
| 75829 | | - i64 *pnByte /* Sum of bytes in all opened PMAs */ |
| 75830 | | -){ |
| 77192 | + nReq = pVal->n + sizeof(SorterRecord); |
| 77193 | + nPMA = pVal->n + sqlite3VarintLen(pVal->n); |
| 77194 | + if( pSorter->mxPmaSize ){ |
| 77195 | + if( pSorter->list.aMemory ){ |
| 77196 | + bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; |
| 77197 | + }else{ |
| 77198 | + bFlush = ( |
| 77199 | + (pSorter->list.szPMA > pSorter->mxPmaSize) |
| 77200 | + || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 77201 | + ); |
| 77202 | + } |
| 77203 | + if( bFlush ){ |
| 77204 | + rc = vdbeSorterFlushPMA(pSorter); |
| 77205 | + pSorter->list.szPMA = 0; |
| 77206 | + pSorter->iMemory = 0; |
| 77207 | + assert( rc!=SQLITE_OK || pSorter->list.pList==0 ); |
| 77208 | + } |
| 77209 | + } |
| 77210 | + |
| 77211 | + pSorter->list.szPMA += nPMA; |
| 77212 | + if( nPMA>pSorter->mxKeysize ){ |
| 77213 | + pSorter->mxKeysize = nPMA; |
| 77214 | + } |
| 77215 | + |
| 77216 | + if( pSorter->list.aMemory ){ |
| 77217 | + int nMin = pSorter->iMemory + nReq; |
| 77218 | + |
| 77219 | + if( nMin>pSorter->nMemory ){ |
| 77220 | + u8 *aNew; |
| 77221 | + int nNew = pSorter->nMemory * 2; |
| 77222 | + while( nNew < nMin ) nNew = nNew*2; |
| 77223 | + if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; |
| 77224 | + if( nNew < nMin ) nNew = nMin; |
| 77225 | + |
| 77226 | + aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); |
| 77227 | + if( !aNew ) return SQLITE_NOMEM; |
| 77228 | + pSorter->list.pList = (SorterRecord*)( |
| 77229 | + aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory) |
| 77230 | + ); |
| 77231 | + pSorter->list.aMemory = aNew; |
| 77232 | + pSorter->nMemory = nNew; |
| 77233 | + } |
| 77234 | + |
| 77235 | + pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; |
| 77236 | + pSorter->iMemory += ROUND8(nReq); |
| 77237 | + pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); |
| 77238 | + }else{ |
| 77239 | + pNew = (SorterRecord *)sqlite3Malloc(nReq); |
| 77240 | + if( pNew==0 ){ |
| 77241 | + return SQLITE_NOMEM; |
| 77242 | + } |
| 77243 | + pNew->u.pNext = pSorter->list.pList; |
| 77244 | + } |
| 77245 | + |
| 77246 | + memcpy(SRVAL(pNew), pVal->z, pVal->n); |
| 77247 | + pNew->nVal = pVal->n; |
| 77248 | + pSorter->list.pList = pNew; |
| 77249 | + |
| 77250 | + return rc; |
| 77251 | +} |
| 77252 | + |
| 77253 | +/* |
| 77254 | +** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format |
| 77255 | +** of the data stored in aFile[1] is the same as that used by regular PMAs, |
| 77256 | +** except that the number-of-bytes varint is omitted from the start. |
| 77257 | +*/ |
| 77258 | +static int vdbeIncrPopulate(IncrMerger *pIncr){ |
| 77259 | + int rc = SQLITE_OK; |
| 77260 | + int rc2; |
| 77261 | + i64 iStart = pIncr->iStartOff; |
| 77262 | + SorterFile *pOut = &pIncr->aFile[1]; |
| 77263 | + SortSubtask *pTask = pIncr->pTask; |
| 77264 | + MergeEngine *pMerger = pIncr->pMerger; |
| 77265 | + PmaWriter writer; |
| 77266 | + assert( pIncr->bEof==0 ); |
| 77267 | + |
| 77268 | + vdbeSorterPopulateDebug(pTask, "enter"); |
| 77269 | + |
| 77270 | + vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); |
| 77271 | + while( rc==SQLITE_OK ){ |
| 77272 | + int dummy; |
| 77273 | + PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ]; |
| 77274 | + int nKey = pReader->nKey; |
| 77275 | + i64 iEof = writer.iWriteOff + writer.iBufEnd; |
| 77276 | + |
| 77277 | + /* Check if the output file is full or if the input has been exhausted. |
| 77278 | + ** In either case exit the loop. */ |
| 77279 | + if( pReader->pFd==0 ) break; |
| 77280 | + if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; |
| 77281 | + |
| 77282 | + /* Write the next key to the output. */ |
| 77283 | + vdbePmaWriteVarint(&writer, nKey); |
| 77284 | + vdbePmaWriteBlob(&writer, pReader->aKey, nKey); |
| 77285 | + assert( pIncr->pMerger->pTask==pTask ); |
| 77286 | + rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy); |
| 77287 | + } |
| 77288 | + |
| 77289 | + rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof); |
| 77290 | + if( rc==SQLITE_OK ) rc = rc2; |
| 77291 | + vdbeSorterPopulateDebug(pTask, "exit"); |
| 77292 | + return rc; |
| 77293 | +} |
| 77294 | + |
| 77295 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77296 | +/* |
| 77297 | +** The main routine for background threads that populate aFile[1] of |
| 77298 | +** multi-threaded IncrMerger objects. |
| 77299 | +*/ |
| 77300 | +static void *vdbeIncrPopulateThread(void *pCtx){ |
| 77301 | + IncrMerger *pIncr = (IncrMerger*)pCtx; |
| 77302 | + void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) ); |
| 77303 | + pIncr->pTask->bDone = 1; |
| 77304 | + return pRet; |
| 77305 | +} |
| 77306 | + |
| 77307 | +/* |
| 77308 | +** Launch a background thread to populate aFile[1] of pIncr. |
| 77309 | +*/ |
| 77310 | +static int vdbeIncrBgPopulate(IncrMerger *pIncr){ |
| 77311 | + void *p = (void*)pIncr; |
| 77312 | + assert( pIncr->bUseThread ); |
| 77313 | + return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); |
| 77314 | +} |
| 77315 | +#endif |
| 77316 | + |
| 77317 | +/* |
| 77318 | +** This function is called when the PmaReader corresponding to pIncr has |
| 77319 | +** finished reading the contents of aFile[0]. Its purpose is to "refill" |
| 77320 | +** aFile[0] such that the PmaReader should start rereading it from the |
| 77321 | +** beginning. |
| 77322 | +** |
| 77323 | +** For single-threaded objects, this is accomplished by literally reading |
| 77324 | +** keys from pIncr->pMerger and repopulating aFile[0]. |
| 77325 | +** |
| 77326 | +** For multi-threaded objects, all that is required is to wait until the |
| 77327 | +** background thread is finished (if it is not already) and then swap |
| 77328 | +** aFile[0] and aFile[1] in place. If the contents of pMerger have not |
| 77329 | +** been exhausted, this function also launches a new background thread |
| 77330 | +** to populate the new aFile[1]. |
| 77331 | +** |
| 77332 | +** SQLITE_OK is returned on success, or an SQLite error code otherwise. |
| 77333 | +*/ |
| 77334 | +static int vdbeIncrSwap(IncrMerger *pIncr){ |
| 77335 | + int rc = SQLITE_OK; |
| 77336 | + |
| 77337 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77338 | + if( pIncr->bUseThread ){ |
| 77339 | + rc = vdbeSorterJoinThread(pIncr->pTask); |
| 77340 | + |
| 77341 | + if( rc==SQLITE_OK ){ |
| 77342 | + SorterFile f0 = pIncr->aFile[0]; |
| 77343 | + pIncr->aFile[0] = pIncr->aFile[1]; |
| 77344 | + pIncr->aFile[1] = f0; |
| 77345 | + } |
| 77346 | + |
| 77347 | + if( rc==SQLITE_OK ){ |
| 77348 | + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ |
| 77349 | + pIncr->bEof = 1; |
| 77350 | + }else{ |
| 77351 | + rc = vdbeIncrBgPopulate(pIncr); |
| 77352 | + } |
| 77353 | + } |
| 77354 | + }else |
| 77355 | +#endif |
| 77356 | + { |
| 77357 | + rc = vdbeIncrPopulate(pIncr); |
| 77358 | + pIncr->aFile[0] = pIncr->aFile[1]; |
| 77359 | + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ |
| 77360 | + pIncr->bEof = 1; |
| 77361 | + } |
| 77362 | + } |
| 77363 | + |
| 77364 | + return rc; |
| 77365 | +} |
| 77366 | + |
| 77367 | +/* |
| 77368 | +** Allocate and return a new IncrMerger object to read data from pMerger. |
| 77369 | +** |
| 77370 | +** If an OOM condition is encountered, return NULL. In this case free the |
| 77371 | +** pMerger argument before returning. |
| 77372 | +*/ |
| 77373 | +static int vdbeIncrMergerNew( |
| 77374 | + SortSubtask *pTask, /* The thread that will be using the new IncrMerger */ |
| 77375 | + MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */ |
| 77376 | + IncrMerger **ppOut /* Write the new IncrMerger here */ |
| 77377 | +){ |
| 77378 | + int rc = SQLITE_OK; |
| 77379 | + IncrMerger *pIncr = *ppOut = (IncrMerger*) |
| 77380 | + (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); |
| 77381 | + if( pIncr ){ |
| 77382 | + pIncr->pMerger = pMerger; |
| 77383 | + pIncr->pTask = pTask; |
| 77384 | + pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2); |
| 77385 | + pTask->file2.iEof += pIncr->mxSz; |
| 77386 | + }else{ |
| 77387 | + vdbeMergeEngineFree(pMerger); |
| 77388 | + rc = SQLITE_NOMEM; |
| 77389 | + } |
| 77390 | + return rc; |
| 77391 | +} |
| 77392 | + |
| 77393 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77394 | +/* |
| 77395 | +** Set the "use-threads" flag on object pIncr. |
| 77396 | +*/ |
| 77397 | +static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){ |
| 77398 | + pIncr->bUseThread = 1; |
| 77399 | + pIncr->pTask->file2.iEof -= pIncr->mxSz; |
| 77400 | +} |
| 77401 | +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ |
| 77402 | + |
| 77403 | + |
| 77404 | + |
| 77405 | +/* |
| 77406 | +** Recompute pMerger->aTree[iOut] by comparing the next keys on the |
| 77407 | +** two PmaReaders that feed that entry. Neither of the PmaReaders |
| 77408 | +** are advanced. This routine merely does the comparison. |
| 77409 | +*/ |
| 77410 | +static void vdbeMergeEngineCompare( |
| 77411 | + MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */ |
| 77412 | + int iOut /* Store the result in pMerger->aTree[iOut] */ |
| 77413 | +){ |
| 77414 | + int i1; |
| 77415 | + int i2; |
| 77416 | + int iRes; |
| 77417 | + PmaReader *p1; |
| 77418 | + PmaReader *p2; |
| 77419 | + |
| 77420 | + assert( iOut<pMerger->nTree && iOut>0 ); |
| 77421 | + |
| 77422 | + if( iOut>=(pMerger->nTree/2) ){ |
| 77423 | + i1 = (iOut - pMerger->nTree/2) * 2; |
| 77424 | + i2 = i1 + 1; |
| 77425 | + }else{ |
| 77426 | + i1 = pMerger->aTree[iOut*2]; |
| 77427 | + i2 = pMerger->aTree[iOut*2+1]; |
| 77428 | + } |
| 77429 | + |
| 77430 | + p1 = &pMerger->aReadr[i1]; |
| 77431 | + p2 = &pMerger->aReadr[i2]; |
| 77432 | + |
| 77433 | + if( p1->pFd==0 ){ |
| 77434 | + iRes = i2; |
| 77435 | + }else if( p2->pFd==0 ){ |
| 77436 | + iRes = i1; |
| 77437 | + }else{ |
| 77438 | + int res; |
| 77439 | + assert( pMerger->pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ |
| 77440 | + res = vdbeSorterCompare( |
| 77441 | + pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey |
| 77442 | + ); |
| 77443 | + if( res<=0 ){ |
| 77444 | + iRes = i1; |
| 77445 | + }else{ |
| 77446 | + iRes = i2; |
| 77447 | + } |
| 77448 | + } |
| 77449 | + |
| 77450 | + pMerger->aTree[iOut] = iRes; |
| 77451 | +} |
| 77452 | + |
| 77453 | +/* |
| 77454 | +** Allowed values for the eMode parameter to vdbeMergeEngineInit() |
| 77455 | +** and vdbePmaReaderIncrMergeInit(). |
| 77456 | +** |
| 77457 | +** Only INCRINIT_NORMAL is valid in single-threaded builds (when |
| 77458 | +** SQLITE_MAX_WORKER_THREADS==0). The other values are only used |
| 77459 | +** when there exists one or more separate worker threads. |
| 77460 | +*/ |
| 77461 | +#define INCRINIT_NORMAL 0 |
| 77462 | +#define INCRINIT_TASK 1 |
| 77463 | +#define INCRINIT_ROOT 2 |
| 77464 | + |
| 77465 | +/* Forward reference. |
| 77466 | +** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each |
| 77467 | +** other (when building a merge tree). |
| 77468 | +*/ |
| 77469 | +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode); |
| 77470 | + |
| 77471 | +/* |
| 77472 | +** Initialize the MergeEngine object passed as the second argument. Once this |
| 77473 | +** function returns, the first key of merged data may be read from the |
| 77474 | +** MergeEngine object in the usual fashion. |
| 77475 | +** |
| 77476 | +** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge |
| 77477 | +** objects attached to the PmaReader objects that the merger reads from have |
| 77478 | +** already been populated, but that they have not yet populated aFile[0] and |
| 77479 | +** set the PmaReader objects up to read from it. In this case all that is |
| 77480 | +** required is to call vdbePmaReaderNext() on each PmaReader to point it at |
| 77481 | +** its first key. |
| 77482 | +** |
| 77483 | +** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use |
| 77484 | +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data |
| 77485 | +** to pMerger. |
| 77486 | +** |
| 77487 | +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 77488 | +*/ |
| 77489 | +static int vdbeMergeEngineInit( |
| 77490 | + SortSubtask *pTask, /* Thread that will run pMerger */ |
| 77491 | + MergeEngine *pMerger, /* MergeEngine to initialize */ |
| 77492 | + int eMode /* One of the INCRINIT_XXX constants */ |
| 77493 | +){ |
| 77494 | + int rc = SQLITE_OK; /* Return code */ |
| 77495 | + int i; /* For looping over PmaReader objects */ |
| 77496 | + int nTree = pMerger->nTree; |
| 77497 | + |
| 77498 | + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ |
| 77499 | + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); |
| 77500 | + |
| 77501 | + /* Verify that the MergeEngine is assigned to a single thread */ |
| 77502 | + assert( pMerger->pTask==0 ); |
| 77503 | + pMerger->pTask = pTask; |
| 77504 | + |
| 77505 | + for(i=0; i<nTree; i++){ |
| 77506 | + if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){ |
| 77507 | + /* PmaReaders should be normally initialized in order, as if they are |
| 77508 | + ** reading from the same temp file this makes for more linear file IO. |
| 77509 | + ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is |
| 77510 | + ** in use it will block the vdbePmaReaderNext() call while it uses |
| 77511 | + ** the main thread to fill its buffer. So calling PmaReaderNext() |
| 77512 | + ** on this PmaReader before any of the multi-threaded PmaReaders takes |
| 77513 | + ** better advantage of multi-processor hardware. */ |
| 77514 | + rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); |
| 77515 | + }else{ |
| 77516 | + rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL); |
| 77517 | + } |
| 77518 | + if( rc!=SQLITE_OK ) return rc; |
| 77519 | + } |
| 77520 | + |
| 77521 | + for(i=pMerger->nTree-1; i>0; i--){ |
| 77522 | + vdbeMergeEngineCompare(pMerger, i); |
| 77523 | + } |
| 77524 | + return pTask->pUnpacked->errCode; |
| 77525 | +} |
| 77526 | + |
| 77527 | +/* |
| 77528 | +** Initialize the IncrMerge field of a PmaReader. |
| 77529 | +** |
| 77530 | +** If the PmaReader passed as the first argument is not an incremental-reader |
| 77531 | +** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves |
| 77532 | +** to open and/or initialize the temp file related fields of the IncrMerge |
| 77533 | +** object at (pReadr->pIncr). |
| 77534 | +** |
| 77535 | +** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders |
| 77536 | +** in the sub-tree headed by pReadr are also initialized. Data is then loaded |
| 77537 | +** into the buffers belonging to pReadr and it is set to |
| 77538 | +** point to the first key in its range. |
| 77539 | +** |
| 77540 | +** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed |
| 77541 | +** to be a multi-threaded PmaReader and this function is being called in a |
| 77542 | +** background thread. In this case all PmaReaders in the sub-tree are |
| 77543 | +** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to |
| 77544 | +** pReadr is populated. However, pReadr itself is not set up to point |
| 77545 | +** to its first key. A call to vdbePmaReaderNext() is still required to do |
| 77546 | +** that. |
| 77547 | +** |
| 77548 | +** The reason this function does not call vdbePmaReaderNext() immediately |
| 77549 | +** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has |
| 77550 | +** to block on thread (pTask->thread) before accessing aFile[1]. But, since |
| 77551 | +** this entire function is being run by thread (pTask->thread), that will |
| 77552 | +** lead to the current background thread attempting to join itself. |
| 77553 | +** |
| 77554 | +** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed |
| 77555 | +** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all |
| 77556 | +** child-trees have already been initialized using IncrInit(INCRINIT_TASK). |
| 77557 | +** In this case vdbePmaReaderNext() is called on all child PmaReaders and |
| 77558 | +** the current PmaReader set to point to the first key in its range. |
| 77559 | +** |
| 77560 | +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 77561 | +*/ |
| 77562 | +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ |
| 77563 | + int rc = SQLITE_OK; |
| 77564 | + IncrMerger *pIncr = pReadr->pIncr; |
| 77565 | + |
| 77566 | + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ |
| 77567 | + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); |
| 77568 | + |
| 77569 | + if( pIncr ){ |
| 77570 | + SortSubtask *pTask = pIncr->pTask; |
| 77571 | + sqlite3 *db = pTask->pSorter->db; |
| 77572 | + |
| 77573 | + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); |
| 77574 | + |
| 77575 | + /* Set up the required files for pIncr. A multi-theaded IncrMerge object |
| 77576 | + ** requires two temp files to itself, whereas a single-threaded object |
| 77577 | + ** only requires a region of pTask->file2. */ |
| 77578 | + if( rc==SQLITE_OK ){ |
| 77579 | + int mxSz = pIncr->mxSz; |
| 77580 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77581 | + if( pIncr->bUseThread ){ |
| 77582 | + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); |
| 77583 | + if( rc==SQLITE_OK ){ |
| 77584 | + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); |
| 77585 | + } |
| 77586 | + }else |
| 77587 | +#endif |
| 77588 | + /*if( !pIncr->bUseThread )*/{ |
| 77589 | + if( pTask->file2.pFd==0 ){ |
| 77590 | + assert( pTask->file2.iEof>0 ); |
| 77591 | + rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); |
| 77592 | + pTask->file2.iEof = 0; |
| 77593 | + } |
| 77594 | + if( rc==SQLITE_OK ){ |
| 77595 | + pIncr->aFile[1].pFd = pTask->file2.pFd; |
| 77596 | + pIncr->iStartOff = pTask->file2.iEof; |
| 77597 | + pTask->file2.iEof += mxSz; |
| 77598 | + } |
| 77599 | + } |
| 77600 | + } |
| 77601 | + |
| 77602 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77603 | + if( rc==SQLITE_OK && pIncr->bUseThread ){ |
| 77604 | + /* Use the current thread to populate aFile[1], even though this |
| 77605 | + ** PmaReader is multi-threaded. The reason being that this function |
| 77606 | + ** is already running in background thread pIncr->pTask->thread. */ |
| 77607 | + assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); |
| 77608 | + rc = vdbeIncrPopulate(pIncr); |
| 77609 | + } |
| 77610 | +#endif |
| 77611 | + |
| 77612 | + if( rc==SQLITE_OK |
| 77613 | + && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) |
| 77614 | + ){ |
| 77615 | + rc = vdbePmaReaderNext(pReadr); |
| 77616 | + } |
| 77617 | + } |
| 77618 | + return rc; |
| 77619 | +} |
| 77620 | + |
| 77621 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77622 | +/* |
| 77623 | +** The main routine for vdbePmaReaderIncrMergeInit() operations run in |
| 77624 | +** background threads. |
| 77625 | +*/ |
| 77626 | +static void *vdbePmaReaderBgInit(void *pCtx){ |
| 77627 | + PmaReader *pReader = (PmaReader*)pCtx; |
| 77628 | + void *pRet = SQLITE_INT_TO_PTR( |
| 77629 | + vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) |
| 77630 | + ); |
| 77631 | + pReader->pIncr->pTask->bDone = 1; |
| 77632 | + return pRet; |
| 77633 | +} |
| 77634 | + |
| 77635 | +/* |
| 77636 | +** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK) |
| 77637 | +** on the the PmaReader object passed as the first argument. |
| 77638 | +** |
| 77639 | +** This call will initialize the various fields of the pReadr->pIncr |
| 77640 | +** structure and, if it is a multi-threaded IncrMerger, launch a |
| 77641 | +** background thread to populate aFile[1]. |
| 77642 | +*/ |
| 77643 | +static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){ |
| 77644 | + void *pCtx = (void*)pReadr; |
| 77645 | + return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx); |
| 77646 | +} |
| 77647 | +#endif |
| 77648 | + |
| 77649 | +/* |
| 77650 | +** Allocate a new MergeEngine object to merge the contents of nPMA level-0 |
| 77651 | +** PMAs from pTask->file. If no error occurs, set *ppOut to point to |
| 77652 | +** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut |
| 77653 | +** to NULL and return an SQLite error code. |
| 77654 | +** |
| 77655 | +** When this function is called, *piOffset is set to the offset of the |
| 77656 | +** first PMA to read from pTask->file. Assuming no error occurs, it is |
| 77657 | +** set to the offset immediately following the last byte of the last |
| 77658 | +** PMA before returning. If an error does occur, then the final value of |
| 77659 | +** *piOffset is undefined. |
| 77660 | +*/ |
| 77661 | +static int vdbeMergeEngineLevel0( |
| 77662 | + SortSubtask *pTask, /* Sorter task to read from */ |
| 77663 | + int nPMA, /* Number of PMAs to read */ |
| 77664 | + i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */ |
| 77665 | + MergeEngine **ppOut /* OUT: New merge-engine */ |
| 77666 | +){ |
| 77667 | + MergeEngine *pNew; /* Merge engine to return */ |
| 77668 | + i64 iOff = *piOffset; |
| 77669 | + int i; |
| 77670 | + int rc = SQLITE_OK; |
| 77671 | + |
| 77672 | + *ppOut = pNew = vdbeMergeEngineNew(nPMA); |
| 77673 | + if( pNew==0 ) rc = SQLITE_NOMEM; |
| 77674 | + |
| 77675 | + for(i=0; i<nPMA && rc==SQLITE_OK; i++){ |
| 77676 | + i64 nDummy; |
| 77677 | + PmaReader *pReadr = &pNew->aReadr[i]; |
| 77678 | + rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy); |
| 77679 | + iOff = pReadr->iEof; |
| 77680 | + } |
| 77681 | + |
| 77682 | + if( rc!=SQLITE_OK ){ |
| 77683 | + vdbeMergeEngineFree(pNew); |
| 77684 | + *ppOut = 0; |
| 77685 | + } |
| 77686 | + *piOffset = iOff; |
| 77687 | + return rc; |
| 77688 | +} |
| 77689 | + |
| 77690 | +/* |
| 77691 | +** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of |
| 77692 | +** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes. |
| 77693 | +** |
| 77694 | +** i.e. |
| 77695 | +** |
| 77696 | +** nPMA<=16 -> TreeDepth() == 0 |
| 77697 | +** nPMA<=256 -> TreeDepth() == 1 |
| 77698 | +** nPMA<=65536 -> TreeDepth() == 2 |
| 77699 | +*/ |
| 77700 | +static int vdbeSorterTreeDepth(int nPMA){ |
| 77701 | + int nDepth = 0; |
| 77702 | + i64 nDiv = SORTER_MAX_MERGE_COUNT; |
| 77703 | + while( nDiv < (i64)nPMA ){ |
| 77704 | + nDiv = nDiv * SORTER_MAX_MERGE_COUNT; |
| 77705 | + nDepth++; |
| 77706 | + } |
| 77707 | + return nDepth; |
| 77708 | +} |
| 77709 | + |
| 77710 | +/* |
| 77711 | +** pRoot is the root of an incremental merge-tree with depth nDepth (according |
| 77712 | +** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the |
| 77713 | +** tree, counting from zero. This function adds pLeaf to the tree. |
| 77714 | +** |
| 77715 | +** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error |
| 77716 | +** code is returned and pLeaf is freed. |
| 77717 | +*/ |
| 77718 | +static int vdbeSorterAddToTree( |
| 77719 | + SortSubtask *pTask, /* Task context */ |
| 77720 | + int nDepth, /* Depth of tree according to TreeDepth() */ |
| 77721 | + int iSeq, /* Sequence number of leaf within tree */ |
| 77722 | + MergeEngine *pRoot, /* Root of tree */ |
| 77723 | + MergeEngine *pLeaf /* Leaf to add to tree */ |
| 77724 | +){ |
| 77725 | + int rc = SQLITE_OK; |
| 77726 | + int nDiv = 1; |
| 77727 | + int i; |
| 77728 | + MergeEngine *p = pRoot; |
| 77729 | + IncrMerger *pIncr; |
| 77730 | + |
| 77731 | + rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr); |
| 77732 | + |
| 77733 | + for(i=1; i<nDepth; i++){ |
| 77734 | + nDiv = nDiv * SORTER_MAX_MERGE_COUNT; |
| 77735 | + } |
| 77736 | + |
| 77737 | + for(i=1; i<nDepth && rc==SQLITE_OK; i++){ |
| 77738 | + int iIter = (iSeq / nDiv) % SORTER_MAX_MERGE_COUNT; |
| 77739 | + PmaReader *pReadr = &p->aReadr[iIter]; |
| 77740 | + |
| 77741 | + if( pReadr->pIncr==0 ){ |
| 77742 | + MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); |
| 77743 | + if( pNew==0 ){ |
| 77744 | + rc = SQLITE_NOMEM; |
| 77745 | + }else{ |
| 77746 | + rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr); |
| 77747 | + } |
| 77748 | + } |
| 77749 | + if( rc==SQLITE_OK ){ |
| 77750 | + p = pReadr->pIncr->pMerger; |
| 77751 | + nDiv = nDiv / SORTER_MAX_MERGE_COUNT; |
| 77752 | + } |
| 77753 | + } |
| 77754 | + |
| 77755 | + if( rc==SQLITE_OK ){ |
| 77756 | + p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr; |
| 77757 | + }else{ |
| 77758 | + vdbeIncrFree(pIncr); |
| 77759 | + } |
| 77760 | + return rc; |
| 77761 | +} |
| 77762 | + |
| 77763 | +/* |
| 77764 | +** This function is called as part of a SorterRewind() operation on a sorter |
| 77765 | +** that has already written two or more level-0 PMAs to one or more temp |
| 77766 | +** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that |
| 77767 | +** can be used to incrementally merge all PMAs on disk. |
| 77768 | +** |
| 77769 | +** If successful, SQLITE_OK is returned and *ppOut set to point to the |
| 77770 | +** MergeEngine object at the root of the tree before returning. Or, if an |
| 77771 | +** error occurs, an SQLite error code is returned and the final value |
| 77772 | +** of *ppOut is undefined. |
| 77773 | +*/ |
| 77774 | +static int vdbeSorterMergeTreeBuild( |
| 77775 | + VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */ |
| 77776 | + MergeEngine **ppOut /* Write the MergeEngine here */ |
| 77777 | +){ |
| 77778 | + MergeEngine *pMain = 0; |
| 77779 | + int rc = SQLITE_OK; |
| 77780 | + int iTask; |
| 77781 | + |
| 77782 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77783 | + /* If the sorter uses more than one task, then create the top-level |
| 77784 | + ** MergeEngine here. This MergeEngine will read data from exactly |
| 77785 | + ** one PmaReader per sub-task. */ |
| 77786 | + assert( pSorter->bUseThreads || pSorter->nTask==1 ); |
| 77787 | + if( pSorter->nTask>1 ){ |
| 77788 | + pMain = vdbeMergeEngineNew(pSorter->nTask); |
| 77789 | + if( pMain==0 ) rc = SQLITE_NOMEM; |
| 77790 | + } |
| 77791 | +#endif |
| 77792 | + |
| 77793 | + for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){ |
| 77794 | + SortSubtask *pTask = &pSorter->aTask[iTask]; |
| 77795 | + assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 ); |
| 77796 | + if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){ |
| 77797 | + MergeEngine *pRoot = 0; /* Root node of tree for this task */ |
| 77798 | + int nDepth = vdbeSorterTreeDepth(pTask->nPMA); |
| 77799 | + i64 iReadOff = 0; |
| 77800 | + |
| 77801 | + if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 77802 | + rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot); |
| 77803 | + }else{ |
| 77804 | + int i; |
| 77805 | + int iSeq = 0; |
| 77806 | + pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); |
| 77807 | + if( pRoot==0 ) rc = SQLITE_NOMEM; |
| 77808 | + for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){ |
| 77809 | + MergeEngine *pMerger = 0; /* New level-0 PMA merger */ |
| 77810 | + int nReader; /* Number of level-0 PMAs to merge */ |
| 77811 | + |
| 77812 | + nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT); |
| 77813 | + rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger); |
| 77814 | + if( rc==SQLITE_OK ){ |
| 77815 | + rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger); |
| 77816 | + } |
| 77817 | + } |
| 77818 | + } |
| 77819 | + |
| 77820 | + if( rc==SQLITE_OK ){ |
| 77821 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77822 | + if( pMain!=0 ){ |
| 77823 | + rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr); |
| 77824 | + }else |
| 77825 | +#endif |
| 77826 | + { |
| 77827 | + assert( pMain==0 ); |
| 77828 | + pMain = pRoot; |
| 77829 | + } |
| 77830 | + }else{ |
| 77831 | + vdbeMergeEngineFree(pRoot); |
| 77832 | + } |
| 77833 | + } |
| 77834 | + } |
| 77835 | + |
| 77836 | + if( rc!=SQLITE_OK ){ |
| 77837 | + vdbeMergeEngineFree(pMain); |
| 77838 | + pMain = 0; |
| 77839 | + } |
| 77840 | + *ppOut = pMain; |
| 77841 | + return rc; |
| 77842 | +} |
| 77843 | + |
| 77844 | +/* |
| 77845 | +** This function is called as part of an sqlite3VdbeSorterRewind() operation |
| 77846 | +** on a sorter that has written two or more PMAs to temporary files. It sets |
| 77847 | +** up either VdbeSorter.pMerger (for single threaded sorters) or pReader |
| 77848 | +** (for multi-threaded sorters) so that it can be used to iterate through |
| 77849 | +** all records stored in the sorter. |
| 77850 | +** |
| 77851 | +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 77852 | +*/ |
| 77853 | +static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ |
| 77854 | + int rc; /* Return code */ |
| 77855 | + SortSubtask *pTask0 = &pSorter->aTask[0]; |
| 77856 | + MergeEngine *pMain = 0; |
| 77857 | +#if SQLITE_MAX_WORKER_THREADS |
| 77858 | + sqlite3 *db = pTask0->pSorter->db; |
| 77859 | +#endif |
| 77860 | + |
| 77861 | + rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); |
| 77862 | + if( rc==SQLITE_OK ){ |
| 77863 | +#if SQLITE_MAX_WORKER_THREADS |
| 77864 | + assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); |
| 77865 | + if( pSorter->bUseThreads ){ |
| 77866 | + int iTask; |
| 77867 | + PmaReader *pReadr; |
| 77868 | + SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; |
| 77869 | + rc = vdbeSortAllocUnpacked(pLast); |
| 77870 | + if( rc==SQLITE_OK ){ |
| 77871 | + pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); |
| 77872 | + pSorter->pReader = pReadr; |
| 77873 | + if( pReadr==0 ) rc = SQLITE_NOMEM; |
| 77874 | + } |
| 77875 | + if( rc==SQLITE_OK ){ |
| 77876 | + rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); |
| 77877 | + if( rc==SQLITE_OK ){ |
| 77878 | + vdbeIncrMergerSetThreads(pReadr->pIncr); |
| 77879 | + for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ |
| 77880 | + IncrMerger *pIncr; |
| 77881 | + if( (pIncr = pMain->aReadr[iTask].pIncr) ){ |
| 77882 | + vdbeIncrMergerSetThreads(pIncr); |
| 77883 | + assert( pIncr->pTask!=pLast ); |
| 77884 | + } |
| 77885 | + } |
| 77886 | + for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){ |
| 77887 | + PmaReader *p = &pMain->aReadr[iTask]; |
| 77888 | + assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] ); |
| 77889 | + if( p->pIncr ){ |
| 77890 | + if( iTask==pSorter->nTask-1 ){ |
| 77891 | + rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK); |
| 77892 | + }else{ |
| 77893 | + rc = vdbePmaReaderBgIncrInit(p); |
| 77894 | + } |
| 77895 | + } |
| 77896 | + } |
| 77897 | + } |
| 77898 | + pMain = 0; |
| 77899 | + } |
| 77900 | + if( rc==SQLITE_OK ){ |
| 77901 | + rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); |
| 77902 | + } |
| 77903 | + }else |
| 77904 | +#endif |
| 77905 | + { |
| 77906 | + rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); |
| 77907 | + pSorter->pMerger = pMain; |
| 77908 | + pMain = 0; |
| 77909 | + } |
| 77910 | + } |
| 77911 | + |
| 77912 | + if( rc!=SQLITE_OK ){ |
| 77913 | + vdbeMergeEngineFree(pMain); |
| 77914 | + } |
| 77915 | + return rc; |
| 77916 | +} |
| 77917 | + |
| 77918 | + |
| 77919 | +/* |
| 77920 | +** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, |
| 77921 | +** this function is called to prepare for iterating through the records |
| 77922 | +** in sorted order. |
| 77923 | +*/ |
| 77924 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ |
| 75831 | 77925 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75832 | 77926 | int rc = SQLITE_OK; /* Return code */ |
| 75833 | | - int i; /* Used to iterator through aIter[] */ |
| 75834 | | - i64 nByte = 0; /* Total bytes in all opened PMAs */ |
| 75835 | | - |
| 75836 | | - /* Initialize the iterators. */ |
| 75837 | | - for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){ |
| 75838 | | - VdbeSorterIter *pIter = &pSorter->aIter[i]; |
| 75839 | | - rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); |
| 75840 | | - pSorter->iReadOff = pIter->iEof; |
| 75841 | | - assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff ); |
| 75842 | | - if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break; |
| 75843 | | - } |
| 75844 | | - |
| 75845 | | - /* Initialize the aTree[] array. */ |
| 75846 | | - for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ |
| 75847 | | - rc = vdbeSorterDoCompare(pCsr, i); |
| 75848 | | - } |
| 75849 | | - |
| 75850 | | - *pnByte = nByte; |
| 75851 | | - return rc; |
| 75852 | | -} |
| 75853 | | - |
| 75854 | | -/* |
| 75855 | | -** Once the sorter has been populated, this function is called to prepare |
| 75856 | | -** for iterating through its contents in sorted order. |
| 75857 | | -*/ |
| 75858 | | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ |
| 75859 | | - VdbeSorter *pSorter = pCsr->pSorter; |
| 75860 | | - int rc; /* Return code */ |
| 75861 | | - sqlite3_file *pTemp2 = 0; /* Second temp file to use */ |
| 75862 | | - i64 iWrite2 = 0; /* Write offset for pTemp2 */ |
| 75863 | | - int nIter; /* Number of iterators used */ |
| 75864 | | - int nByte; /* Bytes of space required for aIter/aTree */ |
| 75865 | | - int N = 2; /* Power of 2 >= nIter */ |
| 75866 | 77927 | |
| 75867 | 77928 | assert( pSorter ); |
| 75868 | 77929 | |
| 75869 | 77930 | /* If no data has been written to disk, then do not do so now. Instead, |
| 75870 | 77931 | ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly |
| 75871 | 77932 | ** from the in-memory list. */ |
| 75872 | | - if( pSorter->nPMA==0 ){ |
| 75873 | | - *pbEof = !pSorter->pRecord; |
| 75874 | | - assert( pSorter->aTree==0 ); |
| 75875 | | - return vdbeSorterSort(pCsr); |
| 75876 | | - } |
| 75877 | | - |
| 75878 | | - /* Write the current in-memory list to a PMA. */ |
| 75879 | | - rc = vdbeSorterListToPMA(db, pCsr); |
| 75880 | | - if( rc!=SQLITE_OK ) return rc; |
| 75881 | | - |
| 75882 | | - /* Allocate space for aIter[] and aTree[]. */ |
| 75883 | | - nIter = pSorter->nPMA; |
| 75884 | | - if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; |
| 75885 | | - assert( nIter>0 ); |
| 75886 | | - while( N<nIter ) N += N; |
| 75887 | | - nByte = N * (sizeof(int) + sizeof(VdbeSorterIter)); |
| 75888 | | - pSorter->aIter = (VdbeSorterIter *)sqlite3DbMallocZero(db, nByte); |
| 75889 | | - if( !pSorter->aIter ) return SQLITE_NOMEM; |
| 75890 | | - pSorter->aTree = (int *)&pSorter->aIter[N]; |
| 75891 | | - pSorter->nTree = N; |
| 75892 | | - |
| 75893 | | - do { |
| 75894 | | - int iNew; /* Index of new, merged, PMA */ |
| 75895 | | - |
| 75896 | | - for(iNew=0; |
| 75897 | | - rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; |
| 75898 | | - iNew++ |
| 75899 | | - ){ |
| 75900 | | - int rc2; /* Return code from fileWriterFinish() */ |
| 75901 | | - FileWriter writer; /* Object used to write to disk */ |
| 75902 | | - i64 nWrite; /* Number of bytes in new PMA */ |
| 75903 | | - |
| 75904 | | - memset(&writer, 0, sizeof(FileWriter)); |
| 75905 | | - |
| 75906 | | - /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, |
| 75907 | | - ** initialize an iterator for each of them and break out of the loop. |
| 75908 | | - ** These iterators will be incrementally merged as the VDBE layer calls |
| 75909 | | - ** sqlite3VdbeSorterNext(). |
| 75910 | | - ** |
| 75911 | | - ** Otherwise, if pTemp1 contains more than SORTER_MAX_MERGE_COUNT PMAs, |
| 75912 | | - ** initialize interators for SORTER_MAX_MERGE_COUNT of them. These PMAs |
| 75913 | | - ** are merged into a single PMA that is written to file pTemp2. |
| 75914 | | - */ |
| 75915 | | - rc = vdbeSorterInitMerge(db, pCsr, &nWrite); |
| 75916 | | - assert( rc!=SQLITE_OK || pSorter->aIter[ pSorter->aTree[1] ].pFile ); |
| 75917 | | - if( rc!=SQLITE_OK || pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 75918 | | - break; |
| 75919 | | - } |
| 75920 | | - |
| 75921 | | - /* Open the second temp file, if it is not already open. */ |
| 75922 | | - if( pTemp2==0 ){ |
| 75923 | | - assert( iWrite2==0 ); |
| 75924 | | - rc = vdbeSorterOpenTempFile(db, &pTemp2); |
| 75925 | | - } |
| 75926 | | - |
| 75927 | | - if( rc==SQLITE_OK ){ |
| 75928 | | - int bEof = 0; |
| 75929 | | - fileWriterInit(db, pTemp2, &writer, iWrite2); |
| 75930 | | - fileWriterWriteVarint(&writer, nWrite); |
| 75931 | | - while( rc==SQLITE_OK && bEof==0 ){ |
| 75932 | | - VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 75933 | | - assert( pIter->pFile ); |
| 75934 | | - |
| 75935 | | - fileWriterWriteVarint(&writer, pIter->nKey); |
| 75936 | | - fileWriterWrite(&writer, pIter->aKey, pIter->nKey); |
| 75937 | | - rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); |
| 75938 | | - } |
| 75939 | | - rc2 = fileWriterFinish(db, &writer, &iWrite2); |
| 75940 | | - if( rc==SQLITE_OK ) rc = rc2; |
| 75941 | | - } |
| 75942 | | - } |
| 75943 | | - |
| 75944 | | - if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 75945 | | - break; |
| 75946 | | - }else{ |
| 75947 | | - sqlite3_file *pTmp = pSorter->pTemp1; |
| 75948 | | - pSorter->nPMA = iNew; |
| 75949 | | - pSorter->pTemp1 = pTemp2; |
| 75950 | | - pTemp2 = pTmp; |
| 75951 | | - pSorter->iWriteOff = iWrite2; |
| 75952 | | - pSorter->iReadOff = 0; |
| 75953 | | - iWrite2 = 0; |
| 75954 | | - } |
| 75955 | | - }while( rc==SQLITE_OK ); |
| 75956 | | - |
| 75957 | | - if( pTemp2 ){ |
| 75958 | | - sqlite3OsCloseFree(pTemp2); |
| 75959 | | - } |
| 75960 | | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 77933 | + if( pSorter->bUsePMA==0 ){ |
| 77934 | + if( pSorter->list.pList ){ |
| 77935 | + *pbEof = 0; |
| 77936 | + rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); |
| 77937 | + }else{ |
| 77938 | + *pbEof = 1; |
| 77939 | + } |
| 77940 | + return rc; |
| 77941 | + } |
| 77942 | + |
| 77943 | + /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() |
| 77944 | + ** function flushes the contents of memory to disk, it immediately always |
| 77945 | + ** creates a new list consisting of a single key immediately afterwards. |
| 77946 | + ** So the list is never empty at this point. */ |
| 77947 | + assert( pSorter->list.pList ); |
| 77948 | + rc = vdbeSorterFlushPMA(pSorter); |
| 77949 | + |
| 77950 | + /* Join all threads */ |
| 77951 | + rc = vdbeSorterJoinAll(pSorter, rc); |
| 77952 | + |
| 77953 | + vdbeSorterRewindDebug("rewind"); |
| 77954 | + |
| 77955 | + /* Assuming no errors have occurred, set up a merger structure to |
| 77956 | + ** incrementally read and merge all remaining PMAs. */ |
| 77957 | + assert( pSorter->pReader==0 ); |
| 77958 | + if( rc==SQLITE_OK ){ |
| 77959 | + rc = vdbeSorterSetupMerge(pSorter); |
| 77960 | + *pbEof = 0; |
| 77961 | + } |
| 77962 | + |
| 77963 | + vdbeSorterRewindDebug("rewinddone"); |
| 75961 | 77964 | return rc; |
| 75962 | 77965 | } |
| 75963 | 77966 | |
| 75964 | 77967 | /* |
| 75965 | 77968 | ** Advance to the next element in the sorter. |
| | @@ -75966,67 +77969,31 @@ |
| 75966 | 77969 | */ |
| 75967 | 77970 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ |
| 75968 | 77971 | VdbeSorter *pSorter = pCsr->pSorter; |
| 75969 | 77972 | int rc; /* Return code */ |
| 75970 | 77973 | |
| 75971 | | - if( pSorter->aTree ){ |
| 75972 | | - int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| 75973 | | - rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 75974 | | - if( rc==SQLITE_OK ){ |
| 75975 | | - int i; /* Index of aTree[] to recalculate */ |
| 75976 | | - VdbeSorterIter *pIter1; /* First iterator to compare */ |
| 75977 | | - VdbeSorterIter *pIter2; /* Second iterator to compare */ |
| 75978 | | - u8 *pKey2; /* To pIter2->aKey, or 0 if record cached */ |
| 75979 | | - |
| 75980 | | - /* Find the first two iterators to compare. The one that was just |
| 75981 | | - ** advanced (iPrev) and the one next to it in the array. */ |
| 75982 | | - pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)]; |
| 75983 | | - pIter2 = &pSorter->aIter[(iPrev | 0x0001)]; |
| 75984 | | - pKey2 = pIter2->aKey; |
| 75985 | | - |
| 75986 | | - for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){ |
| 75987 | | - /* Compare pIter1 and pIter2. Store the result in variable iRes. */ |
| 75988 | | - int iRes; |
| 75989 | | - if( pIter1->pFile==0 ){ |
| 75990 | | - iRes = +1; |
| 75991 | | - }else if( pIter2->pFile==0 ){ |
| 75992 | | - iRes = -1; |
| 75993 | | - }else{ |
| 75994 | | - vdbeSorterCompare(pCsr, 0, |
| 75995 | | - pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes |
| 75996 | | - ); |
| 75997 | | - } |
| 75998 | | - |
| 75999 | | - /* If pIter1 contained the smaller value, set aTree[i] to its index. |
| 76000 | | - ** Then set pIter2 to the next iterator to compare to pIter1. In this |
| 76001 | | - ** case there is no cache of pIter2 in pSorter->pUnpacked, so set |
| 76002 | | - ** pKey2 to point to the record belonging to pIter2. |
| 76003 | | - ** |
| 76004 | | - ** Alternatively, if pIter2 contains the smaller of the two values, |
| 76005 | | - ** set aTree[i] to its index and update pIter1. If vdbeSorterCompare() |
| 76006 | | - ** was actually called above, then pSorter->pUnpacked now contains |
| 76007 | | - ** a value equivalent to pIter2. So set pKey2 to NULL to prevent |
| 76008 | | - ** vdbeSorterCompare() from decoding pIter2 again. */ |
| 76009 | | - if( iRes<=0 ){ |
| 76010 | | - pSorter->aTree[i] = (int)(pIter1 - pSorter->aIter); |
| 76011 | | - pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ]; |
| 76012 | | - pKey2 = pIter2->aKey; |
| 76013 | | - }else{ |
| 76014 | | - if( pIter1->pFile ) pKey2 = 0; |
| 76015 | | - pSorter->aTree[i] = (int)(pIter2 - pSorter->aIter); |
| 76016 | | - pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ]; |
| 76017 | | - } |
| 76018 | | - |
| 76019 | | - } |
| 76020 | | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 76021 | | - } |
| 76022 | | - }else{ |
| 76023 | | - SorterRecord *pFree = pSorter->pRecord; |
| 76024 | | - pSorter->pRecord = pFree->pNext; |
| 76025 | | - pFree->pNext = 0; |
| 76026 | | - vdbeSorterRecordFree(db, pFree); |
| 76027 | | - *pbEof = !pSorter->pRecord; |
| 77974 | + assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); |
| 77975 | + if( pSorter->bUsePMA ){ |
| 77976 | + assert( pSorter->pReader==0 || pSorter->pMerger==0 ); |
| 77977 | + assert( pSorter->bUseThreads==0 || pSorter->pReader ); |
| 77978 | + assert( pSorter->bUseThreads==1 || pSorter->pMerger ); |
| 77979 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 77980 | + if( pSorter->bUseThreads ){ |
| 77981 | + rc = vdbePmaReaderNext(pSorter->pReader); |
| 77982 | + *pbEof = (pSorter->pReader->pFd==0); |
| 77983 | + }else |
| 77984 | +#endif |
| 77985 | + /*if( !pSorter->bUseThreads )*/ { |
| 77986 | + assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); |
| 77987 | + rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); |
| 77988 | + } |
| 77989 | + }else{ |
| 77990 | + SorterRecord *pFree = pSorter->list.pList; |
| 77991 | + pSorter->list.pList = pFree->u.pNext; |
| 77992 | + pFree->u.pNext = 0; |
| 77993 | + if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); |
| 77994 | + *pbEof = !pSorter->list.pList; |
| 76028 | 77995 | rc = SQLITE_OK; |
| 76029 | 77996 | } |
| 76030 | 77997 | return rc; |
| 76031 | 77998 | } |
| 76032 | 77999 | |
| | @@ -76037,18 +78004,25 @@ |
| 76037 | 78004 | static void *vdbeSorterRowkey( |
| 76038 | 78005 | const VdbeSorter *pSorter, /* Sorter object */ |
| 76039 | 78006 | int *pnKey /* OUT: Size of current key in bytes */ |
| 76040 | 78007 | ){ |
| 76041 | 78008 | void *pKey; |
| 76042 | | - if( pSorter->aTree ){ |
| 76043 | | - VdbeSorterIter *pIter; |
| 76044 | | - pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 76045 | | - *pnKey = pIter->nKey; |
| 76046 | | - pKey = pIter->aKey; |
| 78009 | + if( pSorter->bUsePMA ){ |
| 78010 | + PmaReader *pReader; |
| 78011 | +#if SQLITE_MAX_WORKER_THREADS>0 |
| 78012 | + if( pSorter->bUseThreads ){ |
| 78013 | + pReader = pSorter->pReader; |
| 78014 | + }else |
| 78015 | +#endif |
| 78016 | + /*if( !pSorter->bUseThreads )*/{ |
| 78017 | + pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]]; |
| 78018 | + } |
| 78019 | + *pnKey = pReader->nKey; |
| 78020 | + pKey = pReader->aKey; |
| 76047 | 78021 | }else{ |
| 76048 | | - *pnKey = pSorter->pRecord->nVal; |
| 76049 | | - pKey = pSorter->pRecord->pVal; |
| 78022 | + *pnKey = pSorter->list.pList->nVal; |
| 78023 | + pKey = SRVAL(pSorter->list.pList); |
| 76050 | 78024 | } |
| 76051 | 78025 | return pKey; |
| 76052 | 78026 | } |
| 76053 | 78027 | |
| 76054 | 78028 | /* |
| | @@ -76071,27 +78045,53 @@ |
| 76071 | 78045 | |
| 76072 | 78046 | /* |
| 76073 | 78047 | ** Compare the key in memory cell pVal with the key that the sorter cursor |
| 76074 | 78048 | ** passed as the first argument currently points to. For the purposes of |
| 76075 | 78049 | ** the comparison, ignore the rowid field at the end of each record. |
| 78050 | +** |
| 78051 | +** If the sorter cursor key contains any NULL values, consider it to be |
| 78052 | +** less than pVal. Even if pVal also contains NULL values. |
| 76076 | 78053 | ** |
| 76077 | 78054 | ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). |
| 76078 | 78055 | ** Otherwise, set *pRes to a negative, zero or positive value if the |
| 76079 | 78056 | ** key in pVal is smaller than, equal to or larger than the current sorter |
| 76080 | 78057 | ** key. |
| 78058 | +** |
| 78059 | +** This routine forms the core of the OP_SorterCompare opcode, which in |
| 78060 | +** turn is used to verify uniqueness when constructing a UNIQUE INDEX. |
| 76081 | 78061 | */ |
| 76082 | 78062 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 76083 | 78063 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 76084 | 78064 | Mem *pVal, /* Value to compare to current sorter key */ |
| 76085 | | - int nKeyCol, /* Only compare this many fields */ |
| 78065 | + int nKeyCol, /* Compare this many columns */ |
| 76086 | 78066 | int *pRes /* OUT: Result of comparison */ |
| 76087 | 78067 | ){ |
| 76088 | 78068 | VdbeSorter *pSorter = pCsr->pSorter; |
| 78069 | + UnpackedRecord *r2 = pSorter->pUnpacked; |
| 78070 | + KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 78071 | + int i; |
| 76089 | 78072 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 76090 | 78073 | |
| 78074 | + if( r2==0 ){ |
| 78075 | + char *p; |
| 78076 | + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); |
| 78077 | + assert( pSorter->pUnpacked==(UnpackedRecord*)p ); |
| 78078 | + if( r2==0 ) return SQLITE_NOMEM; |
| 78079 | + r2->nField = nKeyCol; |
| 78080 | + } |
| 78081 | + assert( r2->nField==nKeyCol ); |
| 78082 | + |
| 76091 | 78083 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 76092 | | - vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes); |
| 78084 | + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); |
| 78085 | + for(i=0; i<nKeyCol; i++){ |
| 78086 | + if( r2->aMem[i].flags & MEM_Null ){ |
| 78087 | + *pRes = -1; |
| 78088 | + return SQLITE_OK; |
| 78089 | + } |
| 78090 | + } |
| 78091 | + |
| 78092 | + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2, 0); |
| 76093 | 78093 | return SQLITE_OK; |
| 76094 | 78094 | } |
| 76095 | 78095 | |
| 76096 | 78096 | /************** End of vdbesort.c ********************************************/ |
| 76097 | 78097 | /************** Begin file journal.c *****************************************/ |
| | @@ -80136,10 +82136,11 @@ |
| 80136 | 82136 | assert( ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 80137 | 82137 | pSel = pExpr->x.pSelect; |
| 80138 | 82138 | sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); |
| 80139 | 82139 | if( pExpr->op==TK_SELECT ){ |
| 80140 | 82140 | dest.eDest = SRT_Mem; |
| 82141 | + dest.iSdst = dest.iSDParm; |
| 80141 | 82142 | sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); |
| 80142 | 82143 | VdbeComment((v, "Init subquery result")); |
| 80143 | 82144 | }else{ |
| 80144 | 82145 | dest.eDest = SRT_Exists; |
| 80145 | 82146 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); |
| | @@ -80819,30 +82820,17 @@ |
| 80819 | 82820 | break; |
| 80820 | 82821 | } |
| 80821 | 82822 | #ifndef SQLITE_OMIT_CAST |
| 80822 | 82823 | case TK_CAST: { |
| 80823 | 82824 | /* Expressions of the form: CAST(pLeft AS token) */ |
| 80824 | | - int aff, to_op; |
| 80825 | 82825 | inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); |
| 80826 | | - assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 80827 | | - aff = sqlite3AffinityType(pExpr->u.zToken, 0); |
| 80828 | | - to_op = aff - SQLITE_AFF_TEXT + OP_ToText; |
| 80829 | | - assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); |
| 80830 | | - assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE ); |
| 80831 | | - assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC ); |
| 80832 | | - assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER ); |
| 80833 | | - assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL ); |
| 80834 | | - testcase( to_op==OP_ToText ); |
| 80835 | | - testcase( to_op==OP_ToBlob ); |
| 80836 | | - testcase( to_op==OP_ToNumeric ); |
| 80837 | | - testcase( to_op==OP_ToInt ); |
| 80838 | | - testcase( to_op==OP_ToReal ); |
| 80839 | 82826 | if( inReg!=target ){ |
| 80840 | 82827 | sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); |
| 80841 | 82828 | inReg = target; |
| 80842 | 82829 | } |
| 80843 | | - sqlite3VdbeAddOp1(v, to_op, inReg); |
| 82830 | + sqlite3VdbeAddOp2(v, OP_Cast, target, |
| 82831 | + sqlite3AffinityType(pExpr->u.zToken, 0)); |
| 80844 | 82832 | testcase( usedAsColumnCache(pParse, inReg, inReg) ); |
| 80845 | 82833 | sqlite3ExprCacheAffinityChange(pParse, inReg, 1); |
| 80846 | 82834 | break; |
| 80847 | 82835 | } |
| 80848 | 82836 | #endif /* SQLITE_OMIT_CAST */ |
| | @@ -86375,20 +88363,18 @@ |
| 86375 | 88363 | ** See also sqlite3LocateTable(). |
| 86376 | 88364 | */ |
| 86377 | 88365 | SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ |
| 86378 | 88366 | Table *p = 0; |
| 86379 | 88367 | int i; |
| 86380 | | - int nName; |
| 86381 | 88368 | assert( zName!=0 ); |
| 86382 | | - nName = sqlite3Strlen30(zName); |
| 86383 | 88369 | /* All mutexes are required for schema access. Make sure we hold them. */ |
| 86384 | 88370 | assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); |
| 86385 | 88371 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| 86386 | 88372 | int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
| 86387 | 88373 | if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; |
| 86388 | 88374 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
| 86389 | | - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName); |
| 88375 | + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); |
| 86390 | 88376 | if( p ) break; |
| 86391 | 88377 | } |
| 86392 | 88378 | return p; |
| 86393 | 88379 | } |
| 86394 | 88380 | |
| | @@ -86467,20 +88453,19 @@ |
| 86467 | 88453 | ** using the ATTACH command. |
| 86468 | 88454 | */ |
| 86469 | 88455 | SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ |
| 86470 | 88456 | Index *p = 0; |
| 86471 | 88457 | int i; |
| 86472 | | - int nName = sqlite3Strlen30(zName); |
| 86473 | 88458 | /* All mutexes are required for schema access. Make sure we hold them. */ |
| 86474 | 88459 | assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); |
| 86475 | 88460 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| 86476 | 88461 | int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
| 86477 | 88462 | Schema *pSchema = db->aDb[j].pSchema; |
| 86478 | 88463 | assert( pSchema ); |
| 86479 | 88464 | if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; |
| 86480 | 88465 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
| 86481 | | - p = sqlite3HashFind(&pSchema->idxHash, zName, nName); |
| 88466 | + p = sqlite3HashFind(&pSchema->idxHash, zName); |
| 86482 | 88467 | if( p ) break; |
| 86483 | 88468 | } |
| 86484 | 88469 | return p; |
| 86485 | 88470 | } |
| 86486 | 88471 | |
| | @@ -86504,17 +88489,15 @@ |
| 86504 | 88489 | ** the index hash table and free all memory structures associated |
| 86505 | 88490 | ** with the index. |
| 86506 | 88491 | */ |
| 86507 | 88492 | SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ |
| 86508 | 88493 | Index *pIndex; |
| 86509 | | - int len; |
| 86510 | 88494 | Hash *pHash; |
| 86511 | 88495 | |
| 86512 | 88496 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 86513 | 88497 | pHash = &db->aDb[iDb].pSchema->idxHash; |
| 86514 | | - len = sqlite3Strlen30(zIdxName); |
| 86515 | | - pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0); |
| 88498 | + pIndex = sqlite3HashInsert(pHash, zIdxName, 0); |
| 86516 | 88499 | if( ALWAYS(pIndex) ){ |
| 86517 | 88500 | if( pIndex->pTable->pIndex==pIndex ){ |
| 86518 | 88501 | pIndex->pTable->pIndex = pIndex->pNext; |
| 86519 | 88502 | }else{ |
| 86520 | 88503 | Index *p; |
| | @@ -86670,11 +88653,11 @@ |
| 86670 | 88653 | pNext = pIndex->pNext; |
| 86671 | 88654 | assert( pIndex->pSchema==pTable->pSchema ); |
| 86672 | 88655 | if( !db || db->pnBytesFreed==0 ){ |
| 86673 | 88656 | char *zName = pIndex->zName; |
| 86674 | 88657 | TESTONLY ( Index *pOld = ) sqlite3HashInsert( |
| 86675 | | - &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0 |
| 88658 | + &pIndex->pSchema->idxHash, zName, 0 |
| 86676 | 88659 | ); |
| 86677 | 88660 | assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); |
| 86678 | 88661 | assert( pOld==pIndex || pOld==0 ); |
| 86679 | 88662 | } |
| 86680 | 88663 | freeIndex(db, pIndex); |
| | @@ -86713,12 +88696,11 @@ |
| 86713 | 88696 | assert( iDb>=0 && iDb<db->nDb ); |
| 86714 | 88697 | assert( zTabName ); |
| 86715 | 88698 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 86716 | 88699 | testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ |
| 86717 | 88700 | pDb = &db->aDb[iDb]; |
| 86718 | | - p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, |
| 86719 | | - sqlite3Strlen30(zTabName),0); |
| 88701 | + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); |
| 86720 | 88702 | sqlite3DeleteTable(db, p); |
| 86721 | 88703 | db->flags |= SQLITE_InternChanges; |
| 86722 | 88704 | } |
| 86723 | 88705 | |
| 86724 | 88706 | /* |
| | @@ -88036,12 +90018,11 @@ |
| 88036 | 90018 | */ |
| 88037 | 90019 | if( db->init.busy ){ |
| 88038 | 90020 | Table *pOld; |
| 88039 | 90021 | Schema *pSchema = p->pSchema; |
| 88040 | 90022 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 88041 | | - pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, |
| 88042 | | - sqlite3Strlen30(p->zName),p); |
| 90023 | + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); |
| 88043 | 90024 | if( pOld ){ |
| 88044 | 90025 | assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ |
| 88045 | 90026 | db->mallocFailed = 1; |
| 88046 | 90027 | return; |
| 88047 | 90028 | } |
| | @@ -88687,11 +90668,11 @@ |
| 88687 | 90668 | pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ |
| 88688 | 90669 | pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ |
| 88689 | 90670 | |
| 88690 | 90671 | assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); |
| 88691 | 90672 | pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, |
| 88692 | | - pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey |
| 90673 | + pFKey->zTo, (void *)pFKey |
| 88693 | 90674 | ); |
| 88694 | 90675 | if( pNextTo==pFKey ){ |
| 88695 | 90676 | db->mallocFailed = 1; |
| 88696 | 90677 | goto fk_end; |
| 88697 | 90678 | } |
| | @@ -88775,11 +90756,11 @@ |
| 88775 | 90756 | } |
| 88776 | 90757 | pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); |
| 88777 | 90758 | |
| 88778 | 90759 | /* Open the sorter cursor if we are to use one. */ |
| 88779 | 90760 | iSorter = pParse->nTab++; |
| 88780 | | - sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*) |
| 90761 | + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) |
| 88781 | 90762 | sqlite3KeyInfoRef(pKey), P4_KEYINFO); |
| 88782 | 90763 | |
| 88783 | 90764 | /* Open the table. Loop through all rows of the table, inserting index |
| 88784 | 90765 | ** records into the sorter. */ |
| 88785 | 90766 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| | @@ -89124,11 +91105,11 @@ |
| 89124 | 91105 | sqlite3ErrorMsg(pParse, "table %s has no column named %s", |
| 89125 | 91106 | pTab->zName, zColName); |
| 89126 | 91107 | pParse->checkSchema = 1; |
| 89127 | 91108 | goto exit_create_index; |
| 89128 | 91109 | } |
| 89129 | | - assert( pTab->nCol<=0x7fff && j<=0x7fff ); |
| 91110 | + assert( j<=0x7fff ); |
| 89130 | 91111 | pIndex->aiColumn[i] = (i16)j; |
| 89131 | 91112 | if( pListItem->pExpr ){ |
| 89132 | 91113 | int nColl; |
| 89133 | 91114 | assert( pListItem->pExpr->op==TK_COLLATE ); |
| 89134 | 91115 | zColl = pListItem->pExpr->u.zToken; |
| | @@ -89235,12 +91216,11 @@ |
| 89235 | 91216 | */ |
| 89236 | 91217 | if( db->init.busy ){ |
| 89237 | 91218 | Index *p; |
| 89238 | 91219 | assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); |
| 89239 | 91220 | p = sqlite3HashInsert(&pIndex->pSchema->idxHash, |
| 89240 | | - pIndex->zName, sqlite3Strlen30(pIndex->zName), |
| 89241 | | - pIndex); |
| 91221 | + pIndex->zName, pIndex); |
| 89242 | 91222 | if( p ){ |
| 89243 | 91223 | assert( p==pIndex ); /* Malloc must have failed */ |
| 89244 | 91224 | db->mallocFailed = 1; |
| 89245 | 91225 | goto exit_create_index; |
| 89246 | 91226 | } |
| | @@ -90505,15 +92485,15 @@ |
| 90505 | 92485 | sqlite3 *db, /* Database connection */ |
| 90506 | 92486 | const char *zName, /* Name of the collating sequence */ |
| 90507 | 92487 | int create /* Create a new entry if true */ |
| 90508 | 92488 | ){ |
| 90509 | 92489 | CollSeq *pColl; |
| 90510 | | - int nName = sqlite3Strlen30(zName); |
| 90511 | | - pColl = sqlite3HashFind(&db->aCollSeq, zName, nName); |
| 92490 | + pColl = sqlite3HashFind(&db->aCollSeq, zName); |
| 90512 | 92491 | |
| 90513 | 92492 | if( 0==pColl && create ){ |
| 90514 | | - pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); |
| 92493 | + int nName = sqlite3Strlen30(zName); |
| 92494 | + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1); |
| 90515 | 92495 | if( pColl ){ |
| 90516 | 92496 | CollSeq *pDel = 0; |
| 90517 | 92497 | pColl[0].zName = (char*)&pColl[3]; |
| 90518 | 92498 | pColl[0].enc = SQLITE_UTF8; |
| 90519 | 92499 | pColl[1].zName = (char*)&pColl[3]; |
| | @@ -90520,11 +92500,11 @@ |
| 90520 | 92500 | pColl[1].enc = SQLITE_UTF16LE; |
| 90521 | 92501 | pColl[2].zName = (char*)&pColl[3]; |
| 90522 | 92502 | pColl[2].enc = SQLITE_UTF16BE; |
| 90523 | 92503 | memcpy(pColl[0].zName, zName, nName); |
| 90524 | 92504 | pColl[0].zName[nName] = 0; |
| 90525 | | - pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); |
| 92505 | + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); |
| 90526 | 92506 | |
| 90527 | 92507 | /* If a malloc() failure occurred in sqlite3HashInsert(), it will |
| 90528 | 92508 | ** return the pColl pointer to be deleted (because it wasn't added |
| 90529 | 92509 | ** to the hash table). |
| 90530 | 92510 | */ |
| | @@ -91296,22 +93276,24 @@ |
| 91296 | 93276 | ** deleting from and all its indices. If this is a view, then the |
| 91297 | 93277 | ** only effect this statement has is to fire the INSTEAD OF |
| 91298 | 93278 | ** triggers. |
| 91299 | 93279 | */ |
| 91300 | 93280 | if( !isView ){ |
| 93281 | + testcase( IsVirtual(pTab) ); |
| 91301 | 93282 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, |
| 91302 | 93283 | &iDataCur, &iIdxCur); |
| 91303 | | - assert( pPk || iDataCur==iTabCur ); |
| 91304 | | - assert( pPk || iIdxCur==iDataCur+1 ); |
| 93284 | + assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); |
| 93285 | + assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); |
| 91305 | 93286 | } |
| 91306 | 93287 | |
| 91307 | 93288 | /* Set up a loop over the rowids/primary-keys that were found in the |
| 91308 | 93289 | ** where-clause loop above. |
| 91309 | 93290 | */ |
| 91310 | 93291 | if( okOnePass ){ |
| 91311 | 93292 | /* Just one row. Hence the top-of-loop is a no-op */ |
| 91312 | | - assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 93293 | + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 93294 | + assert( !IsVirtual(pTab) ); |
| 91313 | 93295 | if( aToOpen[iDataCur-iTabCur] ){ |
| 91314 | 93296 | assert( pPk!=0 ); |
| 91315 | 93297 | sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); |
| 91316 | 93298 | VdbeCoverage(v); |
| 91317 | 93299 | } |
| | @@ -94077,12 +96059,11 @@ |
| 94077 | 96059 | ** "t2". Calling this function with "t2" as the argument would return a |
| 94078 | 96060 | ** NULL pointer (as there are no FK constraints for which t2 is the parent |
| 94079 | 96061 | ** table). |
| 94080 | 96062 | */ |
| 94081 | 96063 | SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ |
| 94082 | | - int nName = sqlite3Strlen30(pTab->zName); |
| 94083 | | - return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName); |
| 96064 | + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); |
| 94084 | 96065 | } |
| 94085 | 96066 | |
| 94086 | 96067 | /* |
| 94087 | 96068 | ** The second argument is a Trigger structure allocated by the |
| 94088 | 96069 | ** fkActionTrigger() routine. This function deletes the Trigger structure |
| | @@ -94756,11 +96737,11 @@ |
| 94756 | 96737 | if( pFKey->pPrevTo ){ |
| 94757 | 96738 | pFKey->pPrevTo->pNextTo = pFKey->pNextTo; |
| 94758 | 96739 | }else{ |
| 94759 | 96740 | void *p = (void *)pFKey->pNextTo; |
| 94760 | 96741 | const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); |
| 94761 | | - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p); |
| 96742 | + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); |
| 94762 | 96743 | } |
| 94763 | 96744 | if( pFKey->pNextTo ){ |
| 94764 | 96745 | pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; |
| 94765 | 96746 | } |
| 94766 | 96747 | } |
| | @@ -96395,10 +98376,13 @@ |
| 96395 | 98376 | ** |
| 96396 | 98377 | ** For a rowid table, *piDataCur will be exactly one less than *piIdxCur. |
| 96397 | 98378 | ** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range |
| 96398 | 98379 | ** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the |
| 96399 | 98380 | ** pTab->pIndex list. |
| 98381 | +** |
| 98382 | +** If pTab is a virtual table, then this routine is a no-op and the |
| 98383 | +** *piDataCur and *piIdxCur values are left uninitialized. |
| 96400 | 98384 | */ |
| 96401 | 98385 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices( |
| 96402 | 98386 | Parse *pParse, /* Parsing context */ |
| 96403 | 98387 | Table *pTab, /* Table to be opened */ |
| 96404 | 98388 | int op, /* OP_OpenRead or OP_OpenWrite */ |
| | @@ -96413,13 +98397,13 @@ |
| 96413 | 98397 | Index *pIdx; |
| 96414 | 98398 | Vdbe *v; |
| 96415 | 98399 | |
| 96416 | 98400 | assert( op==OP_OpenRead || op==OP_OpenWrite ); |
| 96417 | 98401 | if( IsVirtual(pTab) ){ |
| 96418 | | - assert( aToOpen==0 ); |
| 96419 | | - *piDataCur = 0; |
| 96420 | | - *piIdxCur = 1; |
| 98402 | + /* This routine is a no-op for virtual tables. Leave the output |
| 98403 | + ** variables *piDataCur and *piIdxCur uninitialized so that valgrind |
| 98404 | + ** can detect if they are used by mistake in the caller. */ |
| 96421 | 98405 | return 0; |
| 96422 | 98406 | } |
| 96423 | 98407 | iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 96424 | 98408 | v = sqlite3GetVdbe(pParse); |
| 96425 | 98409 | assert( v!=0 ); |
| | @@ -96847,11 +98831,11 @@ |
| 96847 | 98831 | |
| 96848 | 98832 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; |
| 96849 | 98833 | if( zSql==0 ) zSql = ""; |
| 96850 | 98834 | |
| 96851 | 98835 | sqlite3_mutex_enter(db->mutex); |
| 96852 | | - sqlite3Error(db, SQLITE_OK, 0); |
| 98836 | + sqlite3Error(db, SQLITE_OK); |
| 96853 | 98837 | while( rc==SQLITE_OK && zSql[0] ){ |
| 96854 | 98838 | int nCol; |
| 96855 | 98839 | char **azVals = 0; |
| 96856 | 98840 | |
| 96857 | 98841 | pStmt = 0; |
| | @@ -96905,11 +98889,11 @@ |
| 96905 | 98889 | ** sqlite3_exec() returns non-zero, then sqlite3_exec() will |
| 96906 | 98890 | ** return SQLITE_ABORT. */ |
| 96907 | 98891 | rc = SQLITE_ABORT; |
| 96908 | 98892 | sqlite3VdbeFinalize((Vdbe *)pStmt); |
| 96909 | 98893 | pStmt = 0; |
| 96910 | | - sqlite3Error(db, SQLITE_ABORT, 0); |
| 98894 | + sqlite3Error(db, SQLITE_ABORT); |
| 96911 | 98895 | goto exec_out; |
| 96912 | 98896 | } |
| 96913 | 98897 | } |
| 96914 | 98898 | |
| 96915 | 98899 | if( rc!=SQLITE_ROW ){ |
| | @@ -96935,11 +98919,11 @@ |
| 96935 | 98919 | *pzErrMsg = sqlite3Malloc(nErrMsg); |
| 96936 | 98920 | if( *pzErrMsg ){ |
| 96937 | 98921 | memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); |
| 96938 | 98922 | }else{ |
| 96939 | 98923 | rc = SQLITE_NOMEM; |
| 96940 | | - sqlite3Error(db, SQLITE_NOMEM, 0); |
| 98924 | + sqlite3Error(db, SQLITE_NOMEM); |
| 96941 | 98925 | } |
| 96942 | 98926 | }else if( pzErrMsg ){ |
| 96943 | 98927 | *pzErrMsg = 0; |
| 96944 | 98928 | } |
| 96945 | 98929 | |
| | @@ -98188,11 +100172,11 @@ |
| 98188 | 100172 | wsdAutoext.aExt[i]; |
| 98189 | 100173 | } |
| 98190 | 100174 | sqlite3_mutex_leave(mutex); |
| 98191 | 100175 | zErrmsg = 0; |
| 98192 | 100176 | if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ |
| 98193 | | - sqlite3Error(db, rc, |
| 100177 | + sqlite3ErrorWithMsg(db, rc, |
| 98194 | 100178 | "automatic extension loading failed: %s", zErrmsg); |
| 98195 | 100179 | go = 0; |
| 98196 | 100180 | } |
| 98197 | 100181 | sqlite3_free(zErrmsg); |
| 98198 | 100182 | } |
| | @@ -98260,18 +100244,19 @@ |
| 98260 | 100244 | #define PragTyp_STATS 28 |
| 98261 | 100245 | #define PragTyp_SYNCHRONOUS 29 |
| 98262 | 100246 | #define PragTyp_TABLE_INFO 30 |
| 98263 | 100247 | #define PragTyp_TEMP_STORE 31 |
| 98264 | 100248 | #define PragTyp_TEMP_STORE_DIRECTORY 32 |
| 98265 | | -#define PragTyp_WAL_AUTOCHECKPOINT 33 |
| 98266 | | -#define PragTyp_WAL_CHECKPOINT 34 |
| 98267 | | -#define PragTyp_ACTIVATE_EXTENSIONS 35 |
| 98268 | | -#define PragTyp_HEXKEY 36 |
| 98269 | | -#define PragTyp_KEY 37 |
| 98270 | | -#define PragTyp_REKEY 38 |
| 98271 | | -#define PragTyp_LOCK_STATUS 39 |
| 98272 | | -#define PragTyp_PARSER_TRACE 40 |
| 100249 | +#define PragTyp_THREADS 33 |
| 100250 | +#define PragTyp_WAL_AUTOCHECKPOINT 34 |
| 100251 | +#define PragTyp_WAL_CHECKPOINT 35 |
| 100252 | +#define PragTyp_ACTIVATE_EXTENSIONS 36 |
| 100253 | +#define PragTyp_HEXKEY 37 |
| 100254 | +#define PragTyp_KEY 38 |
| 100255 | +#define PragTyp_REKEY 39 |
| 100256 | +#define PragTyp_LOCK_STATUS 40 |
| 100257 | +#define PragTyp_PARSER_TRACE 41 |
| 98273 | 100258 | #define PragFlag_NeedSchema 0x01 |
| 98274 | 100259 | static const struct sPragmaNames { |
| 98275 | 100260 | const char *const zName; /* Name of pragma */ |
| 98276 | 100261 | u8 ePragTyp; /* PragTyp_XXX value */ |
| 98277 | 100262 | u8 mPragFlag; /* Zero or more PragFlag_XXX values */ |
| | @@ -98617,10 +100602,14 @@ |
| 98617 | 100602 | { /* zName: */ "temp_store_directory", |
| 98618 | 100603 | /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, |
| 98619 | 100604 | /* ePragFlag: */ 0, |
| 98620 | 100605 | /* iArg: */ 0 }, |
| 98621 | 100606 | #endif |
| 100607 | + { /* zName: */ "threads", |
| 100608 | + /* ePragTyp: */ PragTyp_THREADS, |
| 100609 | + /* ePragFlag: */ 0, |
| 100610 | + /* iArg: */ 0 }, |
| 98622 | 100611 | #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 98623 | 100612 | { /* zName: */ "user_version", |
| 98624 | 100613 | /* ePragTyp: */ PragTyp_HEADER_VALUE, |
| 98625 | 100614 | /* ePragFlag: */ 0, |
| 98626 | 100615 | /* iArg: */ 0 }, |
| | @@ -98664,11 +100653,11 @@ |
| 98664 | 100653 | /* ePragTyp: */ PragTyp_FLAG, |
| 98665 | 100654 | /* ePragFlag: */ 0, |
| 98666 | 100655 | /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 98667 | 100656 | #endif |
| 98668 | 100657 | }; |
| 98669 | | -/* Number of pragmas: 56 on by default, 69 total. */ |
| 100658 | +/* Number of pragmas: 57 on by default, 70 total. */ |
| 98670 | 100659 | /* End of the automatically generated pragma table. |
| 98671 | 100660 | ***************************************************************************/ |
| 98672 | 100661 | |
| 98673 | 100662 | /* |
| 98674 | 100663 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| | @@ -100471,10 +102460,30 @@ |
| 100471 | 102460 | sqlite3_soft_heap_limit64(N); |
| 100472 | 102461 | } |
| 100473 | 102462 | returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 100474 | 102463 | break; |
| 100475 | 102464 | } |
| 102465 | + |
| 102466 | + /* |
| 102467 | + ** PRAGMA threads |
| 102468 | + ** PRAGMA threads = N |
| 102469 | + ** |
| 102470 | + ** Configure the maximum number of worker threads. Return the new |
| 102471 | + ** maximum, which might be less than requested. |
| 102472 | + */ |
| 102473 | + case PragTyp_THREADS: { |
| 102474 | + sqlite3_int64 N; |
| 102475 | + if( zRight |
| 102476 | + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK |
| 102477 | + && N>=0 |
| 102478 | + ){ |
| 102479 | + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); |
| 102480 | + } |
| 102481 | + returnSingleInt(pParse, "threads", |
| 102482 | + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); |
| 102483 | + break; |
| 102484 | + } |
| 100476 | 102485 | |
| 100477 | 102486 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 100478 | 102487 | /* |
| 100479 | 102488 | ** Report the current state of file logs for all databases |
| 100480 | 102489 | */ |
| | @@ -101153,11 +103162,11 @@ |
| 101153 | 103162 | if( pBt ){ |
| 101154 | 103163 | assert( sqlite3BtreeHoldsMutex(pBt) ); |
| 101155 | 103164 | rc = sqlite3BtreeSchemaLocked(pBt); |
| 101156 | 103165 | if( rc ){ |
| 101157 | 103166 | const char *zDb = db->aDb[i].zName; |
| 101158 | | - sqlite3Error(db, rc, "database schema is locked: %s", zDb); |
| 103167 | + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); |
| 101159 | 103168 | testcase( db->flags & SQLITE_ReadUncommitted ); |
| 101160 | 103169 | goto end_prepare; |
| 101161 | 103170 | } |
| 101162 | 103171 | } |
| 101163 | 103172 | } |
| | @@ -101170,11 +103179,11 @@ |
| 101170 | 103179 | char *zSqlCopy; |
| 101171 | 103180 | int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; |
| 101172 | 103181 | testcase( nBytes==mxLen ); |
| 101173 | 103182 | testcase( nBytes==mxLen+1 ); |
| 101174 | 103183 | if( nBytes>mxLen ){ |
| 101175 | | - sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); |
| 103184 | + sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); |
| 101176 | 103185 | rc = sqlite3ApiExit(db, SQLITE_TOOBIG); |
| 101177 | 103186 | goto end_prepare; |
| 101178 | 103187 | } |
| 101179 | 103188 | zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); |
| 101180 | 103189 | if( zSqlCopy ){ |
| | @@ -101237,14 +103246,14 @@ |
| 101237 | 103246 | }else{ |
| 101238 | 103247 | *ppStmt = (sqlite3_stmt*)pParse->pVdbe; |
| 101239 | 103248 | } |
| 101240 | 103249 | |
| 101241 | 103250 | if( zErrMsg ){ |
| 101242 | | - sqlite3Error(db, rc, "%s", zErrMsg); |
| 103251 | + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); |
| 101243 | 103252 | sqlite3DbFree(db, zErrMsg); |
| 101244 | 103253 | }else{ |
| 101245 | | - sqlite3Error(db, rc, 0); |
| 103254 | + sqlite3Error(db, rc); |
| 101246 | 103255 | } |
| 101247 | 103256 | |
| 101248 | 103257 | /* Delete any TriggerPrg structures allocated while parsing this statement. */ |
| 101249 | 103258 | while( pParse->pTriggerPrg ){ |
| 101250 | 103259 | TriggerPrg *pT = pParse->pTriggerPrg; |
| | @@ -101902,32 +103911,47 @@ |
| 101902 | 103911 | int iStart, /* Begin with this column of pList */ |
| 101903 | 103912 | int nExtra /* Add this many extra columns to the end */ |
| 101904 | 103913 | ); |
| 101905 | 103914 | |
| 101906 | 103915 | /* |
| 101907 | | -** Insert code into "v" that will push the record in register regData |
| 101908 | | -** into the sorter. |
| 103916 | +** Generate code that will push the record in registers regData |
| 103917 | +** through regData+nData-1 onto the sorter. |
| 101909 | 103918 | */ |
| 101910 | 103919 | static void pushOntoSorter( |
| 101911 | 103920 | Parse *pParse, /* Parser context */ |
| 101912 | 103921 | SortCtx *pSort, /* Information about the ORDER BY clause */ |
| 101913 | 103922 | Select *pSelect, /* The whole SELECT statement */ |
| 101914 | | - int regData /* Register holding data to be sorted */ |
| 103923 | + int regData, /* First register holding data to be sorted */ |
| 103924 | + int nData, /* Number of elements in the data array */ |
| 103925 | + int nPrefixReg /* No. of reg prior to regData available for use */ |
| 101915 | 103926 | ){ |
| 101916 | | - Vdbe *v = pParse->pVdbe; |
| 101917 | | - int nExpr = pSort->pOrderBy->nExpr; |
| 101918 | | - int regRecord = ++pParse->nMem; |
| 101919 | | - int regBase = pParse->nMem+1; |
| 101920 | | - int nOBSat = pSort->nOBSat; |
| 101921 | | - int op; |
| 101922 | | - |
| 101923 | | - pParse->nMem += nExpr+2; /* nExpr+2 registers allocated at regBase */ |
| 101924 | | - sqlite3ExprCacheClear(pParse); |
| 101925 | | - sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 101926 | | - sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 101927 | | - sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 101928 | | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat,regRecord); |
| 103927 | + Vdbe *v = pParse->pVdbe; /* Stmt under construction */ |
| 103928 | + int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); |
| 103929 | + int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ |
| 103930 | + int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ |
| 103931 | + int regBase; /* Regs for sorter record */ |
| 103932 | + int regRecord = ++pParse->nMem; /* Assembled sorter record */ |
| 103933 | + int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ |
| 103934 | + int op; /* Opcode to add sorter record to sorter */ |
| 103935 | + |
| 103936 | + assert( bSeq==0 || bSeq==1 ); |
| 103937 | + if( nPrefixReg ){ |
| 103938 | + assert( nPrefixReg==nExpr+bSeq ); |
| 103939 | + regBase = regData - nExpr - bSeq; |
| 103940 | + }else{ |
| 103941 | + regBase = pParse->nMem + 1; |
| 103942 | + pParse->nMem += nBase; |
| 103943 | + } |
| 103944 | + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP); |
| 103945 | + if( bSeq ){ |
| 103946 | + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 103947 | + } |
| 103948 | + if( nPrefixReg==0 ){ |
| 103949 | + sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+bSeq, nData); |
| 103950 | + } |
| 103951 | + |
| 103952 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); |
| 101929 | 103953 | if( nOBSat>0 ){ |
| 101930 | 103954 | int regPrevKey; /* The first nOBSat columns of the previous row */ |
| 101931 | 103955 | int addrFirst; /* Address of the OP_IfNot opcode */ |
| 101932 | 103956 | int addrJmp; /* Address of the OP_Jump opcode */ |
| 101933 | 103957 | VdbeOp *pOp; /* Opcode that opens the sorter */ |
| | @@ -101934,16 +103958,21 @@ |
| 101934 | 103958 | int nKey; /* Number of sorting key columns, including OP_Sequence */ |
| 101935 | 103959 | KeyInfo *pKI; /* Original KeyInfo on the sorter table */ |
| 101936 | 103960 | |
| 101937 | 103961 | regPrevKey = pParse->nMem+1; |
| 101938 | 103962 | pParse->nMem += pSort->nOBSat; |
| 101939 | | - nKey = nExpr - pSort->nOBSat + 1; |
| 101940 | | - addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); VdbeCoverage(v); |
| 103963 | + nKey = nExpr - pSort->nOBSat + bSeq; |
| 103964 | + if( bSeq ){ |
| 103965 | + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); |
| 103966 | + }else{ |
| 103967 | + addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); |
| 103968 | + } |
| 103969 | + VdbeCoverage(v); |
| 101941 | 103970 | sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); |
| 101942 | 103971 | pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); |
| 101943 | 103972 | if( pParse->db->mallocFailed ) return; |
| 101944 | | - pOp->p2 = nKey + 1; |
| 103973 | + pOp->p2 = nKey + nData; |
| 101945 | 103974 | pKI = pOp->p4.pKeyInfo; |
| 101946 | 103975 | memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */ |
| 101947 | 103976 | sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); |
| 101948 | 103977 | pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1); |
| 101949 | 103978 | addrJmp = sqlite3VdbeCurrentAddr(v); |
| | @@ -102073,10 +104102,11 @@ |
| 102073 | 104102 | int hasDistinct; /* True if the DISTINCT keyword is present */ |
| 102074 | 104103 | int regResult; /* Start of memory holding result set */ |
| 102075 | 104104 | int eDest = pDest->eDest; /* How to dispose of results */ |
| 102076 | 104105 | int iParm = pDest->iSDParm; /* First argument to disposal method */ |
| 102077 | 104106 | int nResultCol; /* Number of result columns */ |
| 104107 | + int nPrefixReg = 0; /* Number of extra registers before regResult */ |
| 102078 | 104108 | |
| 102079 | 104109 | assert( v ); |
| 102080 | 104110 | assert( pEList!=0 ); |
| 102081 | 104111 | hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; |
| 102082 | 104112 | if( pSort && pSort->pOrderBy==0 ) pSort = 0; |
| | @@ -102088,10 +104118,15 @@ |
| 102088 | 104118 | /* Pull the requested columns. |
| 102089 | 104119 | */ |
| 102090 | 104120 | nResultCol = pEList->nExpr; |
| 102091 | 104121 | |
| 102092 | 104122 | if( pDest->iSdst==0 ){ |
| 104123 | + if( pSort ){ |
| 104124 | + nPrefixReg = pSort->pOrderBy->nExpr; |
| 104125 | + if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; |
| 104126 | + pParse->nMem += nPrefixReg; |
| 104127 | + } |
| 102093 | 104128 | pDest->iSdst = pParse->nMem+1; |
| 102094 | 104129 | pParse->nMem += nResultCol; |
| 102095 | 104130 | }else if( pDest->iSdst+nResultCol > pParse->nMem ){ |
| 102096 | 104131 | /* This is an error condition that can result, for example, when a SELECT |
| 102097 | 104132 | ** on the right-hand side of an INSERT contains more result columns than |
| | @@ -102204,14 +104239,14 @@ |
| 102204 | 104239 | */ |
| 102205 | 104240 | case SRT_Fifo: |
| 102206 | 104241 | case SRT_DistFifo: |
| 102207 | 104242 | case SRT_Table: |
| 102208 | 104243 | case SRT_EphemTab: { |
| 102209 | | - int r1 = sqlite3GetTempReg(pParse); |
| 104244 | + int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); |
| 102210 | 104245 | testcase( eDest==SRT_Table ); |
| 102211 | 104246 | testcase( eDest==SRT_EphemTab ); |
| 102212 | | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 104247 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); |
| 102213 | 104248 | #ifndef SQLITE_OMIT_CTE |
| 102214 | 104249 | if( eDest==SRT_DistFifo ){ |
| 102215 | 104250 | /* If the destination is DistFifo, then cursor (iParm+1) is open |
| 102216 | 104251 | ** on an ephemeral index. If the current row is already present |
| 102217 | 104252 | ** in the index, do not write it to the output. If not, add the |
| | @@ -102222,19 +104257,19 @@ |
| 102222 | 104257 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); |
| 102223 | 104258 | assert( pSort==0 ); |
| 102224 | 104259 | } |
| 102225 | 104260 | #endif |
| 102226 | 104261 | if( pSort ){ |
| 102227 | | - pushOntoSorter(pParse, pSort, p, r1); |
| 104262 | + pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg); |
| 102228 | 104263 | }else{ |
| 102229 | 104264 | int r2 = sqlite3GetTempReg(pParse); |
| 102230 | 104265 | sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); |
| 102231 | 104266 | sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); |
| 102232 | 104267 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 102233 | 104268 | sqlite3ReleaseTempReg(pParse, r2); |
| 102234 | 104269 | } |
| 102235 | | - sqlite3ReleaseTempReg(pParse, r1); |
| 104270 | + sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); |
| 102236 | 104271 | break; |
| 102237 | 104272 | } |
| 102238 | 104273 | |
| 102239 | 104274 | #ifndef SQLITE_OMIT_SUBQUERY |
| 102240 | 104275 | /* If we are creating a set for an "expr IN (SELECT ...)" construct, |
| | @@ -102248,11 +104283,11 @@ |
| 102248 | 104283 | if( pSort ){ |
| 102249 | 104284 | /* At first glance you would think we could optimize out the |
| 102250 | 104285 | ** ORDER BY in this case since the order of entries in the set |
| 102251 | 104286 | ** does not matter. But there might be a LIMIT clause, in which |
| 102252 | 104287 | ** case the order does matter */ |
| 102253 | | - pushOntoSorter(pParse, pSort, p, regResult); |
| 104288 | + pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg); |
| 102254 | 104289 | }else{ |
| 102255 | 104290 | int r1 = sqlite3GetTempReg(pParse); |
| 102256 | 104291 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); |
| 102257 | 104292 | sqlite3ExprCacheAffinityChange(pParse, regResult, 1); |
| 102258 | 104293 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); |
| | @@ -102274,13 +104309,13 @@ |
| 102274 | 104309 | ** of the scan loop. |
| 102275 | 104310 | */ |
| 102276 | 104311 | case SRT_Mem: { |
| 102277 | 104312 | assert( nResultCol==1 ); |
| 102278 | 104313 | if( pSort ){ |
| 102279 | | - pushOntoSorter(pParse, pSort, p, regResult); |
| 104314 | + pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg); |
| 102280 | 104315 | }else{ |
| 102281 | | - sqlite3ExprCodeMove(pParse, regResult, iParm, 1); |
| 104316 | + assert( regResult==iParm ); |
| 102282 | 104317 | /* The LIMIT clause will jump out of the loop for us */ |
| 102283 | 104318 | } |
| 102284 | 104319 | break; |
| 102285 | 104320 | } |
| 102286 | 104321 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ |
| | @@ -102288,14 +104323,11 @@ |
| 102288 | 104323 | case SRT_Coroutine: /* Send data to a co-routine */ |
| 102289 | 104324 | case SRT_Output: { /* Return the results */ |
| 102290 | 104325 | testcase( eDest==SRT_Coroutine ); |
| 102291 | 104326 | testcase( eDest==SRT_Output ); |
| 102292 | 104327 | if( pSort ){ |
| 102293 | | - int r1 = sqlite3GetTempReg(pParse); |
| 102294 | | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 102295 | | - pushOntoSorter(pParse, pSort, p, r1); |
| 102296 | | - sqlite3ReleaseTempReg(pParse, r1); |
| 104328 | + pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg); |
| 102297 | 104329 | }else if( eDest==SRT_Coroutine ){ |
| 102298 | 104330 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 102299 | 104331 | }else{ |
| 102300 | 104332 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); |
| 102301 | 104333 | sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); |
| | @@ -102571,50 +104603,66 @@ |
| 102571 | 104603 | int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ |
| 102572 | 104604 | int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ |
| 102573 | 104605 | int addr; |
| 102574 | 104606 | int addrOnce = 0; |
| 102575 | 104607 | int iTab; |
| 102576 | | - int pseudoTab = 0; |
| 102577 | 104608 | ExprList *pOrderBy = pSort->pOrderBy; |
| 102578 | 104609 | int eDest = pDest->eDest; |
| 102579 | 104610 | int iParm = pDest->iSDParm; |
| 102580 | 104611 | int regRow; |
| 102581 | 104612 | int regRowid; |
| 102582 | 104613 | int nKey; |
| 104614 | + int iSortTab; /* Sorter cursor to read from */ |
| 104615 | + int nSortData; /* Trailing values to read from sorter */ |
| 104616 | + u8 p5; /* p5 parameter for 1st OP_Column */ |
| 104617 | + int i; |
| 104618 | + int bSeq; /* True if sorter record includes seq. no. */ |
| 104619 | +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 104620 | + struct ExprList_item *aOutEx = p->pEList->a; |
| 104621 | +#endif |
| 102583 | 104622 | |
| 102584 | 104623 | if( pSort->labelBkOut ){ |
| 102585 | 104624 | sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); |
| 102586 | 104625 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak); |
| 102587 | 104626 | sqlite3VdbeResolveLabel(v, pSort->labelBkOut); |
| 102588 | | - addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 102589 | 104627 | } |
| 102590 | 104628 | iTab = pSort->iECursor; |
| 102591 | | - regRow = sqlite3GetTempReg(pParse); |
| 102592 | 104629 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 102593 | | - pseudoTab = pParse->nTab++; |
| 102594 | | - sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 102595 | 104630 | regRowid = 0; |
| 104631 | + regRow = pDest->iSdst; |
| 104632 | + nSortData = nColumn; |
| 102596 | 104633 | }else{ |
| 102597 | 104634 | regRowid = sqlite3GetTempReg(pParse); |
| 104635 | + regRow = sqlite3GetTempReg(pParse); |
| 104636 | + nSortData = 1; |
| 102598 | 104637 | } |
| 102599 | 104638 | nKey = pOrderBy->nExpr - pSort->nOBSat; |
| 102600 | 104639 | if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 102601 | 104640 | int regSortOut = ++pParse->nMem; |
| 102602 | | - int ptab2 = pParse->nTab++; |
| 102603 | | - sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, nKey+2); |
| 104641 | + iSortTab = pParse->nTab++; |
| 104642 | + if( pSort->labelBkOut ){ |
| 104643 | + addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 104644 | + } |
| 104645 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); |
| 102604 | 104646 | if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 102605 | 104647 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 102606 | 104648 | VdbeCoverage(v); |
| 102607 | 104649 | codeOffset(v, p->iOffset, addrContinue); |
| 102608 | 104650 | sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 102609 | | - sqlite3VdbeAddOp3(v, OP_Column, ptab2, nKey+1, regRow); |
| 102610 | | - sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 104651 | + p5 = OPFLAG_CLEARCACHE; |
| 104652 | + bSeq = 0; |
| 102611 | 104653 | }else{ |
| 102612 | | - if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 102613 | 104654 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 102614 | 104655 | codeOffset(v, p->iOffset, addrContinue); |
| 102615 | | - sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow); |
| 104656 | + iSortTab = iTab; |
| 104657 | + p5 = 0; |
| 104658 | + bSeq = 1; |
| 104659 | + } |
| 104660 | + for(i=0; i<nSortData; i++){ |
| 104661 | + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i); |
| 104662 | + if( i==0 ) sqlite3VdbeChangeP5(v, p5); |
| 104663 | + VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); |
| 102616 | 104664 | } |
| 102617 | 104665 | switch( eDest ){ |
| 102618 | 104666 | case SRT_Table: |
| 102619 | 104667 | case SRT_EphemTab: { |
| 102620 | 104668 | testcase( eDest==SRT_Table ); |
| | @@ -102639,33 +104687,26 @@ |
| 102639 | 104687 | /* The LIMIT clause will terminate the loop for us */ |
| 102640 | 104688 | break; |
| 102641 | 104689 | } |
| 102642 | 104690 | #endif |
| 102643 | 104691 | default: { |
| 102644 | | - int i; |
| 102645 | 104692 | assert( eDest==SRT_Output || eDest==SRT_Coroutine ); |
| 102646 | 104693 | testcase( eDest==SRT_Output ); |
| 102647 | 104694 | testcase( eDest==SRT_Coroutine ); |
| 102648 | | - for(i=0; i<nColumn; i++){ |
| 102649 | | - assert( regRow!=pDest->iSdst+i ); |
| 102650 | | - sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i); |
| 102651 | | - if( i==0 ){ |
| 102652 | | - sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 102653 | | - } |
| 102654 | | - } |
| 102655 | 104695 | if( eDest==SRT_Output ){ |
| 102656 | 104696 | sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); |
| 102657 | 104697 | sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); |
| 102658 | 104698 | }else{ |
| 102659 | 104699 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 102660 | 104700 | } |
| 102661 | 104701 | break; |
| 102662 | 104702 | } |
| 102663 | 104703 | } |
| 102664 | | - sqlite3ReleaseTempReg(pParse, regRow); |
| 102665 | | - sqlite3ReleaseTempReg(pParse, regRowid); |
| 102666 | | - |
| 104704 | + if( regRowid ){ |
| 104705 | + sqlite3ReleaseTempReg(pParse, regRow); |
| 104706 | + sqlite3ReleaseTempReg(pParse, regRowid); |
| 104707 | + } |
| 102667 | 104708 | /* The bottom of the loop |
| 102668 | 104709 | */ |
| 102669 | 104710 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 102670 | 104711 | if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 102671 | 104712 | sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); |
| | @@ -106202,12 +108243,13 @@ |
| 106202 | 108243 | KeyInfo *pKeyInfo; |
| 106203 | 108244 | pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0); |
| 106204 | 108245 | sSort.iECursor = pParse->nTab++; |
| 106205 | 108246 | sSort.addrSortIndex = |
| 106206 | 108247 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 106207 | | - sSort.iECursor, sSort.pOrderBy->nExpr+2, 0, |
| 106208 | | - (char*)pKeyInfo, P4_KEYINFO); |
| 108248 | + sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, |
| 108249 | + (char*)pKeyInfo, P4_KEYINFO |
| 108250 | + ); |
| 106209 | 108251 | }else{ |
| 106210 | 108252 | sSort.addrSortIndex = -1; |
| 106211 | 108253 | } |
| 106212 | 108254 | |
| 106213 | 108255 | /* If the output is destined for a temporary table, open that table. |
| | @@ -106334,11 +108376,11 @@ |
| 106334 | 108376 | memset(&sNC, 0, sizeof(sNC)); |
| 106335 | 108377 | sNC.pParse = pParse; |
| 106336 | 108378 | sNC.pSrcList = pTabList; |
| 106337 | 108379 | sNC.pAggInfo = &sAggInfo; |
| 106338 | 108380 | sAggInfo.mnReg = pParse->nMem+1; |
| 106339 | | - sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; |
| 108381 | + sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; |
| 106340 | 108382 | sAggInfo.pGroupBy = pGroupBy; |
| 106341 | 108383 | sqlite3ExprAnalyzeAggList(&sNC, pEList); |
| 106342 | 108384 | sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); |
| 106343 | 108385 | if( pHaving ){ |
| 106344 | 108386 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); |
| | @@ -106427,23 +108469,22 @@ |
| 106427 | 108469 | (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? |
| 106428 | 108470 | "DISTINCT" : "GROUP BY"); |
| 106429 | 108471 | |
| 106430 | 108472 | groupBySort = 1; |
| 106431 | 108473 | nGroupBy = pGroupBy->nExpr; |
| 106432 | | - nCol = nGroupBy + 1; |
| 106433 | | - j = nGroupBy+1; |
| 108474 | + nCol = nGroupBy; |
| 108475 | + j = nGroupBy; |
| 106434 | 108476 | for(i=0; i<sAggInfo.nColumn; i++){ |
| 106435 | 108477 | if( sAggInfo.aCol[i].iSorterColumn>=j ){ |
| 106436 | 108478 | nCol++; |
| 106437 | 108479 | j++; |
| 106438 | 108480 | } |
| 106439 | 108481 | } |
| 106440 | 108482 | regBase = sqlite3GetTempRange(pParse, nCol); |
| 106441 | 108483 | sqlite3ExprCacheClear(pParse); |
| 106442 | 108484 | sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); |
| 106443 | | - sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); |
| 106444 | | - j = nGroupBy+1; |
| 108485 | + j = nGroupBy; |
| 106445 | 108486 | for(i=0; i<sAggInfo.nColumn; i++){ |
| 106446 | 108487 | struct AggInfo_col *pCol = &sAggInfo.aCol[i]; |
| 106447 | 108488 | if( pCol->iSorterColumn>=j ){ |
| 106448 | 108489 | int r1 = j + regBase; |
| 106449 | 108490 | int r2; |
| | @@ -107236,12 +109277,11 @@ |
| 107236 | 109277 | zName = sqlite3NameFromToken(db, pName); |
| 107237 | 109278 | if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ |
| 107238 | 109279 | goto trigger_cleanup; |
| 107239 | 109280 | } |
| 107240 | 109281 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 107241 | | - if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), |
| 107242 | | - zName, sqlite3Strlen30(zName)) ){ |
| 109282 | + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ |
| 107243 | 109283 | if( !noErr ){ |
| 107244 | 109284 | sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); |
| 107245 | 109285 | }else{ |
| 107246 | 109286 | assert( !db->init.busy ); |
| 107247 | 109287 | sqlite3CodeVerifySchema(pParse, iDb); |
| | @@ -107380,17 +109420,16 @@ |
| 107380 | 109420 | |
| 107381 | 109421 | if( db->init.busy ){ |
| 107382 | 109422 | Trigger *pLink = pTrig; |
| 107383 | 109423 | Hash *pHash = &db->aDb[iDb].pSchema->trigHash; |
| 107384 | 109424 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 107385 | | - pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig); |
| 109425 | + pTrig = sqlite3HashInsert(pHash, zName, pTrig); |
| 107386 | 109426 | if( pTrig ){ |
| 107387 | 109427 | db->mallocFailed = 1; |
| 107388 | 109428 | }else if( pLink->pSchema==pLink->pTabSchema ){ |
| 107389 | 109429 | Table *pTab; |
| 107390 | | - int n = sqlite3Strlen30(pLink->table); |
| 107391 | | - pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n); |
| 109430 | + pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); |
| 107392 | 109431 | assert( pTab!=0 ); |
| 107393 | 109432 | pLink->pNext = pTab->pTrigger; |
| 107394 | 109433 | pTab->pTrigger = pLink; |
| 107395 | 109434 | } |
| 107396 | 109435 | } |
| | @@ -107545,11 +109584,10 @@ |
| 107545 | 109584 | SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ |
| 107546 | 109585 | Trigger *pTrigger = 0; |
| 107547 | 109586 | int i; |
| 107548 | 109587 | const char *zDb; |
| 107549 | 109588 | const char *zName; |
| 107550 | | - int nName; |
| 107551 | 109589 | sqlite3 *db = pParse->db; |
| 107552 | 109590 | |
| 107553 | 109591 | if( db->mallocFailed ) goto drop_trigger_cleanup; |
| 107554 | 109592 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
| 107555 | 109593 | goto drop_trigger_cleanup; |
| | @@ -107556,17 +109594,16 @@ |
| 107556 | 109594 | } |
| 107557 | 109595 | |
| 107558 | 109596 | assert( pName->nSrc==1 ); |
| 107559 | 109597 | zDb = pName->a[0].zDatabase; |
| 107560 | 109598 | zName = pName->a[0].zName; |
| 107561 | | - nName = sqlite3Strlen30(zName); |
| 107562 | 109599 | assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); |
| 107563 | 109600 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
| 107564 | 109601 | int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
| 107565 | 109602 | if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue; |
| 107566 | 109603 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
| 107567 | | - pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName); |
| 109604 | + pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); |
| 107568 | 109605 | if( pTrigger ) break; |
| 107569 | 109606 | } |
| 107570 | 109607 | if( !pTrigger ){ |
| 107571 | 109608 | if( !noErr ){ |
| 107572 | 109609 | sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); |
| | @@ -107585,12 +109622,11 @@ |
| 107585 | 109622 | /* |
| 107586 | 109623 | ** Return a pointer to the Table structure for the table that a trigger |
| 107587 | 109624 | ** is set on. |
| 107588 | 109625 | */ |
| 107589 | 109626 | static Table *tableOfTrigger(Trigger *pTrigger){ |
| 107590 | | - int n = sqlite3Strlen30(pTrigger->table); |
| 107591 | | - return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n); |
| 109627 | + return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); |
| 107592 | 109628 | } |
| 107593 | 109629 | |
| 107594 | 109630 | |
| 107595 | 109631 | /* |
| 107596 | 109632 | ** Drop a trigger given a pointer to that trigger. |
| | @@ -107658,11 +109694,11 @@ |
| 107658 | 109694 | Trigger *pTrigger; |
| 107659 | 109695 | Hash *pHash; |
| 107660 | 109696 | |
| 107661 | 109697 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 107662 | 109698 | pHash = &(db->aDb[iDb].pSchema->trigHash); |
| 107663 | | - pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0); |
| 109699 | + pTrigger = sqlite3HashInsert(pHash, zName, 0); |
| 107664 | 109700 | if( ALWAYS(pTrigger) ){ |
| 107665 | 109701 | if( pTrigger->pSchema==pTrigger->pTabSchema ){ |
| 107666 | 109702 | Table *pTab = tableOfTrigger(pTrigger); |
| 107667 | 109703 | Trigger **pp; |
| 107668 | 109704 | for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); |
| | @@ -109371,11 +111407,11 @@ |
| 109371 | 111407 | int rc = SQLITE_OK; |
| 109372 | 111408 | int nName; |
| 109373 | 111409 | |
| 109374 | 111410 | sqlite3_mutex_enter(db->mutex); |
| 109375 | 111411 | nName = sqlite3Strlen30(zName); |
| 109376 | | - if( sqlite3HashFind(&db->aModule, zName, nName) ){ |
| 111412 | + if( sqlite3HashFind(&db->aModule, zName) ){ |
| 109377 | 111413 | rc = SQLITE_MISUSE_BKPT; |
| 109378 | 111414 | }else{ |
| 109379 | 111415 | Module *pMod; |
| 109380 | 111416 | pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); |
| 109381 | 111417 | if( pMod ){ |
| | @@ -109384,11 +111420,11 @@ |
| 109384 | 111420 | memcpy(zCopy, zName, nName+1); |
| 109385 | 111421 | pMod->zName = zCopy; |
| 109386 | 111422 | pMod->pModule = pModule; |
| 109387 | 111423 | pMod->pAux = pAux; |
| 109388 | 111424 | pMod->xDestroy = xDestroy; |
| 109389 | | - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod); |
| 111425 | + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); |
| 109390 | 111426 | assert( pDel==0 || pDel==pMod ); |
| 109391 | 111427 | if( pDel ){ |
| 109392 | 111428 | db->mallocFailed = 1; |
| 109393 | 111429 | sqlite3DbFree(db, pDel); |
| 109394 | 111430 | } |
| | @@ -109753,13 +111789,12 @@ |
| 109753 | 111789 | ** the required virtual table implementations are registered. */ |
| 109754 | 111790 | else { |
| 109755 | 111791 | Table *pOld; |
| 109756 | 111792 | Schema *pSchema = pTab->pSchema; |
| 109757 | 111793 | const char *zName = pTab->zName; |
| 109758 | | - int nName = sqlite3Strlen30(zName); |
| 109759 | 111794 | assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); |
| 109760 | | - pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); |
| 111795 | + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); |
| 109761 | 111796 | if( pOld ){ |
| 109762 | 111797 | db->mallocFailed = 1; |
| 109763 | 111798 | assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ |
| 109764 | 111799 | return; |
| 109765 | 111800 | } |
| | @@ -109921,11 +111956,11 @@ |
| 109921 | 111956 | return SQLITE_OK; |
| 109922 | 111957 | } |
| 109923 | 111958 | |
| 109924 | 111959 | /* Locate the required virtual table module */ |
| 109925 | 111960 | zMod = pTab->azModuleArg[0]; |
| 109926 | | - pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod)); |
| 111961 | + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); |
| 109927 | 111962 | |
| 109928 | 111963 | if( !pMod ){ |
| 109929 | 111964 | const char *zModule = pTab->azModuleArg[0]; |
| 109930 | 111965 | sqlite3ErrorMsg(pParse, "no such module: %s", zModule); |
| 109931 | 111966 | rc = SQLITE_ERROR; |
| | @@ -109989,11 +112024,11 @@ |
| 109989 | 112024 | pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); |
| 109990 | 112025 | assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); |
| 109991 | 112026 | |
| 109992 | 112027 | /* Locate the required virtual table module */ |
| 109993 | 112028 | zMod = pTab->azModuleArg[0]; |
| 109994 | | - pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod)); |
| 112029 | + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); |
| 109995 | 112030 | |
| 109996 | 112031 | /* If the module has been registered and includes a Create method, |
| 109997 | 112032 | ** invoke it now. If the module has not been registered, return an |
| 109998 | 112033 | ** error. Otherwise, do nothing. |
| 109999 | 112034 | */ |
| | @@ -110028,11 +112063,11 @@ |
| 110028 | 112063 | Table *pTab; |
| 110029 | 112064 | char *zErr = 0; |
| 110030 | 112065 | |
| 110031 | 112066 | sqlite3_mutex_enter(db->mutex); |
| 110032 | 112067 | if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){ |
| 110033 | | - sqlite3Error(db, SQLITE_MISUSE, 0); |
| 112068 | + sqlite3Error(db, SQLITE_MISUSE); |
| 110034 | 112069 | sqlite3_mutex_leave(db->mutex); |
| 110035 | 112070 | return SQLITE_MISUSE_BKPT; |
| 110036 | 112071 | } |
| 110037 | 112072 | assert( (pTab->tabFlags & TF_Virtual)!=0 ); |
| 110038 | 112073 | |
| | @@ -110056,11 +112091,11 @@ |
| 110056 | 112091 | pParse->pNewTable->nCol = 0; |
| 110057 | 112092 | pParse->pNewTable->aCol = 0; |
| 110058 | 112093 | } |
| 110059 | 112094 | db->pVtabCtx->pTab = 0; |
| 110060 | 112095 | }else{ |
| 110061 | | - sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); |
| 112096 | + sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); |
| 110062 | 112097 | sqlite3DbFree(db, zErr); |
| 110063 | 112098 | rc = SQLITE_ERROR; |
| 110064 | 112099 | } |
| 110065 | 112100 | pParse->declareVtab = 0; |
| 110066 | 112101 | |
| | @@ -110417,11 +112452,11 @@ |
| 110417 | 112452 | rc = SQLITE_MISUSE_BKPT; |
| 110418 | 112453 | break; |
| 110419 | 112454 | } |
| 110420 | 112455 | va_end(ap); |
| 110421 | 112456 | |
| 110422 | | - if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0); |
| 112457 | + if( rc!=SQLITE_OK ) sqlite3Error(db, rc); |
| 110423 | 112458 | sqlite3_mutex_leave(db->mutex); |
| 110424 | 112459 | return rc; |
| 110425 | 112460 | } |
| 110426 | 112461 | |
| 110427 | 112462 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -113083,10 +115118,14 @@ |
| 113083 | 115118 | ** of iUpper are requested of whereKeyStats() and the smaller used. |
| 113084 | 115119 | */ |
| 113085 | 115120 | tRowcnt iLower; |
| 113086 | 115121 | tRowcnt iUpper; |
| 113087 | 115122 | |
| 115123 | + if( pRec ){ |
| 115124 | + testcase( pRec->nField!=pBuilder->nRecValid ); |
| 115125 | + pRec->nField = pBuilder->nRecValid; |
| 115126 | + } |
| 113088 | 115127 | if( nEq==p->nKeyCol ){ |
| 113089 | 115128 | aff = SQLITE_AFF_INTEGER; |
| 113090 | 115129 | }else{ |
| 113091 | 115130 | aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 113092 | 115131 | } |
| | @@ -113112,10 +115151,11 @@ |
| 113112 | 115151 | tRowcnt iNew; |
| 113113 | 115152 | whereKeyStats(pParse, p, pRec, 0, a); |
| 113114 | 115153 | iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 113115 | 115154 | if( iNew>iLower ) iLower = iNew; |
| 113116 | 115155 | nOut--; |
| 115156 | + pLower = 0; |
| 113117 | 115157 | } |
| 113118 | 115158 | } |
| 113119 | 115159 | |
| 113120 | 115160 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 113121 | 115161 | if( pUpper ){ |
| | @@ -113127,10 +115167,11 @@ |
| 113127 | 115167 | tRowcnt iNew; |
| 113128 | 115168 | whereKeyStats(pParse, p, pRec, 1, a); |
| 113129 | 115169 | iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 113130 | 115170 | if( iNew<iUpper ) iUpper = iNew; |
| 113131 | 115171 | nOut--; |
| 115172 | + pUpper = 0; |
| 113132 | 115173 | } |
| 113133 | 115174 | } |
| 113134 | 115175 | |
| 113135 | 115176 | pBuilder->pRec = pRec; |
| 113136 | 115177 | if( rc==SQLITE_OK ){ |
| | @@ -113140,14 +115181,12 @@ |
| 113140 | 115181 | nNew = 10; assert( 10==sqlite3LogEst(2) ); |
| 113141 | 115182 | } |
| 113142 | 115183 | if( nNew<nOut ){ |
| 113143 | 115184 | nOut = nNew; |
| 113144 | 115185 | } |
| 113145 | | - pLoop->nOut = (LogEst)nOut; |
| 113146 | | - WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n", |
| 115186 | + WHERETRACE(0x10, ("STAT4 range scan: %u..%u est=%d\n", |
| 113147 | 115187 | (u32)iLower, (u32)iUpper, nOut)); |
| 113148 | | - return SQLITE_OK; |
| 113149 | 115188 | } |
| 113150 | 115189 | }else{ |
| 113151 | 115190 | int bDone = 0; |
| 113152 | 115191 | rc = whereRangeSkipScanEst(pParse, pLower, pUpper, pLoop, &bDone); |
| 113153 | 115192 | if( bDone ) return rc; |
| | @@ -113154,12 +115193,12 @@ |
| 113154 | 115193 | } |
| 113155 | 115194 | } |
| 113156 | 115195 | #else |
| 113157 | 115196 | UNUSED_PARAMETER(pParse); |
| 113158 | 115197 | UNUSED_PARAMETER(pBuilder); |
| 113159 | | -#endif |
| 113160 | 115198 | assert( pLower || pUpper ); |
| 115199 | +#endif |
| 113161 | 115200 | assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); |
| 113162 | 115201 | nNew = whereRangeAdjust(pLower, nOut); |
| 113163 | 115202 | nNew = whereRangeAdjust(pUpper, nNew); |
| 113164 | 115203 | |
| 113165 | 115204 | /* TUNING: If there is both an upper and lower limit, assume the range is |
| | @@ -113170,10 +115209,16 @@ |
| 113170 | 115209 | if( pLower && pUpper ) nNew -= 20; |
| 113171 | 115210 | |
| 113172 | 115211 | nOut -= (pLower!=0) + (pUpper!=0); |
| 113173 | 115212 | if( nNew<10 ) nNew = 10; |
| 113174 | 115213 | if( nNew<nOut ) nOut = nNew; |
| 115214 | +#if defined(WHERETRACE_ENABLED) |
| 115215 | + if( pLoop->nOut>nOut ){ |
| 115216 | + WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", |
| 115217 | + pLoop->nOut, nOut)); |
| 115218 | + } |
| 115219 | +#endif |
| 113175 | 115220 | pLoop->nOut = (LogEst)nOut; |
| 113176 | 115221 | return rc; |
| 113177 | 115222 | } |
| 113178 | 115223 | |
| 113179 | 115224 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| | @@ -113282,11 +115327,11 @@ |
| 113282 | 115327 | } |
| 113283 | 115328 | |
| 113284 | 115329 | if( rc==SQLITE_OK ){ |
| 113285 | 115330 | if( nRowEst > nRow0 ) nRowEst = nRow0; |
| 113286 | 115331 | *pnRow = nRowEst; |
| 113287 | | - WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst)); |
| 115332 | + WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); |
| 113288 | 115333 | } |
| 113289 | 115334 | assert( pBuilder->nRecValid==nRecValid ); |
| 113290 | 115335 | return rc; |
| 113291 | 115336 | } |
| 113292 | 115337 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| | @@ -114673,12 +116718,12 @@ |
| 114673 | 116718 | sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, |
| 114674 | 116719 | p->iTab, nb, p->maskSelf, nb, p->prereq); |
| 114675 | 116720 | sqlite3DebugPrintf(" %12s", |
| 114676 | 116721 | pItem->zAlias ? pItem->zAlias : pTab->zName); |
| 114677 | 116722 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 114678 | | - const char *zName; |
| 114679 | | - if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ |
| 116723 | + const char *zName; |
| 116724 | + if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ |
| 114680 | 116725 | if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ |
| 114681 | 116726 | int i = sqlite3Strlen30(zName) - 1; |
| 114682 | 116727 | while( zName[i]!='_' ) i--; |
| 114683 | 116728 | zName += i; |
| 114684 | 116729 | } |
| | @@ -114695,11 +116740,15 @@ |
| 114695 | 116740 | z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); |
| 114696 | 116741 | } |
| 114697 | 116742 | sqlite3DebugPrintf(" %-19s", z); |
| 114698 | 116743 | sqlite3_free(z); |
| 114699 | 116744 | } |
| 114700 | | - sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); |
| 116745 | + if( p->wsFlags & WHERE_SKIPSCAN ){ |
| 116746 | + sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip); |
| 116747 | + }else{ |
| 116748 | + sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); |
| 116749 | + } |
| 114701 | 116750 | sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); |
| 114702 | 116751 | #ifdef SQLITE_ENABLE_TREE_EXPLAIN |
| 114703 | 116752 | /* If the 0x100 bit of wheretracing is set, then show all of the constraint |
| 114704 | 116753 | ** expressions in the WhereLoop.aLTerm[] array. |
| 114705 | 116754 | */ |
| | @@ -115208,12 +117257,11 @@ |
| 115208 | 117257 | ** contains fewer than 2^17 rows we assume otherwise in other parts of |
| 115209 | 117258 | ** the code). And, even if it is not, it should not be too much slower. |
| 115210 | 117259 | ** On the other hand, the extra seeks could end up being significantly |
| 115211 | 117260 | ** more expensive. */ |
| 115212 | 117261 | assert( 42==sqlite3LogEst(18) ); |
| 115213 | | - if( pTerm==0 |
| 115214 | | - && saved_nEq==saved_nSkip |
| 117262 | + if( saved_nEq==saved_nSkip |
| 115215 | 117263 | && saved_nEq+1<pProbe->nKeyCol |
| 115216 | 117264 | && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ |
| 115217 | 117265 | && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK |
| 115218 | 117266 | ){ |
| 115219 | 117267 | LogEst nIter; |
| | @@ -115220,13 +117268,21 @@ |
| 115220 | 117268 | pNew->u.btree.nEq++; |
| 115221 | 117269 | pNew->u.btree.nSkip++; |
| 115222 | 117270 | pNew->aLTerm[pNew->nLTerm++] = 0; |
| 115223 | 117271 | pNew->wsFlags |= WHERE_SKIPSCAN; |
| 115224 | 117272 | nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; |
| 117273 | + if( pTerm ){ |
| 117274 | + /* TUNING: When estimating skip-scan for a term that is also indexable, |
| 117275 | + ** increase the cost of the skip-scan by 2x, to make it a little less |
| 117276 | + ** desirable than the regular index lookup. */ |
| 117277 | + nIter += 10; assert( 10==sqlite3LogEst(2) ); |
| 117278 | + } |
| 115225 | 117279 | pNew->nOut -= nIter; |
| 115226 | 117280 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); |
| 115227 | 117281 | pNew->nOut = saved_nOut; |
| 117282 | + pNew->u.btree.nEq = saved_nEq; |
| 117283 | + pNew->u.btree.nSkip = saved_nSkip; |
| 115228 | 117284 | } |
| 115229 | 117285 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 115230 | 117286 | u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ |
| 115231 | 117287 | LogEst rCostIdx; |
| 115232 | 117288 | LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ |
| | @@ -115594,11 +117650,12 @@ |
| 115594 | 117650 | |
| 115595 | 117651 | /* Loop over all indices |
| 115596 | 117652 | */ |
| 115597 | 117653 | for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 115598 | 117654 | if( pProbe->pPartIdxWhere!=0 |
| 115599 | | - && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 117655 | + && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ |
| 117656 | + testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ |
| 115600 | 117657 | continue; /* Partial index inappropriate for this query */ |
| 115601 | 117658 | } |
| 115602 | 117659 | rSize = pProbe->aiRowLogEst[0]; |
| 115603 | 117660 | pNew->u.btree.nEq = 0; |
| 115604 | 117661 | pNew->u.btree.nSkip = 0; |
| | @@ -123012,11 +125069,11 @@ |
| 123012 | 125069 | |
| 123013 | 125070 | /* Legacy behavior (sqlite3_close() behavior) is to return |
| 123014 | 125071 | ** SQLITE_BUSY if the connection can not be closed immediately. |
| 123015 | 125072 | */ |
| 123016 | 125073 | if( !forceZombie && connectionIsBusy(db) ){ |
| 123017 | | - sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized " |
| 125074 | + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " |
| 123018 | 125075 | "statements or unfinished backups"); |
| 123019 | 125076 | sqlite3_mutex_leave(db->mutex); |
| 123020 | 125077 | return SQLITE_BUSY; |
| 123021 | 125078 | } |
| 123022 | 125079 | |
| | @@ -123142,11 +125199,11 @@ |
| 123142 | 125199 | sqlite3DbFree(db, pMod); |
| 123143 | 125200 | } |
| 123144 | 125201 | sqlite3HashClear(&db->aModule); |
| 123145 | 125202 | #endif |
| 123146 | 125203 | |
| 123147 | | - sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ |
| 125204 | + sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ |
| 123148 | 125205 | sqlite3ValueFree(db->pErr); |
| 123149 | 125206 | sqlite3CloseExtensions(db); |
| 123150 | 125207 | |
| 123151 | 125208 | db->magic = SQLITE_MAGIC_ERROR; |
| 123152 | 125209 | |
| | @@ -123575,11 +125632,11 @@ |
| 123575 | 125632 | ** operation to continue but invalidate all precompiled statements. |
| 123576 | 125633 | */ |
| 123577 | 125634 | p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); |
| 123578 | 125635 | if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ |
| 123579 | 125636 | if( db->nVdbeActive ){ |
| 123580 | | - sqlite3Error(db, SQLITE_BUSY, |
| 125637 | + sqlite3ErrorWithMsg(db, SQLITE_BUSY, |
| 123581 | 125638 | "unable to delete/modify user-function due to active statements"); |
| 123582 | 125639 | assert( !db->mallocFailed ); |
| 123583 | 125640 | return SQLITE_BUSY; |
| 123584 | 125641 | }else{ |
| 123585 | 125642 | sqlite3ExpirePreparedStatements(db); |
| | @@ -123913,14 +125970,14 @@ |
| 123913 | 125970 | if( zDb && zDb[0] ){ |
| 123914 | 125971 | iDb = sqlite3FindDbName(db, zDb); |
| 123915 | 125972 | } |
| 123916 | 125973 | if( iDb<0 ){ |
| 123917 | 125974 | rc = SQLITE_ERROR; |
| 123918 | | - sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb); |
| 125975 | + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); |
| 123919 | 125976 | }else{ |
| 123920 | 125977 | rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); |
| 123921 | | - sqlite3Error(db, rc, 0); |
| 125978 | + sqlite3Error(db, rc); |
| 123922 | 125979 | } |
| 123923 | 125980 | rc = sqlite3ApiExit(db, rc); |
| 123924 | 125981 | sqlite3_mutex_leave(db->mutex); |
| 123925 | 125982 | return rc; |
| 123926 | 125983 | #endif |
| | @@ -124071,11 +126128,11 @@ |
| 124071 | 126128 | if( db->mallocFailed ){ |
| 124072 | 126129 | z = (void *)outOfMem; |
| 124073 | 126130 | }else{ |
| 124074 | 126131 | z = sqlite3_value_text16(db->pErr); |
| 124075 | 126132 | if( z==0 ){ |
| 124076 | | - sqlite3Error(db, db->errCode, sqlite3ErrStr(db->errCode)); |
| 126133 | + sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); |
| 124077 | 126134 | z = sqlite3_value_text16(db->pErr); |
| 124078 | 126135 | } |
| 124079 | 126136 | /* A malloc() may have failed within the call to sqlite3_value_text16() |
| 124080 | 126137 | ** above. If this is the case, then the db->mallocFailed flag needs to |
| 124081 | 126138 | ** be cleared before returning. Do this directly, instead of via |
| | @@ -124158,11 +126215,10 @@ |
| 124158 | 126215 | int(*xCompare)(void*,int,const void*,int,const void*), |
| 124159 | 126216 | void(*xDel)(void*) |
| 124160 | 126217 | ){ |
| 124161 | 126218 | CollSeq *pColl; |
| 124162 | 126219 | int enc2; |
| 124163 | | - int nName = sqlite3Strlen30(zName); |
| 124164 | 126220 | |
| 124165 | 126221 | assert( sqlite3_mutex_held(db->mutex) ); |
| 124166 | 126222 | |
| 124167 | 126223 | /* If SQLITE_UTF16 is specified as the encoding type, transform this |
| 124168 | 126224 | ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the |
| | @@ -124183,11 +126239,11 @@ |
| 124183 | 126239 | ** are no active VMs, invalidate any pre-compiled statements. |
| 124184 | 126240 | */ |
| 124185 | 126241 | pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); |
| 124186 | 126242 | if( pColl && pColl->xCmp ){ |
| 124187 | 126243 | if( db->nVdbeActive ){ |
| 124188 | | - sqlite3Error(db, SQLITE_BUSY, |
| 126244 | + sqlite3ErrorWithMsg(db, SQLITE_BUSY, |
| 124189 | 126245 | "unable to delete/modify collation sequence due to active statements"); |
| 124190 | 126246 | return SQLITE_BUSY; |
| 124191 | 126247 | } |
| 124192 | 126248 | sqlite3ExpirePreparedStatements(db); |
| 124193 | 126249 | invalidateCachedKeyInfo(db); |
| | @@ -124197,11 +126253,11 @@ |
| 124197 | 126253 | ** then any copies made by synthCollSeq() need to be invalidated. |
| 124198 | 126254 | ** Also, collation destructor - CollSeq.xDel() - function may need |
| 124199 | 126255 | ** to be called. |
| 124200 | 126256 | */ |
| 124201 | 126257 | if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ |
| 124202 | | - CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName); |
| 126258 | + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); |
| 124203 | 126259 | int j; |
| 124204 | 126260 | for(j=0; j<3; j++){ |
| 124205 | 126261 | CollSeq *p = &aColl[j]; |
| 124206 | 126262 | if( p->enc==pColl->enc ){ |
| 124207 | 126263 | if( p->xDel ){ |
| | @@ -124217,11 +126273,11 @@ |
| 124217 | 126273 | if( pColl==0 ) return SQLITE_NOMEM; |
| 124218 | 126274 | pColl->xCmp = xCompare; |
| 124219 | 126275 | pColl->pUser = pCtx; |
| 124220 | 126276 | pColl->xDel = xDel; |
| 124221 | 126277 | pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); |
| 124222 | | - sqlite3Error(db, SQLITE_OK, 0); |
| 126278 | + sqlite3Error(db, SQLITE_OK); |
| 124223 | 126279 | return SQLITE_OK; |
| 124224 | 126280 | } |
| 124225 | 126281 | |
| 124226 | 126282 | |
| 124227 | 126283 | /* |
| | @@ -124239,10 +126295,11 @@ |
| 124239 | 126295 | SQLITE_MAX_FUNCTION_ARG, |
| 124240 | 126296 | SQLITE_MAX_ATTACHED, |
| 124241 | 126297 | SQLITE_MAX_LIKE_PATTERN_LENGTH, |
| 124242 | 126298 | SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ |
| 124243 | 126299 | SQLITE_MAX_TRIGGER_DEPTH, |
| 126300 | + SQLITE_MAX_WORKER_THREADS, |
| 124244 | 126301 | }; |
| 124245 | 126302 | |
| 124246 | 126303 | /* |
| 124247 | 126304 | ** Make sure the hard limits are set to reasonable values |
| 124248 | 126305 | */ |
| | @@ -124274,10 +126331,13 @@ |
| 124274 | 126331 | # error SQLITE_MAX_COLUMN must not exceed 32767 |
| 124275 | 126332 | #endif |
| 124276 | 126333 | #if SQLITE_MAX_TRIGGER_DEPTH<1 |
| 124277 | 126334 | # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 |
| 124278 | 126335 | #endif |
| 126336 | +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 |
| 126337 | +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 |
| 126338 | +#endif |
| 124279 | 126339 | |
| 124280 | 126340 | |
| 124281 | 126341 | /* |
| 124282 | 126342 | ** Change the value of a limit. Report the old value. |
| 124283 | 126343 | ** If an invalid limit index is supplied, report -1. |
| | @@ -124307,11 +126367,12 @@ |
| 124307 | 126367 | assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); |
| 124308 | 126368 | assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== |
| 124309 | 126369 | SQLITE_MAX_LIKE_PATTERN_LENGTH ); |
| 124310 | 126370 | assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); |
| 124311 | 126371 | assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); |
| 124312 | | - assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) ); |
| 126372 | + assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); |
| 126373 | + assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); |
| 124313 | 126374 | |
| 124314 | 126375 | |
| 124315 | 126376 | if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ |
| 124316 | 126377 | return -1; |
| 124317 | 126378 | } |
| | @@ -124654,14 +126715,16 @@ |
| 124654 | 126715 | db->magic = SQLITE_MAGIC_BUSY; |
| 124655 | 126716 | db->aDb = db->aDbStatic; |
| 124656 | 126717 | |
| 124657 | 126718 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); |
| 124658 | 126719 | memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); |
| 126720 | + db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; |
| 124659 | 126721 | db->autoCommit = 1; |
| 124660 | 126722 | db->nextAutovac = -1; |
| 124661 | 126723 | db->szMmap = sqlite3GlobalConfig.szMmap; |
| 124662 | 126724 | db->nextPagesize = 0; |
| 126725 | + db->nMaxSorterMmap = 0x7FFFFFFF; |
| 124663 | 126726 | db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill |
| 124664 | 126727 | #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX |
| 124665 | 126728 | | SQLITE_AutoIndex |
| 124666 | 126729 | #endif |
| 124667 | 126730 | #if SQLITE_DEFAULT_FILE_FORMAT<4 |
| | @@ -124702,11 +126765,11 @@ |
| 124702 | 126765 | /* Parse the filename/URI argument. */ |
| 124703 | 126766 | db->openFlags = flags; |
| 124704 | 126767 | rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); |
| 124705 | 126768 | if( rc!=SQLITE_OK ){ |
| 124706 | 126769 | if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; |
| 124707 | | - sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg); |
| 126770 | + sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); |
| 124708 | 126771 | sqlite3_free(zErrMsg); |
| 124709 | 126772 | goto opendb_out; |
| 124710 | 126773 | } |
| 124711 | 126774 | |
| 124712 | 126775 | /* Open the backend database driver */ |
| | @@ -124714,11 +126777,11 @@ |
| 124714 | 126777 | flags | SQLITE_OPEN_MAIN_DB); |
| 124715 | 126778 | if( rc!=SQLITE_OK ){ |
| 124716 | 126779 | if( rc==SQLITE_IOERR_NOMEM ){ |
| 124717 | 126780 | rc = SQLITE_NOMEM; |
| 124718 | 126781 | } |
| 124719 | | - sqlite3Error(db, rc, 0); |
| 126782 | + sqlite3Error(db, rc); |
| 124720 | 126783 | goto opendb_out; |
| 124721 | 126784 | } |
| 124722 | 126785 | db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); |
| 124723 | 126786 | db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); |
| 124724 | 126787 | |
| | @@ -124738,11 +126801,11 @@ |
| 124738 | 126801 | |
| 124739 | 126802 | /* Register all built-in functions, but do not attempt to read the |
| 124740 | 126803 | ** database schema yet. This is delayed until the first time the database |
| 124741 | 126804 | ** is accessed. |
| 124742 | 126805 | */ |
| 124743 | | - sqlite3Error(db, SQLITE_OK, 0); |
| 126806 | + sqlite3Error(db, SQLITE_OK); |
| 124744 | 126807 | sqlite3RegisterBuiltinFunctions(db); |
| 124745 | 126808 | |
| 124746 | 126809 | /* Load automatic extensions - extensions that have been registered |
| 124747 | 126810 | ** using the sqlite3_automatic_extension() API. |
| 124748 | 126811 | */ |
| | @@ -124795,11 +126858,11 @@ |
| 124795 | 126858 | db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; |
| 124796 | 126859 | sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), |
| 124797 | 126860 | SQLITE_DEFAULT_LOCKING_MODE); |
| 124798 | 126861 | #endif |
| 124799 | 126862 | |
| 124800 | | - if( rc ) sqlite3Error(db, rc, 0); |
| 126863 | + if( rc ) sqlite3Error(db, rc); |
| 124801 | 126864 | |
| 124802 | 126865 | /* Enable the lookaside-malloc subsystem */ |
| 124803 | 126866 | setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, |
| 124804 | 126867 | sqlite3GlobalConfig.nLookaside); |
| 124805 | 126868 | |
| | @@ -125157,11 +127220,11 @@ |
| 125157 | 127220 | sqlite3DbFree(db, zErrMsg); |
| 125158 | 127221 | zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, |
| 125159 | 127222 | zColumnName); |
| 125160 | 127223 | rc = SQLITE_ERROR; |
| 125161 | 127224 | } |
| 125162 | | - sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); |
| 127225 | + sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); |
| 125163 | 127226 | sqlite3DbFree(db, zErrMsg); |
| 125164 | 127227 | rc = sqlite3ApiExit(db, rc); |
| 125165 | 127228 | sqlite3_mutex_leave(db->mutex); |
| 125166 | 127229 | return rc; |
| 125167 | 127230 | } |
| | @@ -125521,10 +127584,17 @@ |
| 125521 | 127584 | sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); |
| 125522 | 127585 | sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); |
| 125523 | 127586 | #endif |
| 125524 | 127587 | break; |
| 125525 | 127588 | } |
| 127589 | + |
| 127590 | + /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ |
| 127591 | + case SQLITE_TESTCTRL_SORTER_MMAP: { |
| 127592 | + sqlite3 *db = va_arg(ap, sqlite3*); |
| 127593 | + db->nMaxSorterMmap = va_arg(ap, int); |
| 127594 | + break; |
| 127595 | + } |
| 125526 | 127596 | |
| 125527 | 127597 | /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); |
| 125528 | 127598 | ** |
| 125529 | 127599 | ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if |
| 125530 | 127600 | ** not. |
| | @@ -125531,11 +127601,10 @@ |
| 125531 | 127601 | */ |
| 125532 | 127602 | case SQLITE_TESTCTRL_ISINIT: { |
| 125533 | 127603 | if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; |
| 125534 | 127604 | break; |
| 125535 | 127605 | } |
| 125536 | | - |
| 125537 | 127606 | } |
| 125538 | 127607 | va_end(ap); |
| 125539 | 127608 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 125540 | 127609 | return rc; |
| 125541 | 127610 | } |
| | @@ -125805,11 +127874,11 @@ |
| 125805 | 127874 | } |
| 125806 | 127875 | } |
| 125807 | 127876 | |
| 125808 | 127877 | leaveMutex(); |
| 125809 | 127878 | assert( !db->mallocFailed ); |
| 125810 | | - sqlite3Error(db, rc, (rc?"database is deadlocked":0)); |
| 127879 | + sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); |
| 125811 | 127880 | sqlite3_mutex_leave(db->mutex); |
| 125812 | 127881 | return rc; |
| 125813 | 127882 | } |
| 125814 | 127883 | |
| 125815 | 127884 | /* |
| 125816 | 127885 | |