| | @@ -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.0. By combining all the individual C code files into this |
| 3 | +** version 3.8.1. 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. |
| | @@ -654,13 +654,13 @@ |
| 654 | 654 | ** |
| 655 | 655 | ** See also: [sqlite3_libversion()], |
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | | -#define SQLITE_VERSION "3.8.0" |
| 660 | | -#define SQLITE_VERSION_NUMBER 3008000 |
| 661 | | -#define SQLITE_SOURCE_ID "2013-08-15 22:40:21 f2d175f975cd0be63425424ec322a98fb650019e" |
| 659 | +#define SQLITE_VERSION "3.8.1" |
| 660 | +#define SQLITE_VERSION_NUMBER 3008001 |
| 661 | +#define SQLITE_SOURCE_ID "2013-08-30 06:20:23 d9c018f8155ab48df8e0e02519bba50588fe49fc" |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| | @@ -8368,10 +8368,24 @@ |
| 8368 | 8368 | #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8369 | 8369 | # undef SQLITE_DEFAULT_MMAP_SIZE |
| 8370 | 8370 | # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8371 | 8371 | #endif |
| 8372 | 8372 | |
| 8373 | +/* |
| 8374 | +** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. |
| 8375 | +** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also |
| 8376 | +** define SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8377 | +*/ |
| 8378 | +#ifdef SQLITE_ENABLE_STAT4 |
| 8379 | +# undef SQLITE_ENABLE_STAT3 |
| 8380 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8381 | +#elif SQLITE_ENABLE_STAT3 |
| 8382 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8383 | +#elif SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8384 | +# undef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8385 | +#endif |
| 8386 | + |
| 8373 | 8387 | /* |
| 8374 | 8388 | ** An instance of the following structure is used to store the busy-handler |
| 8375 | 8389 | ** callback for a given sqlite handle. |
| 8376 | 8390 | ** |
| 8377 | 8391 | ** The sqlite.busyHandler member of the sqlite struct contains the busy |
| | @@ -8587,11 +8601,11 @@ |
| 8587 | 8601 | #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ |
| 8588 | 8602 | |
| 8589 | 8603 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 8590 | 8604 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 8591 | 8605 | SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); |
| 8592 | | -SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); |
| 8606 | +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); |
| 8593 | 8607 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| 8594 | 8608 | SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); |
| 8595 | 8609 | SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); |
| 8596 | 8610 | SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); |
| 8597 | 8611 | SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); |
| | @@ -9288,12 +9302,24 @@ |
| 9288 | 9302 | #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ |
| 9289 | 9303 | |
| 9290 | 9304 | /* |
| 9291 | 9305 | ** Flags that make up the mask passed to sqlite3PagerAcquire(). |
| 9292 | 9306 | */ |
| 9293 | | -#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */ |
| 9294 | | -#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */ |
| 9307 | +#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ |
| 9308 | +#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ |
| 9309 | + |
| 9310 | +/* |
| 9311 | +** Flags for sqlite3PagerSetFlags() |
| 9312 | +*/ |
| 9313 | +#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ |
| 9314 | +#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ |
| 9315 | +#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ |
| 9316 | +#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */ |
| 9317 | +#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */ |
| 9318 | +#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */ |
| 9319 | +#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */ |
| 9320 | +#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */ |
| 9295 | 9321 | |
| 9296 | 9322 | /* |
| 9297 | 9323 | ** The remainder of this file contains the declarations of the functions |
| 9298 | 9324 | ** that make up the Pager sub-system API. See source code comments for |
| 9299 | 9325 | ** a detailed description of each routine. |
| | @@ -9317,11 +9343,11 @@ |
| 9317 | 9343 | SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); |
| 9318 | 9344 | SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); |
| 9319 | 9345 | SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); |
| 9320 | 9346 | SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); |
| 9321 | 9347 | SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); |
| 9322 | | -SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int); |
| 9348 | +SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned); |
| 9323 | 9349 | SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); |
| 9324 | 9350 | SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); |
| 9325 | 9351 | SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); |
| 9326 | 9352 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); |
| 9327 | 9353 | SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); |
| | @@ -10180,36 +10206,37 @@ |
| 10180 | 10206 | /* |
| 10181 | 10207 | ** Possible values for the sqlite3.flags. |
| 10182 | 10208 | */ |
| 10183 | 10209 | #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ |
| 10184 | 10210 | #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ |
| 10185 | | -#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ |
| 10186 | | -#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */ |
| 10187 | | -#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */ |
| 10211 | +#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */ |
| 10212 | +#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */ |
| 10213 | +#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */ |
| 10214 | +#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */ |
| 10215 | +#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ |
| 10216 | +#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ |
| 10188 | 10217 | /* DELETE, or UPDATE and return */ |
| 10189 | 10218 | /* the count using a callback. */ |
| 10190 | | -#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */ |
| 10219 | +#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ |
| 10191 | 10220 | /* result set is empty */ |
| 10192 | | -#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */ |
| 10193 | | -#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */ |
| 10194 | | -#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */ |
| 10195 | | -#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */ |
| 10196 | | -#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */ |
| 10197 | | -#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */ |
| 10198 | | -#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */ |
| 10199 | | -#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */ |
| 10200 | | -#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */ |
| 10201 | | -#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */ |
| 10202 | | -#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */ |
| 10203 | | -#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */ |
| 10204 | | -#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */ |
| 10205 | | -#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */ |
| 10206 | | -#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */ |
| 10207 | | -#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */ |
| 10208 | | -#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */ |
| 10209 | | -#define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */ |
| 10210 | | -#define SQLITE_QueryOnly 0x01000000 /* Disable database changes */ |
| 10221 | +#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ |
| 10222 | +#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ |
| 10223 | +#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ |
| 10224 | +#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */ |
| 10225 | +#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ |
| 10226 | +#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */ |
| 10227 | +#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ |
| 10228 | +#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */ |
| 10229 | +#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */ |
| 10230 | +#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */ |
| 10231 | +#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */ |
| 10232 | +#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ |
| 10233 | +#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ |
| 10234 | +#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ |
| 10235 | +#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ |
| 10236 | +#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ |
| 10237 | +#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ |
| 10211 | 10238 | |
| 10212 | 10239 | |
| 10213 | 10240 | /* |
| 10214 | 10241 | ** Bits of the sqlite3.dbOptFlags field that are used by the |
| 10215 | 10242 | ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to |
| | @@ -10757,13 +10784,14 @@ |
| 10757 | 10784 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10758 | 10785 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10759 | 10786 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10760 | 10787 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10761 | 10788 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 10762 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 10789 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 10763 | 10790 | int nSample; /* Number of elements in aSample[] */ |
| 10764 | | - tRowcnt avgEq; /* Average nEq value for key values not in aSample */ |
| 10791 | + int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 10792 | + tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 10765 | 10793 | IndexSample *aSample; /* Samples of the left-most key */ |
| 10766 | 10794 | #endif |
| 10767 | 10795 | }; |
| 10768 | 10796 | |
| 10769 | 10797 | /* |
| | @@ -10770,20 +10798,15 @@ |
| 10770 | 10798 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 10771 | 10799 | ** using a structure of this type. See documentation at the top of the |
| 10772 | 10800 | ** analyze.c source file for additional information. |
| 10773 | 10801 | */ |
| 10774 | 10802 | struct IndexSample { |
| 10775 | | - union { |
| 10776 | | - char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ |
| 10777 | | - double r; /* Value if eType is SQLITE_FLOAT */ |
| 10778 | | - i64 i; /* Value if eType is SQLITE_INTEGER */ |
| 10779 | | - } u; |
| 10780 | | - u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ |
| 10781 | | - int nByte; /* Size in byte of text or blob. */ |
| 10782 | | - tRowcnt nEq; /* Est. number of rows where the key equals this sample */ |
| 10783 | | - tRowcnt nLt; /* Est. number of rows where key is less than this sample */ |
| 10784 | | - tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ |
| 10803 | + void *p; /* Pointer to sampled record */ |
| 10804 | + int n; /* Size of record in bytes */ |
| 10805 | + tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ |
| 10806 | + tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ |
| 10807 | + tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ |
| 10785 | 10808 | }; |
| 10786 | 10809 | |
| 10787 | 10810 | /* |
| 10788 | 10811 | ** Each token coming out of the lexer is an instance of |
| 10789 | 10812 | ** this structure. Tokens are also used as part of an expression. |
| | @@ -11632,14 +11655,15 @@ |
| 11632 | 11655 | char *zBase; /* A base allocation. Not from malloc. */ |
| 11633 | 11656 | char *zText; /* The string collected so far */ |
| 11634 | 11657 | int nChar; /* Length of the string so far */ |
| 11635 | 11658 | int nAlloc; /* Amount of space allocated in zText */ |
| 11636 | 11659 | int mxAlloc; /* Maximum allowed string length */ |
| 11637 | | - u8 mallocFailed; /* Becomes true if any memory allocation fails */ |
| 11638 | 11660 | u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */ |
| 11639 | | - u8 tooBig; /* Becomes true if string size exceeds limits */ |
| 11661 | + u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ |
| 11640 | 11662 | }; |
| 11663 | +#define STRACCUM_NOMEM 1 |
| 11664 | +#define STRACCUM_TOOBIG 2 |
| 11641 | 11665 | |
| 11642 | 11666 | /* |
| 11643 | 11667 | ** A pointer to this structure is used to communicate information |
| 11644 | 11668 | ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. |
| 11645 | 11669 | */ |
| | @@ -12250,13 +12274,10 @@ |
| 12250 | 12274 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12251 | 12275 | void(*)(void*)); |
| 12252 | 12276 | SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); |
| 12253 | 12277 | SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); |
| 12254 | 12278 | SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); |
| 12255 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 12256 | | -SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); |
| 12257 | | -#endif |
| 12258 | 12279 | SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); |
| 12259 | 12280 | SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); |
| 12260 | 12281 | #ifndef SQLITE_AMALGAMATION |
| 12261 | 12282 | SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; |
| 12262 | 12283 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| | @@ -12319,10 +12340,16 @@ |
| 12319 | 12340 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 12320 | 12341 | |
| 12321 | 12342 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); |
| 12322 | 12343 | SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
| 12323 | 12344 | |
| 12345 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 12346 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); |
| 12347 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); |
| 12348 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); |
| 12349 | +#endif |
| 12350 | + |
| 12324 | 12351 | /* |
| 12325 | 12352 | ** The interface to the LEMON-generated parser |
| 12326 | 12353 | */ |
| 12327 | 12354 | SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); |
| 12328 | 12355 | SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); |
| | @@ -12360,17 +12387,18 @@ |
| 12360 | 12387 | # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK |
| 12361 | 12388 | # define sqlite3GetVTable(X,Y) ((VTable*)0) |
| 12362 | 12389 | #else |
| 12363 | 12390 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); |
| 12364 | 12391 | SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); |
| 12365 | | -SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); |
| 12392 | +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*); |
| 12366 | 12393 | SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); |
| 12367 | 12394 | SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); |
| 12368 | 12395 | SQLITE_PRIVATE void sqlite3VtabLock(VTable *); |
| 12369 | 12396 | SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); |
| 12370 | 12397 | SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); |
| 12371 | 12398 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); |
| 12399 | +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); |
| 12372 | 12400 | SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); |
| 12373 | 12401 | # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) |
| 12374 | 12402 | #endif |
| 12375 | 12403 | SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); |
| 12376 | 12404 | SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); |
| | @@ -12901,11 +12929,13 @@ |
| 12901 | 12929 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 12902 | 12930 | #endif |
| 12903 | 12931 | #ifdef SQLITE_ENABLE_RTREE |
| 12904 | 12932 | "ENABLE_RTREE", |
| 12905 | 12933 | #endif |
| 12906 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 12934 | +#if defined(SQLITE_ENABLE_STAT4) |
| 12935 | + "ENABLE_STAT4", |
| 12936 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 12907 | 12937 | "ENABLE_STAT3", |
| 12908 | 12938 | #endif |
| 12909 | 12939 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 12910 | 12940 | "ENABLE_UNLOCK_NOTIFY", |
| 12911 | 12941 | #endif |
| | @@ -13473,14 +13503,15 @@ |
| 13473 | 13503 | struct sqlite3_context { |
| 13474 | 13504 | FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ |
| 13475 | 13505 | Mem s; /* The return value is stored here */ |
| 13476 | 13506 | Mem *pMem; /* Memory cell used to store aggregate context */ |
| 13477 | 13507 | CollSeq *pColl; /* Collating sequence */ |
| 13478 | | - int isError; /* Error code returned by the function. */ |
| 13479 | | - int skipFlag; /* Skip skip accumulator loading if true */ |
| 13508 | + Vdbe *pVdbe; /* The VM that owns this context */ |
| 13480 | 13509 | int iOp; /* Instruction number of OP_Function */ |
| 13481 | | - Vdbe *pVdbe; /* The VM that owns this context */ |
| 13510 | + int isError; /* Error code returned by the function. */ |
| 13511 | + u8 skipFlag; /* Skip skip accumulator loading if true */ |
| 13512 | + u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ |
| 13482 | 13513 | }; |
| 13483 | 13514 | |
| 13484 | 13515 | /* |
| 13485 | 13516 | ** An Explain object accumulates indented output which is helpful |
| 13486 | 13517 | ** in describing recursive data structures. |
| | @@ -13552,11 +13583,11 @@ |
| 13552 | 13583 | bft doingRerun:1; /* True if rerunning after an auto-reprepare */ |
| 13553 | 13584 | int nChange; /* Number of db changes made since last reset */ |
| 13554 | 13585 | yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 13555 | 13586 | yDbMask lockMask; /* Subset of btreeMask that requires a lock */ |
| 13556 | 13587 | int iStatement; /* Statement number (or 0 if has not opened stmt) */ |
| 13557 | | - int aCounter[4]; /* Counters used by sqlite3_stmt_status() */ |
| 13588 | + u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ |
| 13558 | 13589 | #ifndef SQLITE_OMIT_TRACE |
| 13559 | 13590 | i64 startTime; /* Time when query started - used for profiling */ |
| 13560 | 13591 | #endif |
| 13561 | 13592 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13562 | 13593 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| | @@ -16059,11 +16090,11 @@ |
| 16059 | 16090 | struct MemBlockHdr *pHdr; |
| 16060 | 16091 | if( !p ){ |
| 16061 | 16092 | return 0; |
| 16062 | 16093 | } |
| 16063 | 16094 | pHdr = sqlite3MemsysGetHeader(p); |
| 16064 | | - return pHdr->iSize; |
| 16095 | + return (int)pHdr->iSize; |
| 16065 | 16096 | } |
| 16066 | 16097 | |
| 16067 | 16098 | /* |
| 16068 | 16099 | ** Initialize the memory allocation subsystem. |
| 16069 | 16100 | */ |
| | @@ -16101,19 +16132,19 @@ |
| 16101 | 16132 | static void randomFill(char *pBuf, int nByte){ |
| 16102 | 16133 | unsigned int x, y, r; |
| 16103 | 16134 | x = SQLITE_PTR_TO_INT(pBuf); |
| 16104 | 16135 | y = nByte | 1; |
| 16105 | 16136 | while( nByte >= 4 ){ |
| 16106 | | - x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16137 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16107 | 16138 | y = y*1103515245 + 12345; |
| 16108 | 16139 | r = x ^ y; |
| 16109 | 16140 | *(int*)pBuf = r; |
| 16110 | 16141 | pBuf += 4; |
| 16111 | 16142 | nByte -= 4; |
| 16112 | 16143 | } |
| 16113 | 16144 | while( nByte-- > 0 ){ |
| 16114 | | - x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16145 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16115 | 16146 | y = y*1103515245 + 12345; |
| 16116 | 16147 | r = x ^ y; |
| 16117 | 16148 | *(pBuf++) = r & 0xff; |
| 16118 | 16149 | } |
| 16119 | 16150 | } |
| | @@ -16204,13 +16235,13 @@ |
| 16204 | 16235 | assert( mem.pLast==pHdr ); |
| 16205 | 16236 | mem.pLast = pHdr->pPrev; |
| 16206 | 16237 | } |
| 16207 | 16238 | z = (char*)pBt; |
| 16208 | 16239 | z -= pHdr->nTitle; |
| 16209 | | - adjustStats(pHdr->iSize, -1); |
| 16240 | + adjustStats((int)pHdr->iSize, -1); |
| 16210 | 16241 | randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |
| 16211 | | - pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16242 | + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16212 | 16243 | free(z); |
| 16213 | 16244 | sqlite3_mutex_leave(mem.mutex); |
| 16214 | 16245 | } |
| 16215 | 16246 | |
| 16216 | 16247 | /* |
| | @@ -16230,11 +16261,11 @@ |
| 16230 | 16261 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16231 | 16262 | pNew = sqlite3MemMalloc(nByte); |
| 16232 | 16263 | if( pNew ){ |
| 16233 | 16264 | memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16234 | 16265 | if( nByte>pOldHdr->iSize ){ |
| 16235 | | - randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize); |
| 16266 | + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16236 | 16267 | } |
| 16237 | 16268 | sqlite3MemFree(pPrior); |
| 16238 | 16269 | } |
| 16239 | 16270 | return pNew; |
| 16240 | 16271 | } |
| | @@ -16345,11 +16376,11 @@ |
| 16345 | 16376 | SQLITE_PRIVATE void sqlite3MemdebugSync(){ |
| 16346 | 16377 | struct MemBlockHdr *pHdr; |
| 16347 | 16378 | for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |
| 16348 | 16379 | void **pBt = (void**)pHdr; |
| 16349 | 16380 | pBt -= pHdr->nBacktraceSlots; |
| 16350 | | - mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16381 | + mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16351 | 16382 | } |
| 16352 | 16383 | } |
| 16353 | 16384 | |
| 16354 | 16385 | /* |
| 16355 | 16386 | ** Open the file indicated and write a log of all unfreed memory |
| | @@ -18467,11 +18498,11 @@ |
| 18467 | 18498 | GetVersionEx(&sInfo); |
| 18468 | 18499 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 18469 | 18500 | } |
| 18470 | 18501 | return osType==2; |
| 18471 | 18502 | } |
| 18472 | | -#endif /* SQLITE_OS_WINCE */ |
| 18503 | +#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ |
| 18473 | 18504 | #endif |
| 18474 | 18505 | |
| 18475 | 18506 | #ifdef SQLITE_DEBUG |
| 18476 | 18507 | /* |
| 18477 | 18508 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| | @@ -18505,11 +18536,11 @@ |
| 18505 | 18536 | /* As winMutexInit() and winMutexEnd() are called as part |
| 18506 | 18537 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 18507 | 18538 | ** processing, the "interlocked" magic is probably not |
| 18508 | 18539 | ** strictly necessary. |
| 18509 | 18540 | */ |
| 18510 | | -static long winMutex_lock = 0; |
| 18541 | +static LONG winMutex_lock = 0; |
| 18511 | 18542 | |
| 18512 | 18543 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18513 | 18544 | |
| 18514 | 18545 | static int winMutexInit(void){ |
| 18515 | 18546 | /* The first to increment to 1 does actual initialization */ |
| | @@ -19885,11 +19916,11 @@ |
| 19885 | 19916 | zOut = buf; |
| 19886 | 19917 | }else{ |
| 19887 | 19918 | nOut = precision + 10; |
| 19888 | 19919 | zOut = zExtra = sqlite3Malloc( nOut ); |
| 19889 | 19920 | if( zOut==0 ){ |
| 19890 | | - pAccum->mallocFailed = 1; |
| 19921 | + pAccum->accError = STRACCUM_NOMEM; |
| 19891 | 19922 | return; |
| 19892 | 19923 | } |
| 19893 | 19924 | } |
| 19894 | 19925 | bufpt = &zOut[nOut-1]; |
| 19895 | 19926 | if( xtype==etORDINAL ){ |
| | @@ -19997,11 +20028,11 @@ |
| 19997 | 20028 | e2 = exp; |
| 19998 | 20029 | } |
| 19999 | 20030 | if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ |
| 20000 | 20031 | bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); |
| 20001 | 20032 | if( bufpt==0 ){ |
| 20002 | | - pAccum->mallocFailed = 1; |
| 20033 | + pAccum->accError = STRACCUM_NOMEM; |
| 20003 | 20034 | return; |
| 20004 | 20035 | } |
| 20005 | 20036 | } |
| 20006 | 20037 | zOut = bufpt; |
| 20007 | 20038 | nsd = 16 + flag_altform2*10; |
| | @@ -20132,11 +20163,11 @@ |
| 20132 | 20163 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 20133 | 20164 | n += i + 1 + needQuote*2; |
| 20134 | 20165 | if( n>etBUFSIZE ){ |
| 20135 | 20166 | bufpt = zExtra = sqlite3Malloc( n ); |
| 20136 | 20167 | if( bufpt==0 ){ |
| 20137 | | - pAccum->mallocFailed = 1; |
| 20168 | + pAccum->accError = STRACCUM_NOMEM; |
| 20138 | 20169 | return; |
| 20139 | 20170 | } |
| 20140 | 20171 | }else{ |
| 20141 | 20172 | bufpt = buf; |
| 20142 | 20173 | } |
| | @@ -20210,26 +20241,24 @@ |
| 20210 | 20241 | /* |
| 20211 | 20242 | ** Append N bytes of text from z to the StrAccum object. |
| 20212 | 20243 | */ |
| 20213 | 20244 | SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
| 20214 | 20245 | assert( z!=0 || N==0 ); |
| 20215 | | - if( p->tooBig | p->mallocFailed ){ |
| 20216 | | - testcase(p->tooBig); |
| 20217 | | - testcase(p->mallocFailed); |
| 20246 | + if( p->accError ){ |
| 20247 | + testcase(p->accError==STRACCUM_TOOBIG); |
| 20248 | + testcase(p->accError==STRACCUM_NOMEM); |
| 20218 | 20249 | return; |
| 20219 | 20250 | } |
| 20220 | 20251 | assert( p->zText!=0 || p->nChar==0 ); |
| 20221 | | - if( N<0 ){ |
| 20252 | + if( N<=0 ){ |
| 20253 | + if( N==0 || z[0]==0 ) return; |
| 20222 | 20254 | N = sqlite3Strlen30(z); |
| 20223 | 20255 | } |
| 20224 | | - if( N==0 || NEVER(z==0) ){ |
| 20225 | | - return; |
| 20226 | | - } |
| 20227 | 20256 | if( p->nChar+N >= p->nAlloc ){ |
| 20228 | 20257 | char *zNew; |
| 20229 | 20258 | if( !p->useMalloc ){ |
| 20230 | | - p->tooBig = 1; |
| 20259 | + p->accError = STRACCUM_TOOBIG; |
| 20231 | 20260 | N = p->nAlloc - p->nChar - 1; |
| 20232 | 20261 | if( N<=0 ){ |
| 20233 | 20262 | return; |
| 20234 | 20263 | } |
| 20235 | 20264 | }else{ |
| | @@ -20236,11 +20265,11 @@ |
| 20236 | 20265 | char *zOld = (p->zText==p->zBase ? 0 : p->zText); |
| 20237 | 20266 | i64 szNew = p->nChar; |
| 20238 | 20267 | szNew += N + 1; |
| 20239 | 20268 | if( szNew > p->mxAlloc ){ |
| 20240 | 20269 | sqlite3StrAccumReset(p); |
| 20241 | | - p->tooBig = 1; |
| 20270 | + p->accError = STRACCUM_TOOBIG; |
| 20242 | 20271 | return; |
| 20243 | 20272 | }else{ |
| 20244 | 20273 | p->nAlloc = (int)szNew; |
| 20245 | 20274 | } |
| 20246 | 20275 | if( p->useMalloc==1 ){ |
| | @@ -20250,11 +20279,11 @@ |
| 20250 | 20279 | } |
| 20251 | 20280 | if( zNew ){ |
| 20252 | 20281 | if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 20253 | 20282 | p->zText = zNew; |
| 20254 | 20283 | }else{ |
| 20255 | | - p->mallocFailed = 1; |
| 20284 | + p->accError = STRACCUM_NOMEM; |
| 20256 | 20285 | sqlite3StrAccumReset(p); |
| 20257 | 20286 | return; |
| 20258 | 20287 | } |
| 20259 | 20288 | } |
| 20260 | 20289 | } |
| | @@ -20278,11 +20307,11 @@ |
| 20278 | 20307 | p->zText = sqlite3_malloc(p->nChar+1); |
| 20279 | 20308 | } |
| 20280 | 20309 | if( p->zText ){ |
| 20281 | 20310 | memcpy(p->zText, p->zBase, p->nChar+1); |
| 20282 | 20311 | }else{ |
| 20283 | | - p->mallocFailed = 1; |
| 20312 | + p->accError = STRACCUM_NOMEM; |
| 20284 | 20313 | } |
| 20285 | 20314 | } |
| 20286 | 20315 | } |
| 20287 | 20316 | return p->zText; |
| 20288 | 20317 | } |
| | @@ -20309,12 +20338,11 @@ |
| 20309 | 20338 | p->db = 0; |
| 20310 | 20339 | p->nChar = 0; |
| 20311 | 20340 | p->nAlloc = n; |
| 20312 | 20341 | p->mxAlloc = mx; |
| 20313 | 20342 | p->useMalloc = 1; |
| 20314 | | - p->tooBig = 0; |
| 20315 | | - p->mallocFailed = 0; |
| 20343 | + p->accError = 0; |
| 20316 | 20344 | } |
| 20317 | 20345 | |
| 20318 | 20346 | /* |
| 20319 | 20347 | ** Print into memory obtained from sqliteMalloc(). Use the internal |
| 20320 | 20348 | ** %-conversion extensions. |
| | @@ -20327,11 +20355,11 @@ |
| 20327 | 20355 | sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), |
| 20328 | 20356 | db->aLimit[SQLITE_LIMIT_LENGTH]); |
| 20329 | 20357 | acc.db = db; |
| 20330 | 20358 | sqlite3VXPrintf(&acc, 1, zFormat, ap); |
| 20331 | 20359 | z = sqlite3StrAccumFinish(&acc); |
| 20332 | | - if( acc.mallocFailed ){ |
| 20360 | + if( acc.accError==STRACCUM_NOMEM ){ |
| 20333 | 20361 | db->mallocFailed = 1; |
| 20334 | 20362 | } |
| 20335 | 20363 | return z; |
| 20336 | 20364 | } |
| 20337 | 20365 | |
| | @@ -20524,28 +20552,15 @@ |
| 20524 | 20552 | unsigned char i, j; /* State variables */ |
| 20525 | 20553 | unsigned char s[256]; /* State variables */ |
| 20526 | 20554 | } sqlite3Prng; |
| 20527 | 20555 | |
| 20528 | 20556 | /* |
| 20529 | | -** Get a single 8-bit random value from the RC4 PRNG. The Mutex |
| 20530 | | -** must be held while executing this routine. |
| 20531 | | -** |
| 20532 | | -** Why not just use a library random generator like lrand48() for this? |
| 20533 | | -** Because the OP_NewRowid opcode in the VDBE depends on having a very |
| 20534 | | -** good source of random numbers. The lrand48() library function may |
| 20535 | | -** well be good enough. But maybe not. Or maybe lrand48() has some |
| 20536 | | -** subtle problems on some systems that could cause problems. It is hard |
| 20537 | | -** to know. To minimize the risk of problems due to bad lrand48() |
| 20538 | | -** implementations, SQLite uses this random number generator based |
| 20539 | | -** on RC4, which we know works very well. |
| 20540 | | -** |
| 20541 | | -** (Later): Actually, OP_NewRowid does not depend on a good source of |
| 20542 | | -** randomness any more. But we will leave this code in all the same. |
| 20557 | +** Return N random bytes. |
| 20543 | 20558 | */ |
| 20544 | | -static u8 randomByte(void){ |
| 20559 | +SQLITE_API void sqlite3_randomness(int N, void *pBuf){ |
| 20545 | 20560 | unsigned char t; |
| 20546 | | - |
| 20561 | + unsigned char *zBuf = pBuf; |
| 20547 | 20562 | |
| 20548 | 20563 | /* The "wsdPrng" macro will resolve to the pseudo-random number generator |
| 20549 | 20564 | ** state vector. If writable static data is unsupported on the target, |
| 20550 | 20565 | ** we have to locate the state vector at run-time. In the more common |
| 20551 | 20566 | ** case where writable static data is supported, wsdPrng can refer directly |
| | @@ -20556,10 +20571,14 @@ |
| 20556 | 20571 | # define wsdPrng p[0] |
| 20557 | 20572 | #else |
| 20558 | 20573 | # define wsdPrng sqlite3Prng |
| 20559 | 20574 | #endif |
| 20560 | 20575 | |
| 20576 | +#if SQLITE_THREADSAFE |
| 20577 | + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); |
| 20578 | + sqlite3_mutex_enter(mutex); |
| 20579 | +#endif |
| 20561 | 20580 | |
| 20562 | 20581 | /* Initialize the state of the random number generator once, |
| 20563 | 20582 | ** the first time this routine is called. The seed value does |
| 20564 | 20583 | ** not need to contain a lot of randomness since we are not |
| 20565 | 20584 | ** trying to do secure encryption or anything like that... |
| | @@ -20584,32 +20603,18 @@ |
| 20584 | 20603 | wsdPrng.s[i] = t; |
| 20585 | 20604 | } |
| 20586 | 20605 | wsdPrng.isInit = 1; |
| 20587 | 20606 | } |
| 20588 | 20607 | |
| 20589 | | - /* Generate and return single random byte |
| 20590 | | - */ |
| 20591 | | - wsdPrng.i++; |
| 20592 | | - t = wsdPrng.s[wsdPrng.i]; |
| 20593 | | - wsdPrng.j += t; |
| 20594 | | - wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; |
| 20595 | | - wsdPrng.s[wsdPrng.j] = t; |
| 20596 | | - t += wsdPrng.s[wsdPrng.i]; |
| 20597 | | - return wsdPrng.s[t]; |
| 20598 | | -} |
| 20599 | | - |
| 20600 | | -/* |
| 20601 | | -** Return N random bytes. |
| 20602 | | -*/ |
| 20603 | | -SQLITE_API void sqlite3_randomness(int N, void *pBuf){ |
| 20604 | | - unsigned char *zBuf = pBuf; |
| 20605 | | -#if SQLITE_THREADSAFE |
| 20606 | | - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); |
| 20607 | | -#endif |
| 20608 | | - sqlite3_mutex_enter(mutex); |
| 20609 | 20608 | while( N-- ){ |
| 20610 | | - *(zBuf++) = randomByte(); |
| 20609 | + wsdPrng.i++; |
| 20610 | + t = wsdPrng.s[wsdPrng.i]; |
| 20611 | + wsdPrng.j += t; |
| 20612 | + wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; |
| 20613 | + wsdPrng.s[wsdPrng.j] = t; |
| 20614 | + t += wsdPrng.s[wsdPrng.i]; |
| 20615 | + *(zBuf++) = wsdPrng.s[t]; |
| 20611 | 20616 | } |
| 20612 | 20617 | sqlite3_mutex_leave(mutex); |
| 20613 | 20618 | } |
| 20614 | 20619 | |
| 20615 | 20620 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| | @@ -21092,36 +21097,10 @@ |
| 21092 | 21097 | assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed ); |
| 21093 | 21098 | assert( m.z || db->mallocFailed ); |
| 21094 | 21099 | return m.z; |
| 21095 | 21100 | } |
| 21096 | 21101 | |
| 21097 | | -/* |
| 21098 | | -** Convert a UTF-8 string to the UTF-16 encoding specified by parameter |
| 21099 | | -** enc. A pointer to the new string is returned, and the value of *pnOut |
| 21100 | | -** is set to the length of the returned string in bytes. The call should |
| 21101 | | -** arrange to call sqlite3DbFree() on the returned pointer when it is |
| 21102 | | -** no longer required. |
| 21103 | | -** |
| 21104 | | -** If a malloc failure occurs, NULL is returned and the db.mallocFailed |
| 21105 | | -** flag set. |
| 21106 | | -*/ |
| 21107 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 21108 | | -SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){ |
| 21109 | | - Mem m; |
| 21110 | | - memset(&m, 0, sizeof(m)); |
| 21111 | | - m.db = db; |
| 21112 | | - sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC); |
| 21113 | | - if( sqlite3VdbeMemTranslate(&m, enc) ){ |
| 21114 | | - assert( db->mallocFailed ); |
| 21115 | | - return 0; |
| 21116 | | - } |
| 21117 | | - assert( m.z==m.zMalloc ); |
| 21118 | | - *pnOut = m.n; |
| 21119 | | - return m.z; |
| 21120 | | -} |
| 21121 | | -#endif |
| 21122 | | - |
| 21123 | 21102 | /* |
| 21124 | 21103 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. |
| 21125 | 21104 | ** Return the number of bytes in the first nChar unicode characters |
| 21126 | 21105 | ** in pZ. nChar must be non-negative. |
| 21127 | 21106 | */ |
| | @@ -23074,15 +23053,17 @@ |
| 23074 | 23053 | void *lockingContext; /* Locking style specific state */ |
| 23075 | 23054 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23076 | 23055 | const char *zPath; /* Name of the file */ |
| 23077 | 23056 | unixShm *pShm; /* Shared memory segment information */ |
| 23078 | 23057 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23058 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 23079 | 23059 | int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23080 | 23060 | sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23081 | 23061 | sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23082 | 23062 | sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23083 | 23063 | void *pMapRegion; /* Memory mapped region */ |
| 23064 | +#endif |
| 23084 | 23065 | #ifdef __QNXNTO__ |
| 23085 | 23066 | int sectorSize; /* Device sector size */ |
| 23086 | 23067 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 23087 | 23068 | #endif |
| 23088 | 23069 | #if SQLITE_ENABLE_LOCKING_STYLE |
| | @@ -23513,10 +23494,11 @@ |
| 23513 | 23494 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23514 | 23495 | |
| 23515 | 23496 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23516 | 23497 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23517 | 23498 | |
| 23499 | +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
| 23518 | 23500 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23519 | 23501 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23520 | 23502 | |
| 23521 | 23503 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23522 | 23504 | #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| | @@ -23525,10 +23507,11 @@ |
| 23525 | 23507 | { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23526 | 23508 | #else |
| 23527 | 23509 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23528 | 23510 | #endif |
| 23529 | 23511 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23512 | +#endif |
| 23530 | 23513 | |
| 23531 | 23514 | }; /* End of the overrideable system calls */ |
| 23532 | 23515 | |
| 23533 | 23516 | /* |
| 23534 | 23517 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -23631,17 +23614,27 @@ |
| 23631 | 23614 | ** recover the hot journals. |
| 23632 | 23615 | */ |
| 23633 | 23616 | static int robust_open(const char *z, int f, mode_t m){ |
| 23634 | 23617 | int fd; |
| 23635 | 23618 | mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS; |
| 23636 | | - do{ |
| 23619 | + while(1){ |
| 23637 | 23620 | #if defined(O_CLOEXEC) |
| 23638 | 23621 | fd = osOpen(z,f|O_CLOEXEC,m2); |
| 23639 | 23622 | #else |
| 23640 | 23623 | fd = osOpen(z,f,m2); |
| 23641 | 23624 | #endif |
| 23642 | | - }while( fd<0 && errno==EINTR ); |
| 23625 | + if( fd<0 ){ |
| 23626 | + if( errno==EINTR ) continue; |
| 23627 | + break; |
| 23628 | + } |
| 23629 | + if( fd>2 ) break; |
| 23630 | + osClose(fd); |
| 23631 | + sqlite3_log(SQLITE_WARNING, |
| 23632 | + "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23633 | + fd = -1; |
| 23634 | + if( osOpen("/dev/null", f, m)<0 ) break; |
| 23635 | + } |
| 23643 | 23636 | if( fd>=0 ){ |
| 23644 | 23637 | if( m!=0 ){ |
| 23645 | 23638 | struct stat statbuf; |
| 23646 | 23639 | if( osFstat(fd, &statbuf)==0 |
| 23647 | 23640 | && statbuf.st_size==0 |
| | @@ -24935,12 +24928,14 @@ |
| 24935 | 24928 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24936 | 24929 | assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24937 | 24930 | return posixUnlock(id, eFileLock, 0); |
| 24938 | 24931 | } |
| 24939 | 24932 | |
| 24933 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 24940 | 24934 | static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24941 | 24935 | static void unixUnmapfile(unixFile *pFd); |
| 24936 | +#endif |
| 24942 | 24937 | |
| 24943 | 24938 | /* |
| 24944 | 24939 | ** This function performs the parts of the "close file" operation |
| 24945 | 24940 | ** common to all locking schemes. It closes the directory and file |
| 24946 | 24941 | ** handles, if they are valid, and sets all fields of the unixFile |
| | @@ -24950,11 +24945,13 @@ |
| 24950 | 24945 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24951 | 24946 | ** vxworksReleaseFileId() routine. |
| 24952 | 24947 | */ |
| 24953 | 24948 | static int closeUnixFile(sqlite3_file *id){ |
| 24954 | 24949 | unixFile *pFile = (unixFile*)id; |
| 24950 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 24955 | 24951 | unixUnmapfile(pFile); |
| 24952 | +#endif |
| 24956 | 24953 | if( pFile->h>=0 ){ |
| 24957 | 24954 | robust_close(pFile, pFile->h, __LINE__); |
| 24958 | 24955 | pFile->h = -1; |
| 24959 | 24956 | } |
| 24960 | 24957 | #if OS_VXWORKS |
| | @@ -26155,10 +26152,11 @@ |
| 26155 | 26152 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26156 | 26153 | i64 newOffset; |
| 26157 | 26154 | #endif |
| 26158 | 26155 | TIMER_START; |
| 26159 | 26156 | assert( cnt==(cnt&0x1ffff) ); |
| 26157 | + assert( id->h>2 ); |
| 26160 | 26158 | cnt &= 0x1ffff; |
| 26161 | 26159 | do{ |
| 26162 | 26160 | #if defined(USE_PREAD) |
| 26163 | 26161 | got = osPread(id->h, pBuf, cnt, offset); |
| 26164 | 26162 | SimulateIOError( got = -1 ); |
| | @@ -26269,10 +26267,11 @@ |
| 26269 | 26267 | int *piErrno /* OUT: Error number if error occurs */ |
| 26270 | 26268 | ){ |
| 26271 | 26269 | int rc = 0; /* Value returned by system call */ |
| 26272 | 26270 | |
| 26273 | 26271 | assert( nBuf==(nBuf&0x1ffff) ); |
| 26272 | + assert( fd>2 ); |
| 26274 | 26273 | nBuf &= 0x1ffff; |
| 26275 | 26274 | TIMER_START; |
| 26276 | 26275 | |
| 26277 | 26276 | #if defined(USE_PREAD) |
| 26278 | 26277 | do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
| | @@ -26654,17 +26653,19 @@ |
| 26654 | 26653 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26655 | 26654 | pFile->transCntrChng = 1; |
| 26656 | 26655 | } |
| 26657 | 26656 | #endif |
| 26658 | 26657 | |
| 26658 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26659 | 26659 | /* If the file was just truncated to a size smaller than the currently |
| 26660 | 26660 | ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26661 | 26661 | ** use read() and write() to access data beyond this point from now on. |
| 26662 | 26662 | */ |
| 26663 | 26663 | if( nByte<pFile->mmapSize ){ |
| 26664 | 26664 | pFile->mmapSize = nByte; |
| 26665 | 26665 | } |
| 26666 | +#endif |
| 26666 | 26667 | |
| 26667 | 26668 | return SQLITE_OK; |
| 26668 | 26669 | } |
| 26669 | 26670 | } |
| 26670 | 26671 | |
| | @@ -26750,10 +26751,11 @@ |
| 26750 | 26751 | } |
| 26751 | 26752 | #endif |
| 26752 | 26753 | } |
| 26753 | 26754 | } |
| 26754 | 26755 | |
| 26756 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26755 | 26757 | if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26756 | 26758 | int rc; |
| 26757 | 26759 | if( pFile->szChunk<=0 ){ |
| 26758 | 26760 | if( robust_ftruncate(pFile->h, nByte) ){ |
| 26759 | 26761 | pFile->lastErrno = errno; |
| | @@ -26762,10 +26764,11 @@ |
| 26762 | 26764 | } |
| 26763 | 26765 | |
| 26764 | 26766 | rc = unixMapfile(pFile, nByte); |
| 26765 | 26767 | return rc; |
| 26766 | 26768 | } |
| 26769 | +#endif |
| 26767 | 26770 | |
| 26768 | 26771 | return SQLITE_OK; |
| 26769 | 26772 | } |
| 26770 | 26773 | |
| 26771 | 26774 | /* |
| | @@ -26830,10 +26833,11 @@ |
| 26830 | 26833 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26831 | 26834 | *(char**)pArg = zTFile; |
| 26832 | 26835 | } |
| 26833 | 26836 | return SQLITE_OK; |
| 26834 | 26837 | } |
| 26838 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26835 | 26839 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 26836 | 26840 | i64 newLimit = *(i64*)pArg; |
| 26837 | 26841 | int rc = SQLITE_OK; |
| 26838 | 26842 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26839 | 26843 | newLimit = sqlite3GlobalConfig.mxMmap; |
| | @@ -26846,10 +26850,11 @@ |
| 26846 | 26850 | rc = unixMapfile(pFile, -1); |
| 26847 | 26851 | } |
| 26848 | 26852 | } |
| 26849 | 26853 | return rc; |
| 26850 | 26854 | } |
| 26855 | +#endif |
| 26851 | 26856 | #ifdef SQLITE_DEBUG |
| 26852 | 26857 | /* The pager calls this method to signal that it has done |
| 26853 | 26858 | ** a rollback and that the database is therefore unchanged and |
| 26854 | 26859 | ** it hence it is OK for the transaction change counter to be |
| 26855 | 26860 | ** unchanged. |
| | @@ -27656,26 +27661,24 @@ |
| 27656 | 27661 | # define unixShmLock 0 |
| 27657 | 27662 | # define unixShmBarrier 0 |
| 27658 | 27663 | # define unixShmUnmap 0 |
| 27659 | 27664 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27660 | 27665 | |
| 27666 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27661 | 27667 | /* |
| 27662 | 27668 | ** If it is currently memory mapped, unmap file pFd. |
| 27663 | 27669 | */ |
| 27664 | 27670 | static void unixUnmapfile(unixFile *pFd){ |
| 27665 | 27671 | assert( pFd->nFetchOut==0 ); |
| 27666 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27667 | 27672 | if( pFd->pMapRegion ){ |
| 27668 | 27673 | osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27669 | 27674 | pFd->pMapRegion = 0; |
| 27670 | 27675 | pFd->mmapSize = 0; |
| 27671 | 27676 | pFd->mmapSizeActual = 0; |
| 27672 | 27677 | } |
| 27673 | | -#endif |
| 27674 | 27678 | } |
| 27675 | 27679 | |
| 27676 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27677 | 27680 | /* |
| 27678 | 27681 | ** Return the system page size. |
| 27679 | 27682 | */ |
| 27680 | 27683 | static int unixGetPagesize(void){ |
| 27681 | 27684 | #if HAVE_MREMAP |
| | @@ -27684,13 +27687,11 @@ |
| 27684 | 27687 | return getpagesize(); |
| 27685 | 27688 | #else |
| 27686 | 27689 | return (int)sysconf(_SC_PAGESIZE); |
| 27687 | 27690 | #endif |
| 27688 | 27691 | } |
| 27689 | | -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27690 | 27692 | |
| 27691 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27692 | 27693 | /* |
| 27693 | 27694 | ** Attempt to set the size of the memory mapping maintained by file |
| 27694 | 27695 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27695 | 27696 | ** |
| 27696 | 27697 | ** If successful, this function sets the following variables: |
| | @@ -27771,11 +27772,10 @@ |
| 27771 | 27772 | pFd->mmapSizeMax = 0; |
| 27772 | 27773 | } |
| 27773 | 27774 | pFd->pMapRegion = (void *)pNew; |
| 27774 | 27775 | pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27775 | 27776 | } |
| 27776 | | -#endif |
| 27777 | 27777 | |
| 27778 | 27778 | /* |
| 27779 | 27779 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27780 | 27780 | ** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27781 | 27781 | ** there already exists a mapping for this file, and there are still |
| | @@ -27790,11 +27790,10 @@ |
| 27790 | 27790 | ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27791 | 27791 | ** recreated as a result of outstanding references) or an SQLite error |
| 27792 | 27792 | ** code otherwise. |
| 27793 | 27793 | */ |
| 27794 | 27794 | static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27795 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27796 | 27795 | i64 nMap = nByte; |
| 27797 | 27796 | int rc; |
| 27798 | 27797 | |
| 27799 | 27798 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27800 | 27799 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| | @@ -27816,14 +27815,14 @@ |
| 27816 | 27815 | unixRemapfile(pFd, nMap); |
| 27817 | 27816 | }else{ |
| 27818 | 27817 | unixUnmapfile(pFd); |
| 27819 | 27818 | } |
| 27820 | 27819 | } |
| 27821 | | -#endif |
| 27822 | 27820 | |
| 27823 | 27821 | return SQLITE_OK; |
| 27824 | 27822 | } |
| 27823 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27825 | 27824 | |
| 27826 | 27825 | /* |
| 27827 | 27826 | ** If possible, return a pointer to a mapping of file fd starting at offset |
| 27828 | 27827 | ** iOff. The mapping must be valid for at least nAmt bytes. |
| 27829 | 27828 | ** |
| | @@ -27868,10 +27867,11 @@ |
| 27868 | 27867 | */ |
| 27869 | 27868 | static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27870 | 27869 | unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27871 | 27870 | UNUSED_PARAMETER(iOff); |
| 27872 | 27871 | |
| 27872 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27873 | 27873 | /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27874 | 27874 | ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27875 | 27875 | ** then there must be at least one outstanding. */ |
| 27876 | 27876 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27877 | 27877 | |
| | @@ -27883,10 +27883,11 @@ |
| 27883 | 27883 | }else{ |
| 27884 | 27884 | unixUnmapfile(pFd); |
| 27885 | 27885 | } |
| 27886 | 27886 | |
| 27887 | 27887 | assert( pFd->nFetchOut>=0 ); |
| 27888 | +#endif |
| 27888 | 27889 | return SQLITE_OK; |
| 27889 | 27890 | } |
| 27890 | 27891 | |
| 27891 | 27892 | /* |
| 27892 | 27893 | ** Here ends the implementation of all sqlite3_file methods. |
| | @@ -28214,11 +28215,13 @@ |
| 28214 | 28215 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 28215 | 28216 | pNew->h = h; |
| 28216 | 28217 | pNew->pVfs = pVfs; |
| 28217 | 28218 | pNew->zPath = zFilename; |
| 28218 | 28219 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28220 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 28219 | 28221 | pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; |
| 28222 | +#endif |
| 28220 | 28223 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 28221 | 28224 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 28222 | 28225 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 28223 | 28226 | } |
| 28224 | 28227 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| | @@ -30715,11 +30718,11 @@ |
| 30715 | 30718 | /* |
| 30716 | 30719 | ** Compiling and using WAL mode requires several APIs that are only |
| 30717 | 30720 | ** available in Windows platforms based on the NT kernel. |
| 30718 | 30721 | */ |
| 30719 | 30722 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 30720 | | -# error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30723 | +# error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30721 | 30724 | with SQLITE_OMIT_WAL." |
| 30722 | 30725 | #endif |
| 30723 | 30726 | |
| 30724 | 30727 | /* |
| 30725 | 30728 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| | @@ -30735,10 +30738,70 @@ |
| 30735 | 30738 | */ |
| 30736 | 30739 | #if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30737 | 30740 | # define SQLITE_WIN32_HAS_WIDE |
| 30738 | 30741 | #endif |
| 30739 | 30742 | |
| 30743 | +/* |
| 30744 | +** Maximum pathname length (in chars) for Win32. This should normally be |
| 30745 | +** MAX_PATH. |
| 30746 | +*/ |
| 30747 | +#ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| 30748 | +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) |
| 30749 | +#endif |
| 30750 | + |
| 30751 | +/* |
| 30752 | +** Maximum pathname length (in chars) for WinNT. This should normally be |
| 30753 | +** 32767. |
| 30754 | +*/ |
| 30755 | +#ifndef SQLITE_WINNT_MAX_PATH_CHARS |
| 30756 | +# define SQLITE_WINNT_MAX_PATH_CHARS (32767) |
| 30757 | +#endif |
| 30758 | + |
| 30759 | +/* |
| 30760 | +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in |
| 30761 | +** characters, so we allocate 3 bytes per character assuming worst-case of |
| 30762 | +** 4-bytes-per-character for UTF8. |
| 30763 | +*/ |
| 30764 | +#ifndef SQLITE_WIN32_MAX_PATH_BYTES |
| 30765 | +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) |
| 30766 | +#endif |
| 30767 | + |
| 30768 | +/* |
| 30769 | +** Maximum pathname length (in bytes) for WinNT. This should normally be |
| 30770 | +** 32767 * sizeof(WCHAR). |
| 30771 | +*/ |
| 30772 | +#ifndef SQLITE_WINNT_MAX_PATH_BYTES |
| 30773 | +# define SQLITE_WINNT_MAX_PATH_BYTES \ |
| 30774 | + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) |
| 30775 | +#endif |
| 30776 | + |
| 30777 | +/* |
| 30778 | +** Maximum error message length (in chars) for WinRT. |
| 30779 | +*/ |
| 30780 | +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS |
| 30781 | +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) |
| 30782 | +#endif |
| 30783 | + |
| 30784 | +/* |
| 30785 | +** Returns non-zero if the character should be treated as a directory |
| 30786 | +** separator. |
| 30787 | +*/ |
| 30788 | +#ifndef winIsDirSep |
| 30789 | +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) |
| 30790 | +#endif |
| 30791 | + |
| 30792 | +/* |
| 30793 | +** Returns the string that should be used as the directory separator. |
| 30794 | +*/ |
| 30795 | +#ifndef winGetDirDep |
| 30796 | +# ifdef __CYGWIN__ |
| 30797 | +# define winGetDirDep() "/" |
| 30798 | +# else |
| 30799 | +# define winGetDirDep() "\\" |
| 30800 | +# endif |
| 30801 | +#endif |
| 30802 | + |
| 30740 | 30803 | /* |
| 30741 | 30804 | ** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 30742 | 30805 | ** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 30743 | 30806 | ** are not present in the header file)? |
| 30744 | 30807 | */ |
| | @@ -31742,15 +31805,15 @@ |
| 31742 | 31805 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31743 | 31806 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31744 | 31807 | ** the LockFileEx() API. |
| 31745 | 31808 | */ |
| 31746 | 31809 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31747 | | -# define isNT() (1) |
| 31810 | +# define osIsNT() (1) |
| 31748 | 31811 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31749 | | -# define isNT() (0) |
| 31812 | +# define osIsNT() (0) |
| 31750 | 31813 | #else |
| 31751 | | - static int isNT(void){ |
| 31814 | + static int osIsNT(void){ |
| 31752 | 31815 | if( sqlite3_os_type==0 ){ |
| 31753 | 31816 | OSVERSIONINFOA sInfo; |
| 31754 | 31817 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31755 | 31818 | osGetVersionExA(&sInfo); |
| 31756 | 31819 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| | @@ -31957,11 +32020,11 @@ |
| 31957 | 32020 | /* |
| 31958 | 32021 | ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
| 31959 | 32022 | ** |
| 31960 | 32023 | ** Space to hold the returned string is obtained from malloc. |
| 31961 | 32024 | */ |
| 31962 | | -static LPWSTR utf8ToUnicode(const char *zFilename){ |
| 32025 | +static LPWSTR winUtf8ToUnicode(const char *zFilename){ |
| 31963 | 32026 | int nChar; |
| 31964 | 32027 | LPWSTR zWideFilename; |
| 31965 | 32028 | |
| 31966 | 32029 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 31967 | 32030 | if( nChar==0 ){ |
| | @@ -31982,11 +32045,11 @@ |
| 31982 | 32045 | |
| 31983 | 32046 | /* |
| 31984 | 32047 | ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
| 31985 | 32048 | ** obtained from sqlite3_malloc(). |
| 31986 | 32049 | */ |
| 31987 | | -static char *unicodeToUtf8(LPCWSTR zWideFilename){ |
| 32050 | +static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ |
| 31988 | 32051 | int nByte; |
| 31989 | 32052 | char *zFilename; |
| 31990 | 32053 | |
| 31991 | 32054 | nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
| 31992 | 32055 | if( nByte == 0 ){ |
| | @@ -32010,11 +32073,11 @@ |
| 32010 | 32073 | ** current codepage settings for file apis. |
| 32011 | 32074 | ** |
| 32012 | 32075 | ** Space to hold the returned string is obtained |
| 32013 | 32076 | ** from sqlite3_malloc. |
| 32014 | 32077 | */ |
| 32015 | | -static LPWSTR mbcsToUnicode(const char *zFilename){ |
| 32078 | +static LPWSTR winMbcsToUnicode(const char *zFilename){ |
| 32016 | 32079 | int nByte; |
| 32017 | 32080 | LPWSTR zMbcsFilename; |
| 32018 | 32081 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32019 | 32082 | |
| 32020 | 32083 | nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
| | @@ -32040,11 +32103,11 @@ |
| 32040 | 32103 | ** user's ANSI codepage. |
| 32041 | 32104 | ** |
| 32042 | 32105 | ** Space to hold the returned string is obtained from |
| 32043 | 32106 | ** sqlite3_malloc(). |
| 32044 | 32107 | */ |
| 32045 | | -static char *unicodeToMbcs(LPCWSTR zWideFilename){ |
| 32108 | +static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ |
| 32046 | 32109 | int nByte; |
| 32047 | 32110 | char *zFilename; |
| 32048 | 32111 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32049 | 32112 | |
| 32050 | 32113 | nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
| | @@ -32070,15 +32133,15 @@ |
| 32070 | 32133 | */ |
| 32071 | 32134 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
| 32072 | 32135 | char *zFilenameUtf8; |
| 32073 | 32136 | LPWSTR zTmpWide; |
| 32074 | 32137 | |
| 32075 | | - zTmpWide = mbcsToUnicode(zFilename); |
| 32138 | + zTmpWide = winMbcsToUnicode(zFilename); |
| 32076 | 32139 | if( zTmpWide==0 ){ |
| 32077 | 32140 | return 0; |
| 32078 | 32141 | } |
| 32079 | | - zFilenameUtf8 = unicodeToUtf8(zTmpWide); |
| 32142 | + zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); |
| 32080 | 32143 | sqlite3_free(zTmpWide); |
| 32081 | 32144 | return zFilenameUtf8; |
| 32082 | 32145 | } |
| 32083 | 32146 | |
| 32084 | 32147 | /* |
| | @@ -32087,15 +32150,15 @@ |
| 32087 | 32150 | */ |
| 32088 | 32151 | SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
| 32089 | 32152 | char *zFilenameMbcs; |
| 32090 | 32153 | LPWSTR zTmpWide; |
| 32091 | 32154 | |
| 32092 | | - zTmpWide = utf8ToUnicode(zFilename); |
| 32155 | + zTmpWide = winUtf8ToUnicode(zFilename); |
| 32093 | 32156 | if( zTmpWide==0 ){ |
| 32094 | 32157 | return 0; |
| 32095 | 32158 | } |
| 32096 | | - zFilenameMbcs = unicodeToMbcs(zTmpWide); |
| 32159 | + zFilenameMbcs = winUnicodeToMbcs(zTmpWide); |
| 32097 | 32160 | sqlite3_free(zTmpWide); |
| 32098 | 32161 | return zFilenameMbcs; |
| 32099 | 32162 | } |
| 32100 | 32163 | |
| 32101 | 32164 | /* |
| | @@ -32121,11 +32184,11 @@ |
| 32121 | 32184 | ); |
| 32122 | 32185 | assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); |
| 32123 | 32186 | if( ppDirectory ){ |
| 32124 | 32187 | char *zValueUtf8 = 0; |
| 32125 | 32188 | if( zValue && zValue[0] ){ |
| 32126 | | - zValueUtf8 = unicodeToUtf8(zValue); |
| 32189 | + zValueUtf8 = winUnicodeToUtf8(zValue); |
| 32127 | 32190 | if ( zValueUtf8==0 ){ |
| 32128 | 32191 | return SQLITE_NOMEM; |
| 32129 | 32192 | } |
| 32130 | 32193 | } |
| 32131 | 32194 | sqlite3_free(*ppDirectory); |
| | @@ -32134,32 +32197,32 @@ |
| 32134 | 32197 | } |
| 32135 | 32198 | return SQLITE_ERROR; |
| 32136 | 32199 | } |
| 32137 | 32200 | |
| 32138 | 32201 | /* |
| 32139 | | -** The return value of getLastErrorMsg |
| 32202 | +** The return value of winGetLastErrorMsg |
| 32140 | 32203 | ** is zero if the error message fits in the buffer, or non-zero |
| 32141 | 32204 | ** otherwise (if the message was truncated). |
| 32142 | 32205 | */ |
| 32143 | | -static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32206 | +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32144 | 32207 | /* FormatMessage returns 0 on failure. Otherwise it |
| 32145 | 32208 | ** returns the number of TCHARs written to the output |
| 32146 | 32209 | ** buffer, excluding the terminating null char. |
| 32147 | 32210 | */ |
| 32148 | 32211 | DWORD dwLen = 0; |
| 32149 | 32212 | char *zOut = 0; |
| 32150 | 32213 | |
| 32151 | | - if( isNT() ){ |
| 32214 | + if( osIsNT() ){ |
| 32152 | 32215 | #if SQLITE_OS_WINRT |
| 32153 | | - WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */ |
| 32216 | + WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; |
| 32154 | 32217 | dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 32155 | 32218 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 32156 | 32219 | NULL, |
| 32157 | 32220 | lastErrno, |
| 32158 | 32221 | 0, |
| 32159 | 32222 | zTempWide, |
| 32160 | | - MAX_PATH, |
| 32223 | + SQLITE_WIN32_MAX_ERRMSG_CHARS, |
| 32161 | 32224 | 0); |
| 32162 | 32225 | #else |
| 32163 | 32226 | LPWSTR zTempWide = NULL; |
| 32164 | 32227 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 32165 | 32228 | FORMAT_MESSAGE_FROM_SYSTEM | |
| | @@ -32172,11 +32235,11 @@ |
| 32172 | 32235 | 0); |
| 32173 | 32236 | #endif |
| 32174 | 32237 | if( dwLen > 0 ){ |
| 32175 | 32238 | /* allocate a buffer and convert to UTF8 */ |
| 32176 | 32239 | sqlite3BeginBenignMalloc(); |
| 32177 | | - zOut = unicodeToUtf8(zTempWide); |
| 32240 | + zOut = winUnicodeToUtf8(zTempWide); |
| 32178 | 32241 | sqlite3EndBenignMalloc(); |
| 32179 | 32242 | #if !SQLITE_OS_WINRT |
| 32180 | 32243 | /* free the system buffer allocated by FormatMessage */ |
| 32181 | 32244 | osLocalFree(zTempWide); |
| 32182 | 32245 | #endif |
| | @@ -32240,11 +32303,11 @@ |
| 32240 | 32303 | ){ |
| 32241 | 32304 | char zMsg[500]; /* Human readable error text */ |
| 32242 | 32305 | int i; /* Loop counter */ |
| 32243 | 32306 | |
| 32244 | 32307 | zMsg[0] = 0; |
| 32245 | | - getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32308 | + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32246 | 32309 | assert( errcode!=SQLITE_OK ); |
| 32247 | 32310 | if( zPath==0 ) zPath = ""; |
| 32248 | 32311 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32249 | 32312 | zMsg[i] = 0; |
| 32250 | 32313 | sqlite3_log(errcode, |
| | @@ -32265,30 +32328,30 @@ |
| 32265 | 32328 | # define SQLITE_WIN32_IOERR_RETRY 10 |
| 32266 | 32329 | #endif |
| 32267 | 32330 | #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY |
| 32268 | 32331 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 32269 | 32332 | #endif |
| 32270 | | -static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32271 | | -static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32333 | +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32334 | +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32272 | 32335 | |
| 32273 | 32336 | /* |
| 32274 | 32337 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 32275 | 32338 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 32276 | 32339 | ** to give up with an error. |
| 32277 | 32340 | */ |
| 32278 | | -static int retryIoerr(int *pnRetry, DWORD *pError){ |
| 32341 | +static int winRetryIoerr(int *pnRetry, DWORD *pError){ |
| 32279 | 32342 | DWORD e = osGetLastError(); |
| 32280 | | - if( *pnRetry>=win32IoerrRetry ){ |
| 32343 | + if( *pnRetry>=winIoerrRetry ){ |
| 32281 | 32344 | if( pError ){ |
| 32282 | 32345 | *pError = e; |
| 32283 | 32346 | } |
| 32284 | 32347 | return 0; |
| 32285 | 32348 | } |
| 32286 | 32349 | if( e==ERROR_ACCESS_DENIED || |
| 32287 | 32350 | e==ERROR_LOCK_VIOLATION || |
| 32288 | 32351 | e==ERROR_SHARING_VIOLATION ){ |
| 32289 | | - sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry)); |
| 32352 | + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 32290 | 32353 | ++*pnRetry; |
| 32291 | 32354 | return 1; |
| 32292 | 32355 | } |
| 32293 | 32356 | if( pError ){ |
| 32294 | 32357 | *pError = e; |
| | @@ -32297,15 +32360,15 @@ |
| 32297 | 32360 | } |
| 32298 | 32361 | |
| 32299 | 32362 | /* |
| 32300 | 32363 | ** Log a I/O error retry episode. |
| 32301 | 32364 | */ |
| 32302 | | -static void logIoerr(int nRetry){ |
| 32365 | +static void winLogIoerr(int nRetry){ |
| 32303 | 32366 | if( nRetry ){ |
| 32304 | 32367 | sqlite3_log(SQLITE_IOERR, |
| 32305 | 32368 | "delayed %dms for lock/sharing conflict", |
| 32306 | | - win32IoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32369 | + winIoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32307 | 32370 | ); |
| 32308 | 32371 | } |
| 32309 | 32372 | } |
| 32310 | 32373 | |
| 32311 | 32374 | #if SQLITE_OS_WINCE |
| | @@ -32366,11 +32429,11 @@ |
| 32366 | 32429 | LPWSTR zName; |
| 32367 | 32430 | DWORD lastErrno; |
| 32368 | 32431 | BOOL bLogged = FALSE; |
| 32369 | 32432 | BOOL bInit = TRUE; |
| 32370 | 32433 | |
| 32371 | | - zName = utf8ToUnicode(zFilename); |
| 32434 | + zName = winUtf8ToUnicode(zFilename); |
| 32372 | 32435 | if( zName==0 ){ |
| 32373 | 32436 | /* out of memory */ |
| 32374 | 32437 | return SQLITE_IOERR_NOMEM; |
| 32375 | 32438 | } |
| 32376 | 32439 | |
| | @@ -32639,11 +32702,11 @@ |
| 32639 | 32702 | ** API LockFile. |
| 32640 | 32703 | */ |
| 32641 | 32704 | return winceLockFile(phFile, offsetLow, offsetHigh, |
| 32642 | 32705 | numBytesLow, numBytesHigh); |
| 32643 | 32706 | #else |
| 32644 | | - if( isNT() ){ |
| 32707 | + if( osIsNT() ){ |
| 32645 | 32708 | OVERLAPPED ovlp; |
| 32646 | 32709 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32647 | 32710 | ovlp.Offset = offsetLow; |
| 32648 | 32711 | ovlp.OffsetHigh = offsetHigh; |
| 32649 | 32712 | return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| | @@ -32670,11 +32733,11 @@ |
| 32670 | 32733 | ** API UnlockFile. |
| 32671 | 32734 | */ |
| 32672 | 32735 | return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 32673 | 32736 | numBytesLow, numBytesHigh); |
| 32674 | 32737 | #else |
| 32675 | | - if( isNT() ){ |
| 32738 | + if( osIsNT() ){ |
| 32676 | 32739 | OVERLAPPED ovlp; |
| 32677 | 32740 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32678 | 32741 | ovlp.Offset = offsetLow; |
| 32679 | 32742 | ovlp.OffsetHigh = offsetHigh; |
| 32680 | 32743 | return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| | @@ -32700,11 +32763,11 @@ |
| 32700 | 32763 | /* |
| 32701 | 32764 | ** Move the current position of the file handle passed as the first |
| 32702 | 32765 | ** argument to offset iOffset within the file. If successful, return 0. |
| 32703 | 32766 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 32704 | 32767 | */ |
| 32705 | | -static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32768 | +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32706 | 32769 | #if !SQLITE_OS_WINRT |
| 32707 | 32770 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32708 | 32771 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32709 | 32772 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32710 | 32773 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| | @@ -32725,11 +32788,11 @@ |
| 32725 | 32788 | |
| 32726 | 32789 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32727 | 32790 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32728 | 32791 | pFile->lastErrno = lastErrno; |
| 32729 | 32792 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32730 | | - "seekWinFile", pFile->zPath); |
| 32793 | + "winSeekFile", pFile->zPath); |
| 32731 | 32794 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32732 | 32795 | return 1; |
| 32733 | 32796 | } |
| 32734 | 32797 | |
| 32735 | 32798 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| | @@ -32746,11 +32809,11 @@ |
| 32746 | 32809 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32747 | 32810 | |
| 32748 | 32811 | if(!bRet){ |
| 32749 | 32812 | pFile->lastErrno = osGetLastError(); |
| 32750 | 32813 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32751 | | - "seekWinFile", pFile->zPath); |
| 32814 | + "winSeekFile", pFile->zPath); |
| 32752 | 32815 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32753 | 32816 | return 1; |
| 32754 | 32817 | } |
| 32755 | 32818 | |
| 32756 | 32819 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| | @@ -32861,11 +32924,11 @@ |
| 32861 | 32924 | } |
| 32862 | 32925 | } |
| 32863 | 32926 | #endif |
| 32864 | 32927 | |
| 32865 | 32928 | #if SQLITE_OS_WINCE |
| 32866 | | - if( seekWinFile(pFile, offset) ){ |
| 32929 | + if( winSeekFile(pFile, offset) ){ |
| 32867 | 32930 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32868 | 32931 | return SQLITE_FULL; |
| 32869 | 32932 | } |
| 32870 | 32933 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32871 | 32934 | #else |
| | @@ -32874,17 +32937,17 @@ |
| 32874 | 32937 | overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); |
| 32875 | 32938 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && |
| 32876 | 32939 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32877 | 32940 | #endif |
| 32878 | 32941 | DWORD lastErrno; |
| 32879 | | - if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32942 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32880 | 32943 | pFile->lastErrno = lastErrno; |
| 32881 | 32944 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32882 | 32945 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32883 | 32946 | "winRead", pFile->zPath); |
| 32884 | 32947 | } |
| 32885 | | - logIoerr(nRetry); |
| 32948 | + winLogIoerr(nRetry); |
| 32886 | 32949 | if( nRead<(DWORD)amt ){ |
| 32887 | 32950 | /* Unread parts of the buffer must be zero-filled */ |
| 32888 | 32951 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32889 | 32952 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32890 | 32953 | return SQLITE_IOERR_SHORT_READ; |
| | @@ -32933,11 +32996,11 @@ |
| 32933 | 32996 | } |
| 32934 | 32997 | } |
| 32935 | 32998 | #endif |
| 32936 | 32999 | |
| 32937 | 33000 | #if SQLITE_OS_WINCE |
| 32938 | | - rc = seekWinFile(pFile, offset); |
| 33001 | + rc = winSeekFile(pFile, offset); |
| 32939 | 33002 | if( rc==0 ){ |
| 32940 | 33003 | #else |
| 32941 | 33004 | { |
| 32942 | 33005 | #endif |
| 32943 | 33006 | #if !SQLITE_OS_WINCE |
| | @@ -32958,11 +33021,11 @@ |
| 32958 | 33021 | #if SQLITE_OS_WINCE |
| 32959 | 33022 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ |
| 32960 | 33023 | #else |
| 32961 | 33024 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 32962 | 33025 | #endif |
| 32963 | | - if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 33026 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32964 | 33027 | break; |
| 32965 | 33028 | } |
| 32966 | 33029 | assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 32967 | 33030 | if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 32968 | 33031 | lastErrno = osGetLastError(); |
| | @@ -32990,11 +33053,11 @@ |
| 32990 | 33053 | } |
| 32991 | 33054 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 32992 | 33055 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 32993 | 33056 | "winWrite", pFile->zPath); |
| 32994 | 33057 | }else{ |
| 32995 | | - logIoerr(nRetry); |
| 33058 | + winLogIoerr(nRetry); |
| 32996 | 33059 | } |
| 32997 | 33060 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32998 | 33061 | return SQLITE_OK; |
| 32999 | 33062 | } |
| 33000 | 33063 | |
| | @@ -33019,11 +33082,11 @@ |
| 33019 | 33082 | if( pFile->szChunk>0 ){ |
| 33020 | 33083 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 33021 | 33084 | } |
| 33022 | 33085 | |
| 33023 | 33086 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 33024 | | - if( seekWinFile(pFile, nByte) ){ |
| 33087 | + if( winSeekFile(pFile, nByte) ){ |
| 33025 | 33088 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 33026 | 33089 | "winTruncate1", pFile->zPath); |
| 33027 | 33090 | }else if( 0==osSetEndOfFile(pFile->h) && |
| 33028 | 33091 | ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33029 | 33092 | pFile->lastErrno = lastErrno; |
| | @@ -33100,10 +33163,11 @@ |
| 33100 | 33163 | |
| 33101 | 33164 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 33102 | 33165 | ** no-op |
| 33103 | 33166 | */ |
| 33104 | 33167 | #ifdef SQLITE_NO_SYNC |
| 33168 | + OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33105 | 33169 | return SQLITE_OK; |
| 33106 | 33170 | #else |
| 33107 | 33171 | rc = osFlushFileBuffers(pFile->h); |
| 33108 | 33172 | SimulateIOError( rc=FALSE ); |
| 33109 | 33173 | if( rc ){ |
| | @@ -33197,14 +33261,14 @@ |
| 33197 | 33261 | /* |
| 33198 | 33262 | ** Acquire a reader lock. |
| 33199 | 33263 | ** Different API routines are called depending on whether or not this |
| 33200 | 33264 | ** is Win9x or WinNT. |
| 33201 | 33265 | */ |
| 33202 | | -static int getReadLock(winFile *pFile){ |
| 33266 | +static int winGetReadLock(winFile *pFile){ |
| 33203 | 33267 | int res; |
| 33204 | 33268 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33205 | | - if( isNT() ){ |
| 33269 | + if( osIsNT() ){ |
| 33206 | 33270 | #if SQLITE_OS_WINCE |
| 33207 | 33271 | /* |
| 33208 | 33272 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33209 | 33273 | ** API LockFileEx. |
| 33210 | 33274 | */ |
| | @@ -33232,15 +33296,15 @@ |
| 33232 | 33296 | } |
| 33233 | 33297 | |
| 33234 | 33298 | /* |
| 33235 | 33299 | ** Undo a readlock |
| 33236 | 33300 | */ |
| 33237 | | -static int unlockReadLock(winFile *pFile){ |
| 33301 | +static int winUnlockReadLock(winFile *pFile){ |
| 33238 | 33302 | int res; |
| 33239 | 33303 | DWORD lastErrno; |
| 33240 | 33304 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33241 | | - if( isNT() ){ |
| 33305 | + if( osIsNT() ){ |
| 33242 | 33306 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33243 | 33307 | } |
| 33244 | 33308 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33245 | 33309 | else{ |
| 33246 | 33310 | res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| | @@ -33247,11 +33311,11 @@ |
| 33247 | 33311 | } |
| 33248 | 33312 | #endif |
| 33249 | 33313 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33250 | 33314 | pFile->lastErrno = lastErrno; |
| 33251 | 33315 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33252 | | - "unlockReadLock", pFile->zPath); |
| 33316 | + "winUnlockReadLock", pFile->zPath); |
| 33253 | 33317 | } |
| 33254 | 33318 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33255 | 33319 | return res; |
| 33256 | 33320 | } |
| 33257 | 33321 | |
| | @@ -33338,11 +33402,11 @@ |
| 33338 | 33402 | |
| 33339 | 33403 | /* Acquire a shared lock |
| 33340 | 33404 | */ |
| 33341 | 33405 | if( locktype==SHARED_LOCK && res ){ |
| 33342 | 33406 | assert( pFile->locktype==NO_LOCK ); |
| 33343 | | - res = getReadLock(pFile); |
| 33407 | + res = winGetReadLock(pFile); |
| 33344 | 33408 | if( res ){ |
| 33345 | 33409 | newLocktype = SHARED_LOCK; |
| 33346 | 33410 | }else{ |
| 33347 | 33411 | lastErrno = osGetLastError(); |
| 33348 | 33412 | } |
| | @@ -33369,18 +33433,18 @@ |
| 33369 | 33433 | |
| 33370 | 33434 | /* Acquire an EXCLUSIVE lock |
| 33371 | 33435 | */ |
| 33372 | 33436 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33373 | 33437 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33374 | | - res = unlockReadLock(pFile); |
| 33438 | + res = winUnlockReadLock(pFile); |
| 33375 | 33439 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33376 | 33440 | SHARED_SIZE, 0); |
| 33377 | 33441 | if( res ){ |
| 33378 | 33442 | newLocktype = EXCLUSIVE_LOCK; |
| 33379 | 33443 | }else{ |
| 33380 | 33444 | lastErrno = osGetLastError(); |
| 33381 | | - getReadLock(pFile); |
| 33445 | + winGetReadLock(pFile); |
| 33382 | 33446 | } |
| 33383 | 33447 | } |
| 33384 | 33448 | |
| 33385 | 33449 | /* If we are holding a PENDING lock that ought to be released, then |
| 33386 | 33450 | ** release it now. |
| | @@ -33393,14 +33457,14 @@ |
| 33393 | 33457 | ** return the appropriate result code. |
| 33394 | 33458 | */ |
| 33395 | 33459 | if( res ){ |
| 33396 | 33460 | rc = SQLITE_OK; |
| 33397 | 33461 | }else{ |
| 33462 | + pFile->lastErrno = lastErrno; |
| 33463 | + rc = SQLITE_BUSY; |
| 33398 | 33464 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33399 | 33465 | pFile->h, locktype, newLocktype)); |
| 33400 | | - pFile->lastErrno = lastErrno; |
| 33401 | | - rc = SQLITE_BUSY; |
| 33402 | 33466 | } |
| 33403 | 33467 | pFile->locktype = (u8)newLocktype; |
| 33404 | 33468 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33405 | 33469 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33406 | 33470 | return rc; |
| | @@ -33456,11 +33520,11 @@ |
| 33456 | 33520 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33457 | 33521 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33458 | 33522 | type = pFile->locktype; |
| 33459 | 33523 | if( type>=EXCLUSIVE_LOCK ){ |
| 33460 | 33524 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33461 | | - if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33525 | + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33462 | 33526 | /* This should never happen. We should always be able to |
| 33463 | 33527 | ** reacquire the read lock */ |
| 33464 | 33528 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33465 | 33529 | "winUnlock", pFile->zPath); |
| 33466 | 33530 | } |
| | @@ -33467,11 +33531,11 @@ |
| 33467 | 33531 | } |
| 33468 | 33532 | if( type>=RESERVED_LOCK ){ |
| 33469 | 33533 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33470 | 33534 | } |
| 33471 | 33535 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 33472 | | - unlockReadLock(pFile); |
| 33536 | + winUnlockReadLock(pFile); |
| 33473 | 33537 | } |
| 33474 | 33538 | if( type>=PENDING_LOCK ){ |
| 33475 | 33539 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33476 | 33540 | } |
| 33477 | 33541 | pFile->locktype = (u8)locktype; |
| | @@ -33495,11 +33559,11 @@ |
| 33495 | 33559 | pFile->ctrlFlags |= mask; |
| 33496 | 33560 | } |
| 33497 | 33561 | } |
| 33498 | 33562 | |
| 33499 | 33563 | /* Forward declaration */ |
| 33500 | | -static int getTempname(int nBuf, char *zBuf); |
| 33564 | +static int winGetTempname(sqlite3_vfs *, char **); |
| 33501 | 33565 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33502 | 33566 | static int winMapfile(winFile*, sqlite3_int64); |
| 33503 | 33567 | #endif |
| 33504 | 33568 | |
| 33505 | 33569 | /* |
| | @@ -33558,30 +33622,30 @@ |
| 33558 | 33622 | return SQLITE_OK; |
| 33559 | 33623 | } |
| 33560 | 33624 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33561 | 33625 | int *a = (int*)pArg; |
| 33562 | 33626 | if( a[0]>0 ){ |
| 33563 | | - win32IoerrRetry = a[0]; |
| 33627 | + winIoerrRetry = a[0]; |
| 33564 | 33628 | }else{ |
| 33565 | | - a[0] = win32IoerrRetry; |
| 33629 | + a[0] = winIoerrRetry; |
| 33566 | 33630 | } |
| 33567 | 33631 | if( a[1]>0 ){ |
| 33568 | | - win32IoerrRetryDelay = a[1]; |
| 33632 | + winIoerrRetryDelay = a[1]; |
| 33569 | 33633 | }else{ |
| 33570 | | - a[1] = win32IoerrRetryDelay; |
| 33634 | + a[1] = winIoerrRetryDelay; |
| 33571 | 33635 | } |
| 33572 | 33636 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33573 | 33637 | return SQLITE_OK; |
| 33574 | 33638 | } |
| 33575 | 33639 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33576 | | - char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33577 | | - if( zTFile ){ |
| 33578 | | - getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33640 | + char *zTFile = 0; |
| 33641 | + int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33642 | + if( rc==SQLITE_OK ){ |
| 33579 | 33643 | *(char**)pArg = zTFile; |
| 33580 | 33644 | } |
| 33581 | | - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33582 | | - return SQLITE_OK; |
| 33645 | + OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); |
| 33646 | + return rc; |
| 33583 | 33647 | } |
| 33584 | 33648 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33585 | 33649 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33586 | 33650 | i64 newLimit = *(i64*)pArg; |
| 33587 | 33651 | int rc = SQLITE_OK; |
| | @@ -34539,14 +34603,14 @@ |
| 34539 | 34603 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34540 | 34604 | ** operating system wants filenames in. Space to hold the result |
| 34541 | 34605 | ** is obtained from malloc and must be freed by the calling |
| 34542 | 34606 | ** function. |
| 34543 | 34607 | */ |
| 34544 | | -static void *convertUtf8Filename(const char *zFilename){ |
| 34608 | +static void *winConvertUtf8Filename(const char *zFilename){ |
| 34545 | 34609 | void *zConverted = 0; |
| 34546 | | - if( isNT() ){ |
| 34547 | | - zConverted = utf8ToUnicode(zFilename); |
| 34610 | + if( osIsNT() ){ |
| 34611 | + zConverted = winUtf8ToUnicode(zFilename); |
| 34548 | 34612 | } |
| 34549 | 34613 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34550 | 34614 | else{ |
| 34551 | 34615 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 34552 | 34616 | } |
| | @@ -34554,117 +34618,135 @@ |
| 34554 | 34618 | /* caller will handle out of memory */ |
| 34555 | 34619 | return zConverted; |
| 34556 | 34620 | } |
| 34557 | 34621 | |
| 34558 | 34622 | /* |
| 34559 | | -** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is |
| 34560 | | -** in characters, so we allocate 3 bytes per character assuming worst-case |
| 34561 | | -** 3-bytes-per-character UTF8. |
| 34623 | +** This function returns non-zero if the specified UTF-8 string buffer |
| 34624 | +** ends with a directory separator character. |
| 34562 | 34625 | */ |
| 34563 | | -#ifndef SQLITE_WIN32_MAX_PATH |
| 34564 | | -# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3) |
| 34565 | | -#endif |
| 34626 | +static int winEndsInDirSep(char *zBuf){ |
| 34627 | + if( zBuf ){ |
| 34628 | + int nLen = sqlite3Strlen30(zBuf); |
| 34629 | + return nLen>0 && winIsDirSep(zBuf[nLen-1]); |
| 34630 | + } |
| 34631 | + return 0; |
| 34632 | +} |
| 34566 | 34633 | |
| 34567 | 34634 | /* |
| 34568 | | -** Create a temporary file name in zBuf. zBuf must be big enough to |
| 34569 | | -** hold at pVfs->mxPathname characters. |
| 34635 | +** Create a temporary file name and store the resulting pointer into pzBuf. |
| 34636 | +** The pointer returned in pzBuf must be freed via sqlite3_free(). |
| 34570 | 34637 | */ |
| 34571 | | -static int getTempname(int nBuf, char *zBuf){ |
| 34638 | +static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
| 34572 | 34639 | static char zChars[] = |
| 34573 | 34640 | "abcdefghijklmnopqrstuvwxyz" |
| 34574 | 34641 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 34575 | 34642 | "0123456789"; |
| 34576 | 34643 | size_t i, j; |
| 34577 | | - int nTempPath; |
| 34578 | | - char zTempPath[SQLITE_WIN32_MAX_PATH+2]; |
| 34644 | + int nBuf, nLen; |
| 34645 | + char *zBuf; |
| 34579 | 34646 | |
| 34580 | 34647 | /* It's odd to simulate an io-error here, but really this is just |
| 34581 | 34648 | ** using the io-error infrastructure to test that SQLite handles this |
| 34582 | 34649 | ** function failing. |
| 34583 | 34650 | */ |
| 34584 | 34651 | SimulateIOError( return SQLITE_IOERR ); |
| 34585 | 34652 | |
| 34653 | + /* Allocate a temporary buffer to store the fully qualified file |
| 34654 | + ** name for the temporary file. If this fails, we cannot continue. |
| 34655 | + */ |
| 34656 | + nBuf = pVfs->mxPathname; |
| 34657 | + zBuf = sqlite3MallocZero( nBuf+2 ); |
| 34658 | + if( !zBuf ){ |
| 34659 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34660 | + return SQLITE_IOERR_NOMEM; |
| 34661 | + } |
| 34662 | + |
| 34663 | + /* Figure out the effective temporary directory. First, check if one |
| 34664 | + ** has been explicitly set by the application; otherwise, use the one |
| 34665 | + ** configured by the operating system. |
| 34666 | + */ |
| 34667 | + assert( nBuf>30 ); |
| 34586 | 34668 | if( sqlite3_temp_directory ){ |
| 34587 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", |
| 34588 | | - sqlite3_temp_directory); |
| 34669 | + sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34670 | + winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34671 | + winGetDirDep()); |
| 34589 | 34672 | } |
| 34590 | 34673 | #if !SQLITE_OS_WINRT |
| 34591 | | - else if( isNT() ){ |
| 34674 | + else if( osIsNT() ){ |
| 34592 | 34675 | char *zMulti; |
| 34593 | | - WCHAR zWidePath[MAX_PATH]; |
| 34594 | | - if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){ |
| 34676 | + LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34677 | + if( !zWidePath ){ |
| 34678 | + sqlite3_free(zBuf); |
| 34679 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34680 | + return SQLITE_IOERR_NOMEM; |
| 34681 | + } |
| 34682 | + if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34683 | + sqlite3_free(zWidePath); |
| 34684 | + sqlite3_free(zBuf); |
| 34595 | 34685 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34596 | 34686 | return SQLITE_IOERR_GETTEMPPATH; |
| 34597 | 34687 | } |
| 34598 | | - zMulti = unicodeToUtf8(zWidePath); |
| 34688 | + zMulti = winUnicodeToUtf8(zWidePath); |
| 34599 | 34689 | if( zMulti ){ |
| 34600 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34690 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34601 | 34691 | sqlite3_free(zMulti); |
| 34692 | + sqlite3_free(zWidePath); |
| 34602 | 34693 | }else{ |
| 34694 | + sqlite3_free(zWidePath); |
| 34695 | + sqlite3_free(zBuf); |
| 34603 | 34696 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34604 | 34697 | return SQLITE_IOERR_NOMEM; |
| 34605 | 34698 | } |
| 34606 | 34699 | } |
| 34607 | 34700 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34608 | 34701 | else{ |
| 34609 | 34702 | char *zUtf8; |
| 34610 | | - char zMbcsPath[SQLITE_WIN32_MAX_PATH]; |
| 34611 | | - if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){ |
| 34703 | + char *zMbcsPath = sqlite3MallocZero( nBuf ); |
| 34704 | + if( !zMbcsPath ){ |
| 34705 | + sqlite3_free(zBuf); |
| 34706 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34707 | + return SQLITE_IOERR_NOMEM; |
| 34708 | + } |
| 34709 | + if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34710 | + sqlite3_free(zBuf); |
| 34612 | 34711 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34613 | 34712 | return SQLITE_IOERR_GETTEMPPATH; |
| 34614 | 34713 | } |
| 34615 | 34714 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34616 | 34715 | if( zUtf8 ){ |
| 34617 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34716 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34618 | 34717 | sqlite3_free(zUtf8); |
| 34619 | 34718 | }else{ |
| 34719 | + sqlite3_free(zBuf); |
| 34620 | 34720 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34621 | 34721 | return SQLITE_IOERR_NOMEM; |
| 34622 | 34722 | } |
| 34623 | 34723 | } |
| 34624 | | -#else |
| 34625 | | - else{ |
| 34626 | | - /* |
| 34627 | | - ** Compiled without ANSI support and the current operating system |
| 34628 | | - ** is not Windows NT; therefore, just zero the temporary buffer. |
| 34629 | | - */ |
| 34630 | | - memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); |
| 34631 | | - } |
| 34632 | 34724 | #endif /* SQLITE_WIN32_HAS_ANSI */ |
| 34633 | | -#else |
| 34634 | | - else{ |
| 34635 | | - /* |
| 34636 | | - ** Compiled for WinRT and the sqlite3_temp_directory is not set; |
| 34637 | | - ** therefore, just zero the temporary buffer. |
| 34638 | | - */ |
| 34639 | | - memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); |
| 34640 | | - } |
| 34641 | 34725 | #endif /* !SQLITE_OS_WINRT */ |
| 34642 | 34726 | |
| 34643 | 34727 | /* Check that the output buffer is large enough for the temporary file |
| 34644 | 34728 | ** name. If it is not, return SQLITE_ERROR. |
| 34645 | 34729 | */ |
| 34646 | | - nTempPath = sqlite3Strlen30(zTempPath); |
| 34730 | + nLen = sqlite3Strlen30(zBuf); |
| 34647 | 34731 | |
| 34648 | | - if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34732 | + if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34733 | + sqlite3_free(zBuf); |
| 34649 | 34734 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34650 | 34735 | return SQLITE_ERROR; |
| 34651 | 34736 | } |
| 34652 | 34737 | |
| 34653 | | - for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34654 | | - zTempPath[i] = 0; |
| 34738 | + sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34655 | 34739 | |
| 34656 | | - sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ? |
| 34657 | | - "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX, |
| 34658 | | - zTempPath); |
| 34659 | 34740 | j = sqlite3Strlen30(zBuf); |
| 34660 | 34741 | sqlite3_randomness(15, &zBuf[j]); |
| 34661 | 34742 | for(i=0; i<15; i++, j++){ |
| 34662 | 34743 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34663 | 34744 | } |
| 34664 | 34745 | zBuf[j] = 0; |
| 34665 | 34746 | zBuf[j+1] = 0; |
| 34747 | + *pzBuf = zBuf; |
| 34666 | 34748 | |
| 34667 | 34749 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34668 | 34750 | return SQLITE_OK; |
| 34669 | 34751 | } |
| 34670 | 34752 | |
| | @@ -34676,17 +34758,17 @@ |
| 34676 | 34758 | static int winIsDir(const void *zConverted){ |
| 34677 | 34759 | DWORD attr; |
| 34678 | 34760 | int rc = 0; |
| 34679 | 34761 | DWORD lastErrno; |
| 34680 | 34762 | |
| 34681 | | - if( isNT() ){ |
| 34763 | + if( osIsNT() ){ |
| 34682 | 34764 | int cnt = 0; |
| 34683 | 34765 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 34684 | 34766 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 34685 | 34767 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 34686 | 34768 | GetFileExInfoStandard, |
| 34687 | | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 34769 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 34688 | 34770 | if( !rc ){ |
| 34689 | 34771 | return 0; /* Invalid name? */ |
| 34690 | 34772 | } |
| 34691 | 34773 | attr = sAttrData.dwFileAttributes; |
| 34692 | 34774 | #if SQLITE_OS_WINCE==0 |
| | @@ -34699,11 +34781,11 @@ |
| 34699 | 34781 | |
| 34700 | 34782 | /* |
| 34701 | 34783 | ** Open a file. |
| 34702 | 34784 | */ |
| 34703 | 34785 | static int winOpen( |
| 34704 | | - sqlite3_vfs *pVfs, /* Not used */ |
| 34786 | + sqlite3_vfs *pVfs, /* Used to get maximum path name length */ |
| 34705 | 34787 | const char *zName, /* Name of the file (UTF-8) */ |
| 34706 | 34788 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 34707 | 34789 | int flags, /* Open mode flags */ |
| 34708 | 34790 | int *pOutFlags /* Status return flags */ |
| 34709 | 34791 | ){ |
| | @@ -34722,11 +34804,11 @@ |
| 34722 | 34804 | int cnt = 0; |
| 34723 | 34805 | |
| 34724 | 34806 | /* If argument zPath is a NULL pointer, this function is required to open |
| 34725 | 34807 | ** a temporary file. Use this buffer to store the file name in. |
| 34726 | 34808 | */ |
| 34727 | | - char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ |
| 34809 | + char *zTmpname = 0; /* For temporary filename, if necessary. */ |
| 34728 | 34810 | |
| 34729 | 34811 | int rc = SQLITE_OK; /* Function Return Code */ |
| 34730 | 34812 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 34731 | 34813 | int eType = flags&0xFFFFFF00; /* Type of file to open */ |
| 34732 | 34814 | #endif |
| | @@ -34777,22 +34859,22 @@ |
| 34777 | 34859 | assert( pFile!=0 ); |
| 34778 | 34860 | memset(pFile, 0, sizeof(winFile)); |
| 34779 | 34861 | pFile->h = INVALID_HANDLE_VALUE; |
| 34780 | 34862 | |
| 34781 | 34863 | #if SQLITE_OS_WINRT |
| 34782 | | - if( !sqlite3_temp_directory ){ |
| 34864 | + if( !zUtf8Name && !sqlite3_temp_directory ){ |
| 34783 | 34865 | sqlite3_log(SQLITE_ERROR, |
| 34784 | 34866 | "sqlite3_temp_directory variable should be set for WinRT"); |
| 34785 | 34867 | } |
| 34786 | 34868 | #endif |
| 34787 | 34869 | |
| 34788 | 34870 | /* If the second argument to this function is NULL, generate a |
| 34789 | 34871 | ** temporary file name to use |
| 34790 | 34872 | */ |
| 34791 | 34873 | if( !zUtf8Name ){ |
| 34792 | | - assert(isDelete && !isOpenJournal); |
| 34793 | | - rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); |
| 34874 | + assert( isDelete && !isOpenJournal ); |
| 34875 | + rc = winGetTempname(pVfs, &zTmpname); |
| 34794 | 34876 | if( rc!=SQLITE_OK ){ |
| 34795 | 34877 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34796 | 34878 | return rc; |
| 34797 | 34879 | } |
| 34798 | 34880 | zUtf8Name = zTmpname; |
| | @@ -34801,21 +34883,23 @@ |
| 34801 | 34883 | /* Database filenames are double-zero terminated if they are not |
| 34802 | 34884 | ** URIs with parameters. Hence, they can always be passed into |
| 34803 | 34885 | ** sqlite3_uri_parameter(). |
| 34804 | 34886 | */ |
| 34805 | 34887 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34806 | | - zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 34888 | + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 34807 | 34889 | |
| 34808 | 34890 | /* Convert the filename to the system encoding. */ |
| 34809 | | - zConverted = convertUtf8Filename(zUtf8Name); |
| 34891 | + zConverted = winConvertUtf8Filename(zUtf8Name); |
| 34810 | 34892 | if( zConverted==0 ){ |
| 34893 | + sqlite3_free(zTmpname); |
| 34811 | 34894 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34812 | 34895 | return SQLITE_IOERR_NOMEM; |
| 34813 | 34896 | } |
| 34814 | 34897 | |
| 34815 | 34898 | if( winIsDir(zConverted) ){ |
| 34816 | 34899 | sqlite3_free(zConverted); |
| 34900 | + sqlite3_free(zTmpname); |
| 34817 | 34901 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34818 | 34902 | return SQLITE_CANTOPEN_ISDIR; |
| 34819 | 34903 | } |
| 34820 | 34904 | |
| 34821 | 34905 | if( isReadWrite ){ |
| | @@ -34858,11 +34942,11 @@ |
| 34858 | 34942 | ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ |
| 34859 | 34943 | #if SQLITE_OS_WINCE |
| 34860 | 34944 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 34861 | 34945 | #endif |
| 34862 | 34946 | |
| 34863 | | - if( isNT() ){ |
| 34947 | + if( osIsNT() ){ |
| 34864 | 34948 | #if SQLITE_OS_WINRT |
| 34865 | 34949 | CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 34866 | 34950 | extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 34867 | 34951 | extendedParameters.dwFileAttributes = |
| 34868 | 34952 | dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| | @@ -34873,21 +34957,21 @@ |
| 34873 | 34957 | while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 34874 | 34958 | dwDesiredAccess, |
| 34875 | 34959 | dwShareMode, |
| 34876 | 34960 | dwCreationDisposition, |
| 34877 | 34961 | &extendedParameters))==INVALID_HANDLE_VALUE && |
| 34878 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 34962 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34879 | 34963 | /* Noop */ |
| 34880 | 34964 | } |
| 34881 | 34965 | #else |
| 34882 | 34966 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 34883 | 34967 | dwDesiredAccess, |
| 34884 | 34968 | dwShareMode, NULL, |
| 34885 | 34969 | dwCreationDisposition, |
| 34886 | 34970 | dwFlagsAndAttributes, |
| 34887 | 34971 | NULL))==INVALID_HANDLE_VALUE && |
| 34888 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 34972 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34889 | 34973 | /* Noop */ |
| 34890 | 34974 | } |
| 34891 | 34975 | #endif |
| 34892 | 34976 | } |
| 34893 | 34977 | #ifdef SQLITE_WIN32_HAS_ANSI |
| | @@ -34896,24 +34980,25 @@ |
| 34896 | 34980 | dwDesiredAccess, |
| 34897 | 34981 | dwShareMode, NULL, |
| 34898 | 34982 | dwCreationDisposition, |
| 34899 | 34983 | dwFlagsAndAttributes, |
| 34900 | 34984 | NULL))==INVALID_HANDLE_VALUE && |
| 34901 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 34985 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34902 | 34986 | /* Noop */ |
| 34903 | 34987 | } |
| 34904 | 34988 | } |
| 34905 | 34989 | #endif |
| 34906 | | - logIoerr(cnt); |
| 34990 | + winLogIoerr(cnt); |
| 34907 | 34991 | |
| 34908 | 34992 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 34909 | 34993 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34910 | 34994 | |
| 34911 | 34995 | if( h==INVALID_HANDLE_VALUE ){ |
| 34912 | 34996 | pFile->lastErrno = lastErrno; |
| 34913 | 34997 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34914 | 34998 | sqlite3_free(zConverted); |
| 34999 | + sqlite3_free(zTmpname); |
| 34915 | 35000 | if( isReadWrite && !isExclusive ){ |
| 34916 | 35001 | return winOpen(pVfs, zName, id, |
| 34917 | 35002 | ((flags|SQLITE_OPEN_READONLY) & |
| 34918 | 35003 | ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 34919 | 35004 | pOutFlags); |
| | @@ -34938,19 +35023,21 @@ |
| 34938 | 35023 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34939 | 35024 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34940 | 35025 | ){ |
| 34941 | 35026 | osCloseHandle(h); |
| 34942 | 35027 | sqlite3_free(zConverted); |
| 35028 | + sqlite3_free(zTmpname); |
| 34943 | 35029 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 34944 | 35030 | return rc; |
| 34945 | 35031 | } |
| 34946 | 35032 | if( isTemp ){ |
| 34947 | 35033 | pFile->zDeleteOnClose = zConverted; |
| 34948 | 35034 | }else |
| 34949 | 35035 | #endif |
| 34950 | 35036 | { |
| 34951 | 35037 | sqlite3_free(zConverted); |
| 35038 | + sqlite3_free(zTmpname); |
| 34952 | 35039 | } |
| 34953 | 35040 | |
| 34954 | 35041 | pFile->pMethod = &winIoMethod; |
| 34955 | 35042 | pFile->pVfs = pVfs; |
| 34956 | 35043 | pFile->h = h; |
| | @@ -35000,15 +35087,16 @@ |
| 35000 | 35087 | UNUSED_PARAMETER(syncDir); |
| 35001 | 35088 | |
| 35002 | 35089 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 35003 | 35090 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35004 | 35091 | |
| 35005 | | - zConverted = convertUtf8Filename(zFilename); |
| 35092 | + zConverted = winConvertUtf8Filename(zFilename); |
| 35006 | 35093 | if( zConverted==0 ){ |
| 35094 | + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35007 | 35095 | return SQLITE_IOERR_NOMEM; |
| 35008 | 35096 | } |
| 35009 | | - if( isNT() ){ |
| 35097 | + if( osIsNT() ){ |
| 35010 | 35098 | do { |
| 35011 | 35099 | #if SQLITE_OS_WINRT |
| 35012 | 35100 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35013 | 35101 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35014 | 35102 | if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| | @@ -35043,11 +35131,11 @@ |
| 35043 | 35131 | } |
| 35044 | 35132 | if ( osDeleteFileW(zConverted) ){ |
| 35045 | 35133 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35046 | 35134 | break; |
| 35047 | 35135 | } |
| 35048 | | - if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35136 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35049 | 35137 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35050 | 35138 | break; |
| 35051 | 35139 | } |
| 35052 | 35140 | } while(1); |
| 35053 | 35141 | } |
| | @@ -35071,11 +35159,11 @@ |
| 35071 | 35159 | } |
| 35072 | 35160 | if ( osDeleteFileA(zConverted) ){ |
| 35073 | 35161 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35074 | 35162 | break; |
| 35075 | 35163 | } |
| 35076 | | - if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35164 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35077 | 35165 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35078 | 35166 | break; |
| 35079 | 35167 | } |
| 35080 | 35168 | } while(1); |
| 35081 | 35169 | } |
| | @@ -35082,11 +35170,11 @@ |
| 35082 | 35170 | #endif |
| 35083 | 35171 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35084 | 35172 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35085 | 35173 | "winDelete", zFilename); |
| 35086 | 35174 | }else{ |
| 35087 | | - logIoerr(cnt); |
| 35175 | + winLogIoerr(cnt); |
| 35088 | 35176 | } |
| 35089 | 35177 | sqlite3_free(zConverted); |
| 35090 | 35178 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35091 | 35179 | return rc; |
| 35092 | 35180 | } |
| | @@ -35108,22 +35196,22 @@ |
| 35108 | 35196 | |
| 35109 | 35197 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35110 | 35198 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35111 | 35199 | zFilename, flags, pResOut)); |
| 35112 | 35200 | |
| 35113 | | - zConverted = convertUtf8Filename(zFilename); |
| 35201 | + zConverted = winConvertUtf8Filename(zFilename); |
| 35114 | 35202 | if( zConverted==0 ){ |
| 35115 | 35203 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35116 | 35204 | return SQLITE_IOERR_NOMEM; |
| 35117 | 35205 | } |
| 35118 | | - if( isNT() ){ |
| 35206 | + if( osIsNT() ){ |
| 35119 | 35207 | int cnt = 0; |
| 35120 | 35208 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35121 | 35209 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35122 | 35210 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 35123 | 35211 | GetFileExInfoStandard, |
| 35124 | | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 35212 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 35125 | 35213 | if( rc ){ |
| 35126 | 35214 | /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 35127 | 35215 | ** as if it does not exist. |
| 35128 | 35216 | */ |
| 35129 | 35217 | if( flags==SQLITE_ACCESS_EXISTS |
| | @@ -35132,11 +35220,11 @@ |
| 35132 | 35220 | attr = INVALID_FILE_ATTRIBUTES; |
| 35133 | 35221 | }else{ |
| 35134 | 35222 | attr = sAttrData.dwFileAttributes; |
| 35135 | 35223 | } |
| 35136 | 35224 | }else{ |
| 35137 | | - logIoerr(cnt); |
| 35225 | + winLogIoerr(cnt); |
| 35138 | 35226 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35139 | 35227 | winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35140 | 35228 | sqlite3_free(zConverted); |
| 35141 | 35229 | return SQLITE_IOERR_ACCESS; |
| 35142 | 35230 | }else{ |
| | @@ -35183,11 +35271,11 @@ |
| 35183 | 35271 | ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 35184 | 35272 | ** "Unix" format on Windows. There is no easy way to differentiate between |
| 35185 | 35273 | ** the final two cases; therefore, we return the safer return value of TRUE |
| 35186 | 35274 | ** so that callers of this function will simply use it verbatim. |
| 35187 | 35275 | */ |
| 35188 | | - if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ |
| 35276 | + if ( winIsDirSep(zPathname[0]) ){ |
| 35189 | 35277 | return TRUE; |
| 35190 | 35278 | } |
| 35191 | 35279 | |
| 35192 | 35280 | /* |
| 35193 | 35281 | ** If the path name starts with a letter and a colon it is either a volume |
| | @@ -35219,28 +35307,33 @@ |
| 35219 | 35307 | ){ |
| 35220 | 35308 | |
| 35221 | 35309 | #if defined(__CYGWIN__) |
| 35222 | 35310 | SimulateIOError( return SQLITE_ERROR ); |
| 35223 | 35311 | UNUSED_PARAMETER(nFull); |
| 35224 | | - assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH ); |
| 35225 | 35312 | assert( nFull>=pVfs->mxPathname ); |
| 35226 | 35313 | if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 35227 | 35314 | /* |
| 35228 | 35315 | ** NOTE: We are dealing with a relative path name and the data |
| 35229 | 35316 | ** directory has been set. Therefore, use it as the basis |
| 35230 | 35317 | ** for converting the relative path name to an absolute |
| 35231 | 35318 | ** one by prepending the data directory and a slash. |
| 35232 | 35319 | */ |
| 35233 | | - char zOut[SQLITE_WIN32_MAX_PATH+1]; |
| 35320 | + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35321 | + if( !zOut ){ |
| 35322 | + winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative); |
| 35323 | + return SQLITE_IOERR_NOMEM; |
| 35324 | + } |
| 35234 | 35325 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35235 | | - SQLITE_WIN32_MAX_PATH+1)<0 ){ |
| 35326 | + pVfs->mxPathname+1)<0 ){ |
| 35236 | 35327 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35237 | 35328 | zRelative); |
| 35329 | + sqlite3_free(zOut); |
| 35238 | 35330 | return SQLITE_CANTOPEN_FULLPATH; |
| 35239 | 35331 | } |
| 35240 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35241 | | - sqlite3_data_directory, zOut); |
| 35332 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35333 | + sqlite3_data_directory, winGetDirDep(), zOut); |
| 35334 | + sqlite3_free(zOut); |
| 35242 | 35335 | }else{ |
| 35243 | 35336 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35244 | 35337 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35245 | 35338 | zRelative); |
| 35246 | 35339 | return SQLITE_CANTOPEN_FULLPATH; |
| | @@ -35258,12 +35351,12 @@ |
| 35258 | 35351 | ** NOTE: We are dealing with a relative path name and the data |
| 35259 | 35352 | ** directory has been set. Therefore, use it as the basis |
| 35260 | 35353 | ** for converting the relative path name to an absolute |
| 35261 | 35354 | ** one by prepending the data directory and a backslash. |
| 35262 | 35355 | */ |
| 35263 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35264 | | - sqlite3_data_directory, zRelative); |
| 35356 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35357 | + sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35265 | 35358 | }else{ |
| 35266 | 35359 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 35267 | 35360 | } |
| 35268 | 35361 | return SQLITE_OK; |
| 35269 | 35362 | #endif |
| | @@ -35291,19 +35384,19 @@ |
| 35291 | 35384 | ** NOTE: We are dealing with a relative path name and the data |
| 35292 | 35385 | ** directory has been set. Therefore, use it as the basis |
| 35293 | 35386 | ** for converting the relative path name to an absolute |
| 35294 | 35387 | ** one by prepending the data directory and a backslash. |
| 35295 | 35388 | */ |
| 35296 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35297 | | - sqlite3_data_directory, zRelative); |
| 35389 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35390 | + sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35298 | 35391 | return SQLITE_OK; |
| 35299 | 35392 | } |
| 35300 | | - zConverted = convertUtf8Filename(zRelative); |
| 35393 | + zConverted = winConvertUtf8Filename(zRelative); |
| 35301 | 35394 | if( zConverted==0 ){ |
| 35302 | 35395 | return SQLITE_IOERR_NOMEM; |
| 35303 | 35396 | } |
| 35304 | | - if( isNT() ){ |
| 35397 | + if( osIsNT() ){ |
| 35305 | 35398 | LPWSTR zTemp; |
| 35306 | 35399 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35307 | 35400 | if( nByte==0 ){ |
| 35308 | 35401 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35309 | 35402 | "GetFullPathNameW1", zConverted); |
| | @@ -35323,11 +35416,11 @@ |
| 35323 | 35416 | sqlite3_free(zConverted); |
| 35324 | 35417 | sqlite3_free(zTemp); |
| 35325 | 35418 | return SQLITE_CANTOPEN_FULLPATH; |
| 35326 | 35419 | } |
| 35327 | 35420 | sqlite3_free(zConverted); |
| 35328 | | - zOut = unicodeToUtf8(zTemp); |
| 35421 | + zOut = winUnicodeToUtf8(zTemp); |
| 35329 | 35422 | sqlite3_free(zTemp); |
| 35330 | 35423 | } |
| 35331 | 35424 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35332 | 35425 | else{ |
| 35333 | 35426 | char *zTemp; |
| | @@ -35376,16 +35469,16 @@ |
| 35376 | 35469 | ** Interfaces for opening a shared library, finding entry points |
| 35377 | 35470 | ** within the shared library, and closing the shared library. |
| 35378 | 35471 | */ |
| 35379 | 35472 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35380 | 35473 | HANDLE h; |
| 35381 | | - void *zConverted = convertUtf8Filename(zFilename); |
| 35474 | + void *zConverted = winConvertUtf8Filename(zFilename); |
| 35382 | 35475 | UNUSED_PARAMETER(pVfs); |
| 35383 | 35476 | if( zConverted==0 ){ |
| 35384 | 35477 | return 0; |
| 35385 | 35478 | } |
| 35386 | | - if( isNT() ){ |
| 35479 | + if( osIsNT() ){ |
| 35387 | 35480 | #if SQLITE_OS_WINRT |
| 35388 | 35481 | h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 35389 | 35482 | #else |
| 35390 | 35483 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35391 | 35484 | #endif |
| | @@ -35398,11 +35491,11 @@ |
| 35398 | 35491 | sqlite3_free(zConverted); |
| 35399 | 35492 | return (void*)h; |
| 35400 | 35493 | } |
| 35401 | 35494 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35402 | 35495 | UNUSED_PARAMETER(pVfs); |
| 35403 | | - getLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35496 | + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35404 | 35497 | } |
| 35405 | 35498 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 35406 | 35499 | UNUSED_PARAMETER(pVfs); |
| 35407 | 35500 | return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym); |
| 35408 | 35501 | } |
| | @@ -35574,21 +35667,21 @@ |
| 35574 | 35667 | ** by sqlite into the error message available to the user using |
| 35575 | 35668 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 35576 | 35669 | */ |
| 35577 | 35670 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 35578 | 35671 | UNUSED_PARAMETER(pVfs); |
| 35579 | | - return getLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35672 | + return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35580 | 35673 | } |
| 35581 | 35674 | |
| 35582 | 35675 | /* |
| 35583 | 35676 | ** Initialize and deinitialize the operating system interface. |
| 35584 | 35677 | */ |
| 35585 | 35678 | SQLITE_API int sqlite3_os_init(void){ |
| 35586 | 35679 | static sqlite3_vfs winVfs = { |
| 35587 | 35680 | 3, /* iVersion */ |
| 35588 | 35681 | sizeof(winFile), /* szOsFile */ |
| 35589 | | - SQLITE_WIN32_MAX_PATH, /* mxPathname */ |
| 35682 | + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ |
| 35590 | 35683 | 0, /* pNext */ |
| 35591 | 35684 | "win32", /* zName */ |
| 35592 | 35685 | 0, /* pAppData */ |
| 35593 | 35686 | winOpen, /* xOpen */ |
| 35594 | 35687 | winDelete, /* xDelete */ |
| | @@ -35605,10 +35698,36 @@ |
| 35605 | 35698 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35606 | 35699 | winSetSystemCall, /* xSetSystemCall */ |
| 35607 | 35700 | winGetSystemCall, /* xGetSystemCall */ |
| 35608 | 35701 | winNextSystemCall, /* xNextSystemCall */ |
| 35609 | 35702 | }; |
| 35703 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 35704 | + static sqlite3_vfs winLongPathVfs = { |
| 35705 | + 3, /* iVersion */ |
| 35706 | + sizeof(winFile), /* szOsFile */ |
| 35707 | + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ |
| 35708 | + 0, /* pNext */ |
| 35709 | + "win32-longpath", /* zName */ |
| 35710 | + 0, /* pAppData */ |
| 35711 | + winOpen, /* xOpen */ |
| 35712 | + winDelete, /* xDelete */ |
| 35713 | + winAccess, /* xAccess */ |
| 35714 | + winFullPathname, /* xFullPathname */ |
| 35715 | + winDlOpen, /* xDlOpen */ |
| 35716 | + winDlError, /* xDlError */ |
| 35717 | + winDlSym, /* xDlSym */ |
| 35718 | + winDlClose, /* xDlClose */ |
| 35719 | + winRandomness, /* xRandomness */ |
| 35720 | + winSleep, /* xSleep */ |
| 35721 | + winCurrentTime, /* xCurrentTime */ |
| 35722 | + winGetLastError, /* xGetLastError */ |
| 35723 | + winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35724 | + winSetSystemCall, /* xSetSystemCall */ |
| 35725 | + winGetSystemCall, /* xGetSystemCall */ |
| 35726 | + winNextSystemCall, /* xNextSystemCall */ |
| 35727 | + }; |
| 35728 | +#endif |
| 35610 | 35729 | |
| 35611 | 35730 | /* Double-check that the aSyscall[] array has been constructed |
| 35612 | 35731 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35613 | 35732 | assert( ArraySize(aSyscall)==74 ); |
| 35614 | 35733 | |
| | @@ -35621,10 +35740,15 @@ |
| 35621 | 35740 | #endif |
| 35622 | 35741 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35623 | 35742 | assert( winSysInfo.dwPageSize>0 ); |
| 35624 | 35743 | |
| 35625 | 35744 | sqlite3_vfs_register(&winVfs, 1); |
| 35745 | + |
| 35746 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 35747 | + sqlite3_vfs_register(&winLongPathVfs, 0); |
| 35748 | +#endif |
| 35749 | + |
| 35626 | 35750 | return SQLITE_OK; |
| 35627 | 35751 | } |
| 35628 | 35752 | |
| 35629 | 35753 | SQLITE_API int sqlite3_os_end(void){ |
| 35630 | 35754 | #if SQLITE_OS_WINRT |
| | @@ -37434,10 +37558,11 @@ |
| 37434 | 37558 | } |
| 37435 | 37559 | |
| 37436 | 37560 | if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){ |
| 37437 | 37561 | goto fetch_out; |
| 37438 | 37562 | } |
| 37563 | + assert( pCache->nHash>0 && pCache->apHash ); |
| 37439 | 37564 | |
| 37440 | 37565 | /* Step 4. Try to recycle a page. */ |
| 37441 | 37566 | if( pCache->bPurgeable && pGroup->pLruTail && ( |
| 37442 | 37567 | (pCache->nPage+1>=pCache->nMax) |
| 37443 | 37568 | || pGroup->nCurrentPage>=pGroup->nMaxPage |
| | @@ -38794,10 +38919,17 @@ |
| 38794 | 38919 | #ifndef SQLITE_OMIT_WAL |
| 38795 | 38920 | u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ |
| 38796 | 38921 | #endif |
| 38797 | 38922 | }; |
| 38798 | 38923 | |
| 38924 | +/* |
| 38925 | +** Bits of the Pager.doNotSpill flag. See further description below. |
| 38926 | +*/ |
| 38927 | +#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ |
| 38928 | +#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ |
| 38929 | +#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ |
| 38930 | + |
| 38799 | 38931 | /* |
| 38800 | 38932 | ** A open page cache is an instance of struct Pager. A description of |
| 38801 | 38933 | ** some of the more important member variables follows: |
| 38802 | 38934 | ** |
| 38803 | 38935 | ** eState |
| | @@ -38860,23 +38992,25 @@ |
| 38860 | 38992 | ** The flag is cleared as soon as the journal file is finalized (either |
| 38861 | 38993 | ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the |
| 38862 | 38994 | ** journal file from being successfully finalized, the setMaster flag |
| 38863 | 38995 | ** is cleared anyway (and the pager will move to ERROR state). |
| 38864 | 38996 | ** |
| 38865 | | -** doNotSpill, doNotSyncSpill |
| 38866 | | -** |
| 38867 | | -** These two boolean variables control the behavior of cache-spills |
| 38868 | | -** (calls made by the pcache module to the pagerStress() routine to |
| 38869 | | -** write cached data to the file-system in order to free up memory). |
| 38870 | | -** |
| 38871 | | -** When doNotSpill is non-zero, writing to the database from pagerStress() |
| 38872 | | -** is disabled altogether. This is done in a very obscure case that |
| 38997 | +** doNotSpill |
| 38998 | +** |
| 38999 | +** This variables control the behavior of cache-spills (calls made by |
| 39000 | +** the pcache module to the pagerStress() routine to write cached data |
| 39001 | +** to the file-system in order to free up memory). |
| 39002 | +** |
| 39003 | +** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, |
| 39004 | +** writing to the database from pagerStress() is disabled altogether. |
| 39005 | +** The SPILLFLAG_ROLLBACK case is done in a very obscure case that |
| 38873 | 39006 | ** comes up during savepoint rollback that requires the pcache module |
| 38874 | 39007 | ** to allocate a new page to prevent the journal file from being written |
| 38875 | | -** while it is being traversed by code in pager_playback(). |
| 39008 | +** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF |
| 39009 | +** case is a user preference. |
| 38876 | 39010 | ** |
| 38877 | | -** If doNotSyncSpill is non-zero, writing to the database from pagerStress() |
| 39011 | +** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress() |
| 38878 | 39012 | ** is permitted, but syncing the journal file is not. This flag is set |
| 38879 | 39013 | ** by sqlite3PagerWrite() when the file-system sector-size is larger than |
| 38880 | 39014 | ** the database page-size in order to prevent a journal sync from happening |
| 38881 | 39015 | ** in between the journalling of two pages on the same sector. |
| 38882 | 39016 | ** |
| | @@ -38976,11 +39110,10 @@ |
| 38976 | 39110 | u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ |
| 38977 | 39111 | u8 eLock; /* Current lock held on database file */ |
| 38978 | 39112 | u8 changeCountDone; /* Set after incrementing the change-counter */ |
| 38979 | 39113 | u8 setMaster; /* True if a m-j name has been written to jrnl */ |
| 38980 | 39114 | u8 doNotSpill; /* Do not spill the cache when non-zero */ |
| 38981 | | - u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */ |
| 38982 | 39115 | u8 subjInMemory; /* True to use in-memory sub-journals */ |
| 38983 | 39116 | Pgno dbSize; /* Number of pages in the database */ |
| 38984 | 39117 | Pgno dbOrigSize; /* dbSize before the current transaction */ |
| 38985 | 39118 | Pgno dbFileSize; /* Number of pages in the database file */ |
| 38986 | 39119 | Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ |
| | @@ -39355,17 +39488,21 @@ |
| 39355 | 39488 | ** * The page-number is less than or equal to PagerSavepoint.nOrig, and |
| 39356 | 39489 | ** * The bit corresponding to the page-number is not set in |
| 39357 | 39490 | ** PagerSavepoint.pInSavepoint. |
| 39358 | 39491 | */ |
| 39359 | 39492 | static int subjRequiresPage(PgHdr *pPg){ |
| 39360 | | - Pgno pgno = pPg->pgno; |
| 39361 | 39493 | Pager *pPager = pPg->pPager; |
| 39494 | + PagerSavepoint *p; |
| 39495 | + Pgno pgno; |
| 39362 | 39496 | int i; |
| 39363 | | - for(i=0; i<pPager->nSavepoint; i++){ |
| 39364 | | - PagerSavepoint *p = &pPager->aSavepoint[i]; |
| 39365 | | - if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ |
| 39366 | | - return 1; |
| 39497 | + if( pPager->nSavepoint ){ |
| 39498 | + pgno = pPg->pgno; |
| 39499 | + for(i=0; i<pPager->nSavepoint; i++){ |
| 39500 | + p = &pPager->aSavepoint[i]; |
| 39501 | + if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ |
| 39502 | + return 1; |
| 39503 | + } |
| 39367 | 39504 | } |
| 39368 | 39505 | } |
| 39369 | 39506 | return 0; |
| 39370 | 39507 | } |
| 39371 | 39508 | |
| | @@ -40636,15 +40773,15 @@ |
| 40636 | 40773 | ** the data just read from the sub-journal. Mark the page as dirty |
| 40637 | 40774 | ** and if the pager requires a journal-sync, then mark the page as |
| 40638 | 40775 | ** requiring a journal-sync before it is written. |
| 40639 | 40776 | */ |
| 40640 | 40777 | assert( isSavepnt ); |
| 40641 | | - assert( pPager->doNotSpill==0 ); |
| 40642 | | - pPager->doNotSpill++; |
| 40778 | + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); |
| 40779 | + pPager->doNotSpill |= SPILLFLAG_ROLLBACK; |
| 40643 | 40780 | rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); |
| 40644 | | - assert( pPager->doNotSpill==1 ); |
| 40645 | | - pPager->doNotSpill--; |
| 40781 | + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); |
| 40782 | + pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; |
| 40646 | 40783 | if( rc!=SQLITE_OK ) return rc; |
| 40647 | 40784 | pPg->flags &= ~PGHDR_NEED_READ; |
| 40648 | 40785 | sqlite3PcacheMakeDirty(pPg); |
| 40649 | 40786 | } |
| 40650 | 40787 | if( pPg ){ |
| | @@ -41207,16 +41344,10 @@ |
| 41207 | 41344 | int pgsz = pPager->pageSize; /* Number of bytes to read */ |
| 41208 | 41345 | |
| 41209 | 41346 | assert( pPager->eState>=PAGER_READER && !MEMDB ); |
| 41210 | 41347 | assert( isOpen(pPager->fd) ); |
| 41211 | 41348 | |
| 41212 | | - if( NEVER(!isOpen(pPager->fd)) ){ |
| 41213 | | - assert( pPager->tempFile ); |
| 41214 | | - memset(pPg->pData, 0, pPager->pageSize); |
| 41215 | | - return SQLITE_OK; |
| 41216 | | - } |
| 41217 | | - |
| 41218 | 41349 | #ifndef SQLITE_OMIT_WAL |
| 41219 | 41350 | if( iFrame ){ |
| 41220 | 41351 | /* Try to pull the page from the write-ahead log. */ |
| 41221 | 41352 | rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); |
| 41222 | 41353 | }else |
| | @@ -41745,13 +41876,16 @@ |
| 41745 | 41876 | SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ |
| 41746 | 41877 | sqlite3PcacheShrink(pPager->pPCache); |
| 41747 | 41878 | } |
| 41748 | 41879 | |
| 41749 | 41880 | /* |
| 41750 | | -** Adjust the robustness of the database to damage due to OS crashes |
| 41751 | | -** or power failures by changing the number of syncs()s when writing |
| 41752 | | -** the rollback journal. There are three levels: |
| 41881 | +** Adjust settings of the pager to those specified in the pgFlags parameter. |
| 41882 | +** |
| 41883 | +** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness |
| 41884 | +** of the database to damage due to OS crashes or power failures by |
| 41885 | +** changing the number of syncs()s when writing the journals. |
| 41886 | +** There are three levels: |
| 41753 | 41887 | ** |
| 41754 | 41888 | ** OFF sqlite3OsSync() is never called. This is the default |
| 41755 | 41889 | ** for temporary and transient files. |
| 41756 | 41890 | ** |
| 41757 | 41891 | ** NORMAL The journal is synced once before writes begin on the |
| | @@ -41788,26 +41922,25 @@ |
| 41788 | 41922 | ** |
| 41789 | 41923 | ** Numeric values associated with these states are OFF==1, NORMAL=2, |
| 41790 | 41924 | ** and FULL=3. |
| 41791 | 41925 | */ |
| 41792 | 41926 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 41793 | | -SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel( |
| 41927 | +SQLITE_PRIVATE void sqlite3PagerSetFlags( |
| 41794 | 41928 | Pager *pPager, /* The pager to set safety level for */ |
| 41795 | | - int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ |
| 41796 | | - int bFullFsync, /* PRAGMA fullfsync */ |
| 41797 | | - int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */ |
| 41929 | + unsigned pgFlags /* Various flags */ |
| 41798 | 41930 | ){ |
| 41931 | + unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; |
| 41799 | 41932 | assert( level>=1 && level<=3 ); |
| 41800 | 41933 | pPager->noSync = (level==1 || pPager->tempFile) ?1:0; |
| 41801 | 41934 | pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; |
| 41802 | 41935 | if( pPager->noSync ){ |
| 41803 | 41936 | pPager->syncFlags = 0; |
| 41804 | 41937 | pPager->ckptSyncFlags = 0; |
| 41805 | | - }else if( bFullFsync ){ |
| 41938 | + }else if( pgFlags & PAGER_FULLFSYNC ){ |
| 41806 | 41939 | pPager->syncFlags = SQLITE_SYNC_FULL; |
| 41807 | 41940 | pPager->ckptSyncFlags = SQLITE_SYNC_FULL; |
| 41808 | | - }else if( bCkptFullFsync ){ |
| 41941 | + }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ |
| 41809 | 41942 | pPager->syncFlags = SQLITE_SYNC_NORMAL; |
| 41810 | 41943 | pPager->ckptSyncFlags = SQLITE_SYNC_FULL; |
| 41811 | 41944 | }else{ |
| 41812 | 41945 | pPager->syncFlags = SQLITE_SYNC_NORMAL; |
| 41813 | 41946 | pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; |
| | @@ -41814,10 +41947,15 @@ |
| 41814 | 41947 | } |
| 41815 | 41948 | pPager->walSyncFlags = pPager->syncFlags; |
| 41816 | 41949 | if( pPager->fullSync ){ |
| 41817 | 41950 | pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; |
| 41818 | 41951 | } |
| 41952 | + if( pgFlags & PAGER_CACHESPILL ){ |
| 41953 | + pPager->doNotSpill &= ~SPILLFLAG_OFF; |
| 41954 | + }else{ |
| 41955 | + pPager->doNotSpill |= SPILLFLAG_OFF; |
| 41956 | + } |
| 41819 | 41957 | } |
| 41820 | 41958 | #endif |
| 41821 | 41959 | |
| 41822 | 41960 | /* |
| 41823 | 41961 | ** The following global variable is incremented whenever the library |
| | @@ -42714,28 +42852,34 @@ |
| 42714 | 42852 | int rc = SQLITE_OK; |
| 42715 | 42853 | |
| 42716 | 42854 | assert( pPg->pPager==pPager ); |
| 42717 | 42855 | assert( pPg->flags&PGHDR_DIRTY ); |
| 42718 | 42856 | |
| 42719 | | - /* The doNotSyncSpill flag is set during times when doing a sync of |
| 42857 | + /* The doNotSpill NOSYNC bit is set during times when doing a sync of |
| 42720 | 42858 | ** journal (and adding a new header) is not allowed. This occurs |
| 42721 | 42859 | ** during calls to sqlite3PagerWrite() while trying to journal multiple |
| 42722 | 42860 | ** pages belonging to the same sector. |
| 42723 | 42861 | ** |
| 42724 | | - ** The doNotSpill flag inhibits all cache spilling regardless of whether |
| 42725 | | - ** or not a sync is required. This is set during a rollback. |
| 42862 | + ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling |
| 42863 | + ** regardless of whether or not a sync is required. This is set during |
| 42864 | + ** a rollback or by user request, respectively. |
| 42726 | 42865 | ** |
| 42727 | 42866 | ** Spilling is also prohibited when in an error state since that could |
| 42728 | 42867 | ** lead to database corruption. In the current implementaton it |
| 42729 | 42868 | ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 |
| 42730 | 42869 | ** while in the error state, hence it is impossible for this routine to |
| 42731 | 42870 | ** be called in the error state. Nevertheless, we include a NEVER() |
| 42732 | 42871 | ** test for the error state as a safeguard against future changes. |
| 42733 | 42872 | */ |
| 42734 | 42873 | if( NEVER(pPager->errCode) ) return SQLITE_OK; |
| 42735 | | - if( pPager->doNotSpill ) return SQLITE_OK; |
| 42736 | | - if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ |
| 42874 | + testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); |
| 42875 | + testcase( pPager->doNotSpill & SPILLFLAG_OFF ); |
| 42876 | + testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); |
| 42877 | + if( pPager->doNotSpill |
| 42878 | + && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 |
| 42879 | + || (pPg->flags & PGHDR_NEED_SYNC)!=0) |
| 42880 | + ){ |
| 42737 | 42881 | return SQLITE_OK; |
| 42738 | 42882 | } |
| 42739 | 42883 | |
| 42740 | 42884 | pPg->pDirty = 0; |
| 42741 | 42885 | if( pagerUseWal(pPager) ){ |
| | @@ -43553,23 +43697,23 @@ |
| 43553 | 43697 | */ |
| 43554 | 43698 | SQLITE_PRIVATE int sqlite3PagerAcquire( |
| 43555 | 43699 | Pager *pPager, /* The pager open on the database file */ |
| 43556 | 43700 | Pgno pgno, /* Page number to fetch */ |
| 43557 | 43701 | DbPage **ppPage, /* Write a pointer to the page here */ |
| 43558 | | - int flags /* PAGER_ACQUIRE_XXX flags */ |
| 43702 | + int flags /* PAGER_GET_XXX flags */ |
| 43559 | 43703 | ){ |
| 43560 | 43704 | int rc = SQLITE_OK; |
| 43561 | 43705 | PgHdr *pPg = 0; |
| 43562 | 43706 | u32 iFrame = 0; /* Frame to read from WAL file */ |
| 43563 | | - const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT); |
| 43707 | + const int noContent = (flags & PAGER_GET_NOCONTENT); |
| 43564 | 43708 | |
| 43565 | 43709 | /* It is acceptable to use a read-only (mmap) page for any page except |
| 43566 | 43710 | ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY |
| 43567 | 43711 | ** flag was specified by the caller. And so long as the db is not a |
| 43568 | 43712 | ** temporary or in-memory database. */ |
| 43569 | 43713 | const int bMmapOk = (pgno!=1 && USEFETCH(pPager) |
| 43570 | | - && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY)) |
| 43714 | + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) |
| 43571 | 43715 | #ifdef SQLITE_HAS_CODEC |
| 43572 | 43716 | && pPager->xCodec==0 |
| 43573 | 43717 | #endif |
| 43574 | 43718 | ); |
| 43575 | 43719 | |
| | @@ -44085,17 +44229,17 @@ |
| 44085 | 44229 | Pgno pg1; /* First page of the sector pPg is located on. */ |
| 44086 | 44230 | int nPage = 0; /* Number of pages starting at pg1 to journal */ |
| 44087 | 44231 | int ii; /* Loop counter */ |
| 44088 | 44232 | int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 44089 | 44233 | |
| 44090 | | - /* Set the doNotSyncSpill flag to 1. This is because we cannot allow |
| 44234 | + /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow |
| 44091 | 44235 | ** a journal header to be written between the pages journaled by |
| 44092 | 44236 | ** this function. |
| 44093 | 44237 | */ |
| 44094 | 44238 | assert( !MEMDB ); |
| 44095 | | - assert( pPager->doNotSyncSpill==0 ); |
| 44096 | | - pPager->doNotSyncSpill++; |
| 44239 | + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); |
| 44240 | + pPager->doNotSpill |= SPILLFLAG_NOSYNC; |
| 44097 | 44241 | |
| 44098 | 44242 | /* This trick assumes that both the page-size and sector-size are |
| 44099 | 44243 | ** an integer power of 2. It sets variable pg1 to the identifier |
| 44100 | 44244 | ** of the first page of the sector pPg is located on. |
| 44101 | 44245 | */ |
| | @@ -44150,12 +44294,12 @@ |
| 44150 | 44294 | sqlite3PagerUnref(pPage); |
| 44151 | 44295 | } |
| 44152 | 44296 | } |
| 44153 | 44297 | } |
| 44154 | 44298 | |
| 44155 | | - assert( pPager->doNotSyncSpill==1 ); |
| 44156 | | - pPager->doNotSyncSpill--; |
| 44299 | + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); |
| 44300 | + pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; |
| 44157 | 44301 | }else{ |
| 44158 | 44302 | rc = pager_write(pDbPage); |
| 44159 | 44303 | } |
| 44160 | 44304 | return rc; |
| 44161 | 44305 | } |
| | @@ -49147,18 +49291,23 @@ |
| 49147 | 49291 | }; |
| 49148 | 49292 | |
| 49149 | 49293 | /* |
| 49150 | 49294 | ** Potential values for BtCursor.eState. |
| 49151 | 49295 | ** |
| 49152 | | -** CURSOR_VALID: |
| 49153 | | -** Cursor points to a valid entry. getPayload() etc. may be called. |
| 49154 | | -** |
| 49155 | 49296 | ** CURSOR_INVALID: |
| 49156 | 49297 | ** Cursor does not point to a valid entry. This can happen (for example) |
| 49157 | 49298 | ** because the table is empty or because BtreeCursorFirst() has not been |
| 49158 | 49299 | ** called. |
| 49159 | 49300 | ** |
| 49301 | +** CURSOR_VALID: |
| 49302 | +** Cursor points to a valid entry. getPayload() etc. may be called. |
| 49303 | +** |
| 49304 | +** CURSOR_SKIPNEXT: |
| 49305 | +** Cursor is valid except that the Cursor.skipNext field is non-zero |
| 49306 | +** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() |
| 49307 | +** operation should be a no-op. |
| 49308 | +** |
| 49160 | 49309 | ** CURSOR_REQUIRESEEK: |
| 49161 | 49310 | ** The table that this cursor was opened on still exists, but has been |
| 49162 | 49311 | ** modified since the cursor was last used. The cursor position is saved |
| 49163 | 49312 | ** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in |
| 49164 | 49313 | ** this state, restoreCursorPosition() can be called to attempt to |
| | @@ -49171,12 +49320,13 @@ |
| 49171 | 49320 | ** Do nothing else with this cursor. Any attempt to use the cursor |
| 49172 | 49321 | ** should return the error code stored in BtCursor.skip |
| 49173 | 49322 | */ |
| 49174 | 49323 | #define CURSOR_INVALID 0 |
| 49175 | 49324 | #define CURSOR_VALID 1 |
| 49176 | | -#define CURSOR_REQUIRESEEK 2 |
| 49177 | | -#define CURSOR_FAULT 3 |
| 49325 | +#define CURSOR_SKIPNEXT 2 |
| 49326 | +#define CURSOR_REQUIRESEEK 3 |
| 49327 | +#define CURSOR_FAULT 4 |
| 49178 | 49328 | |
| 49179 | 49329 | /* |
| 49180 | 49330 | ** The database page the PENDING_BYTE occupies. This page is never used. |
| 49181 | 49331 | */ |
| 49182 | 49332 | # define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) |
| | @@ -50286,10 +50436,13 @@ |
| 50286 | 50436 | rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext); |
| 50287 | 50437 | if( rc==SQLITE_OK ){ |
| 50288 | 50438 | sqlite3_free(pCur->pKey); |
| 50289 | 50439 | pCur->pKey = 0; |
| 50290 | 50440 | assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); |
| 50441 | + if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ |
| 50442 | + pCur->eState = CURSOR_SKIPNEXT; |
| 50443 | + } |
| 50291 | 50444 | } |
| 50292 | 50445 | return rc; |
| 50293 | 50446 | } |
| 50294 | 50447 | |
| 50295 | 50448 | #define restoreCursorPosition(p) \ |
| | @@ -50311,11 +50464,11 @@ |
| 50311 | 50464 | rc = restoreCursorPosition(pCur); |
| 50312 | 50465 | if( rc ){ |
| 50313 | 50466 | *pHasMoved = 1; |
| 50314 | 50467 | return rc; |
| 50315 | 50468 | } |
| 50316 | | - if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){ |
| 50469 | + if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){ |
| 50317 | 50470 | *pHasMoved = 1; |
| 50318 | 50471 | }else{ |
| 50319 | 50472 | *pHasMoved = 0; |
| 50320 | 50473 | } |
| 50321 | 50474 | return SQLITE_OK; |
| | @@ -50499,11 +50652,12 @@ |
| 50499 | 50652 | assert( pPage->leaf==0 || pPage->leaf==1 ); |
| 50500 | 50653 | n = pPage->childPtrSize; |
| 50501 | 50654 | assert( n==4-4*pPage->leaf ); |
| 50502 | 50655 | if( pPage->intKey ){ |
| 50503 | 50656 | if( pPage->hasData ){ |
| 50504 | | - n += getVarint32(&pCell[n], nPayload); |
| 50657 | + assert( n==0 ); |
| 50658 | + n = getVarint32(pCell, nPayload); |
| 50505 | 50659 | }else{ |
| 50506 | 50660 | nPayload = 0; |
| 50507 | 50661 | } |
| 50508 | 50662 | n += getVarint(&pCell[n], (u64*)&pInfo->nKey); |
| 50509 | 50663 | pInfo->nData = nPayload; |
| | @@ -51143,19 +51297,16 @@ |
| 51143 | 51297 | */ |
| 51144 | 51298 | static int btreeGetPage( |
| 51145 | 51299 | BtShared *pBt, /* The btree */ |
| 51146 | 51300 | Pgno pgno, /* Number of the page to fetch */ |
| 51147 | 51301 | MemPage **ppPage, /* Return the page in this parameter */ |
| 51148 | | - int noContent, /* Do not load page content if true */ |
| 51149 | | - int bReadonly /* True if a read-only (mmap) page is ok */ |
| 51302 | + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ |
| 51150 | 51303 | ){ |
| 51151 | 51304 | int rc; |
| 51152 | 51305 | DbPage *pDbPage; |
| 51153 | | - int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0) |
| 51154 | | - | (bReadonly ? PAGER_ACQUIRE_READONLY : 0); |
| 51155 | 51306 | |
| 51156 | | - assert( noContent==0 || bReadonly==0 ); |
| 51307 | + assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); |
| 51157 | 51308 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51158 | 51309 | rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); |
| 51159 | 51310 | if( rc ) return rc; |
| 51160 | 51311 | *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); |
| 51161 | 51312 | return SQLITE_OK; |
| | @@ -51199,19 +51350,20 @@ |
| 51199 | 51350 | */ |
| 51200 | 51351 | static int getAndInitPage( |
| 51201 | 51352 | BtShared *pBt, /* The database file */ |
| 51202 | 51353 | Pgno pgno, /* Number of the page to get */ |
| 51203 | 51354 | MemPage **ppPage, /* Write the page pointer here */ |
| 51204 | | - int bReadonly /* True if a read-only (mmap) page is ok */ |
| 51355 | + int bReadonly /* PAGER_GET_READONLY or 0 */ |
| 51205 | 51356 | ){ |
| 51206 | 51357 | int rc; |
| 51207 | 51358 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51359 | + assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 ); |
| 51208 | 51360 | |
| 51209 | 51361 | if( pgno>btreePagecount(pBt) ){ |
| 51210 | 51362 | rc = SQLITE_CORRUPT_BKPT; |
| 51211 | 51363 | }else{ |
| 51212 | | - rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly); |
| 51364 | + rc = btreeGetPage(pBt, pgno, ppPage, bReadonly); |
| 51213 | 51365 | if( rc==SQLITE_OK ){ |
| 51214 | 51366 | rc = btreeInitPage(*ppPage); |
| 51215 | 51367 | if( rc!=SQLITE_OK ){ |
| 51216 | 51368 | releasePage(*ppPage); |
| 51217 | 51369 | } |
| | @@ -51727,21 +51879,18 @@ |
| 51727 | 51879 | ** there is a high probability of damage) Level 2 is the default. There |
| 51728 | 51880 | ** is a very low but non-zero probability of damage. Level 3 reduces the |
| 51729 | 51881 | ** probability of damage to near zero but with a write performance reduction. |
| 51730 | 51882 | */ |
| 51731 | 51883 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 51732 | | -SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel( |
| 51884 | +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( |
| 51733 | 51885 | Btree *p, /* The btree to set the safety level on */ |
| 51734 | | - int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */ |
| 51735 | | - int fullSync, /* PRAGMA fullfsync. */ |
| 51736 | | - int ckptFullSync /* PRAGMA checkpoint_fullfync */ |
| 51886 | + unsigned pgFlags /* Various PAGER_* flags */ |
| 51737 | 51887 | ){ |
| 51738 | 51888 | BtShared *pBt = p->pBt; |
| 51739 | 51889 | assert( sqlite3_mutex_held(p->db->mutex) ); |
| 51740 | | - assert( level>=1 && level<=3 ); |
| 51741 | 51890 | sqlite3BtreeEnter(p); |
| 51742 | | - sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync); |
| 51891 | + sqlite3PagerSetFlags(pBt->pPager, pgFlags); |
| 51743 | 51892 | sqlite3BtreeLeave(p); |
| 51744 | 51893 | return SQLITE_OK; |
| 51745 | 51894 | } |
| 51746 | 51895 | #endif |
| 51747 | 51896 | |
| | @@ -51943,11 +52092,11 @@ |
| 51943 | 52092 | |
| 51944 | 52093 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51945 | 52094 | assert( pBt->pPage1==0 ); |
| 51946 | 52095 | rc = sqlite3PagerSharedLock(pBt->pPager); |
| 51947 | 52096 | if( rc!=SQLITE_OK ) return rc; |
| 51948 | | - rc = btreeGetPage(pBt, 1, &pPage1, 0, 0); |
| 52097 | + rc = btreeGetPage(pBt, 1, &pPage1, 0); |
| 51949 | 52098 | if( rc!=SQLITE_OK ) return rc; |
| 51950 | 52099 | |
| 51951 | 52100 | /* Do some checking to help insure the file we opened really is |
| 51952 | 52101 | ** a valid database file. |
| 51953 | 52102 | */ |
| | @@ -52071,10 +52220,11 @@ |
| 52071 | 52220 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52072 | 52221 | } |
| 52073 | 52222 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52074 | 52223 | pBt->pPage1 = pPage1; |
| 52075 | 52224 | pBt->nPage = nPage; |
| 52225 | +assert( pPage1->leaf==0 || pPage1->leaf==1 ); |
| 52076 | 52226 | return SQLITE_OK; |
| 52077 | 52227 | |
| 52078 | 52228 | page1_init_failed: |
| 52079 | 52229 | releasePage(pPage1); |
| 52080 | 52230 | pBt->pPage1 = 0; |
| | @@ -52525,11 +52675,11 @@ |
| 52525 | 52675 | /* Fix the database pointer on page iPtrPage that pointed at iDbPage so |
| 52526 | 52676 | ** that it points at iFreePage. Also fix the pointer map entry for |
| 52527 | 52677 | ** iPtrPage. |
| 52528 | 52678 | */ |
| 52529 | 52679 | if( eType!=PTRMAP_ROOTPAGE ){ |
| 52530 | | - rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0); |
| 52680 | + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); |
| 52531 | 52681 | if( rc!=SQLITE_OK ){ |
| 52532 | 52682 | return rc; |
| 52533 | 52683 | } |
| 52534 | 52684 | rc = sqlite3PagerWrite(pPtrPage->pDbPage); |
| 52535 | 52685 | if( rc!=SQLITE_OK ){ |
| | @@ -52609,11 +52759,11 @@ |
| 52609 | 52759 | Pgno iFreePg; /* Index of free page to move pLastPg to */ |
| 52610 | 52760 | MemPage *pLastPg; |
| 52611 | 52761 | u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ |
| 52612 | 52762 | Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ |
| 52613 | 52763 | |
| 52614 | | - rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0); |
| 52764 | + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); |
| 52615 | 52765 | if( rc!=SQLITE_OK ){ |
| 52616 | 52766 | return rc; |
| 52617 | 52767 | } |
| 52618 | 52768 | |
| 52619 | 52769 | /* If bCommit is zero, this loop runs exactly once and page pLastPg |
| | @@ -53008,11 +53158,11 @@ |
| 53008 | 53158 | } |
| 53009 | 53159 | |
| 53010 | 53160 | /* The rollback may have destroyed the pPage1->aData value. So |
| 53011 | 53161 | ** call btreeGetPage() on page 1 again to make |
| 53012 | 53162 | ** sure pPage1->aData is set correctly. */ |
| 53013 | | - if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){ |
| 53163 | + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ |
| 53014 | 53164 | int nPage = get4byte(28+(u8*)pPage1->aData); |
| 53015 | 53165 | testcase( nPage==0 ); |
| 53016 | 53166 | if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); |
| 53017 | 53167 | testcase( pBt->nPage!=nPage ); |
| 53018 | 53168 | pBt->nPage = nPage; |
| | @@ -53443,11 +53593,11 @@ |
| 53443 | 53593 | } |
| 53444 | 53594 | #endif |
| 53445 | 53595 | |
| 53446 | 53596 | assert( next==0 || rc==SQLITE_DONE ); |
| 53447 | 53597 | if( rc==SQLITE_OK ){ |
| 53448 | | - rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0)); |
| 53598 | + rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0); |
| 53449 | 53599 | assert( rc==SQLITE_OK || pPage==0 ); |
| 53450 | 53600 | if( rc==SQLITE_OK ){ |
| 53451 | 53601 | next = get4byte(pPage->aData); |
| 53452 | 53602 | } |
| 53453 | 53603 | } |
| | @@ -53665,11 +53815,11 @@ |
| 53665 | 53815 | #endif |
| 53666 | 53816 | |
| 53667 | 53817 | { |
| 53668 | 53818 | DbPage *pDbPage; |
| 53669 | 53819 | rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, |
| 53670 | | - (eOp==0 ? PAGER_ACQUIRE_READONLY : 0) |
| 53820 | + (eOp==0 ? PAGER_GET_READONLY : 0) |
| 53671 | 53821 | ); |
| 53672 | 53822 | if( rc==SQLITE_OK ){ |
| 53673 | 53823 | aPayload = sqlite3PagerGetData(pDbPage); |
| 53674 | 53824 | nextPage = get4byte(aPayload); |
| 53675 | 53825 | rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); |
| | @@ -53849,11 +53999,12 @@ |
| 53849 | 53999 | assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); |
| 53850 | 54000 | assert( pCur->iPage>=0 ); |
| 53851 | 54001 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ |
| 53852 | 54002 | return SQLITE_CORRUPT_BKPT; |
| 53853 | 54003 | } |
| 53854 | | - rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0)); |
| 54004 | + rc = getAndInitPage(pBt, newPgno, &pNewPage, |
| 54005 | + pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 53855 | 54006 | if( rc ) return rc; |
| 53856 | 54007 | pCur->apPage[i+1] = pNewPage; |
| 53857 | 54008 | pCur->aiIdx[i+1] = 0; |
| 53858 | 54009 | pCur->iPage++; |
| 53859 | 54010 | |
| | @@ -53966,11 +54117,12 @@ |
| 53966 | 54117 | pCur->iPage = 0; |
| 53967 | 54118 | }else if( pCur->pgnoRoot==0 ){ |
| 53968 | 54119 | pCur->eState = CURSOR_INVALID; |
| 53969 | 54120 | return SQLITE_OK; |
| 53970 | 54121 | }else{ |
| 53971 | | - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0); |
| 54122 | + rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], |
| 54123 | + pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 53972 | 54124 | if( rc!=SQLITE_OK ){ |
| 53973 | 54125 | pCur->eState = CURSOR_INVALID; |
| 53974 | 54126 | return rc; |
| 53975 | 54127 | } |
| 53976 | 54128 | pCur->iPage = 0; |
| | @@ -54361,25 +54513,33 @@ |
| 54361 | 54513 | int rc; |
| 54362 | 54514 | int idx; |
| 54363 | 54515 | MemPage *pPage; |
| 54364 | 54516 | |
| 54365 | 54517 | assert( cursorHoldsMutex(pCur) ); |
| 54366 | | - rc = restoreCursorPosition(pCur); |
| 54367 | | - if( rc!=SQLITE_OK ){ |
| 54368 | | - return rc; |
| 54369 | | - } |
| 54370 | 54518 | assert( pRes!=0 ); |
| 54371 | | - if( CURSOR_INVALID==pCur->eState ){ |
| 54372 | | - *pRes = 1; |
| 54373 | | - return SQLITE_OK; |
| 54374 | | - } |
| 54375 | | - if( pCur->skipNext>0 ){ |
| 54376 | | - pCur->skipNext = 0; |
| 54377 | | - *pRes = 0; |
| 54378 | | - return SQLITE_OK; |
| 54379 | | - } |
| 54380 | | - pCur->skipNext = 0; |
| 54519 | + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 54520 | + if( pCur->eState!=CURSOR_VALID ){ |
| 54521 | + rc = restoreCursorPosition(pCur); |
| 54522 | + if( rc!=SQLITE_OK ){ |
| 54523 | + *pRes = 0; |
| 54524 | + return rc; |
| 54525 | + } |
| 54526 | + if( CURSOR_INVALID==pCur->eState ){ |
| 54527 | + *pRes = 1; |
| 54528 | + return SQLITE_OK; |
| 54529 | + } |
| 54530 | + if( pCur->skipNext ){ |
| 54531 | + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); |
| 54532 | + pCur->eState = CURSOR_VALID; |
| 54533 | + if( pCur->skipNext>0 ){ |
| 54534 | + pCur->skipNext = 0; |
| 54535 | + *pRes = 0; |
| 54536 | + return SQLITE_OK; |
| 54537 | + } |
| 54538 | + pCur->skipNext = 0; |
| 54539 | + } |
| 54540 | + } |
| 54381 | 54541 | |
| 54382 | 54542 | pPage = pCur->apPage[pCur->iPage]; |
| 54383 | 54543 | idx = ++pCur->aiIdx[pCur->iPage]; |
| 54384 | 54544 | assert( pPage->isInit ); |
| 54385 | 54545 | |
| | @@ -54393,11 +54553,14 @@ |
| 54393 | 54553 | pCur->info.nSize = 0; |
| 54394 | 54554 | pCur->validNKey = 0; |
| 54395 | 54555 | if( idx>=pPage->nCell ){ |
| 54396 | 54556 | if( !pPage->leaf ){ |
| 54397 | 54557 | rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); |
| 54398 | | - if( rc ) return rc; |
| 54558 | + if( rc ){ |
| 54559 | + *pRes = 0; |
| 54560 | + return rc; |
| 54561 | + } |
| 54399 | 54562 | rc = moveToLeftmost(pCur); |
| 54400 | 54563 | *pRes = 0; |
| 54401 | 54564 | return rc; |
| 54402 | 54565 | } |
| 54403 | 54566 | do{ |
| | @@ -54435,32 +54598,44 @@ |
| 54435 | 54598 | SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ |
| 54436 | 54599 | int rc; |
| 54437 | 54600 | MemPage *pPage; |
| 54438 | 54601 | |
| 54439 | 54602 | assert( cursorHoldsMutex(pCur) ); |
| 54440 | | - rc = restoreCursorPosition(pCur); |
| 54441 | | - if( rc!=SQLITE_OK ){ |
| 54442 | | - return rc; |
| 54443 | | - } |
| 54603 | + assert( pRes!=0 ); |
| 54604 | + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 54444 | 54605 | pCur->atLast = 0; |
| 54445 | | - if( CURSOR_INVALID==pCur->eState ){ |
| 54446 | | - *pRes = 1; |
| 54447 | | - return SQLITE_OK; |
| 54448 | | - } |
| 54449 | | - if( pCur->skipNext<0 ){ |
| 54450 | | - pCur->skipNext = 0; |
| 54451 | | - *pRes = 0; |
| 54452 | | - return SQLITE_OK; |
| 54453 | | - } |
| 54454 | | - pCur->skipNext = 0; |
| 54606 | + if( pCur->eState!=CURSOR_VALID ){ |
| 54607 | + if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ |
| 54608 | + rc = btreeRestoreCursorPosition(pCur); |
| 54609 | + if( rc!=SQLITE_OK ){ |
| 54610 | + *pRes = 0; |
| 54611 | + return rc; |
| 54612 | + } |
| 54613 | + } |
| 54614 | + if( CURSOR_INVALID==pCur->eState ){ |
| 54615 | + *pRes = 1; |
| 54616 | + return SQLITE_OK; |
| 54617 | + } |
| 54618 | + if( pCur->skipNext ){ |
| 54619 | + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); |
| 54620 | + pCur->eState = CURSOR_VALID; |
| 54621 | + if( pCur->skipNext<0 ){ |
| 54622 | + pCur->skipNext = 0; |
| 54623 | + *pRes = 0; |
| 54624 | + return SQLITE_OK; |
| 54625 | + } |
| 54626 | + pCur->skipNext = 0; |
| 54627 | + } |
| 54628 | + } |
| 54455 | 54629 | |
| 54456 | 54630 | pPage = pCur->apPage[pCur->iPage]; |
| 54457 | 54631 | assert( pPage->isInit ); |
| 54458 | 54632 | if( !pPage->leaf ){ |
| 54459 | 54633 | int idx = pCur->aiIdx[pCur->iPage]; |
| 54460 | 54634 | rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); |
| 54461 | 54635 | if( rc ){ |
| 54636 | + *pRes = 0; |
| 54462 | 54637 | return rc; |
| 54463 | 54638 | } |
| 54464 | 54639 | rc = moveToRightmost(pCur); |
| 54465 | 54640 | }else{ |
| 54466 | 54641 | while( pCur->aiIdx[pCur->iPage]==0 ){ |
| | @@ -54580,11 +54755,11 @@ |
| 54580 | 54755 | } |
| 54581 | 54756 | testcase( iTrunk==mxPage ); |
| 54582 | 54757 | if( iTrunk>mxPage ){ |
| 54583 | 54758 | rc = SQLITE_CORRUPT_BKPT; |
| 54584 | 54759 | }else{ |
| 54585 | | - rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0); |
| 54760 | + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); |
| 54586 | 54761 | } |
| 54587 | 54762 | if( rc ){ |
| 54588 | 54763 | pTrunk = 0; |
| 54589 | 54764 | goto end_allocate_page; |
| 54590 | 54765 | } |
| | @@ -54644,11 +54819,11 @@ |
| 54644 | 54819 | if( iNewTrunk>mxPage ){ |
| 54645 | 54820 | rc = SQLITE_CORRUPT_BKPT; |
| 54646 | 54821 | goto end_allocate_page; |
| 54647 | 54822 | } |
| 54648 | 54823 | testcase( iNewTrunk==mxPage ); |
| 54649 | | - rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0); |
| 54824 | + rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); |
| 54650 | 54825 | if( rc!=SQLITE_OK ){ |
| 54651 | 54826 | goto end_allocate_page; |
| 54652 | 54827 | } |
| 54653 | 54828 | rc = sqlite3PagerWrite(pNewTrunk->pDbPage); |
| 54654 | 54829 | if( rc!=SQLITE_OK ){ |
| | @@ -54723,12 +54898,12 @@ |
| 54723 | 54898 | if( rc ) goto end_allocate_page; |
| 54724 | 54899 | if( closest<k-1 ){ |
| 54725 | 54900 | memcpy(&aData[8+closest*4], &aData[4+k*4], 4); |
| 54726 | 54901 | } |
| 54727 | 54902 | put4byte(&aData[4], k-1); |
| 54728 | | - noContent = !btreeGetHasContent(pBt, *pPgno); |
| 54729 | | - rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0); |
| 54903 | + noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0; |
| 54904 | + rc = btreeGetPage(pBt, *pPgno, ppPage, noContent); |
| 54730 | 54905 | if( rc==SQLITE_OK ){ |
| 54731 | 54906 | rc = sqlite3PagerWrite((*ppPage)->pDbPage); |
| 54732 | 54907 | if( rc!=SQLITE_OK ){ |
| 54733 | 54908 | releasePage(*ppPage); |
| 54734 | 54909 | } |
| | @@ -54756,11 +54931,11 @@ |
| 54756 | 54931 | ** content for any page that really does lie past the end of the database |
| 54757 | 54932 | ** file on disk. So the effects of disabling the no-content optimization |
| 54758 | 54933 | ** here are confined to those pages that lie between the end of the |
| 54759 | 54934 | ** database image and the end of the database file. |
| 54760 | 54935 | */ |
| 54761 | | - int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)); |
| 54936 | + int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0; |
| 54762 | 54937 | |
| 54763 | 54938 | rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); |
| 54764 | 54939 | if( rc ) return rc; |
| 54765 | 54940 | pBt->nPage++; |
| 54766 | 54941 | if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; |
| | @@ -54772,11 +54947,11 @@ |
| 54772 | 54947 | ** becomes a new pointer-map page, the second is used by the caller. |
| 54773 | 54948 | */ |
| 54774 | 54949 | MemPage *pPg = 0; |
| 54775 | 54950 | TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); |
| 54776 | 54951 | assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); |
| 54777 | | - rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0); |
| 54952 | + rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent); |
| 54778 | 54953 | if( rc==SQLITE_OK ){ |
| 54779 | 54954 | rc = sqlite3PagerWrite(pPg->pDbPage); |
| 54780 | 54955 | releasePage(pPg); |
| 54781 | 54956 | } |
| 54782 | 54957 | if( rc ) return rc; |
| | @@ -54786,11 +54961,11 @@ |
| 54786 | 54961 | #endif |
| 54787 | 54962 | put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); |
| 54788 | 54963 | *pPgno = pBt->nPage; |
| 54789 | 54964 | |
| 54790 | 54965 | assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); |
| 54791 | | - rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0); |
| 54966 | + rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent); |
| 54792 | 54967 | if( rc ) return rc; |
| 54793 | 54968 | rc = sqlite3PagerWrite((*ppPage)->pDbPage); |
| 54794 | 54969 | if( rc!=SQLITE_OK ){ |
| 54795 | 54970 | releasePage(*ppPage); |
| 54796 | 54971 | } |
| | @@ -54854,11 +55029,11 @@ |
| 54854 | 55029 | |
| 54855 | 55030 | if( pBt->btsFlags & BTS_SECURE_DELETE ){ |
| 54856 | 55031 | /* If the secure_delete option is enabled, then |
| 54857 | 55032 | ** always fully overwrite deleted information with zeros. |
| 54858 | 55033 | */ |
| 54859 | | - if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) ) |
| 55034 | + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) |
| 54860 | 55035 | || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) |
| 54861 | 55036 | ){ |
| 54862 | 55037 | goto freepage_out; |
| 54863 | 55038 | } |
| 54864 | 55039 | memset(pPage->aData, 0, pPage->pBt->pageSize); |
| | @@ -54881,11 +55056,11 @@ |
| 54881 | 55056 | */ |
| 54882 | 55057 | if( nFree!=0 ){ |
| 54883 | 55058 | u32 nLeaf; /* Initial number of leaf cells on trunk page */ |
| 54884 | 55059 | |
| 54885 | 55060 | iTrunk = get4byte(&pPage1->aData[32]); |
| 54886 | | - rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0); |
| 55061 | + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); |
| 54887 | 55062 | if( rc!=SQLITE_OK ){ |
| 54888 | 55063 | goto freepage_out; |
| 54889 | 55064 | } |
| 54890 | 55065 | |
| 54891 | 55066 | nLeaf = get4byte(&pTrunk->aData[4]); |
| | @@ -54927,11 +55102,11 @@ |
| 54927 | 55102 | ** the page being freed as a leaf page of the first trunk in the free-list. |
| 54928 | 55103 | ** Possibly because the free-list is empty, or possibly because the |
| 54929 | 55104 | ** first trunk in the free-list is full. Either way, the page being freed |
| 54930 | 55105 | ** will become the new first trunk page in the free-list. |
| 54931 | 55106 | */ |
| 54932 | | - if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){ |
| 55107 | + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ |
| 54933 | 55108 | goto freepage_out; |
| 54934 | 55109 | } |
| 54935 | 55110 | rc = sqlite3PagerWrite(pPage->pDbPage); |
| 54936 | 55111 | if( rc!=SQLITE_OK ){ |
| 54937 | 55112 | goto freepage_out; |
| | @@ -56826,11 +57001,11 @@ |
| 56826 | 57001 | if( rc!=SQLITE_OK ){ |
| 56827 | 57002 | return rc; |
| 56828 | 57003 | } |
| 56829 | 57004 | |
| 56830 | 57005 | /* Move the page currently at pgnoRoot to pgnoMove. */ |
| 56831 | | - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0); |
| 57006 | + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); |
| 56832 | 57007 | if( rc!=SQLITE_OK ){ |
| 56833 | 57008 | return rc; |
| 56834 | 57009 | } |
| 56835 | 57010 | rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); |
| 56836 | 57011 | if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ |
| | @@ -56847,11 +57022,11 @@ |
| 56847 | 57022 | |
| 56848 | 57023 | /* Obtain the page at pgnoRoot */ |
| 56849 | 57024 | if( rc!=SQLITE_OK ){ |
| 56850 | 57025 | return rc; |
| 56851 | 57026 | } |
| 56852 | | - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0); |
| 57027 | + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); |
| 56853 | 57028 | if( rc!=SQLITE_OK ){ |
| 56854 | 57029 | return rc; |
| 56855 | 57030 | } |
| 56856 | 57031 | rc = sqlite3PagerWrite(pRoot->pDbPage); |
| 56857 | 57032 | if( rc!=SQLITE_OK ){ |
| | @@ -57025,11 +57200,11 @@ |
| 57025 | 57200 | if( NEVER(pBt->pCursor) ){ |
| 57026 | 57201 | sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); |
| 57027 | 57202 | return SQLITE_LOCKED_SHAREDCACHE; |
| 57028 | 57203 | } |
| 57029 | 57204 | |
| 57030 | | - rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0); |
| 57205 | + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); |
| 57031 | 57206 | if( rc ) return rc; |
| 57032 | 57207 | rc = sqlite3BtreeClearTable(p, iTable, 0); |
| 57033 | 57208 | if( rc ){ |
| 57034 | 57209 | releasePage(pPage); |
| 57035 | 57210 | return rc; |
| | @@ -57060,21 +57235,21 @@ |
| 57060 | 57235 | ** number in the database. So move the page that does into the |
| 57061 | 57236 | ** gap left by the deleted root-page. |
| 57062 | 57237 | */ |
| 57063 | 57238 | MemPage *pMove; |
| 57064 | 57239 | releasePage(pPage); |
| 57065 | | - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0); |
| 57240 | + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); |
| 57066 | 57241 | if( rc!=SQLITE_OK ){ |
| 57067 | 57242 | return rc; |
| 57068 | 57243 | } |
| 57069 | 57244 | rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); |
| 57070 | 57245 | releasePage(pMove); |
| 57071 | 57246 | if( rc!=SQLITE_OK ){ |
| 57072 | 57247 | return rc; |
| 57073 | 57248 | } |
| 57074 | 57249 | pMove = 0; |
| 57075 | | - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0); |
| 57250 | + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); |
| 57076 | 57251 | freePage(pMove, &rc); |
| 57077 | 57252 | releasePage(pMove); |
| 57078 | 57253 | if( rc!=SQLITE_OK ){ |
| 57079 | 57254 | return rc; |
| 57080 | 57255 | } |
| | @@ -57285,11 +57460,11 @@ |
| 57285 | 57460 | if( zMsg1 ){ |
| 57286 | 57461 | sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); |
| 57287 | 57462 | } |
| 57288 | 57463 | sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); |
| 57289 | 57464 | va_end(ap); |
| 57290 | | - if( pCheck->errMsg.mallocFailed ){ |
| 57465 | + if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ |
| 57291 | 57466 | pCheck->mallocFailed = 1; |
| 57292 | 57467 | } |
| 57293 | 57468 | } |
| 57294 | 57469 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 57295 | 57470 | |
| | @@ -57482,11 +57657,11 @@ |
| 57482 | 57657 | */ |
| 57483 | 57658 | pBt = pCheck->pBt; |
| 57484 | 57659 | usableSize = pBt->usableSize; |
| 57485 | 57660 | if( iPage==0 ) return 0; |
| 57486 | 57661 | if( checkRef(pCheck, iPage, zParentContext) ) return 0; |
| 57487 | | - if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){ |
| 57662 | + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ |
| 57488 | 57663 | checkAppendMsg(pCheck, zContext, |
| 57489 | 57664 | "unable to get the page. error code=%d", rc); |
| 57490 | 57665 | return 0; |
| 57491 | 57666 | } |
| 57492 | 57667 | |
| | @@ -58441,11 +58616,11 @@ |
| 58441 | 58616 | for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){ |
| 58442 | 58617 | const Pgno iSrcPg = p->iNext; /* Source page number */ |
| 58443 | 58618 | if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ |
| 58444 | 58619 | DbPage *pSrcPg; /* Source page object */ |
| 58445 | 58620 | rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg, |
| 58446 | | - PAGER_ACQUIRE_READONLY); |
| 58621 | + PAGER_GET_READONLY); |
| 58447 | 58622 | if( rc==SQLITE_OK ){ |
| 58448 | 58623 | rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); |
| 58449 | 58624 | sqlite3PagerUnref(pSrcPg); |
| 58450 | 58625 | } |
| 58451 | 58626 | } |
| | @@ -59596,38 +59771,33 @@ |
| 59596 | 59771 | /* If one value is a number and the other is not, the number is less. |
| 59597 | 59772 | ** If both are numbers, compare as reals if one is a real, or as integers |
| 59598 | 59773 | ** if both values are integers. |
| 59599 | 59774 | */ |
| 59600 | 59775 | if( combined_flags&(MEM_Int|MEM_Real) ){ |
| 59601 | | - if( !(f1&(MEM_Int|MEM_Real)) ){ |
| 59602 | | - return 1; |
| 59603 | | - } |
| 59604 | | - if( !(f2&(MEM_Int|MEM_Real)) ){ |
| 59605 | | - return -1; |
| 59606 | | - } |
| 59607 | | - if( (f1 & f2 & MEM_Int)==0 ){ |
| 59608 | | - double r1, r2; |
| 59609 | | - if( (f1&MEM_Real)==0 ){ |
| 59610 | | - r1 = (double)pMem1->u.i; |
| 59611 | | - }else{ |
| 59612 | | - r1 = pMem1->r; |
| 59613 | | - } |
| 59614 | | - if( (f2&MEM_Real)==0 ){ |
| 59615 | | - r2 = (double)pMem2->u.i; |
| 59616 | | - }else{ |
| 59617 | | - r2 = pMem2->r; |
| 59618 | | - } |
| 59619 | | - if( r1<r2 ) return -1; |
| 59620 | | - if( r1>r2 ) return 1; |
| 59621 | | - return 0; |
| 59622 | | - }else{ |
| 59623 | | - assert( f1&MEM_Int ); |
| 59624 | | - assert( f2&MEM_Int ); |
| 59776 | + double r1, r2; |
| 59777 | + if( (f1 & f2 & MEM_Int)!=0 ){ |
| 59625 | 59778 | if( pMem1->u.i < pMem2->u.i ) return -1; |
| 59626 | 59779 | if( pMem1->u.i > pMem2->u.i ) return 1; |
| 59627 | 59780 | return 0; |
| 59628 | 59781 | } |
| 59782 | + if( (f1&MEM_Real)!=0 ){ |
| 59783 | + r1 = pMem1->r; |
| 59784 | + }else if( (f1&MEM_Int)!=0 ){ |
| 59785 | + r1 = (double)pMem1->u.i; |
| 59786 | + }else{ |
| 59787 | + return 1; |
| 59788 | + } |
| 59789 | + if( (f2&MEM_Real)!=0 ){ |
| 59790 | + r2 = pMem2->r; |
| 59791 | + }else if( (f2&MEM_Int)!=0 ){ |
| 59792 | + r2 = (double)pMem2->u.i; |
| 59793 | + }else{ |
| 59794 | + return -1; |
| 59795 | + } |
| 59796 | + if( r1<r2 ) return -1; |
| 59797 | + if( r1>r2 ) return 1; |
| 59798 | + return 0; |
| 59629 | 59799 | } |
| 59630 | 59800 | |
| 59631 | 59801 | /* If one value is a string and the other is a blob, the string is less. |
| 59632 | 59802 | ** If both are strings, compare using the collating functions. |
| 59633 | 59803 | */ |
| | @@ -59803,43 +59973,108 @@ |
| 59803 | 59973 | } |
| 59804 | 59974 | return p; |
| 59805 | 59975 | } |
| 59806 | 59976 | |
| 59807 | 59977 | /* |
| 59808 | | -** Create a new sqlite3_value object, containing the value of pExpr. |
| 59978 | +** Context object passed by sqlite3Stat4ProbeSetValue() through to |
| 59979 | +** valueNew(). See comments above valueNew() for details. |
| 59980 | +*/ |
| 59981 | +struct ValueNewStat4Ctx { |
| 59982 | + Parse *pParse; |
| 59983 | + Index *pIdx; |
| 59984 | + UnpackedRecord **ppRec; |
| 59985 | + int iVal; |
| 59986 | +}; |
| 59987 | + |
| 59988 | +/* |
| 59989 | +** Allocate and return a pointer to a new sqlite3_value object. If |
| 59990 | +** the second argument to this function is NULL, the object is allocated |
| 59991 | +** by calling sqlite3ValueNew(). |
| 59809 | 59992 | ** |
| 59810 | | -** This only works for very simple expressions that consist of one constant |
| 59811 | | -** token (i.e. "5", "5.1", "'a string'"). If the expression can |
| 59812 | | -** be converted directly into a value, then the value is allocated and |
| 59813 | | -** a pointer written to *ppVal. The caller is responsible for deallocating |
| 59814 | | -** the value by passing it to sqlite3ValueFree() later on. If the expression |
| 59815 | | -** cannot be converted to a value, then *ppVal is set to NULL. |
| 59993 | +** Otherwise, if the second argument is non-zero, then this function is |
| 59994 | +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not |
| 59995 | +** already been allocated, allocate the UnpackedRecord structure that |
| 59996 | +** that function will return to its caller here. Then return a pointer |
| 59997 | +** an sqlite3_value within the UnpackedRecord.a[] array. |
| 59816 | 59998 | */ |
| 59817 | | -SQLITE_PRIVATE int sqlite3ValueFromExpr( |
| 59818 | | - sqlite3 *db, /* The database connection */ |
| 59819 | | - Expr *pExpr, /* The expression to evaluate */ |
| 59820 | | - u8 enc, /* Encoding to use */ |
| 59821 | | - u8 affinity, /* Affinity to use */ |
| 59822 | | - sqlite3_value **ppVal /* Write the new value here */ |
| 59999 | +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ |
| 60000 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60001 | + if( p ){ |
| 60002 | + UnpackedRecord *pRec = p->ppRec[0]; |
| 60003 | + |
| 60004 | + if( pRec==0 ){ |
| 60005 | + Index *pIdx = p->pIdx; /* Index being probed */ |
| 60006 | + int nByte; /* Bytes of space to allocate */ |
| 60007 | + int i; /* Counter variable */ |
| 60008 | + int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */ |
| 60009 | + |
| 60010 | + nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); |
| 60011 | + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); |
| 60012 | + if( pRec ){ |
| 60013 | + pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx); |
| 60014 | + if( pRec->pKeyInfo ){ |
| 60015 | + assert( pRec->pKeyInfo->nField+1==nCol ); |
| 60016 | + pRec->pKeyInfo->enc = ENC(db); |
| 60017 | + pRec->flags = UNPACKED_PREFIX_MATCH; |
| 60018 | + pRec->aMem = (Mem *)&pRec[1]; |
| 60019 | + for(i=0; i<nCol; i++){ |
| 60020 | + pRec->aMem[i].flags = MEM_Null; |
| 60021 | + pRec->aMem[i].type = SQLITE_NULL; |
| 60022 | + pRec->aMem[i].db = db; |
| 60023 | + } |
| 60024 | + }else{ |
| 60025 | + sqlite3DbFree(db, pRec); |
| 60026 | + pRec = 0; |
| 60027 | + } |
| 60028 | + } |
| 60029 | + if( pRec==0 ) return 0; |
| 60030 | + p->ppRec[0] = pRec; |
| 60031 | + } |
| 60032 | + |
| 60033 | + pRec->nField = p->iVal+1; |
| 60034 | + return &pRec->aMem[p->iVal]; |
| 60035 | + } |
| 60036 | +#endif |
| 60037 | + return sqlite3ValueNew(db); |
| 60038 | +} |
| 60039 | + |
| 60040 | +/* |
| 60041 | +** Extract a value from the supplied expression in the manner described |
| 60042 | +** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object |
| 60043 | +** using valueNew(). |
| 60044 | +** |
| 60045 | +** If pCtx is NULL and an error occurs after the sqlite3_value object |
| 60046 | +** has been allocated, it is freed before returning. Or, if pCtx is not |
| 60047 | +** NULL, it is assumed that the caller will free any allocated object |
| 60048 | +** in all cases. |
| 60049 | +*/ |
| 60050 | +int valueFromExpr( |
| 60051 | + sqlite3 *db, /* The database connection */ |
| 60052 | + Expr *pExpr, /* The expression to evaluate */ |
| 60053 | + u8 enc, /* Encoding to use */ |
| 60054 | + u8 affinity, /* Affinity to use */ |
| 60055 | + sqlite3_value **ppVal, /* Write the new value here */ |
| 60056 | + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ |
| 59823 | 60057 | ){ |
| 59824 | 60058 | int op; |
| 59825 | 60059 | char *zVal = 0; |
| 59826 | 60060 | sqlite3_value *pVal = 0; |
| 59827 | 60061 | int negInt = 1; |
| 59828 | 60062 | const char *zNeg = ""; |
| 60063 | + int rc = SQLITE_OK; |
| 59829 | 60064 | |
| 59830 | 60065 | if( !pExpr ){ |
| 59831 | 60066 | *ppVal = 0; |
| 59832 | 60067 | return SQLITE_OK; |
| 59833 | 60068 | } |
| 59834 | 60069 | op = pExpr->op; |
| 59835 | 60070 | |
| 59836 | | - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3. |
| 60071 | + /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. |
| 59837 | 60072 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 59838 | | - ** when SQLITE_ENABLE_STAT3 is omitted. |
| 60073 | + ** when SQLITE_ENABLE_STAT4 is omitted. |
| 59839 | 60074 | */ |
| 59840 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 60075 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 59841 | 60076 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 59842 | 60077 | #else |
| 59843 | 60078 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 59844 | 60079 | #endif |
| 59845 | 60080 | |
| | @@ -59853,11 +60088,11 @@ |
| 59853 | 60088 | negInt = -1; |
| 59854 | 60089 | zNeg = "-"; |
| 59855 | 60090 | } |
| 59856 | 60091 | |
| 59857 | 60092 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 59858 | | - pVal = sqlite3ValueNew(db); |
| 60093 | + pVal = valueNew(db, pCtx); |
| 59859 | 60094 | if( pVal==0 ) goto no_mem; |
| 59860 | 60095 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 59861 | 60096 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 59862 | 60097 | }else{ |
| 59863 | 60098 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); |
| | @@ -59870,15 +60105,17 @@ |
| 59870 | 60105 | }else{ |
| 59871 | 60106 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 59872 | 60107 | } |
| 59873 | 60108 | if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; |
| 59874 | 60109 | if( enc!=SQLITE_UTF8 ){ |
| 59875 | | - sqlite3VdbeChangeEncoding(pVal, enc); |
| 60110 | + rc = sqlite3VdbeChangeEncoding(pVal, enc); |
| 59876 | 60111 | } |
| 59877 | 60112 | }else if( op==TK_UMINUS ) { |
| 59878 | 60113 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 59879 | | - if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ |
| 60114 | + if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) |
| 60115 | + && pVal!=0 |
| 60116 | + ){ |
| 59880 | 60117 | sqlite3VdbeMemNumerify(pVal); |
| 59881 | 60118 | if( pVal->u.i==SMALLEST_INT64 ){ |
| 59882 | 60119 | pVal->flags &= MEM_Int; |
| 59883 | 60120 | pVal->flags |= MEM_Real; |
| 59884 | 60121 | pVal->r = (double)LARGEST_INT64; |
| | @@ -59887,19 +60124,19 @@ |
| 59887 | 60124 | } |
| 59888 | 60125 | pVal->r = -pVal->r; |
| 59889 | 60126 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 59890 | 60127 | } |
| 59891 | 60128 | }else if( op==TK_NULL ){ |
| 59892 | | - pVal = sqlite3ValueNew(db); |
| 60129 | + pVal = valueNew(db, pCtx); |
| 59893 | 60130 | if( pVal==0 ) goto no_mem; |
| 59894 | 60131 | } |
| 59895 | 60132 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 59896 | 60133 | else if( op==TK_BLOB ){ |
| 59897 | 60134 | int nVal; |
| 59898 | 60135 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| 59899 | 60136 | assert( pExpr->u.zToken[1]=='\'' ); |
| 59900 | | - pVal = sqlite3ValueNew(db); |
| 60137 | + pVal = valueNew(db, pCtx); |
| 59901 | 60138 | if( !pVal ) goto no_mem; |
| 59902 | 60139 | zVal = &pExpr->u.zToken[2]; |
| 59903 | 60140 | nVal = sqlite3Strlen30(zVal)-1; |
| 59904 | 60141 | assert( zVal[nVal]=='\'' ); |
| 59905 | 60142 | sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, |
| | @@ -59909,20 +60146,203 @@ |
| 59909 | 60146 | |
| 59910 | 60147 | if( pVal ){ |
| 59911 | 60148 | sqlite3VdbeMemStoreType(pVal); |
| 59912 | 60149 | } |
| 59913 | 60150 | *ppVal = pVal; |
| 59914 | | - return SQLITE_OK; |
| 60151 | + return rc; |
| 59915 | 60152 | |
| 59916 | 60153 | no_mem: |
| 59917 | 60154 | db->mallocFailed = 1; |
| 59918 | 60155 | sqlite3DbFree(db, zVal); |
| 59919 | | - sqlite3ValueFree(pVal); |
| 59920 | | - *ppVal = 0; |
| 60156 | + assert( *ppVal==0 ); |
| 60157 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60158 | + if( pCtx==0 ) sqlite3ValueFree(pVal); |
| 60159 | +#else |
| 60160 | + assert( pCtx==0 ); sqlite3ValueFree(pVal); |
| 60161 | +#endif |
| 59921 | 60162 | return SQLITE_NOMEM; |
| 59922 | 60163 | } |
| 59923 | 60164 | |
| 60165 | +/* |
| 60166 | +** Create a new sqlite3_value object, containing the value of pExpr. |
| 60167 | +** |
| 60168 | +** This only works for very simple expressions that consist of one constant |
| 60169 | +** token (i.e. "5", "5.1", "'a string'"). If the expression can |
| 60170 | +** be converted directly into a value, then the value is allocated and |
| 60171 | +** a pointer written to *ppVal. The caller is responsible for deallocating |
| 60172 | +** the value by passing it to sqlite3ValueFree() later on. If the expression |
| 60173 | +** cannot be converted to a value, then *ppVal is set to NULL. |
| 60174 | +*/ |
| 60175 | +SQLITE_PRIVATE int sqlite3ValueFromExpr( |
| 60176 | + sqlite3 *db, /* The database connection */ |
| 60177 | + Expr *pExpr, /* The expression to evaluate */ |
| 60178 | + u8 enc, /* Encoding to use */ |
| 60179 | + u8 affinity, /* Affinity to use */ |
| 60180 | + sqlite3_value **ppVal /* Write the new value here */ |
| 60181 | +){ |
| 60182 | + return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); |
| 60183 | +} |
| 60184 | + |
| 60185 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60186 | +/* |
| 60187 | +** The implementation of the sqlite_record() function. This function accepts |
| 60188 | +** a single argument of any type. The return value is a formatted database |
| 60189 | +** record (a blob) containing the argument value. |
| 60190 | +** |
| 60191 | +** This is used to convert the value stored in the 'sample' column of the |
| 60192 | +** sqlite_stat3 table to the record format SQLite uses internally. |
| 60193 | +*/ |
| 60194 | +static void recordFunc( |
| 60195 | + sqlite3_context *context, |
| 60196 | + int argc, |
| 60197 | + sqlite3_value **argv |
| 60198 | +){ |
| 60199 | + const int file_format = 1; |
| 60200 | + int iSerial; /* Serial type */ |
| 60201 | + int nSerial; /* Bytes of space for iSerial as varint */ |
| 60202 | + int nVal; /* Bytes of space required for argv[0] */ |
| 60203 | + int nRet; |
| 60204 | + sqlite3 *db; |
| 60205 | + u8 *aRet; |
| 60206 | + |
| 60207 | + iSerial = sqlite3VdbeSerialType(argv[0], file_format); |
| 60208 | + nSerial = sqlite3VarintLen(iSerial); |
| 60209 | + nVal = sqlite3VdbeSerialTypeLen(iSerial); |
| 60210 | + db = sqlite3_context_db_handle(context); |
| 60211 | + |
| 60212 | + nRet = 1 + nSerial + nVal; |
| 60213 | + aRet = sqlite3DbMallocRaw(db, nRet); |
| 60214 | + if( aRet==0 ){ |
| 60215 | + sqlite3_result_error_nomem(context); |
| 60216 | + }else{ |
| 60217 | + aRet[0] = nSerial+1; |
| 60218 | + sqlite3PutVarint(&aRet[1], iSerial); |
| 60219 | + sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); |
| 60220 | + sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
| 60221 | + sqlite3DbFree(db, aRet); |
| 60222 | + } |
| 60223 | +} |
| 60224 | + |
| 60225 | +/* |
| 60226 | +** Register built-in functions used to help read ANALYZE data. |
| 60227 | +*/ |
| 60228 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ |
| 60229 | + static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { |
| 60230 | + FUNCTION(sqlite_record, 1, 0, 0, recordFunc), |
| 60231 | + }; |
| 60232 | + int i; |
| 60233 | + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); |
| 60234 | + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); |
| 60235 | + for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){ |
| 60236 | + sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 60237 | + } |
| 60238 | +} |
| 60239 | + |
| 60240 | +/* |
| 60241 | +** This function is used to allocate and populate UnpackedRecord |
| 60242 | +** structures intended to be compared against sample index keys stored |
| 60243 | +** in the sqlite_stat4 table. |
| 60244 | +** |
| 60245 | +** A single call to this function attempts to populates field iVal (leftmost |
| 60246 | +** is 0 etc.) of the unpacked record with a value extracted from expression |
| 60247 | +** pExpr. Extraction of values is possible if: |
| 60248 | +** |
| 60249 | +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, |
| 60250 | +** |
| 60251 | +** * The expression is a bound variable, and this is a reprepare, or |
| 60252 | +** |
| 60253 | +** * The sqlite3ValueFromExpr() function is able to extract a value |
| 60254 | +** from the expression (i.e. the expression is a literal value). |
| 60255 | +** |
| 60256 | +** If a value can be extracted, the affinity passed as the 5th argument |
| 60257 | +** is applied to it before it is copied into the UnpackedRecord. Output |
| 60258 | +** parameter *pbOk is set to true if a value is extracted, or false |
| 60259 | +** otherwise. |
| 60260 | +** |
| 60261 | +** When this function is called, *ppRec must either point to an object |
| 60262 | +** allocated by an earlier call to this function, or must be NULL. If it |
| 60263 | +** is NULL and a value can be successfully extracted, a new UnpackedRecord |
| 60264 | +** is allocated (and *ppRec set to point to it) before returning. |
| 60265 | +** |
| 60266 | +** Unless an error is encountered, SQLITE_OK is returned. It is not an |
| 60267 | +** error if a value cannot be extracted from pExpr. If an error does |
| 60268 | +** occur, an SQLite error code is returned. |
| 60269 | +*/ |
| 60270 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( |
| 60271 | + Parse *pParse, /* Parse context */ |
| 60272 | + Index *pIdx, /* Index being probed */ |
| 60273 | + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ |
| 60274 | + Expr *pExpr, /* The expression to extract a value from */ |
| 60275 | + u8 affinity, /* Affinity to use */ |
| 60276 | + int iVal, /* Array element to populate */ |
| 60277 | + int *pbOk /* OUT: True if value was extracted */ |
| 60278 | +){ |
| 60279 | + int rc = SQLITE_OK; |
| 60280 | + sqlite3_value *pVal = 0; |
| 60281 | + |
| 60282 | + struct ValueNewStat4Ctx alloc; |
| 60283 | + alloc.pParse = pParse; |
| 60284 | + alloc.pIdx = pIdx; |
| 60285 | + alloc.ppRec = ppRec; |
| 60286 | + alloc.iVal = iVal; |
| 60287 | + |
| 60288 | + if( !pExpr ){ |
| 60289 | + pVal = valueNew(pParse->db, &alloc); |
| 60290 | + if( pVal ){ |
| 60291 | + sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60292 | + *pbOk = 1; |
| 60293 | + } |
| 60294 | + }else if( pExpr->op==TK_VARIABLE |
| 60295 | + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 60296 | + ){ |
| 60297 | + Vdbe *v; |
| 60298 | + int iBindVar = pExpr->iColumn; |
| 60299 | + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); |
| 60300 | + if( (v = pParse->pReprepare)!=0 ){ |
| 60301 | + pVal = valueNew(pParse->db, &alloc); |
| 60302 | + if( pVal ){ |
| 60303 | + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); |
| 60304 | + if( rc==SQLITE_OK ){ |
| 60305 | + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 60306 | + } |
| 60307 | + pVal->db = pParse->db; |
| 60308 | + *pbOk = 1; |
| 60309 | + sqlite3VdbeMemStoreType((Mem*)pVal); |
| 60310 | + } |
| 60311 | + }else{ |
| 60312 | + *pbOk = 0; |
| 60313 | + } |
| 60314 | + }else{ |
| 60315 | + sqlite3 *db = pParse->db; |
| 60316 | + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); |
| 60317 | + *pbOk = (pVal!=0); |
| 60318 | + } |
| 60319 | + |
| 60320 | + assert( pVal==0 || pVal->db==pParse->db ); |
| 60321 | + return rc; |
| 60322 | +} |
| 60323 | + |
| 60324 | +/* |
| 60325 | +** Unless it is NULL, the argument must be an UnpackedRecord object returned |
| 60326 | +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes |
| 60327 | +** the object. |
| 60328 | +*/ |
| 60329 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ |
| 60330 | + if( pRec ){ |
| 60331 | + int i; |
| 60332 | + int nCol = pRec->pKeyInfo->nField+1; |
| 60333 | + Mem *aMem = pRec->aMem; |
| 60334 | + sqlite3 *db = aMem[0].db; |
| 60335 | + for(i=0; i<nCol; i++){ |
| 60336 | + sqlite3DbFree(db, aMem[i].zMalloc); |
| 60337 | + } |
| 60338 | + sqlite3DbFree(db, pRec->pKeyInfo); |
| 60339 | + sqlite3DbFree(db, pRec); |
| 60340 | + } |
| 60341 | +} |
| 60342 | +#endif /* ifdef SQLITE_ENABLE_STAT4 */ |
| 60343 | + |
| 59924 | 60344 | /* |
| 59925 | 60345 | ** Change the string value of an sqlite3_value object |
| 59926 | 60346 | */ |
| 59927 | 60347 | SQLITE_PRIVATE void sqlite3ValueSetStr( |
| 59928 | 60348 | sqlite3_value *v, /* Value to be set */ |
| | @@ -61724,11 +62144,11 @@ |
| 61724 | 62144 | ** virtual module tables written in this transaction. This has to |
| 61725 | 62145 | ** be done before determining whether a master journal file is |
| 61726 | 62146 | ** required, as an xSync() callback may add an attached database |
| 61727 | 62147 | ** to the transaction. |
| 61728 | 62148 | */ |
| 61729 | | - rc = sqlite3VtabSync(db, &p->zErrMsg); |
| 62149 | + rc = sqlite3VtabSync(db, p); |
| 61730 | 62150 | |
| 61731 | 62151 | /* This loop determines (a) if the commit hook should be invoked and |
| 61732 | 62152 | ** (b) how many database files have open write transactions, not |
| 61733 | 62153 | ** including the temp database. (b) is important because if more than |
| 61734 | 62154 | ** one database file has an open write transaction, a master journal |
| | @@ -63264,10 +63684,25 @@ |
| 63264 | 63684 | }else{ |
| 63265 | 63685 | v->expmask |= ((u32)1 << (iVar-1)); |
| 63266 | 63686 | } |
| 63267 | 63687 | } |
| 63268 | 63688 | |
| 63689 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 63690 | +/* |
| 63691 | +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored |
| 63692 | +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored |
| 63693 | +** in memory obtained from sqlite3DbMalloc). |
| 63694 | +*/ |
| 63695 | +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ |
| 63696 | + sqlite3 *db = p->db; |
| 63697 | + sqlite3DbFree(db, p->zErrMsg); |
| 63698 | + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); |
| 63699 | + sqlite3_free(pVtab->zErrMsg); |
| 63700 | + pVtab->zErrMsg = 0; |
| 63701 | +} |
| 63702 | +#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 63703 | + |
| 63269 | 63704 | /************** End of vdbeaux.c *********************************************/ |
| 63270 | 63705 | /************** Begin file vdbeapi.c *****************************************/ |
| 63271 | 63706 | /* |
| 63272 | 63707 | ** 2004 May 26 |
| 63273 | 63708 | ** |
| | @@ -63477,16 +63912,18 @@ |
| 63477 | 63912 | sqlite3VdbeMemSetDouble(&pCtx->s, rVal); |
| 63478 | 63913 | } |
| 63479 | 63914 | SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ |
| 63480 | 63915 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 63481 | 63916 | pCtx->isError = SQLITE_ERROR; |
| 63917 | + pCtx->fErrorOrAux = 1; |
| 63482 | 63918 | sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); |
| 63483 | 63919 | } |
| 63484 | 63920 | #ifndef SQLITE_OMIT_UTF16 |
| 63485 | 63921 | SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ |
| 63486 | 63922 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 63487 | 63923 | pCtx->isError = SQLITE_ERROR; |
| 63924 | + pCtx->fErrorOrAux = 1; |
| 63488 | 63925 | sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); |
| 63489 | 63926 | } |
| 63490 | 63927 | #endif |
| 63491 | 63928 | SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ |
| 63492 | 63929 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| | @@ -63546,10 +63983,11 @@ |
| 63546 | 63983 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 63547 | 63984 | sqlite3VdbeMemSetZeroBlob(&pCtx->s, n); |
| 63548 | 63985 | } |
| 63549 | 63986 | SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ |
| 63550 | 63987 | pCtx->isError = errCode; |
| 63988 | + pCtx->fErrorOrAux = 1; |
| 63551 | 63989 | if( pCtx->s.flags & MEM_Null ){ |
| 63552 | 63990 | sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, |
| 63553 | 63991 | SQLITE_UTF8, SQLITE_STATIC); |
| 63554 | 63992 | } |
| 63555 | 63993 | } |
| | @@ -63556,19 +63994,21 @@ |
| 63556 | 63994 | |
| 63557 | 63995 | /* Force an SQLITE_TOOBIG error. */ |
| 63558 | 63996 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ |
| 63559 | 63997 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 63560 | 63998 | pCtx->isError = SQLITE_TOOBIG; |
| 63999 | + pCtx->fErrorOrAux = 1; |
| 63561 | 64000 | sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, |
| 63562 | 64001 | SQLITE_UTF8, SQLITE_STATIC); |
| 63563 | 64002 | } |
| 63564 | 64003 | |
| 63565 | 64004 | /* An SQLITE_NOMEM error. */ |
| 63566 | 64005 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ |
| 63567 | 64006 | assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); |
| 63568 | 64007 | sqlite3VdbeMemSetNull(&pCtx->s); |
| 63569 | 64008 | pCtx->isError = SQLITE_NOMEM; |
| 64009 | + pCtx->fErrorOrAux = 1; |
| 63570 | 64010 | pCtx->s.db->mallocFailed = 1; |
| 63571 | 64011 | } |
| 63572 | 64012 | |
| 63573 | 64013 | /* |
| 63574 | 64014 | ** This function is called after a transaction has been committed. It |
| | @@ -63887,10 +64327,14 @@ |
| 63887 | 64327 | if( !pAuxData ) goto failed; |
| 63888 | 64328 | pAuxData->iOp = pCtx->iOp; |
| 63889 | 64329 | pAuxData->iArg = iArg; |
| 63890 | 64330 | pAuxData->pNext = pVdbe->pAuxData; |
| 63891 | 64331 | pVdbe->pAuxData = pAuxData; |
| 64332 | + if( pCtx->fErrorOrAux==0 ){ |
| 64333 | + pCtx->isError = 0; |
| 64334 | + pCtx->fErrorOrAux = 1; |
| 64335 | + } |
| 63892 | 64336 | }else if( pAuxData->xDelete ){ |
| 63893 | 64337 | pAuxData->xDelete(pAuxData->pAux); |
| 63894 | 64338 | } |
| 63895 | 64339 | |
| 63896 | 64340 | pAuxData->pAux = pAux; |
| | @@ -64555,13 +64999,13 @@ |
| 64555 | 64999 | /* |
| 64556 | 65000 | ** Return the value of a status counter for a prepared statement |
| 64557 | 65001 | */ |
| 64558 | 65002 | SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ |
| 64559 | 65003 | Vdbe *pVdbe = (Vdbe*)pStmt; |
| 64560 | | - int v = pVdbe->aCounter[op-1]; |
| 64561 | | - if( resetFlag ) pVdbe->aCounter[op-1] = 0; |
| 64562 | | - return v; |
| 65004 | + u32 v = pVdbe->aCounter[op]; |
| 65005 | + if( resetFlag ) pVdbe->aCounter[op] = 0; |
| 65006 | + return (int)v; |
| 64563 | 65007 | } |
| 64564 | 65008 | |
| 64565 | 65009 | /************** End of vdbeapi.c *********************************************/ |
| 64566 | 65010 | /************** Begin file vdbetrace.c ***************************************/ |
| 64567 | 65011 | /* |
| | @@ -65444,23 +65888,10 @@ |
| 65444 | 65888 | assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); |
| 65445 | 65889 | return 1; |
| 65446 | 65890 | } |
| 65447 | 65891 | #endif |
| 65448 | 65892 | |
| 65449 | | -/* |
| 65450 | | -** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored |
| 65451 | | -** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored |
| 65452 | | -** in memory obtained from sqlite3DbMalloc). |
| 65453 | | -*/ |
| 65454 | | -static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){ |
| 65455 | | - sqlite3 *db = p->db; |
| 65456 | | - sqlite3DbFree(db, p->zErrMsg); |
| 65457 | | - p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); |
| 65458 | | - sqlite3_free(pVtab->zErrMsg); |
| 65459 | | - pVtab->zErrMsg = 0; |
| 65460 | | -} |
| 65461 | | - |
| 65462 | 65893 | |
| 65463 | 65894 | /* |
| 65464 | 65895 | ** Execute as much of a VDBE program as we can then return. |
| 65465 | 65896 | ** |
| 65466 | 65897 | ** sqlite3VdbeMakeReady() must be called before this routine in order to |
| | @@ -65964,11 +66395,11 @@ |
| 65964 | 66395 | CHECK_FOR_INTERRUPT; |
| 65965 | 66396 | sqlite3VdbeIOTraceSql(p); |
| 65966 | 66397 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 65967 | 66398 | if( db->xProgress ){ |
| 65968 | 66399 | assert( 0 < db->nProgressOps ); |
| 65969 | | - nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1]; |
| 66400 | + nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; |
| 65970 | 66401 | if( nProgressLimit==0 ){ |
| 65971 | 66402 | nProgressLimit = db->nProgressOps; |
| 65972 | 66403 | }else{ |
| 65973 | 66404 | nProgressLimit %= (unsigned)db->nProgressOps; |
| 65974 | 66405 | } |
| | @@ -66027,11 +66458,11 @@ |
| 66027 | 66458 | ** value or convert mem[p2] to a different type. |
| 66028 | 66459 | */ |
| 66029 | 66460 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 66030 | 66461 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 66031 | 66462 | assert( pOp->p2>0 ); |
| 66032 | | - assert( pOp->p2<=p->nMem ); |
| 66463 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66033 | 66464 | pOut = &aMem[pOp->p2]; |
| 66034 | 66465 | memAboutToChange(p, pOut); |
| 66035 | 66466 | VdbeMemRelease(pOut); |
| 66036 | 66467 | pOut->flags = MEM_Int; |
| 66037 | 66468 | } |
| | @@ -66038,34 +66469,34 @@ |
| 66038 | 66469 | |
| 66039 | 66470 | /* Sanity checking on other operands */ |
| 66040 | 66471 | #ifdef SQLITE_DEBUG |
| 66041 | 66472 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 66042 | 66473 | assert( pOp->p1>0 ); |
| 66043 | | - assert( pOp->p1<=p->nMem ); |
| 66474 | + assert( pOp->p1<=(p->nMem-p->nCursor) ); |
| 66044 | 66475 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 66045 | 66476 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 66046 | 66477 | } |
| 66047 | 66478 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 66048 | 66479 | assert( pOp->p2>0 ); |
| 66049 | | - assert( pOp->p2<=p->nMem ); |
| 66480 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66050 | 66481 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 66051 | 66482 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 66052 | 66483 | } |
| 66053 | 66484 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 66054 | 66485 | assert( pOp->p3>0 ); |
| 66055 | | - assert( pOp->p3<=p->nMem ); |
| 66486 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66056 | 66487 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 66057 | 66488 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 66058 | 66489 | } |
| 66059 | 66490 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 66060 | 66491 | assert( pOp->p2>0 ); |
| 66061 | | - assert( pOp->p2<=p->nMem ); |
| 66492 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66062 | 66493 | memAboutToChange(p, &aMem[pOp->p2]); |
| 66063 | 66494 | } |
| 66064 | 66495 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 66065 | 66496 | assert( pOp->p3>0 ); |
| 66066 | | - assert( pOp->p3<=p->nMem ); |
| 66497 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66067 | 66498 | memAboutToChange(p, &aMem[pOp->p3]); |
| 66068 | 66499 | } |
| 66069 | 66500 | #endif |
| 66070 | 66501 | |
| 66071 | 66502 | switch( pOp->opcode ){ |
| | @@ -66154,11 +66585,11 @@ |
| 66154 | 66585 | ** |
| 66155 | 66586 | ** Write the current address onto register P1 |
| 66156 | 66587 | ** and then jump to address P2. |
| 66157 | 66588 | */ |
| 66158 | 66589 | case OP_Gosub: { /* jump */ |
| 66159 | | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 66590 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 66160 | 66591 | pIn1 = &aMem[pOp->p1]; |
| 66161 | 66592 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 66162 | 66593 | memAboutToChange(p, pIn1); |
| 66163 | 66594 | pIn1->flags = MEM_Int; |
| 66164 | 66595 | pIn1->u.i = pc; |
| | @@ -66370,11 +66801,11 @@ |
| 66370 | 66801 | #if 0 /* local variables moved into u.ab */ |
| 66371 | 66802 | int cnt; |
| 66372 | 66803 | u16 nullFlag; |
| 66373 | 66804 | #endif /* local variables moved into u.ab */ |
| 66374 | 66805 | u.ab.cnt = pOp->p3-pOp->p2; |
| 66375 | | - assert( pOp->p3<=p->nMem ); |
| 66806 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66376 | 66807 | pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 66377 | 66808 | while( u.ab.cnt>0 ){ |
| 66378 | 66809 | pOut++; |
| 66379 | 66810 | memAboutToChange(p, pOut); |
| 66380 | 66811 | VdbeMemRelease(pOut); |
| | @@ -66443,12 +66874,12 @@ |
| 66443 | 66874 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 66444 | 66875 | |
| 66445 | 66876 | pIn1 = &aMem[u.ad.p1]; |
| 66446 | 66877 | pOut = &aMem[u.ad.p2]; |
| 66447 | 66878 | while( u.ad.n-- ){ |
| 66448 | | - assert( pOut<=&aMem[p->nMem] ); |
| 66449 | | - assert( pIn1<=&aMem[p->nMem] ); |
| 66879 | + assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 66880 | + assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 66450 | 66881 | assert( memIsValid(pIn1) ); |
| 66451 | 66882 | memAboutToChange(p, pOut); |
| 66452 | 66883 | u.ad.zMalloc = pOut->zMalloc; |
| 66453 | 66884 | pOut->zMalloc = 0; |
| 66454 | 66885 | sqlite3VdbeMemMove(pOut, pIn1); |
| | @@ -66532,11 +66963,11 @@ |
| 66532 | 66963 | Mem *pMem; |
| 66533 | 66964 | int i; |
| 66534 | 66965 | #endif /* local variables moved into u.af */ |
| 66535 | 66966 | assert( p->nResColumn==pOp->p2 ); |
| 66536 | 66967 | assert( pOp->p1>0 ); |
| 66537 | | - assert( pOp->p1+pOp->p2<=p->nMem+1 ); |
| 66968 | + assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 66538 | 66969 | |
| 66539 | 66970 | /* If this statement has violated immediate foreign key constraints, do |
| 66540 | 66971 | ** not return the number of rows modified. And do not RELEASE the statement |
| 66541 | 66972 | ** transaction. It needs to be rolled back. */ |
| 66542 | 66973 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| | @@ -66812,15 +67243,15 @@ |
| 66812 | 67243 | #endif /* local variables moved into u.ai */ |
| 66813 | 67244 | |
| 66814 | 67245 | u.ai.n = pOp->p5; |
| 66815 | 67246 | u.ai.apVal = p->apArg; |
| 66816 | 67247 | assert( u.ai.apVal || u.ai.n==0 ); |
| 66817 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 67248 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 66818 | 67249 | pOut = &aMem[pOp->p3]; |
| 66819 | 67250 | memAboutToChange(p, pOut); |
| 66820 | 67251 | |
| 66821 | | - assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) ); |
| 67252 | + assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) ); |
| 66822 | 67253 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 66823 | 67254 | u.ai.pArg = &aMem[pOp->p2]; |
| 66824 | 67255 | for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 66825 | 67256 | assert( memIsValid(u.ai.pArg) ); |
| 66826 | 67257 | u.ai.apVal[u.ai.i] = u.ai.pArg; |
| | @@ -66843,11 +67274,11 @@ |
| 66843 | 67274 | ** the already allocated buffer instead of allocating a new one. |
| 66844 | 67275 | */ |
| 66845 | 67276 | sqlite3VdbeMemMove(&u.ai.ctx.s, pOut); |
| 66846 | 67277 | MemSetTypeFlag(&u.ai.ctx.s, MEM_Null); |
| 66847 | 67278 | |
| 66848 | | - u.ai.ctx.isError = 0; |
| 67279 | + u.ai.ctx.fErrorOrAux = 0; |
| 66849 | 67280 | if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 66850 | 67281 | assert( pOp>aOp ); |
| 66851 | 67282 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 66852 | 67283 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 66853 | 67284 | u.ai.ctx.pColl = pOp[-1].p4.pColl; |
| | @@ -66854,15 +67285,10 @@ |
| 66854 | 67285 | } |
| 66855 | 67286 | db->lastRowid = lastRowid; |
| 66856 | 67287 | (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */ |
| 66857 | 67288 | lastRowid = db->lastRowid; |
| 66858 | 67289 | |
| 66859 | | - /* If any auxiliary data functions have been called by this user function, |
| 66860 | | - ** immediately call the destructor for any non-static values. |
| 66861 | | - */ |
| 66862 | | - sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); |
| 66863 | | - |
| 66864 | 67290 | if( db->mallocFailed ){ |
| 66865 | 67291 | /* Even though a malloc() has failed, the implementation of the |
| 66866 | 67292 | ** user function may have called an sqlite3_result_XXX() function |
| 66867 | 67293 | ** to return a value. The following call releases any resources |
| 66868 | 67294 | ** associated with such a value. |
| | @@ -66870,13 +67296,16 @@ |
| 66870 | 67296 | sqlite3VdbeMemRelease(&u.ai.ctx.s); |
| 66871 | 67297 | goto no_mem; |
| 66872 | 67298 | } |
| 66873 | 67299 | |
| 66874 | 67300 | /* If the function returned an error, throw an exception */ |
| 66875 | | - if( u.ai.ctx.isError ){ |
| 66876 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s)); |
| 66877 | | - rc = u.ai.ctx.isError; |
| 67301 | + if( u.ai.ctx.fErrorOrAux ){ |
| 67302 | + if( u.ai.ctx.isError ){ |
| 67303 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s)); |
| 67304 | + rc = u.ai.ctx.isError; |
| 67305 | + } |
| 67306 | + sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); |
| 66878 | 67307 | } |
| 66879 | 67308 | |
| 66880 | 67309 | /* Copy the result of the function into register P3 */ |
| 66881 | 67310 | sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding); |
| 66882 | 67311 | sqlite3VdbeMemMove(pOut, &u.ai.ctx.s); |
| | @@ -67248,16 +67677,16 @@ |
| 67248 | 67677 | }else{ |
| 67249 | 67678 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 67250 | 67679 | ** then the result is always NULL. |
| 67251 | 67680 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 67252 | 67681 | */ |
| 67253 | | - if( pOp->p5 & SQLITE_STOREP2 ){ |
| 67682 | + if( pOp->p5 & SQLITE_JUMPIFNULL ){ |
| 67683 | + pc = pOp->p2-1; |
| 67684 | + }else if( pOp->p5 & SQLITE_STOREP2 ){ |
| 67254 | 67685 | pOut = &aMem[pOp->p2]; |
| 67255 | 67686 | MemSetTypeFlag(pOut, MEM_Null); |
| 67256 | 67687 | REGISTER_TRACE(pOp->p2, pOut); |
| 67257 | | - }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ |
| 67258 | | - pc = pOp->p2-1; |
| 67259 | 67688 | } |
| 67260 | 67689 | break; |
| 67261 | 67690 | } |
| 67262 | 67691 | }else{ |
| 67263 | 67692 | /* Neither operand is NULL. Do a comparison. */ |
| | @@ -67354,15 +67783,15 @@ |
| 67354 | 67783 | u.al.p2 = pOp->p2; |
| 67355 | 67784 | #if SQLITE_DEBUG |
| 67356 | 67785 | if( aPermute ){ |
| 67357 | 67786 | int k, mx = 0; |
| 67358 | 67787 | for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 67359 | | - assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 ); |
| 67360 | | - assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 ); |
| 67788 | + assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 67789 | + assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 67361 | 67790 | }else{ |
| 67362 | | - assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 ); |
| 67363 | | - assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 ); |
| 67791 | + assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67792 | + assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67364 | 67793 | } |
| 67365 | 67794 | #endif /* SQLITE_DEBUG */ |
| 67366 | 67795 | for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 67367 | 67796 | u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 67368 | 67797 | assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| | @@ -67615,11 +68044,11 @@ |
| 67615 | 68044 | u.ao.p1 = pOp->p1; |
| 67616 | 68045 | u.ao.p2 = pOp->p2; |
| 67617 | 68046 | u.ao.pC = 0; |
| 67618 | 68047 | memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 67619 | 68048 | assert( u.ao.p1<p->nCursor ); |
| 67620 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68049 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 67621 | 68050 | u.ao.pDest = &aMem[pOp->p3]; |
| 67622 | 68051 | memAboutToChange(p, u.ao.pDest); |
| 67623 | 68052 | u.ao.zRec = 0; |
| 67624 | 68053 | |
| 67625 | 68054 | /* This block sets the variable u.ao.payloadSize to be the total number of |
| | @@ -67915,11 +68344,11 @@ |
| 67915 | 68344 | u.ap.zAffinity = pOp->p4.z; |
| 67916 | 68345 | assert( u.ap.zAffinity!=0 ); |
| 67917 | 68346 | assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 67918 | 68347 | pIn1 = &aMem[pOp->p1]; |
| 67919 | 68348 | while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 67920 | | - assert( pIn1 <= &p->aMem[p->nMem] ); |
| 68349 | + assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); |
| 67921 | 68350 | assert( memIsValid(pIn1) ); |
| 67922 | 68351 | ExpandBlob(pIn1); |
| 67923 | 68352 | applyAffinity(pIn1, u.ap.cAff, encoding); |
| 67924 | 68353 | pIn1++; |
| 67925 | 68354 | } |
| | @@ -67978,11 +68407,11 @@ |
| 67978 | 68407 | u.aq.nData = 0; /* Number of bytes of data space */ |
| 67979 | 68408 | u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 67980 | 68409 | u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 67981 | 68410 | u.aq.nField = pOp->p1; |
| 67982 | 68411 | u.aq.zAffinity = pOp->p4.z; |
| 67983 | | - assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 ); |
| 68412 | + assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 ); |
| 67984 | 68413 | u.aq.pData0 = &aMem[u.aq.nField]; |
| 67985 | 68414 | u.aq.nField = pOp->p2; |
| 67986 | 68415 | u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 67987 | 68416 | u.aq.file_format = p->minWriteFileFormat; |
| 67988 | 68417 | |
| | @@ -68044,11 +68473,11 @@ |
| 68044 | 68473 | for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 68045 | 68474 | u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format); |
| 68046 | 68475 | } |
| 68047 | 68476 | assert( u.aq.i==u.aq.nByte ); |
| 68048 | 68477 | |
| 68049 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68478 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 68050 | 68479 | pOut->n = (int)u.aq.nByte; |
| 68051 | 68480 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 68052 | 68481 | pOut->xDel = 0; |
| 68053 | 68482 | if( u.aq.nZero ){ |
| 68054 | 68483 | pOut->u.nZero = u.aq.nZero; |
| | @@ -68640,11 +69069,11 @@ |
| 68640 | 69069 | }else{ |
| 68641 | 69070 | u.ay.wrFlag = 0; |
| 68642 | 69071 | } |
| 68643 | 69072 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 68644 | 69073 | assert( u.ay.p2>0 ); |
| 68645 | | - assert( u.ay.p2<=p->nMem ); |
| 69074 | + assert( u.ay.p2<=(p->nMem-p->nCursor) ); |
| 68646 | 69075 | pIn2 = &aMem[u.ay.p2]; |
| 68647 | 69076 | assert( memIsValid(pIn2) ); |
| 68648 | 69077 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 68649 | 69078 | sqlite3VdbeMemIntegerify(pIn2); |
| 68650 | 69079 | u.ay.p2 = (int)pIn2->u.i; |
| | @@ -69191,11 +69620,11 @@ |
| 69191 | 69620 | |
| 69192 | 69621 | pIn3 = &aMem[pOp->p3]; |
| 69193 | 69622 | u.bf.aMx = &aMem[pOp->p4.i]; |
| 69194 | 69623 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 69195 | 69624 | assert( pOp->p4type==P4_INT32 ); |
| 69196 | | - assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 69625 | + assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) ); |
| 69197 | 69626 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69198 | 69627 | |
| 69199 | 69628 | /* Find the index cursor. */ |
| 69200 | 69629 | u.bf.pCx = p->apCsr[pOp->p1]; |
| 69201 | 69630 | assert( u.bf.pCx->deferredMoveto==0 ); |
| | @@ -69398,11 +69827,11 @@ |
| 69398 | 69827 | /* Assert that P3 is a valid memory cell. */ |
| 69399 | 69828 | assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 69400 | 69829 | u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 69401 | 69830 | }else{ |
| 69402 | 69831 | /* Assert that P3 is a valid memory cell. */ |
| 69403 | | - assert( pOp->p3<=p->nMem ); |
| 69832 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 69404 | 69833 | u.bh.pMem = &aMem[pOp->p3]; |
| 69405 | 69834 | memAboutToChange(p, u.bh.pMem); |
| 69406 | 69835 | } |
| 69407 | 69836 | assert( memIsValid(u.bh.pMem) ); |
| 69408 | 69837 | |
| | @@ -69808,11 +70237,11 @@ |
| 69808 | 70237 | }else if( u.bn.pC->pVtabCursor ){ |
| 69809 | 70238 | u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab; |
| 69810 | 70239 | u.bn.pModule = u.bn.pVtab->pModule; |
| 69811 | 70240 | assert( u.bn.pModule->xRowid ); |
| 69812 | 70241 | rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v); |
| 69813 | | - importVtabErrMsg(p, u.bn.pVtab); |
| 70242 | + sqlite3VtabImportErrmsg(p, u.bn.pVtab); |
| 69814 | 70243 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69815 | 70244 | }else{ |
| 69816 | 70245 | assert( u.bn.pC->pCursor!=0 ); |
| 69817 | 70246 | rc = sqlite3VdbeCursorMoveto(u.bn.pC); |
| 69818 | 70247 | if( rc ) goto abort_due_to_error; |
| | @@ -69900,11 +70329,11 @@ |
| 69900 | 70329 | case OP_Sort: { /* jump */ |
| 69901 | 70330 | #ifdef SQLITE_TEST |
| 69902 | 70331 | sqlite3_sort_count++; |
| 69903 | 70332 | sqlite3_search_count--; |
| 69904 | 70333 | #endif |
| 69905 | | - p->aCounter[SQLITE_STMTSTATUS_SORT-1]++; |
| 70334 | + p->aCounter[SQLITE_STMTSTATUS_SORT]++; |
| 69906 | 70335 | /* Fall through into OP_Rewind */ |
| 69907 | 70336 | } |
| 69908 | 70337 | /* Opcode: Rewind P1 P2 * * * |
| 69909 | 70338 | ** |
| 69910 | 70339 | ** The next use of the Rowid or Column or Next instruction for P1 |
| | @@ -69983,21 +70412,21 @@ |
| 69983 | 70412 | VdbeCursor *pC; |
| 69984 | 70413 | int res; |
| 69985 | 70414 | #endif /* local variables moved into u.br */ |
| 69986 | 70415 | |
| 69987 | 70416 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69988 | | - assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 70417 | + assert( pOp->p5<ArraySize(p->aCounter) ); |
| 69989 | 70418 | u.br.pC = p->apCsr[pOp->p1]; |
| 69990 | 70419 | if( u.br.pC==0 ){ |
| 69991 | 70420 | break; /* See ticket #2273 */ |
| 69992 | 70421 | } |
| 69993 | 70422 | assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 69994 | 70423 | if( isSorter(u.br.pC) ){ |
| 69995 | 70424 | assert( pOp->opcode==OP_SorterNext ); |
| 69996 | 70425 | rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res); |
| 69997 | 70426 | }else{ |
| 69998 | | - u.br.res = 1; |
| 70427 | + /* u.br.res = 1; // Always initialized by the xAdvance() call */ |
| 69999 | 70428 | assert( u.br.pC->deferredMoveto==0 ); |
| 70000 | 70429 | assert( u.br.pC->pCursor ); |
| 70001 | 70430 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 70002 | 70431 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 70003 | 70432 | rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res); |
| | @@ -70004,11 +70433,11 @@ |
| 70004 | 70433 | } |
| 70005 | 70434 | u.br.pC->nullRow = (u8)u.br.res; |
| 70006 | 70435 | u.br.pC->cacheStatus = CACHE_STALE; |
| 70007 | 70436 | if( u.br.res==0 ){ |
| 70008 | 70437 | pc = pOp->p2 - 1; |
| 70009 | | - if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 70438 | + p->aCounter[pOp->p5]++; |
| 70010 | 70439 | #ifdef SQLITE_TEST |
| 70011 | 70440 | sqlite3_search_count++; |
| 70012 | 70441 | #endif |
| 70013 | 70442 | } |
| 70014 | 70443 | u.br.pC->rowidIsValid = 0; |
| | @@ -70076,11 +70505,11 @@ |
| 70076 | 70505 | int res; |
| 70077 | 70506 | UnpackedRecord r; |
| 70078 | 70507 | #endif /* local variables moved into u.bt */ |
| 70079 | 70508 | |
| 70080 | 70509 | assert( pOp->p3>0 ); |
| 70081 | | - assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 70510 | + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); |
| 70082 | 70511 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70083 | 70512 | u.bt.pC = p->apCsr[pOp->p1]; |
| 70084 | 70513 | assert( u.bt.pC!=0 ); |
| 70085 | 70514 | u.bt.pCrsr = u.bt.pC->pCursor; |
| 70086 | 70515 | if( ALWAYS(u.bt.pCrsr!=0) ){ |
| | @@ -70292,10 +70721,11 @@ |
| 70292 | 70721 | int nChange; |
| 70293 | 70722 | #endif /* local variables moved into u.bx */ |
| 70294 | 70723 | |
| 70295 | 70724 | u.bx.nChange = 0; |
| 70296 | 70725 | assert( p->readOnly==0 ); |
| 70726 | + assert( pOp->p1!=1 ); |
| 70297 | 70727 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70298 | 70728 | rc = sqlite3BtreeClearTable( |
| 70299 | 70729 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70300 | 70730 | ); |
| 70301 | 70731 | if( pOp->p3 ){ |
| | @@ -70498,11 +70928,11 @@ |
| 70498 | 70928 | assert( p->bIsReader ); |
| 70499 | 70929 | u.ca.nRoot = pOp->p2; |
| 70500 | 70930 | assert( u.ca.nRoot>0 ); |
| 70501 | 70931 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70502 | 70932 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70503 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 70933 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 70504 | 70934 | u.ca.pnErr = &aMem[pOp->p3]; |
| 70505 | 70935 | assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 70506 | 70936 | assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 70507 | 70937 | pIn1 = &aMem[pOp->p1]; |
| 70508 | 70938 | for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| | @@ -70934,11 +71364,11 @@ |
| 70934 | 71364 | u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 70935 | 71365 | memAboutToChange(p, u.cg.pRec); |
| 70936 | 71366 | sqlite3VdbeMemStoreType(u.cg.pRec); |
| 70937 | 71367 | } |
| 70938 | 71368 | u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 70939 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71369 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 70940 | 71370 | u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 70941 | 71371 | u.cg.pMem->n++; |
| 70942 | 71372 | u.cg.ctx.s.flags = MEM_Null; |
| 70943 | 71373 | u.cg.ctx.s.z = 0; |
| 70944 | 71374 | u.cg.ctx.s.zMalloc = 0; |
| | @@ -70983,11 +71413,11 @@ |
| 70983 | 71413 | */ |
| 70984 | 71414 | case OP_AggFinal: { |
| 70985 | 71415 | #if 0 /* local variables moved into u.ch */ |
| 70986 | 71416 | Mem *pMem; |
| 70987 | 71417 | #endif /* local variables moved into u.ch */ |
| 70988 | | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 71418 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 70989 | 71419 | u.ch.pMem = &aMem[pOp->p1]; |
| 70990 | 71420 | assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 70991 | 71421 | rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 70992 | 71422 | if( rc ){ |
| 70993 | 71423 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| | @@ -71249,11 +71679,11 @@ |
| 71249 | 71679 | #if 0 /* local variables moved into u.cl */ |
| 71250 | 71680 | VTable *pVTab; |
| 71251 | 71681 | #endif /* local variables moved into u.cl */ |
| 71252 | 71682 | u.cl.pVTab = pOp->p4.pVtab; |
| 71253 | 71683 | rc = sqlite3VtabBegin(db, u.cl.pVTab); |
| 71254 | | - if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab); |
| 71684 | + if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab); |
| 71255 | 71685 | break; |
| 71256 | 71686 | } |
| 71257 | 71687 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 71258 | 71688 | |
| 71259 | 71689 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -71302,11 +71732,11 @@ |
| 71302 | 71732 | u.cm.pVtabCursor = 0; |
| 71303 | 71733 | u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 71304 | 71734 | u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 71305 | 71735 | assert(u.cm.pVtab && u.cm.pModule); |
| 71306 | 71736 | rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor); |
| 71307 | | - importVtabErrMsg(p, u.cm.pVtab); |
| 71737 | + sqlite3VtabImportErrmsg(p, u.cm.pVtab); |
| 71308 | 71738 | if( SQLITE_OK==rc ){ |
| 71309 | 71739 | /* Initialize sqlite3_vtab_cursor base class */ |
| 71310 | 71740 | u.cm.pVtabCursor->pVtab = u.cm.pVtab; |
| 71311 | 71741 | |
| 71312 | 71742 | /* Initialize vdbe cursor object */ |
| | @@ -71382,11 +71812,11 @@ |
| 71382 | 71812 | } |
| 71383 | 71813 | |
| 71384 | 71814 | p->inVtabMethod = 1; |
| 71385 | 71815 | rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg); |
| 71386 | 71816 | p->inVtabMethod = 0; |
| 71387 | | - importVtabErrMsg(p, u.cn.pVtab); |
| 71817 | + sqlite3VtabImportErrmsg(p, u.cn.pVtab); |
| 71388 | 71818 | if( rc==SQLITE_OK ){ |
| 71389 | 71819 | u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor); |
| 71390 | 71820 | } |
| 71391 | 71821 | |
| 71392 | 71822 | if( u.cn.res ){ |
| | @@ -71414,11 +71844,11 @@ |
| 71414 | 71844 | sqlite3_context sContext; |
| 71415 | 71845 | #endif /* local variables moved into u.co */ |
| 71416 | 71846 | |
| 71417 | 71847 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 71418 | 71848 | assert( pCur->pVtabCursor ); |
| 71419 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71849 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 71420 | 71850 | u.co.pDest = &aMem[pOp->p3]; |
| 71421 | 71851 | memAboutToChange(p, u.co.pDest); |
| 71422 | 71852 | if( pCur->nullRow ){ |
| 71423 | 71853 | sqlite3VdbeMemSetNull(u.co.pDest); |
| 71424 | 71854 | break; |
| | @@ -71435,11 +71865,11 @@ |
| 71435 | 71865 | */ |
| 71436 | 71866 | sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest); |
| 71437 | 71867 | MemSetTypeFlag(&u.co.sContext.s, MEM_Null); |
| 71438 | 71868 | |
| 71439 | 71869 | rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2); |
| 71440 | | - importVtabErrMsg(p, u.co.pVtab); |
| 71870 | + sqlite3VtabImportErrmsg(p, u.co.pVtab); |
| 71441 | 71871 | if( u.co.sContext.isError ){ |
| 71442 | 71872 | rc = u.co.sContext.isError; |
| 71443 | 71873 | } |
| 71444 | 71874 | |
| 71445 | 71875 | /* Copy the result of the function to the P3 register. We |
| | @@ -71490,11 +71920,11 @@ |
| 71490 | 71920 | ** some other method is next invoked on the save virtual table cursor. |
| 71491 | 71921 | */ |
| 71492 | 71922 | p->inVtabMethod = 1; |
| 71493 | 71923 | rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor); |
| 71494 | 71924 | p->inVtabMethod = 0; |
| 71495 | | - importVtabErrMsg(p, u.cp.pVtab); |
| 71925 | + sqlite3VtabImportErrmsg(p, u.cp.pVtab); |
| 71496 | 71926 | if( rc==SQLITE_OK ){ |
| 71497 | 71927 | u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor); |
| 71498 | 71928 | } |
| 71499 | 71929 | |
| 71500 | 71930 | if( !u.cp.res ){ |
| | @@ -71529,11 +71959,11 @@ |
| 71529 | 71959 | testcase( u.cq.pName->enc==SQLITE_UTF16BE ); |
| 71530 | 71960 | testcase( u.cq.pName->enc==SQLITE_UTF16LE ); |
| 71531 | 71961 | rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8); |
| 71532 | 71962 | if( rc==SQLITE_OK ){ |
| 71533 | 71963 | rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z); |
| 71534 | | - importVtabErrMsg(p, u.cq.pVtab); |
| 71964 | + sqlite3VtabImportErrmsg(p, u.cq.pVtab); |
| 71535 | 71965 | p->expired = 0; |
| 71536 | 71966 | } |
| 71537 | 71967 | break; |
| 71538 | 71968 | } |
| 71539 | 71969 | #endif |
| | @@ -71593,11 +72023,11 @@ |
| 71593 | 72023 | u.cr.pX++; |
| 71594 | 72024 | } |
| 71595 | 72025 | db->vtabOnConflict = pOp->p5; |
| 71596 | 72026 | rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid); |
| 71597 | 72027 | db->vtabOnConflict = vtabOnConflict; |
| 71598 | | - importVtabErrMsg(p, u.cr.pVtab); |
| 72028 | + sqlite3VtabImportErrmsg(p, u.cr.pVtab); |
| 71599 | 72029 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 71600 | 72030 | assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) ); |
| 71601 | 72031 | db->lastRowid = lastRowid = u.cr.rowid; |
| 71602 | 72032 | } |
| 71603 | 72033 | if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| | @@ -71760,11 +72190,12 @@ |
| 71760 | 72190 | /* This is the only way out of this procedure. We have to |
| 71761 | 72191 | ** release the mutexes on btrees that were acquired at the |
| 71762 | 72192 | ** top. */ |
| 71763 | 72193 | vdbe_return: |
| 71764 | 72194 | db->lastRowid = lastRowid; |
| 71765 | | - p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep; |
| 72195 | + testcase( nVmStep>0 ); |
| 72196 | + p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; |
| 71766 | 72197 | sqlite3VdbeLeave(p); |
| 71767 | 72198 | return rc; |
| 71768 | 72199 | |
| 71769 | 72200 | /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH |
| 71770 | 72201 | ** is encountered. |
| | @@ -75520,12 +75951,11 @@ |
| 75520 | 75951 | int op = p->op; |
| 75521 | 75952 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 75522 | 75953 | p = p->pLeft; |
| 75523 | 75954 | continue; |
| 75524 | 75955 | } |
| 75525 | | - assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); |
| 75526 | | - if( op==TK_COLLATE ){ |
| 75956 | + if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ |
| 75527 | 75957 | pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); |
| 75528 | 75958 | break; |
| 75529 | 75959 | } |
| 75530 | 75960 | if( p->pTab!=0 |
| 75531 | 75961 | && (op==TK_AGG_COLUMN || op==TK_COLUMN |
| | @@ -76685,10 +77115,11 @@ |
| 76685 | 77115 | break; |
| 76686 | 77116 | } |
| 76687 | 77117 | case TK_UMINUS: { |
| 76688 | 77118 | int v; |
| 76689 | 77119 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 77120 | + assert( v!=(-2147483647-1) ); |
| 76690 | 77121 | *pValue = -v; |
| 76691 | 77122 | rc = 1; |
| 76692 | 77123 | } |
| 76693 | 77124 | break; |
| 76694 | 77125 | } |
| | @@ -78910,10 +79341,11 @@ |
| 78910 | 79341 | compLeft.pRight = pExpr->x.pList->a[0].pExpr; |
| 78911 | 79342 | compRight.op = TK_LE; |
| 78912 | 79343 | compRight.pLeft = &exprX; |
| 78913 | 79344 | compRight.pRight = pExpr->x.pList->a[1].pExpr; |
| 78914 | 79345 | exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); |
| 79346 | + exprX.op2 = exprX.op; |
| 78915 | 79347 | exprX.op = TK_REGISTER; |
| 78916 | 79348 | if( jumpIfTrue ){ |
| 78917 | 79349 | sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); |
| 78918 | 79350 | }else{ |
| 78919 | 79351 | sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); |
| | @@ -80343,11 +80775,11 @@ |
| 80343 | 80775 | |
| 80344 | 80776 | /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 80345 | 80777 | ** can handle (i.e. not CURRENT_TIME etc.) |
| 80346 | 80778 | */ |
| 80347 | 80779 | if( pDflt ){ |
| 80348 | | - sqlite3_value *pVal; |
| 80780 | + sqlite3_value *pVal = 0; |
| 80349 | 80781 | if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 80350 | 80782 | db->mallocFailed = 1; |
| 80351 | 80783 | return; |
| 80352 | 80784 | } |
| 80353 | 80785 | if( !pVal ){ |
| | @@ -80484,11 +80916,11 @@ |
| 80484 | 80916 | #endif /* SQLITE_ALTER_TABLE */ |
| 80485 | 80917 | |
| 80486 | 80918 | /************** End of alter.c ***********************************************/ |
| 80487 | 80919 | /************** Begin file analyze.c *****************************************/ |
| 80488 | 80920 | /* |
| 80489 | | -** 2005 July 8 |
| 80921 | +** 2005-07-08 |
| 80490 | 80922 | ** |
| 80491 | 80923 | ** The author disclaims copyright to this source code. In place of |
| 80492 | 80924 | ** a legal notice, here is a blessing: |
| 80493 | 80925 | ** |
| 80494 | 80926 | ** May you do good and not evil. |
| | @@ -80505,27 +80937,36 @@ |
| 80505 | 80937 | ** The following system tables are or have been supported: |
| 80506 | 80938 | ** |
| 80507 | 80939 | ** CREATE TABLE sqlite_stat1(tbl, idx, stat); |
| 80508 | 80940 | ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); |
| 80509 | 80941 | ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); |
| 80942 | +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); |
| 80510 | 80943 | ** |
| 80511 | 80944 | ** Additional tables might be added in future releases of SQLite. |
| 80512 | 80945 | ** The sqlite_stat2 table is not created or used unless the SQLite version |
| 80513 | 80946 | ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled |
| 80514 | 80947 | ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. |
| 80515 | 80948 | ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only |
| 80516 | 80949 | ** created and used by SQLite versions 3.7.9 and later and with |
| 80517 | | -** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3 |
| 80518 | | -** is a superset of sqlite_stat2. |
| 80950 | +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 80951 | +** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 80952 | +** version of sqlite_stat3 and is only available when compiled with |
| 80953 | +** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 80954 | +** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 80955 | +** are both enabled, then STAT4 is precedence. |
| 80956 | +** |
| 80957 | +** For most applications, sqlite_stat1 provides all the statisics required |
| 80958 | +** for the query planner to make good choices. |
| 80519 | 80959 | ** |
| 80520 | 80960 | ** Format of sqlite_stat1: |
| 80521 | 80961 | ** |
| 80522 | 80962 | ** There is normally one row per index, with the index identified by the |
| 80523 | 80963 | ** name in the idx column. The tbl column is the name of the table to |
| 80524 | 80964 | ** which the index belongs. In each such row, the stat column will be |
| 80525 | 80965 | ** a string consisting of a list of integers. The first integer in this |
| 80526 | | -** list is the number of rows in the index and in the table. The second |
| 80966 | +** list is the number of rows in the index. (This is the same as the |
| 80967 | +** number of rows in the table, except for partial indices.) The second |
| 80527 | 80968 | ** integer is the average number of rows in the index that have the same |
| 80528 | 80969 | ** value in the first column of the index. The third integer is the average |
| 80529 | 80970 | ** number of rows in the index that have the same value for the first two |
| 80530 | 80971 | ** columns. The N-th integer (for N>1) is the average number of rows in |
| 80531 | 80972 | ** the index which have the same value for the first N-1 columns. For |
| | @@ -80568,57 +81009,85 @@ |
| 80568 | 81009 | ** writes the sqlite_stat2 table. This version of SQLite only supports |
| 80569 | 81010 | ** sqlite_stat3. |
| 80570 | 81011 | ** |
| 80571 | 81012 | ** Format for sqlite_stat3: |
| 80572 | 81013 | ** |
| 80573 | | -** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is |
| 80574 | | -** used to avoid compatibility problems. |
| 81014 | +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the |
| 81015 | +** sqlite_stat4 format will be described first. Further information |
| 81016 | +** about sqlite_stat3 follows the sqlite_stat4 description. |
| 80575 | 81017 | ** |
| 80576 | | -** The format of the sqlite_stat3 table is similar to the format of |
| 80577 | | -** the sqlite_stat2 table. There are multiple entries for each index. |
| 81018 | +** Format for sqlite_stat4: |
| 81019 | +** |
| 81020 | +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data |
| 81021 | +** to aid the query planner in choosing good indices based on the values |
| 81022 | +** that indexed columns are compared against in the WHERE clauses of |
| 81023 | +** queries. |
| 81024 | +** |
| 81025 | +** The sqlite_stat4 table contains multiple entries for each index. |
| 80578 | 81026 | ** The idx column names the index and the tbl column is the table of the |
| 80579 | 81027 | ** index. If the idx and tbl columns are the same, then the sample is |
| 80580 | | -** of the INTEGER PRIMARY KEY. The sample column is a value taken from |
| 80581 | | -** the left-most column of the index. The nEq column is the approximate |
| 80582 | | -** number of entires in the index whose left-most column exactly matches |
| 80583 | | -** the sample. nLt is the approximate number of entires whose left-most |
| 80584 | | -** column is less than the sample. The nDLt column is the approximate |
| 80585 | | -** number of distinct left-most entries in the index that are less than |
| 80586 | | -** the sample. |
| 80587 | | -** |
| 80588 | | -** Future versions of SQLite might change to store a string containing |
| 80589 | | -** multiple integers values in the nDLt column of sqlite_stat3. The first |
| 80590 | | -** integer will be the number of prior index entires that are distinct in |
| 80591 | | -** the left-most column. The second integer will be the number of prior index |
| 80592 | | -** entries that are distinct in the first two columns. The third integer |
| 80593 | | -** will be the number of prior index entries that are distinct in the first |
| 80594 | | -** three columns. And so forth. With that extension, the nDLt field is |
| 80595 | | -** similar in function to the sqlite_stat1.stat field. |
| 80596 | | -** |
| 80597 | | -** There can be an arbitrary number of sqlite_stat3 entries per index. |
| 80598 | | -** The ANALYZE command will typically generate sqlite_stat3 tables |
| 81028 | +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the |
| 81029 | +** binary encoding of a key from the index, with the trailing rowid |
| 81030 | +** omitted. The nEq column is a list of integers. The first integer |
| 81031 | +** is the approximate number of entries in the index whose left-most |
| 81032 | +** column exactly matches the left-most column of the sample. The second |
| 81033 | +** integer in nEq is the approximate number of entries in the index where |
| 81034 | +** the first two columns match the first two columns of the sample. |
| 81035 | +** And so forth. nLt is another list of integers that show the approximate |
| 81036 | +** number of entries that are strictly less than the sample. The first |
| 81037 | +** integer in nLt contains the number of entries in the index where the |
| 81038 | +** left-most column is less than the left-most column of the sample. |
| 81039 | +** The K-th integer in the nLt entry is the number of index entries |
| 81040 | +** where the first K columns are less than the first K columns of the |
| 81041 | +** sample. The nDLt column is like nLt except that it contains the |
| 81042 | +** number of distinct entries in the index that are less than the |
| 81043 | +** sample. |
| 81044 | +** |
| 81045 | +** There can be an arbitrary number of sqlite_stat4 entries per index. |
| 81046 | +** The ANALYZE command will typically generate sqlite_stat4 tables |
| 80599 | 81047 | ** that contain between 10 and 40 samples which are distributed across |
| 80600 | 81048 | ** the key space, though not uniformly, and which include samples with |
| 80601 | | -** largest possible nEq values. |
| 81049 | +** large nEq values. |
| 81050 | +** |
| 81051 | +** Format for sqlite_stat3 redux: |
| 81052 | +** |
| 81053 | +** The sqlite_stat3 table is like sqlite_stat4 except that it only |
| 81054 | +** looks at the left-most column of the index. The sqlite_stat3.sample |
| 81055 | +** column contains the actual value of the left-most column instead |
| 81056 | +** of a blob encoding of the complete index key as is found in |
| 81057 | +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 |
| 81058 | +** all contain just a single integer which is the same as the first |
| 81059 | +** integer in the equivalent columns in sqlite_stat4. |
| 80602 | 81060 | */ |
| 80603 | 81061 | #ifndef SQLITE_OMIT_ANALYZE |
| 80604 | 81062 | |
| 81063 | +#if defined(SQLITE_ENABLE_STAT4) |
| 81064 | +# define IsStat4 1 |
| 81065 | +# define IsStat3 0 |
| 81066 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 81067 | +# define IsStat4 0 |
| 81068 | +# define IsStat3 1 |
| 81069 | +#else |
| 81070 | +# define IsStat4 0 |
| 81071 | +# define IsStat3 0 |
| 81072 | +# undef SQLITE_STAT4_SAMPLES |
| 81073 | +# define SQLITE_STAT4_SAMPLES 1 |
| 81074 | +#endif |
| 81075 | +#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ |
| 81076 | + |
| 80605 | 81077 | /* |
| 80606 | | -** This routine generates code that opens the sqlite_stat1 table for |
| 80607 | | -** writing with cursor iStatCur. If the library was built with the |
| 80608 | | -** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is |
| 80609 | | -** opened for writing using cursor (iStatCur+1) |
| 81078 | +** This routine generates code that opens the sqlite_statN tables. |
| 81079 | +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now |
| 81080 | +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when |
| 81081 | +** appropriate compile-time options are provided. |
| 80610 | 81082 | ** |
| 80611 | | -** If the sqlite_stat1 tables does not previously exist, it is created. |
| 80612 | | -** Similarly, if the sqlite_stat3 table does not exist and the library |
| 80613 | | -** is compiled with SQLITE_ENABLE_STAT3 defined, it is created. |
| 81083 | +** If the sqlite_statN tables do not previously exist, it is created. |
| 80614 | 81084 | ** |
| 80615 | 81085 | ** Argument zWhere may be a pointer to a buffer containing a table name, |
| 80616 | 81086 | ** or it may be a NULL pointer. If it is not NULL, then all entries in |
| 80617 | | -** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated |
| 80618 | | -** with the named table are deleted. If zWhere==0, then code is generated |
| 80619 | | -** to delete all stat table entries. |
| 81087 | +** the sqlite_statN tables associated with the named table are deleted. |
| 81088 | +** If zWhere==0, then code is generated to delete all stat table entries. |
| 80620 | 81089 | */ |
| 80621 | 81090 | static void openStatTable( |
| 80622 | 81091 | Parse *pParse, /* Parsing context */ |
| 80623 | 81092 | int iDb, /* The database we are looking in */ |
| 80624 | 81093 | int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
| | @@ -80628,22 +81097,28 @@ |
| 80628 | 81097 | static const struct { |
| 80629 | 81098 | const char *zName; |
| 80630 | 81099 | const char *zCols; |
| 80631 | 81100 | } aTable[] = { |
| 80632 | 81101 | { "sqlite_stat1", "tbl,idx,stat" }, |
| 80633 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81102 | +#if defined(SQLITE_ENABLE_STAT4) |
| 81103 | + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81104 | + { "sqlite_stat3", 0 }, |
| 81105 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 80634 | 81106 | { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81107 | + { "sqlite_stat4", 0 }, |
| 81108 | +#else |
| 81109 | + { "sqlite_stat3", 0 }, |
| 81110 | + { "sqlite_stat4", 0 }, |
| 80635 | 81111 | #endif |
| 80636 | 81112 | }; |
| 80637 | | - |
| 80638 | | - int aRoot[] = {0, 0}; |
| 80639 | | - u8 aCreateTbl[] = {0, 0}; |
| 80640 | | - |
| 80641 | 81113 | int i; |
| 80642 | 81114 | sqlite3 *db = pParse->db; |
| 80643 | 81115 | Db *pDb; |
| 80644 | 81116 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 81117 | + int aRoot[ArraySize(aTable)]; |
| 81118 | + u8 aCreateTbl[ArraySize(aTable)]; |
| 81119 | + |
| 80645 | 81120 | if( v==0 ) return; |
| 80646 | 81121 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 80647 | 81122 | assert( sqlite3VdbeDb(v)==db ); |
| 80648 | 81123 | pDb = &db->aDb[iDb]; |
| 80649 | 81124 | |
| | @@ -80652,262 +81127,592 @@ |
| 80652 | 81127 | */ |
| 80653 | 81128 | for(i=0; i<ArraySize(aTable); i++){ |
| 80654 | 81129 | const char *zTab = aTable[i].zName; |
| 80655 | 81130 | Table *pStat; |
| 80656 | 81131 | if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ |
| 80657 | | - /* The sqlite_stat[12] table does not exist. Create it. Note that a |
| 80658 | | - ** side-effect of the CREATE TABLE statement is to leave the rootpage |
| 80659 | | - ** of the new table in register pParse->regRoot. This is important |
| 80660 | | - ** because the OpenWrite opcode below will be needing it. */ |
| 80661 | | - sqlite3NestedParse(pParse, |
| 80662 | | - "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 80663 | | - ); |
| 80664 | | - aRoot[i] = pParse->regRoot; |
| 80665 | | - aCreateTbl[i] = OPFLAG_P2ISREG; |
| 81132 | + if( aTable[i].zCols ){ |
| 81133 | + /* The sqlite_statN table does not exist. Create it. Note that a |
| 81134 | + ** side-effect of the CREATE TABLE statement is to leave the rootpage |
| 81135 | + ** of the new table in register pParse->regRoot. This is important |
| 81136 | + ** because the OpenWrite opcode below will be needing it. */ |
| 81137 | + sqlite3NestedParse(pParse, |
| 81138 | + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 81139 | + ); |
| 81140 | + aRoot[i] = pParse->regRoot; |
| 81141 | + aCreateTbl[i] = OPFLAG_P2ISREG; |
| 81142 | + } |
| 80666 | 81143 | }else{ |
| 80667 | 81144 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 80668 | 81145 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 80669 | 81146 | ** entire contents of the table. */ |
| 80670 | 81147 | aRoot[i] = pStat->tnum; |
| 81148 | + aCreateTbl[i] = 0; |
| 80671 | 81149 | sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
| 80672 | 81150 | if( zWhere ){ |
| 80673 | 81151 | sqlite3NestedParse(pParse, |
| 80674 | | - "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere |
| 81152 | + "DELETE FROM %Q.%s WHERE %s=%Q", |
| 81153 | + pDb->zName, zTab, zWhereType, zWhere |
| 80675 | 81154 | ); |
| 80676 | 81155 | }else{ |
| 80677 | | - /* The sqlite_stat[12] table already exists. Delete all rows. */ |
| 81156 | + /* The sqlite_stat[134] table already exists. Delete all rows. */ |
| 80678 | 81157 | sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
| 80679 | 81158 | } |
| 80680 | 81159 | } |
| 80681 | 81160 | } |
| 80682 | 81161 | |
| 80683 | | - /* Open the sqlite_stat[13] tables for writing. */ |
| 80684 | | - for(i=0; i<ArraySize(aTable); i++){ |
| 81162 | + /* Open the sqlite_stat[134] tables for writing. */ |
| 81163 | + for(i=0; aTable[i].zCols; i++){ |
| 81164 | + assert( i<ArraySize(aTable) ); |
| 80685 | 81165 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); |
| 80686 | 81166 | sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); |
| 80687 | 81167 | sqlite3VdbeChangeP5(v, aCreateTbl[i]); |
| 80688 | 81168 | } |
| 80689 | 81169 | } |
| 80690 | 81170 | |
| 80691 | 81171 | /* |
| 80692 | | -** Recommended number of samples for sqlite_stat3 |
| 81172 | +** Recommended number of samples for sqlite_stat4 |
| 80693 | 81173 | */ |
| 80694 | | -#ifndef SQLITE_STAT3_SAMPLES |
| 80695 | | -# define SQLITE_STAT3_SAMPLES 24 |
| 81174 | +#ifndef SQLITE_STAT4_SAMPLES |
| 81175 | +# define SQLITE_STAT4_SAMPLES 24 |
| 80696 | 81176 | #endif |
| 80697 | 81177 | |
| 80698 | 81178 | /* |
| 80699 | | -** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() - |
| 81179 | +** Three SQL functions - stat_init(), stat_push(), and stat_get() - |
| 80700 | 81180 | ** share an instance of the following structure to hold their state |
| 80701 | 81181 | ** information. |
| 80702 | 81182 | */ |
| 80703 | | -typedef struct Stat3Accum Stat3Accum; |
| 80704 | | -struct Stat3Accum { |
| 81183 | +typedef struct Stat4Accum Stat4Accum; |
| 81184 | +typedef struct Stat4Sample Stat4Sample; |
| 81185 | +struct Stat4Sample { |
| 81186 | + tRowcnt *anEq; /* sqlite_stat4.nEq */ |
| 81187 | + tRowcnt *anDLt; /* sqlite_stat4.nDLt */ |
| 81188 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81189 | + tRowcnt *anLt; /* sqlite_stat4.nLt */ |
| 81190 | + i64 iRowid; /* Rowid in main table of the key */ |
| 81191 | + u8 isPSample; /* True if a periodic sample */ |
| 81192 | + int iCol; /* If !isPSample, the reason for inclusion */ |
| 81193 | + u32 iHash; /* Tiebreaker hash */ |
| 81194 | +#endif |
| 81195 | +}; |
| 81196 | +struct Stat4Accum { |
| 80705 | 81197 | tRowcnt nRow; /* Number of rows in the entire table */ |
| 80706 | 81198 | tRowcnt nPSample; /* How often to do a periodic sample */ |
| 80707 | | - int iMin; /* Index of entry with minimum nEq and hash */ |
| 81199 | + int nCol; /* Number of columns in index + rowid */ |
| 80708 | 81200 | int mxSample; /* Maximum number of samples to accumulate */ |
| 80709 | | - int nSample; /* Current number of samples */ |
| 81201 | + Stat4Sample current; /* Current row as a Stat4Sample */ |
| 80710 | 81202 | u32 iPrn; /* Pseudo-random number used for sampling */ |
| 80711 | | - struct Stat3Sample { |
| 80712 | | - i64 iRowid; /* Rowid in main table of the key */ |
| 80713 | | - tRowcnt nEq; /* sqlite_stat3.nEq */ |
| 80714 | | - tRowcnt nLt; /* sqlite_stat3.nLt */ |
| 80715 | | - tRowcnt nDLt; /* sqlite_stat3.nDLt */ |
| 80716 | | - u8 isPSample; /* True if a periodic sample */ |
| 80717 | | - u32 iHash; /* Tiebreaker hash */ |
| 80718 | | - } *a; /* An array of samples */ |
| 81203 | + Stat4Sample *aBest; /* Array of (nCol-1) best samples */ |
| 81204 | + int iMin; /* Index in a[] of entry with minimum score */ |
| 81205 | + int nSample; /* Current number of samples */ |
| 81206 | + int iGet; /* Index of current sample accessed by stat_get() */ |
| 81207 | + Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ |
| 80719 | 81208 | }; |
| 80720 | 81209 | |
| 80721 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 80722 | 81210 | /* |
| 80723 | | -** Implementation of the stat3_init(C,S) SQL function. The two parameters |
| 80724 | | -** are the number of rows in the table or index (C) and the number of samples |
| 80725 | | -** to accumulate (S). |
| 80726 | | -** |
| 80727 | | -** This routine allocates the Stat3Accum object. |
| 80728 | | -** |
| 80729 | | -** The return value is the Stat3Accum object (P). |
| 80730 | | -*/ |
| 80731 | | -static void stat3Init( |
| 81211 | +** Implementation of the stat_init(N,C) SQL function. The two parameters |
| 81212 | +** are the number of rows in the table or index (C) and the number of columns |
| 81213 | +** in the index (N). The second argument (C) is only used for STAT3 and STAT4. |
| 81214 | +** |
| 81215 | +** This routine allocates the Stat4Accum object in heap memory. The return |
| 81216 | +** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 81217 | +** the size of the blob is sizeof(void*) bytes). |
| 81218 | +*/ |
| 81219 | +static void statInit( |
| 80732 | 81220 | sqlite3_context *context, |
| 80733 | 81221 | int argc, |
| 80734 | 81222 | sqlite3_value **argv |
| 80735 | 81223 | ){ |
| 80736 | | - Stat3Accum *p; |
| 80737 | | - tRowcnt nRow; |
| 80738 | | - int mxSample; |
| 80739 | | - int n; |
| 81224 | + Stat4Accum *p; |
| 81225 | + int nCol; /* Number of columns in index being sampled */ |
| 81226 | + int nColUp; /* nCol rounded up for alignment */ |
| 81227 | + int n; /* Bytes of space to allocate */ |
| 81228 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81229 | + int mxSample = SQLITE_STAT4_SAMPLES; |
| 81230 | +#endif |
| 80740 | 81231 | |
| 81232 | + /* Decode the three function arguments */ |
| 80741 | 81233 | UNUSED_PARAMETER(argc); |
| 80742 | | - nRow = (tRowcnt)sqlite3_value_int64(argv[0]); |
| 80743 | | - mxSample = sqlite3_value_int(argv[1]); |
| 80744 | | - n = sizeof(*p) + sizeof(p->a[0])*mxSample; |
| 80745 | | - p = sqlite3MallocZero( n ); |
| 81234 | + nCol = sqlite3_value_int(argv[0]); |
| 81235 | + assert( nCol>1 ); /* >1 because it includes the rowid column */ |
| 81236 | + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; |
| 81237 | + |
| 81238 | + /* Allocate the space required for the Stat4Accum object */ |
| 81239 | + n = sizeof(*p) |
| 81240 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ |
| 81241 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ |
| 81242 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81243 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ |
| 81244 | + + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ |
| 81245 | + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) |
| 81246 | +#endif |
| 81247 | + ; |
| 81248 | + p = sqlite3MallocZero(n); |
| 80746 | 81249 | if( p==0 ){ |
| 80747 | 81250 | sqlite3_result_error_nomem(context); |
| 80748 | 81251 | return; |
| 80749 | 81252 | } |
| 80750 | | - p->a = (struct Stat3Sample*)&p[1]; |
| 80751 | | - p->nRow = nRow; |
| 80752 | | - p->mxSample = mxSample; |
| 80753 | | - p->nPSample = p->nRow/(mxSample/3+1) + 1; |
| 80754 | | - sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81253 | + |
| 81254 | + p->nRow = 0; |
| 81255 | + p->nCol = nCol; |
| 81256 | + p->current.anDLt = (tRowcnt*)&p[1]; |
| 81257 | + p->current.anEq = &p->current.anDLt[nColUp]; |
| 81258 | + |
| 81259 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81260 | + { |
| 81261 | + u8 *pSpace; /* Allocated space not yet assigned */ |
| 81262 | + int i; /* Used to iterate through p->aSample[] */ |
| 81263 | + |
| 81264 | + p->iGet = -1; |
| 81265 | + p->mxSample = mxSample; |
| 81266 | + p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1; |
| 81267 | + p->current.anLt = &p->current.anEq[nColUp]; |
| 81268 | + sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81269 | + |
| 81270 | + /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81271 | + p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| 81272 | + p->aBest = &p->a[mxSample]; |
| 81273 | + pSpace = (u8*)(&p->a[mxSample+nCol]); |
| 81274 | + for(i=0; i<(mxSample+nCol); i++){ |
| 81275 | + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81276 | + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81277 | + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81278 | + } |
| 81279 | + assert( (pSpace - (u8*)p)==n ); |
| 81280 | + |
| 81281 | + for(i=0; i<nCol; i++){ |
| 81282 | + p->aBest[i].iCol = i; |
| 81283 | + } |
| 81284 | + } |
| 81285 | +#endif |
| 81286 | + |
| 81287 | + /* Return a pointer to the allocated object to the caller */ |
| 80755 | 81288 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 80756 | 81289 | } |
| 80757 | | -static const FuncDef stat3InitFuncdef = { |
| 80758 | | - 2, /* nArg */ |
| 80759 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80760 | | - 0, /* flags */ |
| 80761 | | - 0, /* pUserData */ |
| 80762 | | - 0, /* pNext */ |
| 80763 | | - stat3Init, /* xFunc */ |
| 80764 | | - 0, /* xStep */ |
| 80765 | | - 0, /* xFinalize */ |
| 80766 | | - "stat3_init", /* zName */ |
| 80767 | | - 0, /* pHash */ |
| 80768 | | - 0 /* pDestructor */ |
| 80769 | | -}; |
| 80770 | | - |
| 80771 | | - |
| 80772 | | -/* |
| 80773 | | -** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The |
| 80774 | | -** arguments describe a single key instance. This routine makes the |
| 80775 | | -** decision about whether or not to retain this key for the sqlite_stat3 |
| 80776 | | -** table. |
| 80777 | | -** |
| 80778 | | -** The return value is NULL. |
| 80779 | | -*/ |
| 80780 | | -static void stat3Push( |
| 80781 | | - sqlite3_context *context, |
| 80782 | | - int argc, |
| 80783 | | - sqlite3_value **argv |
| 80784 | | -){ |
| 80785 | | - Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]); |
| 80786 | | - tRowcnt nEq = sqlite3_value_int64(argv[0]); |
| 80787 | | - tRowcnt nLt = sqlite3_value_int64(argv[1]); |
| 80788 | | - tRowcnt nDLt = sqlite3_value_int64(argv[2]); |
| 80789 | | - i64 rowid = sqlite3_value_int64(argv[3]); |
| 80790 | | - u8 isPSample = 0; |
| 80791 | | - u8 doInsert = 0; |
| 80792 | | - int iMin = p->iMin; |
| 80793 | | - struct Stat3Sample *pSample; |
| 80794 | | - int i; |
| 80795 | | - u32 h; |
| 80796 | | - |
| 80797 | | - UNUSED_PARAMETER(context); |
| 80798 | | - UNUSED_PARAMETER(argc); |
| 80799 | | - if( nEq==0 ) return; |
| 80800 | | - h = p->iPrn = p->iPrn*1103515245 + 12345; |
| 80801 | | - if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ |
| 80802 | | - doInsert = isPSample = 1; |
| 80803 | | - }else if( p->nSample<p->mxSample ){ |
| 80804 | | - doInsert = 1; |
| 80805 | | - }else{ |
| 80806 | | - if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ |
| 80807 | | - doInsert = 1; |
| 80808 | | - } |
| 80809 | | - } |
| 80810 | | - if( !doInsert ) return; |
| 80811 | | - if( p->nSample==p->mxSample ){ |
| 80812 | | - assert( p->nSample - iMin - 1 >= 0 ); |
| 80813 | | - memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); |
| 81290 | +static const FuncDef statInitFuncdef = { |
| 81291 | + 1+IsStat34, /* nArg */ |
| 81292 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81293 | + 0, /* flags */ |
| 81294 | + 0, /* pUserData */ |
| 81295 | + 0, /* pNext */ |
| 81296 | + statInit, /* xFunc */ |
| 81297 | + 0, /* xStep */ |
| 81298 | + 0, /* xFinalize */ |
| 81299 | + "stat_init", /* zName */ |
| 81300 | + 0, /* pHash */ |
| 81301 | + 0 /* pDestructor */ |
| 81302 | +}; |
| 81303 | + |
| 81304 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81305 | +/* |
| 81306 | +** Return true if pNew is to be preferred over pOld. |
| 81307 | +*/ |
| 81308 | +static int sampleIsBetter(Stat4Sample *pNew, Stat4Sample *pOld){ |
| 81309 | + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81310 | + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81311 | + |
| 81312 | + assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81313 | + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81314 | + |
| 81315 | + if( (nEqNew>nEqOld) |
| 81316 | + || (nEqNew==nEqOld && pNew->iCol<pOld->iCol) |
| 81317 | + || (nEqNew==nEqOld && pNew->iCol==pOld->iCol && pNew->iHash>pOld->iHash) |
| 81318 | + ){ |
| 81319 | + return 1; |
| 81320 | + } |
| 81321 | + return 0; |
| 81322 | +} |
| 81323 | + |
| 81324 | +/* |
| 81325 | +** Copy the contents of object (*pFrom) into (*pTo). |
| 81326 | +*/ |
| 81327 | +void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ |
| 81328 | + pTo->iRowid = pFrom->iRowid; |
| 81329 | + pTo->isPSample = pFrom->isPSample; |
| 81330 | + pTo->iCol = pFrom->iCol; |
| 81331 | + pTo->iHash = pFrom->iHash; |
| 81332 | + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); |
| 81333 | + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); |
| 81334 | + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); |
| 81335 | +} |
| 81336 | + |
| 81337 | +/* |
| 81338 | +** Copy the contents of sample *pNew into the p->a[] array. If necessary, |
| 81339 | +** remove the least desirable sample from p->a[] to make room. |
| 81340 | +*/ |
| 81341 | +static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81342 | + Stat4Sample *pSample; |
| 81343 | + int i; |
| 81344 | + i64 iSeq; |
| 81345 | + i64 iPos; |
| 81346 | + |
| 81347 | + assert( IsStat4 || nEqZero==0 ); |
| 81348 | + |
| 81349 | + if( pNew->isPSample==0 ){ |
| 81350 | + Stat4Sample *pUpgrade = 0; |
| 81351 | + assert( pNew->anEq[pNew->iCol]>0 ); |
| 81352 | + |
| 81353 | + /* This sample is being added because the prefix that ends in column |
| 81354 | + ** iCol occurs many times in the table. However, if we have already |
| 81355 | + ** added a sample that shares this prefix, there is no need to add |
| 81356 | + ** this one. Instead, upgrade the priority of the highest priority |
| 81357 | + ** existing sample that shares this prefix. */ |
| 81358 | + for(i=p->nSample-1; i>=0; i--){ |
| 81359 | + Stat4Sample *pOld = &p->a[i]; |
| 81360 | + if( pOld->anEq[pNew->iCol]==0 ){ |
| 81361 | + if( pOld->isPSample ) return; |
| 81362 | + assert( sampleIsBetter(pNew, pOld) ); |
| 81363 | + if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ |
| 81364 | + pUpgrade = pOld; |
| 81365 | + } |
| 81366 | + } |
| 81367 | + } |
| 81368 | + if( pUpgrade ){ |
| 81369 | + pUpgrade->iCol = pNew->iCol; |
| 81370 | + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; |
| 81371 | + goto find_new_min; |
| 81372 | + } |
| 81373 | + } |
| 81374 | + |
| 81375 | + /* If necessary, remove sample iMin to make room for the new sample. */ |
| 81376 | + if( p->nSample>=p->mxSample ){ |
| 81377 | + Stat4Sample *pMin = &p->a[p->iMin]; |
| 81378 | + tRowcnt *anEq = pMin->anEq; |
| 81379 | + tRowcnt *anLt = pMin->anLt; |
| 81380 | + tRowcnt *anDLt = pMin->anDLt; |
| 81381 | + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); |
| 80814 | 81382 | pSample = &p->a[p->nSample-1]; |
| 80815 | | - }else{ |
| 80816 | | - pSample = &p->a[p->nSample++]; |
| 80817 | | - } |
| 80818 | | - pSample->iRowid = rowid; |
| 80819 | | - pSample->nEq = nEq; |
| 80820 | | - pSample->nLt = nLt; |
| 80821 | | - pSample->nDLt = nDLt; |
| 80822 | | - pSample->iHash = h; |
| 80823 | | - pSample->isPSample = isPSample; |
| 80824 | | - |
| 80825 | | - /* Find the new minimum */ |
| 80826 | | - if( p->nSample==p->mxSample ){ |
| 80827 | | - pSample = p->a; |
| 80828 | | - i = 0; |
| 80829 | | - while( pSample->isPSample ){ |
| 80830 | | - i++; |
| 80831 | | - pSample++; |
| 80832 | | - assert( i<p->nSample ); |
| 80833 | | - } |
| 80834 | | - nEq = pSample->nEq; |
| 80835 | | - h = pSample->iHash; |
| 80836 | | - iMin = i; |
| 80837 | | - for(i++, pSample++; i<p->nSample; i++, pSample++){ |
| 80838 | | - if( pSample->isPSample ) continue; |
| 80839 | | - if( pSample->nEq<nEq |
| 80840 | | - || (pSample->nEq==nEq && pSample->iHash<h) |
| 80841 | | - ){ |
| 80842 | | - iMin = i; |
| 80843 | | - nEq = pSample->nEq; |
| 80844 | | - h = pSample->iHash; |
| 80845 | | - } |
| 80846 | | - } |
| 81383 | + pSample->anEq = anEq; |
| 81384 | + pSample->anDLt = anDLt; |
| 81385 | + pSample->anLt = anLt; |
| 81386 | + p->nSample = p->mxSample-1; |
| 81387 | + } |
| 81388 | + |
| 81389 | + /* Figure out where in the a[] array the new sample should be inserted. */ |
| 81390 | + iSeq = pNew->anLt[p->nCol-1]; |
| 81391 | + for(iPos=p->nSample; iPos>0; iPos--){ |
| 81392 | + if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break; |
| 81393 | + } |
| 81394 | + |
| 81395 | + /* Insert the new sample */ |
| 81396 | + pSample = &p->a[iPos]; |
| 81397 | + if( iPos!=p->nSample ){ |
| 81398 | + Stat4Sample *pEnd = &p->a[p->nSample]; |
| 81399 | + tRowcnt *anEq = pEnd->anEq; |
| 81400 | + tRowcnt *anLt = pEnd->anLt; |
| 81401 | + tRowcnt *anDLt = pEnd->anDLt; |
| 81402 | + memmove(&p->a[iPos], &p->a[iPos+1], (p->nSample-iPos)*sizeof(p->a[0])); |
| 81403 | + pSample->anEq = anEq; |
| 81404 | + pSample->anDLt = anDLt; |
| 81405 | + pSample->anLt = anLt; |
| 81406 | + } |
| 81407 | + p->nSample++; |
| 81408 | + sampleCopy(p, pSample, pNew); |
| 81409 | + |
| 81410 | + /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81411 | + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81412 | + |
| 81413 | + find_new_min: |
| 81414 | + if( p->nSample>=p->mxSample ){ |
| 81415 | + int iMin = -1; |
| 81416 | + for(i=0; i<p->mxSample; i++){ |
| 81417 | + if( p->a[i].isPSample ) continue; |
| 81418 | + if( iMin<0 || sampleIsBetter(&p->a[iMin], &p->a[i]) ){ |
| 81419 | + iMin = i; |
| 81420 | + } |
| 81421 | + } |
| 81422 | + assert( iMin>=0 ); |
| 80847 | 81423 | p->iMin = iMin; |
| 80848 | 81424 | } |
| 80849 | 81425 | } |
| 80850 | | -static const FuncDef stat3PushFuncdef = { |
| 80851 | | - 5, /* nArg */ |
| 80852 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80853 | | - 0, /* flags */ |
| 80854 | | - 0, /* pUserData */ |
| 80855 | | - 0, /* pNext */ |
| 80856 | | - stat3Push, /* xFunc */ |
| 80857 | | - 0, /* xStep */ |
| 80858 | | - 0, /* xFinalize */ |
| 80859 | | - "stat3_push", /* zName */ |
| 80860 | | - 0, /* pHash */ |
| 80861 | | - 0 /* pDestructor */ |
| 80862 | | -}; |
| 80863 | | - |
| 80864 | | -/* |
| 80865 | | -** Implementation of the stat3_get(P,N,...) SQL function. This routine is |
| 80866 | | -** used to query the results. Content is returned for the Nth sqlite_stat3 |
| 80867 | | -** row where N is between 0 and S-1 and S is the number of samples. The |
| 80868 | | -** value returned depends on the number of arguments. |
| 80869 | | -** |
| 80870 | | -** argc==2 result: rowid |
| 80871 | | -** argc==3 result: nEq |
| 80872 | | -** argc==4 result: nLt |
| 80873 | | -** argc==5 result: nDLt |
| 80874 | | -*/ |
| 80875 | | -static void stat3Get( |
| 81426 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81427 | + |
| 81428 | +/* |
| 81429 | +** Field iChng of the index being scanned has changed. So at this point |
| 81430 | +** p->current contains a sample that reflects the previous row of the |
| 81431 | +** index. The value of anEq[iChng] and subsequent anEq[] elements are |
| 81432 | +** correct at this point. |
| 81433 | +*/ |
| 81434 | +static void samplePushPrevious(Stat4Accum *p, int iChng){ |
| 81435 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81436 | + int i; |
| 81437 | + |
| 81438 | + /* Check if any samples from the aBest[] array should be pushed |
| 81439 | + ** into IndexSample.a[] at this point. */ |
| 81440 | + for(i=(p->nCol-2); i>=iChng; i--){ |
| 81441 | + Stat4Sample *pBest = &p->aBest[i]; |
| 81442 | + if( p->nSample<p->mxSample |
| 81443 | + || sampleIsBetter(pBest, &p->a[p->iMin]) |
| 81444 | + ){ |
| 81445 | + sampleInsert(p, pBest, i); |
| 81446 | + } |
| 81447 | + } |
| 81448 | + |
| 81449 | + /* Update the anEq[] fields of any samples already collected. */ |
| 81450 | + for(i=p->nSample-1; i>=0; i--){ |
| 81451 | + int j; |
| 81452 | + for(j=iChng; j<p->nCol; j++){ |
| 81453 | + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; |
| 81454 | + } |
| 81455 | + } |
| 81456 | +#endif |
| 81457 | + |
| 81458 | +#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) |
| 81459 | + if( iChng==0 ){ |
| 81460 | + tRowcnt nLt = p->current.anLt[0]; |
| 81461 | + tRowcnt nEq = p->current.anEq[0]; |
| 81462 | + |
| 81463 | + /* Check if this is to be a periodic sample. If so, add it. */ |
| 81464 | + if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ |
| 81465 | + p->current.isPSample = 1; |
| 81466 | + sampleInsert(p, &p->current, 0); |
| 81467 | + p->current.isPSample = 0; |
| 81468 | + }else |
| 81469 | + |
| 81470 | + /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81471 | + if( p->nSample<p->mxSample || sampleIsBetter(&p->current, &p->a[p->iMin]) ){ |
| 81472 | + sampleInsert(p, &p->current, 0); |
| 81473 | + } |
| 81474 | + } |
| 81475 | +#endif |
| 81476 | +} |
| 81477 | + |
| 81478 | +/* |
| 81479 | +** Implementation of the stat_push SQL function: stat_push(P,R,C) |
| 81480 | +** Arguments: |
| 81481 | +** |
| 81482 | +** P Pointer to the Stat4Accum object created by stat_init() |
| 81483 | +** C Index of left-most column to differ from previous row |
| 81484 | +** R Rowid for the current row |
| 81485 | +** |
| 81486 | +** The SQL function always returns NULL. |
| 81487 | +** |
| 81488 | +** The R parameter is only used for STAT3 and STAT4. |
| 81489 | +*/ |
| 81490 | +static void statPush( |
| 81491 | + sqlite3_context *context, |
| 81492 | + int argc, |
| 81493 | + sqlite3_value **argv |
| 81494 | +){ |
| 81495 | + int i; |
| 81496 | + |
| 81497 | + /* The three function arguments */ |
| 81498 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81499 | + int iChng = sqlite3_value_int(argv[1]); |
| 81500 | + |
| 81501 | + assert( p->nCol>1 ); /* Includes rowid field */ |
| 81502 | + assert( iChng<p->nCol ); |
| 81503 | + |
| 81504 | + if( p->nRow==0 ){ |
| 81505 | + /* anEq[0] is only zero for the very first call to this function. Do |
| 81506 | + ** appropriate initialization */ |
| 81507 | + for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81508 | + }else{ |
| 81509 | + /* Second and subsequent calls get processed here */ |
| 81510 | + samplePushPrevious(p, iChng); |
| 81511 | + |
| 81512 | + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply |
| 81513 | + ** to the current row of the index. */ |
| 81514 | + for(i=0; i<iChng; i++){ |
| 81515 | + p->current.anEq[i]++; |
| 81516 | + } |
| 81517 | + for(i=iChng; i<p->nCol; i++){ |
| 81518 | + p->current.anDLt[i]++; |
| 81519 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81520 | + p->current.anLt[i] += p->current.anEq[i]; |
| 81521 | +#endif |
| 81522 | + p->current.anEq[i] = 1; |
| 81523 | + } |
| 81524 | + } |
| 81525 | + p->nRow++; |
| 81526 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81527 | + p->current.iRowid = sqlite3_value_int64(argv[2]); |
| 81528 | + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; |
| 81529 | +#endif |
| 81530 | + |
| 81531 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81532 | + { |
| 81533 | + tRowcnt nLt = p->current.anLt[p->nCol-1]; |
| 81534 | + |
| 81535 | + /* Check if this is to be a periodic sample. If so, add it. */ |
| 81536 | + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ |
| 81537 | + p->current.isPSample = 1; |
| 81538 | + p->current.iCol = 0; |
| 81539 | + sampleInsert(p, &p->current, p->nCol-1); |
| 81540 | + p->current.isPSample = 0; |
| 81541 | + } |
| 81542 | + |
| 81543 | + /* Update the aBest[] array. */ |
| 81544 | + for(i=0; i<(p->nCol-1); i++){ |
| 81545 | + p->current.iCol = i; |
| 81546 | + if( i>=iChng || sampleIsBetter(&p->current, &p->aBest[i]) ){ |
| 81547 | + sampleCopy(p, &p->aBest[i], &p->current); |
| 81548 | + } |
| 81549 | + } |
| 81550 | + } |
| 81551 | +#endif |
| 81552 | +} |
| 81553 | +static const FuncDef statPushFuncdef = { |
| 81554 | + 2+IsStat34, /* nArg */ |
| 81555 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81556 | + 0, /* flags */ |
| 81557 | + 0, /* pUserData */ |
| 81558 | + 0, /* pNext */ |
| 81559 | + statPush, /* xFunc */ |
| 81560 | + 0, /* xStep */ |
| 81561 | + 0, /* xFinalize */ |
| 81562 | + "stat_push", /* zName */ |
| 81563 | + 0, /* pHash */ |
| 81564 | + 0 /* pDestructor */ |
| 81565 | +}; |
| 81566 | + |
| 81567 | +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ |
| 81568 | +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ |
| 81569 | +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ |
| 81570 | +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 81571 | +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 81572 | + |
| 81573 | +/* |
| 81574 | +** Implementation of the stat_get(P,J) SQL function. This routine is |
| 81575 | +** used to query the results. Content is returned for parameter J |
| 81576 | +** which is one of the STAT_GET_xxxx values defined above. |
| 81577 | +** |
| 81578 | +** If neither STAT3 nor STAT4 are enabled, then J is always |
| 81579 | +** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 81580 | +** a one-parameter function, stat_get(P), that always returns the |
| 81581 | +** stat1 table entry information. |
| 81582 | +*/ |
| 81583 | +static void statGet( |
| 80876 | 81584 | sqlite3_context *context, |
| 80877 | 81585 | int argc, |
| 80878 | 81586 | sqlite3_value **argv |
| 80879 | 81587 | ){ |
| 80880 | | - int n = sqlite3_value_int(argv[1]); |
| 80881 | | - Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); |
| 80882 | | - |
| 80883 | | - assert( p!=0 ); |
| 80884 | | - if( p->nSample<=n ) return; |
| 80885 | | - switch( argc ){ |
| 80886 | | - case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; |
| 80887 | | - case 3: sqlite3_result_int64(context, p->a[n].nEq); break; |
| 80888 | | - case 4: sqlite3_result_int64(context, p->a[n].nLt); break; |
| 80889 | | - default: sqlite3_result_int64(context, p->a[n].nDLt); break; |
| 80890 | | - } |
| 80891 | | -} |
| 80892 | | -static const FuncDef stat3GetFuncdef = { |
| 80893 | | - -1, /* nArg */ |
| 80894 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80895 | | - 0, /* flags */ |
| 80896 | | - 0, /* pUserData */ |
| 80897 | | - 0, /* pNext */ |
| 80898 | | - stat3Get, /* xFunc */ |
| 80899 | | - 0, /* xStep */ |
| 80900 | | - 0, /* xFinalize */ |
| 80901 | | - "stat3_get", /* zName */ |
| 80902 | | - 0, /* pHash */ |
| 80903 | | - 0 /* pDestructor */ |
| 80904 | | -}; |
| 80905 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 80906 | | - |
| 80907 | | - |
| 80908 | | - |
| 81588 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81589 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81590 | + /* STAT3 and STAT4 have a parameter on this routine. */ |
| 81591 | + int eCall = sqlite3_value_int(argv[1]); |
| 81592 | + assert( argc==2 ); |
| 81593 | + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ |
| 81594 | + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT |
| 81595 | + || eCall==STAT_GET_NDLT |
| 81596 | + ); |
| 81597 | + if( eCall==STAT_GET_STAT1 ) |
| 81598 | +#else |
| 81599 | + assert( argc==1 ); |
| 81600 | +#endif |
| 81601 | + { |
| 81602 | + /* Return the value to store in the "stat" column of the sqlite_stat1 |
| 81603 | + ** table for this index. |
| 81604 | + ** |
| 81605 | + ** The value is a string composed of a list of integers describing |
| 81606 | + ** the index. The first integer in the list is the total number of |
| 81607 | + ** entries in the index. There is one additional integer in the list |
| 81608 | + ** for each indexed column. This additional integer is an estimate of |
| 81609 | + ** the number of rows matched by a stabbing query on the index using |
| 81610 | + ** a key with the corresponding number of fields. In other words, |
| 81611 | + ** if the index is on columns (a,b) and the sqlite_stat1 value is |
| 81612 | + ** "100 10 2", then SQLite estimates that: |
| 81613 | + ** |
| 81614 | + ** * the index contains 100 rows, |
| 81615 | + ** * "WHERE a=?" matches 10 rows, and |
| 81616 | + ** * "WHERE a=? AND b=?" matches 2 rows. |
| 81617 | + ** |
| 81618 | + ** If D is the count of distinct values and K is the total number of |
| 81619 | + ** rows, then each estimate is computed as: |
| 81620 | + ** |
| 81621 | + ** I = (K+D-1)/D |
| 81622 | + */ |
| 81623 | + char *z; |
| 81624 | + int i; |
| 81625 | + |
| 81626 | + char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81627 | + if( zRet==0 ){ |
| 81628 | + sqlite3_result_error_nomem(context); |
| 81629 | + return; |
| 81630 | + } |
| 81631 | + |
| 81632 | + sqlite3_snprintf(24, zRet, "%lld", p->nRow); |
| 81633 | + z = zRet + sqlite3Strlen30(zRet); |
| 81634 | + for(i=0; i<(p->nCol-1); i++){ |
| 81635 | + i64 nDistinct = p->current.anDLt[i] + 1; |
| 81636 | + i64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 81637 | + sqlite3_snprintf(24, z, " %lld", iVal); |
| 81638 | + z += sqlite3Strlen30(z); |
| 81639 | + assert( p->current.anEq[i] ); |
| 81640 | + } |
| 81641 | + assert( z[0]=='\0' && z>zRet ); |
| 81642 | + |
| 81643 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81644 | + } |
| 81645 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81646 | + else if( eCall==STAT_GET_ROWID ){ |
| 81647 | + if( p->iGet<0 ){ |
| 81648 | + samplePushPrevious(p, 0); |
| 81649 | + p->iGet = 0; |
| 81650 | + } |
| 81651 | + if( p->iGet<p->nSample ){ |
| 81652 | + sqlite3_result_int64(context, p->a[p->iGet].iRowid); |
| 81653 | + } |
| 81654 | + }else{ |
| 81655 | + tRowcnt *aCnt = 0; |
| 81656 | + |
| 81657 | + assert( p->iGet<p->nSample ); |
| 81658 | + switch( eCall ){ |
| 81659 | + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; |
| 81660 | + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; |
| 81661 | + default: { |
| 81662 | + aCnt = p->a[p->iGet].anDLt; |
| 81663 | + p->iGet++; |
| 81664 | + break; |
| 81665 | + } |
| 81666 | + } |
| 81667 | + |
| 81668 | + if( IsStat3 ){ |
| 81669 | + sqlite3_result_int64(context, (i64)aCnt[0]); |
| 81670 | + }else{ |
| 81671 | + char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81672 | + if( zRet==0 ){ |
| 81673 | + sqlite3_result_error_nomem(context); |
| 81674 | + }else{ |
| 81675 | + int i; |
| 81676 | + char *z = zRet; |
| 81677 | + for(i=0; i<p->nCol; i++){ |
| 81678 | + sqlite3_snprintf(24, z, "%lld ", aCnt[i]); |
| 81679 | + z += sqlite3Strlen30(z); |
| 81680 | + } |
| 81681 | + assert( z[0]=='\0' && z>zRet ); |
| 81682 | + z[-1] = '\0'; |
| 81683 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81684 | + } |
| 81685 | + } |
| 81686 | + } |
| 81687 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81688 | +} |
| 81689 | +static const FuncDef statGetFuncdef = { |
| 81690 | + 1+IsStat34, /* nArg */ |
| 81691 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81692 | + 0, /* flags */ |
| 81693 | + 0, /* pUserData */ |
| 81694 | + 0, /* pNext */ |
| 81695 | + statGet, /* xFunc */ |
| 81696 | + 0, /* xStep */ |
| 81697 | + 0, /* xFinalize */ |
| 81698 | + "stat_get", /* zName */ |
| 81699 | + 0, /* pHash */ |
| 81700 | + 0 /* pDestructor */ |
| 81701 | +}; |
| 81702 | + |
| 81703 | +static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
| 81704 | + assert( regOut!=regStat4 && regOut!=regStat4+1 ); |
| 81705 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81706 | + sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); |
| 81707 | +#else |
| 81708 | + assert( iParam==STAT_GET_STAT1 ); |
| 81709 | +#endif |
| 81710 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); |
| 81711 | + sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); |
| 81712 | + sqlite3VdbeChangeP5(v, 1 + IsStat34); |
| 81713 | +} |
| 80909 | 81714 | |
| 80910 | 81715 | /* |
| 80911 | 81716 | ** Generate code to do an analysis of all indices associated with |
| 80912 | 81717 | ** a single table. |
| 80913 | 81718 | */ |
| | @@ -80914,46 +81719,35 @@ |
| 80914 | 81719 | static void analyzeOneTable( |
| 80915 | 81720 | Parse *pParse, /* Parser context */ |
| 80916 | 81721 | Table *pTab, /* Table whose indices are to be analyzed */ |
| 80917 | 81722 | Index *pOnlyIdx, /* If not NULL, only analyze this one index */ |
| 80918 | 81723 | int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ |
| 80919 | | - int iMem /* Available memory locations begin here */ |
| 81724 | + int iMem, /* Available memory locations begin here */ |
| 81725 | + int iTab /* Next available cursor */ |
| 80920 | 81726 | ){ |
| 80921 | 81727 | sqlite3 *db = pParse->db; /* Database handle */ |
| 80922 | 81728 | Index *pIdx; /* An index to being analyzed */ |
| 80923 | 81729 | int iIdxCur; /* Cursor open on index being analyzed */ |
| 81730 | + int iTabCur; /* Table cursor */ |
| 80924 | 81731 | Vdbe *v; /* The virtual machine being built up */ |
| 80925 | 81732 | int i; /* Loop counter */ |
| 80926 | | - int topOfLoop; /* The top of the loop */ |
| 80927 | | - int endOfLoop; /* The end of the loop */ |
| 80928 | 81733 | int jZeroRows = -1; /* Jump from here if number of rows is zero */ |
| 80929 | 81734 | int iDb; /* Index of database containing pTab */ |
| 80930 | 81735 | u8 needTableCnt = 1; /* True to count the table */ |
| 81736 | + int regNewRowid = iMem++; /* Rowid for the inserted record */ |
| 81737 | + int regStat4 = iMem++; /* Register to hold Stat4Accum object */ |
| 81738 | + int regChng = iMem++; /* Index of changed index field */ |
| 81739 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81740 | + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ |
| 81741 | +#endif |
| 81742 | + int regTemp = iMem++; /* Temporary use register */ |
| 80931 | 81743 | int regTabname = iMem++; /* Register containing table name */ |
| 80932 | 81744 | int regIdxname = iMem++; /* Register containing index name */ |
| 80933 | | - int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ |
| 80934 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 80935 | | - int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ |
| 80936 | | - int regNumLt = iMem++; /* Number of keys less than regSample */ |
| 80937 | | - int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ |
| 80938 | | - int regSample = iMem++; /* The next sample value */ |
| 80939 | | - int regRowid = regSample; /* Rowid of a sample */ |
| 80940 | | - int regAccum = iMem++; /* Register to hold Stat3Accum object */ |
| 80941 | | - int regLoop = iMem++; /* Loop counter */ |
| 80942 | | - int regCount = iMem++; /* Number of rows in the table or index */ |
| 80943 | | - int regTemp1 = iMem++; /* Intermediate register */ |
| 80944 | | - int regTemp2 = iMem++; /* Intermediate register */ |
| 80945 | | - int once = 1; /* One-time initialization */ |
| 80946 | | - int shortJump = 0; /* Instruction address */ |
| 80947 | | - int iTabCur = pParse->nTab++; /* Table cursor */ |
| 80948 | | -#endif |
| 80949 | | - int regCol = iMem++; /* Content of a column in analyzed table */ |
| 80950 | | - int regRec = iMem++; /* Register holding completed record */ |
| 80951 | | - int regTemp = iMem++; /* Temporary use register */ |
| 80952 | | - int regNewRowid = iMem++; /* Rowid for the inserted record */ |
| 80953 | | - |
| 80954 | | - |
| 81745 | + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ |
| 81746 | + int regPrev = iMem; /* MUST BE LAST (see below) */ |
| 81747 | + |
| 81748 | + pParse->nMem = MAX(pParse->nMem, iMem); |
| 80955 | 81749 | v = sqlite3GetVdbe(pParse); |
| 80956 | 81750 | if( v==0 || NEVER(pTab==0) ){ |
| 80957 | 81751 | return; |
| 80958 | 81752 | } |
| 80959 | 81753 | if( pTab->tnum==0 ){ |
| | @@ -80973,217 +81767,230 @@ |
| 80973 | 81767 | db->aDb[iDb].zName ) ){ |
| 80974 | 81768 | return; |
| 80975 | 81769 | } |
| 80976 | 81770 | #endif |
| 80977 | 81771 | |
| 80978 | | - /* Establish a read-lock on the table at the shared-cache level. */ |
| 81772 | + /* Establish a read-lock on the table at the shared-cache level. |
| 81773 | + ** Open a read-only cursor on the table. Also allocate a cursor number |
| 81774 | + ** to use for scanning indexes (iIdxCur). No index cursor is opened at |
| 81775 | + ** this time though. */ |
| 80979 | 81776 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 80980 | | - |
| 80981 | | - iIdxCur = pParse->nTab++; |
| 81777 | + iTabCur = iTab++; |
| 81778 | + iIdxCur = iTab++; |
| 81779 | + pParse->nTab = MAX(pParse->nTab, iTab); |
| 81780 | + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 80982 | 81781 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 81782 | + |
| 80983 | 81783 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 80984 | | - int nCol; |
| 80985 | | - KeyInfo *pKey; |
| 80986 | | - int addrIfNot = 0; /* address of OP_IfNot */ |
| 80987 | | - int *aChngAddr; /* Array of jump instruction addresses */ |
| 81784 | + int nCol; /* Number of columns indexed by pIdx */ |
| 81785 | + KeyInfo *pKey; /* KeyInfo structure for pIdx */ |
| 81786 | + int *aGotoChng; /* Array of jump instruction addresses */ |
| 81787 | + int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 81788 | + int addrGotoChng0; /* Address of "Goto addr_chng_0" */ |
| 81789 | + int addrNextRow; /* Address of "next_row:" */ |
| 80988 | 81790 | |
| 80989 | 81791 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 80990 | 81792 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 80991 | 81793 | VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); |
| 80992 | 81794 | nCol = pIdx->nColumn; |
| 80993 | | - aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); |
| 80994 | | - if( aChngAddr==0 ) continue; |
| 81795 | + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 81796 | + if( aGotoChng==0 ) continue; |
| 80995 | 81797 | pKey = sqlite3IndexKeyinfo(pParse, pIdx); |
| 80996 | | - if( iMem+1+(nCol*2)>pParse->nMem ){ |
| 80997 | | - pParse->nMem = iMem+1+(nCol*2); |
| 80998 | | - } |
| 80999 | | - |
| 81000 | | - /* Open a cursor to the index to be analyzed. */ |
| 81001 | | - assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 81002 | | - sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb, |
| 81003 | | - (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81004 | | - VdbeComment((v, "%s", pIdx->zName)); |
| 81005 | 81798 | |
| 81006 | 81799 | /* Populate the register containing the index name. */ |
| 81007 | 81800 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); |
| 81008 | 81801 | |
| 81009 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81010 | | - if( once ){ |
| 81011 | | - once = 0; |
| 81012 | | - sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 81013 | | - } |
| 81014 | | - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); |
| 81015 | | - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); |
| 81016 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); |
| 81017 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); |
| 81018 | | - sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); |
| 81019 | | - sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum); |
| 81020 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, |
| 81021 | | - (char*)&stat3InitFuncdef, P4_FUNCDEF); |
| 81022 | | - sqlite3VdbeChangeP5(v, 2); |
| 81023 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 81024 | | - |
| 81025 | | - /* The block of memory cells initialized here is used as follows. |
| 81026 | | - ** |
| 81027 | | - ** iMem: |
| 81028 | | - ** The total number of rows in the table. |
| 81029 | | - ** |
| 81030 | | - ** iMem+1 .. iMem+nCol: |
| 81031 | | - ** Number of distinct entries in index considering the |
| 81032 | | - ** left-most N columns only, where N is between 1 and nCol, |
| 81033 | | - ** inclusive. |
| 81034 | | - ** |
| 81035 | | - ** iMem+nCol+1 .. Mem+2*nCol: |
| 81036 | | - ** Previous value of indexed columns, from left to right. |
| 81037 | | - ** |
| 81038 | | - ** Cells iMem through iMem+nCol are initialized to 0. The others are |
| 81039 | | - ** initialized to contain an SQL NULL. |
| 81040 | | - */ |
| 81041 | | - for(i=0; i<=nCol; i++){ |
| 81042 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i); |
| 81043 | | - } |
| 81044 | | - for(i=0; i<nCol; i++){ |
| 81045 | | - sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1); |
| 81046 | | - } |
| 81047 | | - |
| 81048 | | - /* Start the analysis loop. This loop runs through all the entries in |
| 81049 | | - ** the index b-tree. */ |
| 81050 | | - endOfLoop = sqlite3VdbeMakeLabel(v); |
| 81051 | | - sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); |
| 81052 | | - topOfLoop = sqlite3VdbeCurrentAddr(v); |
| 81053 | | - sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */ |
| 81054 | | - |
| 81055 | | - for(i=0; i<nCol; i++){ |
| 81056 | | - CollSeq *pColl; |
| 81057 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol); |
| 81058 | | - if( i==0 ){ |
| 81059 | | - /* Always record the very first row */ |
| 81060 | | - addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1); |
| 81061 | | - } |
| 81062 | | - assert( pIdx->azColl!=0 ); |
| 81063 | | - assert( pIdx->azColl[i]!=0 ); |
| 81064 | | - pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 81065 | | - aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, |
| 81066 | | - (char*)pColl, P4_COLLSEQ); |
| 81802 | + /* |
| 81803 | + ** Pseudo-code for loop that calls stat_push(): |
| 81804 | + ** |
| 81805 | + ** Rewind csr |
| 81806 | + ** if eof(csr) goto end_of_scan; |
| 81807 | + ** regChng = 0 |
| 81808 | + ** goto chng_addr_0; |
| 81809 | + ** |
| 81810 | + ** next_row: |
| 81811 | + ** regChng = 0 |
| 81812 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 81813 | + ** regChng = 1 |
| 81814 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 81815 | + ** ... |
| 81816 | + ** regChng = N |
| 81817 | + ** goto chng_addr_N |
| 81818 | + ** |
| 81819 | + ** chng_addr_0: |
| 81820 | + ** regPrev(0) = idx(0) |
| 81821 | + ** chng_addr_1: |
| 81822 | + ** regPrev(1) = idx(1) |
| 81823 | + ** ... |
| 81824 | + ** |
| 81825 | + ** chng_addr_N: |
| 81826 | + ** regRowid = idx(rowid) |
| 81827 | + ** stat_push(P, regChng, regRowid) |
| 81828 | + ** Next csr |
| 81829 | + ** if !eof(csr) goto next_row; |
| 81830 | + ** |
| 81831 | + ** end_of_scan: |
| 81832 | + */ |
| 81833 | + |
| 81834 | + /* Make sure there are enough memory cells allocated to accommodate |
| 81835 | + ** the regPrev array and a trailing rowid (the rowid slot is required |
| 81836 | + ** when building a record to insert into the sample column of |
| 81837 | + ** the sqlite_stat4 table. */ |
| 81838 | + pParse->nMem = MAX(pParse->nMem, regPrev+nCol); |
| 81839 | + |
| 81840 | + /* Open a read-only cursor on the index being analyzed. */ |
| 81841 | + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 81842 | + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 81843 | + sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); |
| 81844 | + VdbeComment((v, "%s", pIdx->zName)); |
| 81845 | + |
| 81846 | + /* Invoke the stat_init() function. The arguments are: |
| 81847 | + ** |
| 81848 | + ** (1) the number of columns in the index including the rowid, |
| 81849 | + ** (2) the number of rows in the index, |
| 81850 | + ** |
| 81851 | + ** The second argument is only used for STAT3 and STAT4 |
| 81852 | + */ |
| 81853 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81854 | + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2); |
| 81855 | +#endif |
| 81856 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1); |
| 81857 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); |
| 81858 | + sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); |
| 81859 | + sqlite3VdbeChangeP5(v, 1+IsStat34); |
| 81860 | + |
| 81861 | + /* Implementation of the following: |
| 81862 | + ** |
| 81863 | + ** Rewind csr |
| 81864 | + ** if eof(csr) goto end_of_scan; |
| 81865 | + ** regChng = 0 |
| 81866 | + ** goto next_push_0; |
| 81867 | + ** |
| 81868 | + */ |
| 81869 | + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 81870 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 81871 | + addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 81872 | + |
| 81873 | + /* |
| 81874 | + ** next_row: |
| 81875 | + ** regChng = 0 |
| 81876 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 81877 | + ** regChng = 1 |
| 81878 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 81879 | + ** ... |
| 81880 | + ** regChng = N |
| 81881 | + ** goto chng_addr_N |
| 81882 | + */ |
| 81883 | + addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 81884 | + for(i=0; i<nCol; i++){ |
| 81885 | + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 81886 | + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 81887 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 81888 | + aGotoChng[i] = |
| 81889 | + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 81067 | 81890 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 81068 | | - VdbeComment((v, "jump if column %d changed", i)); |
| 81069 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81070 | | - if( i==0 ){ |
| 81071 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1); |
| 81072 | | - VdbeComment((v, "incr repeat count")); |
| 81073 | | - } |
| 81074 | | -#endif |
| 81075 | | - } |
| 81076 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); |
| 81077 | | - for(i=0; i<nCol; i++){ |
| 81078 | | - sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */ |
| 81079 | | - if( i==0 ){ |
| 81080 | | - sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */ |
| 81081 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81082 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, |
| 81083 | | - (char*)&stat3PushFuncdef, P4_FUNCDEF); |
| 81084 | | - sqlite3VdbeChangeP5(v, 5); |
| 81085 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid); |
| 81086 | | - sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt); |
| 81087 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1); |
| 81088 | | - sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq); |
| 81089 | | -#endif |
| 81090 | | - } |
| 81091 | | - sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); |
| 81092 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); |
| 81093 | | - } |
| 81094 | | - sqlite3DbFree(db, aChngAddr); |
| 81095 | | - |
| 81096 | | - /* Always jump here after updating the iMem+1...iMem+1+nCol counters */ |
| 81097 | | - sqlite3VdbeResolveLabel(v, endOfLoop); |
| 81098 | | - |
| 81099 | | - sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop); |
| 81100 | | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); |
| 81101 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81102 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, |
| 81103 | | - (char*)&stat3PushFuncdef, P4_FUNCDEF); |
| 81104 | | - sqlite3VdbeChangeP5(v, 5); |
| 81105 | | - sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop); |
| 81106 | | - shortJump = |
| 81107 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1); |
| 81108 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1, |
| 81109 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81110 | | - sqlite3VdbeChangeP5(v, 2); |
| 81111 | | - sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1); |
| 81112 | | - sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1); |
| 81113 | | - sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample); |
| 81114 | | - sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample); |
| 81115 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq, |
| 81116 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81117 | | - sqlite3VdbeChangeP5(v, 3); |
| 81118 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt, |
| 81119 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81120 | | - sqlite3VdbeChangeP5(v, 4); |
| 81121 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt, |
| 81122 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81123 | | - sqlite3VdbeChangeP5(v, 5); |
| 81124 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0); |
| 81125 | | - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 81126 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid); |
| 81127 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump); |
| 81128 | | - sqlite3VdbeJumpHere(v, shortJump+2); |
| 81129 | | -#endif |
| 81130 | | - |
| 81131 | | - /* Store the results in sqlite_stat1. |
| 81132 | | - ** |
| 81133 | | - ** The result is a single row of the sqlite_stat1 table. The first |
| 81134 | | - ** two columns are the names of the table and index. The third column |
| 81135 | | - ** is a string composed of a list of integer statistics about the |
| 81136 | | - ** index. The first integer in the list is the total number of entries |
| 81137 | | - ** in the index. There is one additional integer in the list for each |
| 81138 | | - ** column of the table. This additional integer is a guess of how many |
| 81139 | | - ** rows of the table the index will select. If D is the count of distinct |
| 81140 | | - ** values and K is the total number of rows, then the integer is computed |
| 81141 | | - ** as: |
| 81142 | | - ** |
| 81143 | | - ** I = (K+D-1)/D |
| 81144 | | - ** |
| 81145 | | - ** If K==0 then no entry is made into the sqlite_stat1 table. |
| 81146 | | - ** If K>0 then it is always the case the D>0 so division by zero |
| 81147 | | - ** is never possible. |
| 81148 | | - */ |
| 81149 | | - sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1); |
| 81150 | | - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); |
| 81151 | | - for(i=0; i<nCol; i++){ |
| 81152 | | - sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0); |
| 81153 | | - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1); |
| 81154 | | - sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp); |
| 81155 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1); |
| 81156 | | - sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp); |
| 81157 | | - sqlite3VdbeAddOp1(v, OP_ToInt, regTemp); |
| 81158 | | - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1); |
| 81159 | | - } |
| 81160 | | - if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows); |
| 81161 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); |
| 81162 | | - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81163 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); |
| 81164 | | - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81165 | | - if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows); |
| 81166 | | - } |
| 81891 | + } |
| 81892 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); |
| 81893 | + aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); |
| 81894 | + |
| 81895 | + /* |
| 81896 | + ** chng_addr_0: |
| 81897 | + ** regPrev(0) = idx(0) |
| 81898 | + ** chng_addr_1: |
| 81899 | + ** regPrev(1) = idx(1) |
| 81900 | + ** ... |
| 81901 | + */ |
| 81902 | + sqlite3VdbeJumpHere(v, addrGotoChng0); |
| 81903 | + for(i=0; i<nCol; i++){ |
| 81904 | + sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 81905 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 81906 | + } |
| 81907 | + |
| 81908 | + /* |
| 81909 | + ** chng_addr_N: |
| 81910 | + ** regRowid = idx(rowid) // STAT34 only |
| 81911 | + ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 81912 | + ** Next csr |
| 81913 | + ** if !eof(csr) goto next_row; |
| 81914 | + */ |
| 81915 | + sqlite3VdbeJumpHere(v, aGotoChng[nCol]); |
| 81916 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81917 | + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 81918 | + assert( regRowid==(regStat4+2) ); |
| 81919 | +#endif |
| 81920 | + assert( regChng==(regStat4+1) ); |
| 81921 | + sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); |
| 81922 | + sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
| 81923 | + sqlite3VdbeChangeP5(v, 2+IsStat34); |
| 81924 | + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); |
| 81925 | + |
| 81926 | + /* Add the entry to the stat1 table. */ |
| 81927 | + callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); |
| 81928 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 81929 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81930 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 81931 | + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81932 | + |
| 81933 | + /* Add the entries to the stat3 or stat4 table. */ |
| 81934 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81935 | + { |
| 81936 | + int regEq = regStat1; |
| 81937 | + int regLt = regStat1+1; |
| 81938 | + int regDLt = regStat1+2; |
| 81939 | + int regSample = regStat1+3; |
| 81940 | + int regCol = regStat1+4; |
| 81941 | + int regSampleRowid = regCol + nCol; |
| 81942 | + int addrNext; |
| 81943 | + int addrIsNull; |
| 81944 | + |
| 81945 | + pParse->nMem = MAX(pParse->nMem, regCol+nCol+1); |
| 81946 | + |
| 81947 | + addrNext = sqlite3VdbeCurrentAddr(v); |
| 81948 | + callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); |
| 81949 | + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); |
| 81950 | + callStatGet(v, regStat4, STAT_GET_NEQ, regEq); |
| 81951 | + callStatGet(v, regStat4, STAT_GET_NLT, regLt); |
| 81952 | + callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); |
| 81953 | + sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid); |
| 81954 | +#ifdef SQLITE_ENABLE_STAT3 |
| 81955 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, |
| 81956 | + pIdx->aiColumn[0], regSample); |
| 81957 | +#else |
| 81958 | + for(i=0; i<nCol; i++){ |
| 81959 | + int iCol = pIdx->aiColumn[i]; |
| 81960 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); |
| 81961 | + } |
| 81962 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample); |
| 81963 | +#endif |
| 81964 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0); |
| 81965 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 81966 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); |
| 81967 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); |
| 81968 | + sqlite3VdbeJumpHere(v, addrIsNull); |
| 81969 | + } |
| 81970 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81971 | + |
| 81972 | + /* End of analysis */ |
| 81973 | + sqlite3VdbeJumpHere(v, addrRewind); |
| 81974 | + sqlite3DbFree(db, aGotoChng); |
| 81975 | + } |
| 81976 | + |
| 81167 | 81977 | |
| 81168 | 81978 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 81169 | 81979 | ** name and the row count as the content. |
| 81170 | 81980 | */ |
| 81171 | 81981 | if( pOnlyIdx==0 && needTableCnt ){ |
| 81172 | | - sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); |
| 81173 | 81982 | VdbeComment((v, "%s", pTab->zName)); |
| 81174 | | - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); |
| 81175 | | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); |
| 81983 | + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); |
| 81176 | 81984 | jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); |
| 81177 | 81985 | sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); |
| 81178 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); |
| 81986 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 81179 | 81987 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81180 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); |
| 81988 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 81181 | 81989 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81182 | 81990 | sqlite3VdbeJumpHere(v, jZeroRows); |
| 81183 | 81991 | } |
| 81184 | | - if( pParse->nMem<regRec ) pParse->nMem = regRec; |
| 81185 | 81992 | } |
| 81186 | 81993 | |
| 81187 | 81994 | |
| 81188 | 81995 | /* |
| 81189 | 81996 | ** Generate code that will cause the most recent index analysis to |
| | @@ -81203,20 +82010,22 @@ |
| 81203 | 82010 | sqlite3 *db = pParse->db; |
| 81204 | 82011 | Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ |
| 81205 | 82012 | HashElem *k; |
| 81206 | 82013 | int iStatCur; |
| 81207 | 82014 | int iMem; |
| 82015 | + int iTab; |
| 81208 | 82016 | |
| 81209 | 82017 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 81210 | 82018 | iStatCur = pParse->nTab; |
| 81211 | 82019 | pParse->nTab += 3; |
| 81212 | 82020 | openStatTable(pParse, iDb, iStatCur, 0, 0); |
| 81213 | 82021 | iMem = pParse->nMem+1; |
| 82022 | + iTab = pParse->nTab; |
| 81214 | 82023 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81215 | 82024 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 81216 | 82025 | Table *pTab = (Table*)sqliteHashData(k); |
| 81217 | | - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); |
| 82026 | + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); |
| 81218 | 82027 | } |
| 81219 | 82028 | loadAnalysis(pParse, iDb); |
| 81220 | 82029 | } |
| 81221 | 82030 | |
| 81222 | 82031 | /* |
| | @@ -81237,11 +82046,11 @@ |
| 81237 | 82046 | if( pOnlyIdx ){ |
| 81238 | 82047 | openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); |
| 81239 | 82048 | }else{ |
| 81240 | 82049 | openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); |
| 81241 | 82050 | } |
| 81242 | | - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); |
| 82051 | + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); |
| 81243 | 82052 | loadAnalysis(pParse, iDb); |
| 81244 | 82053 | } |
| 81245 | 82054 | |
| 81246 | 82055 | /* |
| 81247 | 82056 | ** Generate code for the ANALYZE command. The parser calls this routine |
| | @@ -81319,10 +82128,47 @@ |
| 81319 | 82128 | typedef struct analysisInfo analysisInfo; |
| 81320 | 82129 | struct analysisInfo { |
| 81321 | 82130 | sqlite3 *db; |
| 81322 | 82131 | const char *zDatabase; |
| 81323 | 82132 | }; |
| 82133 | + |
| 82134 | +/* |
| 82135 | +** The first argument points to a nul-terminated string containing a |
| 82136 | +** list of space separated integers. Read the first nOut of these into |
| 82137 | +** the array aOut[]. |
| 82138 | +*/ |
| 82139 | +static void decodeIntArray( |
| 82140 | + char *zIntArray, |
| 82141 | + int nOut, |
| 82142 | + tRowcnt *aOut, |
| 82143 | + int *pbUnordered |
| 82144 | +){ |
| 82145 | + char *z = zIntArray; |
| 82146 | + int c; |
| 82147 | + int i; |
| 82148 | + tRowcnt v; |
| 82149 | + |
| 82150 | + assert( pbUnordered==0 || *pbUnordered==0 ); |
| 82151 | + |
| 82152 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82153 | + if( z==0 ) z = ""; |
| 82154 | +#else |
| 82155 | + if( NEVER(z==0) ) z = ""; |
| 82156 | +#endif |
| 82157 | + for(i=0; *z && i<nOut; i++){ |
| 82158 | + v = 0; |
| 82159 | + while( (c=z[0])>='0' && c<='9' ){ |
| 82160 | + v = v*10 + c - '0'; |
| 82161 | + z++; |
| 82162 | + } |
| 82163 | + aOut[i] = v; |
| 82164 | + if( *z==' ' ) z++; |
| 82165 | + } |
| 82166 | + if( pbUnordered && strcmp(z, "unordered")==0 ){ |
| 82167 | + *pbUnordered = 1; |
| 82168 | + } |
| 82169 | +} |
| 81324 | 82170 | |
| 81325 | 82171 | /* |
| 81326 | 82172 | ** This callback is invoked once for each index when reading the |
| 81327 | 82173 | ** sqlite_stat1 table. |
| 81328 | 82174 | ** |
| | @@ -81335,12 +82181,10 @@ |
| 81335 | 82181 | */ |
| 81336 | 82182 | static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
| 81337 | 82183 | analysisInfo *pInfo = (analysisInfo*)pData; |
| 81338 | 82184 | Index *pIndex; |
| 81339 | 82185 | Table *pTable; |
| 81340 | | - int i, c, n; |
| 81341 | | - tRowcnt v; |
| 81342 | 82186 | const char *z; |
| 81343 | 82187 | |
| 81344 | 82188 | assert( argc==3 ); |
| 81345 | 82189 | UNUSED_PARAMETER2(NotUsed, argc); |
| 81346 | 82190 | |
| | @@ -81354,45 +82198,35 @@ |
| 81354 | 82198 | if( argv[1] ){ |
| 81355 | 82199 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 81356 | 82200 | }else{ |
| 81357 | 82201 | pIndex = 0; |
| 81358 | 82202 | } |
| 81359 | | - n = pIndex ? pIndex->nColumn : 0; |
| 81360 | 82203 | z = argv[2]; |
| 81361 | | - for(i=0; *z && i<=n; i++){ |
| 81362 | | - v = 0; |
| 81363 | | - while( (c=z[0])>='0' && c<='9' ){ |
| 81364 | | - v = v*10 + c - '0'; |
| 81365 | | - z++; |
| 81366 | | - } |
| 81367 | | - if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){ |
| 81368 | | - if( v>0 ) pTable->nRowEst = v; |
| 81369 | | - if( pIndex==0 ) break; |
| 81370 | | - } |
| 81371 | | - pIndex->aiRowEst[i] = v; |
| 81372 | | - if( *z==' ' ) z++; |
| 81373 | | - if( strcmp(z, "unordered")==0 ){ |
| 81374 | | - pIndex->bUnordered = 1; |
| 81375 | | - break; |
| 81376 | | - } |
| 81377 | | - } |
| 82204 | + |
| 82205 | + if( pIndex ){ |
| 82206 | + int bUnordered = 0; |
| 82207 | + decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered); |
| 82208 | + if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; |
| 82209 | + pIndex->bUnordered = bUnordered; |
| 82210 | + }else{ |
| 82211 | + decodeIntArray((char*)z, 1, &pTable->nRowEst, 0); |
| 82212 | + } |
| 82213 | + |
| 81378 | 82214 | return 0; |
| 81379 | 82215 | } |
| 81380 | 82216 | |
| 81381 | 82217 | /* |
| 81382 | 82218 | ** If the Index.aSample variable is not NULL, delete the aSample[] array |
| 81383 | 82219 | ** and its contents. |
| 81384 | 82220 | */ |
| 81385 | 82221 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 81386 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82222 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81387 | 82223 | if( pIdx->aSample ){ |
| 81388 | 82224 | int j; |
| 81389 | 82225 | for(j=0; j<pIdx->nSample; j++){ |
| 81390 | 82226 | IndexSample *p = &pIdx->aSample[j]; |
| 81391 | | - if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ |
| 81392 | | - sqlite3DbFree(db, p->u.z); |
| 81393 | | - } |
| 82227 | + sqlite3DbFree(db, p->p); |
| 81394 | 82228 | } |
| 81395 | 82229 | sqlite3DbFree(db, pIdx->aSample); |
| 81396 | 82230 | } |
| 81397 | 82231 | if( db && db->pnBytesFreed==0 ){ |
| 81398 | 82232 | pIdx->nSample = 0; |
| | @@ -81399,155 +82233,222 @@ |
| 81399 | 82233 | pIdx->aSample = 0; |
| 81400 | 82234 | } |
| 81401 | 82235 | #else |
| 81402 | 82236 | UNUSED_PARAMETER(db); |
| 81403 | 82237 | UNUSED_PARAMETER(pIdx); |
| 81404 | | -#endif |
| 82238 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81405 | 82239 | } |
| 81406 | 82240 | |
| 81407 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82241 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81408 | 82242 | /* |
| 81409 | | -** Load content from the sqlite_stat3 table into the Index.aSample[] |
| 81410 | | -** arrays of all indices. |
| 82243 | +** Populate the pIdx->aAvgEq[] array based on the samples currently |
| 82244 | +** stored in pIdx->aSample[]. |
| 81411 | 82245 | */ |
| 81412 | | -static int loadStat3(sqlite3 *db, const char *zDb){ |
| 82246 | +static void initAvgEq(Index *pIdx){ |
| 82247 | + if( pIdx ){ |
| 82248 | + IndexSample *aSample = pIdx->aSample; |
| 82249 | + IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82250 | + int iCol; |
| 82251 | + for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82252 | + int i; /* Used to iterate through samples */ |
| 82253 | + tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82254 | + int nSum = 0; /* Number of terms contributing to sumEq */ |
| 82255 | + tRowcnt avgEq = 0; |
| 82256 | + tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82257 | + |
| 82258 | + /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82259 | + ** occur in the stat4 table for this index before pFinal. Set |
| 82260 | + ** sumEq to the sum of the nEq values for column iCol for the same |
| 82261 | + ** set (adding the value only once where there exist dupicate |
| 82262 | + ** prefixes). */ |
| 82263 | + for(i=0; i<(pIdx->nSample-1); i++){ |
| 82264 | + if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ |
| 82265 | + sumEq += aSample[i].anEq[iCol]; |
| 82266 | + nSum++; |
| 82267 | + } |
| 82268 | + } |
| 82269 | + if( nDLt>nSum ){ |
| 82270 | + avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); |
| 82271 | + } |
| 82272 | + if( avgEq==0 ) avgEq = 1; |
| 82273 | + pIdx->aAvgEq[iCol] = avgEq; |
| 82274 | + if( pIdx->nSampleCol==1 ) break; |
| 82275 | + } |
| 82276 | + } |
| 82277 | +} |
| 82278 | + |
| 82279 | +/* |
| 82280 | +** Load the content from either the sqlite_stat4 or sqlite_stat3 table |
| 82281 | +** into the relevant Index.aSample[] arrays. |
| 82282 | +** |
| 82283 | +** Arguments zSql1 and zSql2 must point to SQL statements that return |
| 82284 | +** data equivalent to the following (statements are different for stat3, |
| 82285 | +** see the caller of this function for details): |
| 82286 | +** |
| 82287 | +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx |
| 82288 | +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 |
| 82289 | +** |
| 82290 | +** where %Q is replaced with the database name before the SQL is executed. |
| 82291 | +*/ |
| 82292 | +static int loadStatTbl( |
| 82293 | + sqlite3 *db, /* Database handle */ |
| 82294 | + int bStat3, /* Assume single column records only */ |
| 82295 | + const char *zSql1, /* SQL statement 1 (see above) */ |
| 82296 | + const char *zSql2, /* SQL statement 2 (see above) */ |
| 82297 | + const char *zDb /* Database name (e.g. "main") */ |
| 82298 | +){ |
| 81413 | 82299 | int rc; /* Result codes from subroutines */ |
| 81414 | 82300 | sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
| 81415 | 82301 | char *zSql; /* Text of the SQL statement */ |
| 81416 | 82302 | Index *pPrevIdx = 0; /* Previous index in the loop */ |
| 81417 | | - int idx = 0; /* slot in pIdx->aSample[] for next sample */ |
| 81418 | | - int eType; /* Datatype of a sample */ |
| 81419 | 82303 | IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
| 81420 | 82304 | |
| 81421 | 82305 | assert( db->lookaside.bEnabled==0 ); |
| 81422 | | - if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
| 81423 | | - return SQLITE_OK; |
| 81424 | | - } |
| 81425 | | - |
| 81426 | | - zSql = sqlite3MPrintf(db, |
| 81427 | | - "SELECT idx,count(*) FROM %Q.sqlite_stat3" |
| 81428 | | - " GROUP BY idx", zDb); |
| 82306 | + zSql = sqlite3MPrintf(db, zSql1, zDb); |
| 81429 | 82307 | if( !zSql ){ |
| 81430 | 82308 | return SQLITE_NOMEM; |
| 81431 | 82309 | } |
| 81432 | 82310 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81433 | 82311 | sqlite3DbFree(db, zSql); |
| 81434 | 82312 | if( rc ) return rc; |
| 81435 | 82313 | |
| 81436 | 82314 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 82315 | + int nIdxCol = 1; /* Number of columns in stat4 records */ |
| 82316 | + int nAvgCol = 1; /* Number of entries in Index.aAvgEq */ |
| 82317 | + |
| 81437 | 82318 | char *zIndex; /* Index name */ |
| 81438 | 82319 | Index *pIdx; /* Pointer to the index object */ |
| 81439 | 82320 | int nSample; /* Number of samples */ |
| 82321 | + int nByte; /* Bytes of space required */ |
| 82322 | + int i; /* Bytes of space required */ |
| 82323 | + tRowcnt *pSpace; |
| 81440 | 82324 | |
| 81441 | 82325 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81442 | 82326 | if( zIndex==0 ) continue; |
| 81443 | 82327 | nSample = sqlite3_column_int(pStmt, 1); |
| 81444 | 82328 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81445 | | - if( pIdx==0 ) continue; |
| 81446 | | - assert( pIdx->nSample==0 ); |
| 81447 | | - pIdx->nSample = nSample; |
| 81448 | | - pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample)); |
| 81449 | | - pIdx->avgEq = pIdx->aiRowEst[1]; |
| 82329 | + assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); |
| 82330 | + /* Index.nSample is non-zero at this point if data has already been |
| 82331 | + ** loaded from the stat4 table. In this case ignore stat3 data. */ |
| 82332 | + if( pIdx==0 || pIdx->nSample ) continue; |
| 82333 | + if( bStat3==0 ){ |
| 82334 | + nIdxCol = pIdx->nColumn+1; |
| 82335 | + nAvgCol = pIdx->nColumn; |
| 82336 | + } |
| 82337 | + pIdx->nSampleCol = nIdxCol; |
| 82338 | + nByte = sizeof(IndexSample) * nSample; |
| 82339 | + nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 82340 | + nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 82341 | + |
| 82342 | + pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
| 81450 | 82343 | if( pIdx->aSample==0 ){ |
| 81451 | | - db->mallocFailed = 1; |
| 81452 | 82344 | sqlite3_finalize(pStmt); |
| 81453 | 82345 | return SQLITE_NOMEM; |
| 81454 | 82346 | } |
| 82347 | + pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
| 82348 | + pIdx->aAvgEq = pSpace; pSpace += nAvgCol; |
| 82349 | + for(i=0; i<nSample; i++){ |
| 82350 | + pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; |
| 82351 | + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; |
| 82352 | + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; |
| 82353 | + } |
| 82354 | + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); |
| 81455 | 82355 | } |
| 81456 | 82356 | rc = sqlite3_finalize(pStmt); |
| 81457 | 82357 | if( rc ) return rc; |
| 81458 | 82358 | |
| 81459 | | - zSql = sqlite3MPrintf(db, |
| 81460 | | - "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); |
| 82359 | + zSql = sqlite3MPrintf(db, zSql2, zDb); |
| 81461 | 82360 | if( !zSql ){ |
| 81462 | 82361 | return SQLITE_NOMEM; |
| 81463 | 82362 | } |
| 81464 | 82363 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81465 | 82364 | sqlite3DbFree(db, zSql); |
| 81466 | 82365 | if( rc ) return rc; |
| 81467 | 82366 | |
| 81468 | 82367 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 81469 | | - char *zIndex; /* Index name */ |
| 81470 | | - Index *pIdx; /* Pointer to the index object */ |
| 81471 | | - int i; /* Loop counter */ |
| 81472 | | - tRowcnt sumEq; /* Sum of the nEq values */ |
| 82368 | + char *zIndex; /* Index name */ |
| 82369 | + Index *pIdx; /* Pointer to the index object */ |
| 82370 | + int nCol = 1; /* Number of columns in index */ |
| 81473 | 82371 | |
| 81474 | 82372 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81475 | 82373 | if( zIndex==0 ) continue; |
| 81476 | 82374 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81477 | 82375 | if( pIdx==0 ) continue; |
| 81478 | | - if( pIdx==pPrevIdx ){ |
| 81479 | | - idx++; |
| 81480 | | - }else{ |
| 82376 | + /* This next condition is true if data has already been loaded from |
| 82377 | + ** the sqlite_stat4 table. In this case ignore stat3 data. */ |
| 82378 | + nCol = pIdx->nSampleCol; |
| 82379 | + if( bStat3 && nCol>1 ) continue; |
| 82380 | + if( pIdx!=pPrevIdx ){ |
| 82381 | + initAvgEq(pPrevIdx); |
| 81481 | 82382 | pPrevIdx = pIdx; |
| 81482 | | - idx = 0; |
| 81483 | | - } |
| 81484 | | - assert( idx<pIdx->nSample ); |
| 81485 | | - pSample = &pIdx->aSample[idx]; |
| 81486 | | - pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1); |
| 81487 | | - pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2); |
| 81488 | | - pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3); |
| 81489 | | - if( idx==pIdx->nSample-1 ){ |
| 81490 | | - if( pSample->nDLt>0 ){ |
| 81491 | | - for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq; |
| 81492 | | - pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt; |
| 81493 | | - } |
| 81494 | | - if( pIdx->avgEq<=0 ) pIdx->avgEq = 1; |
| 81495 | | - } |
| 81496 | | - eType = sqlite3_column_type(pStmt, 4); |
| 81497 | | - pSample->eType = (u8)eType; |
| 81498 | | - switch( eType ){ |
| 81499 | | - case SQLITE_INTEGER: { |
| 81500 | | - pSample->u.i = sqlite3_column_int64(pStmt, 4); |
| 81501 | | - break; |
| 81502 | | - } |
| 81503 | | - case SQLITE_FLOAT: { |
| 81504 | | - pSample->u.r = sqlite3_column_double(pStmt, 4); |
| 81505 | | - break; |
| 81506 | | - } |
| 81507 | | - case SQLITE_NULL: { |
| 81508 | | - break; |
| 81509 | | - } |
| 81510 | | - default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { |
| 81511 | | - const char *z = (const char *)( |
| 81512 | | - (eType==SQLITE_BLOB) ? |
| 81513 | | - sqlite3_column_blob(pStmt, 4): |
| 81514 | | - sqlite3_column_text(pStmt, 4) |
| 81515 | | - ); |
| 81516 | | - int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; |
| 81517 | | - pSample->nByte = n; |
| 81518 | | - if( n < 1){ |
| 81519 | | - pSample->u.z = 0; |
| 81520 | | - }else{ |
| 81521 | | - pSample->u.z = sqlite3DbMallocRaw(db, n); |
| 81522 | | - if( pSample->u.z==0 ){ |
| 81523 | | - db->mallocFailed = 1; |
| 81524 | | - sqlite3_finalize(pStmt); |
| 81525 | | - return SQLITE_NOMEM; |
| 81526 | | - } |
| 81527 | | - memcpy(pSample->u.z, z, n); |
| 81528 | | - } |
| 81529 | | - } |
| 81530 | | - } |
| 81531 | | - } |
| 81532 | | - return sqlite3_finalize(pStmt); |
| 81533 | | -} |
| 81534 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 81535 | | - |
| 81536 | | -/* |
| 81537 | | -** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The |
| 82383 | + } |
| 82384 | + pSample = &pIdx->aSample[pIdx->nSample]; |
| 82385 | + decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); |
| 82386 | + decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); |
| 82387 | + decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); |
| 82388 | + |
| 82389 | + /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 82390 | + ** This is in case the sample record is corrupted. In that case, the |
| 82391 | + ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 82392 | + ** end of the allocated buffer before it realizes it is dealing with |
| 82393 | + ** a corrupt record. Adding the two 0x00 bytes prevents this from causing |
| 82394 | + ** a buffer overread. */ |
| 82395 | + pSample->n = sqlite3_column_bytes(pStmt, 4); |
| 82396 | + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); |
| 82397 | + if( pSample->p==0 ){ |
| 82398 | + sqlite3_finalize(pStmt); |
| 82399 | + return SQLITE_NOMEM; |
| 82400 | + } |
| 82401 | + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
| 82402 | + pIdx->nSample++; |
| 82403 | + } |
| 82404 | + rc = sqlite3_finalize(pStmt); |
| 82405 | + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); |
| 82406 | + return rc; |
| 82407 | +} |
| 82408 | + |
| 82409 | +/* |
| 82410 | +** Load content from the sqlite_stat4 and sqlite_stat3 tables into |
| 82411 | +** the Index.aSample[] arrays of all indices. |
| 82412 | +*/ |
| 82413 | +static int loadStat4(sqlite3 *db, const char *zDb){ |
| 82414 | + int rc = SQLITE_OK; /* Result codes from subroutines */ |
| 82415 | + |
| 82416 | + assert( db->lookaside.bEnabled==0 ); |
| 82417 | + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ |
| 82418 | + rc = loadStatTbl(db, 0, |
| 82419 | + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", |
| 82420 | + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", |
| 82421 | + zDb |
| 82422 | + ); |
| 82423 | + } |
| 82424 | + |
| 82425 | + if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
| 82426 | + rc = loadStatTbl(db, 1, |
| 82427 | + "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", |
| 82428 | + "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", |
| 82429 | + zDb |
| 82430 | + ); |
| 82431 | + } |
| 82432 | + |
| 82433 | + return rc; |
| 82434 | +} |
| 82435 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 82436 | + |
| 82437 | +/* |
| 82438 | +** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The |
| 81538 | 82439 | ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] |
| 81539 | | -** arrays. The contents of sqlite_stat3 are used to populate the |
| 82440 | +** arrays. The contents of sqlite_stat3/4 are used to populate the |
| 81540 | 82441 | ** Index.aSample[] arrays. |
| 81541 | 82442 | ** |
| 81542 | 82443 | ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR |
| 81543 | | -** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined |
| 81544 | | -** during compilation and the sqlite_stat3 table is present, no data is |
| 82444 | +** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined |
| 82445 | +** during compilation and the sqlite_stat3/4 table is present, no data is |
| 81545 | 82446 | ** read from it. |
| 81546 | 82447 | ** |
| 81547 | | -** If SQLITE_ENABLE_STAT3 was defined during compilation and the |
| 81548 | | -** sqlite_stat3 table is not present in the database, SQLITE_ERROR is |
| 82448 | +** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the |
| 82449 | +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is |
| 81549 | 82450 | ** returned. However, in this case, data is read from the sqlite_stat1 |
| 81550 | 82451 | ** table (if it is present) before returning. |
| 81551 | 82452 | ** |
| 81552 | 82453 | ** If an OOM error occurs, this function always sets db->mallocFailed. |
| 81553 | 82454 | ** This means if the caller does not care about other errors, the return |
| | @@ -81565,11 +82466,11 @@ |
| 81565 | 82466 | /* Clear any prior statistics */ |
| 81566 | 82467 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81567 | 82468 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 81568 | 82469 | Index *pIdx = sqliteHashData(i); |
| 81569 | 82470 | sqlite3DefaultRowEst(pIdx); |
| 81570 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82471 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81571 | 82472 | sqlite3DeleteIndexSamples(db, pIdx); |
| 81572 | 82473 | pIdx->aSample = 0; |
| 81573 | 82474 | #endif |
| 81574 | 82475 | } |
| 81575 | 82476 | |
| | @@ -81589,16 +82490,16 @@ |
| 81589 | 82490 | rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 81590 | 82491 | sqlite3DbFree(db, zSql); |
| 81591 | 82492 | } |
| 81592 | 82493 | |
| 81593 | 82494 | |
| 81594 | | - /* Load the statistics from the sqlite_stat3 table. */ |
| 81595 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82495 | + /* Load the statistics from the sqlite_stat4 table. */ |
| 82496 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81596 | 82497 | if( rc==SQLITE_OK ){ |
| 81597 | 82498 | int lookasideEnabled = db->lookaside.bEnabled; |
| 81598 | 82499 | db->lookaside.bEnabled = 0; |
| 81599 | | - rc = loadStat3(db, sInfo.zDatabase); |
| 82500 | + rc = loadStat4(db, sInfo.zDatabase); |
| 81600 | 82501 | db->lookaside.bEnabled = lookasideEnabled; |
| 81601 | 82502 | } |
| 81602 | 82503 | #endif |
| 81603 | 82504 | |
| 81604 | 82505 | if( rc==SQLITE_NOMEM ){ |
| | @@ -81769,10 +82670,13 @@ |
| 81769 | 82670 | } |
| 81770 | 82671 | pPager = sqlite3BtreePager(aNew->pBt); |
| 81771 | 82672 | sqlite3PagerLockingMode(pPager, db->dfltLockMode); |
| 81772 | 82673 | sqlite3BtreeSecureDelete(aNew->pBt, |
| 81773 | 82674 | sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); |
| 82675 | +#ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 82676 | + sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); |
| 82677 | +#endif |
| 81774 | 82678 | } |
| 81775 | 82679 | aNew->safety_level = 3; |
| 81776 | 82680 | aNew->zName = sqlite3DbStrDup(db, zName); |
| 81777 | 82681 | if( rc==SQLITE_OK && aNew->zName==0 ){ |
| 81778 | 82682 | rc = SQLITE_NOMEM; |
| | @@ -84447,11 +85351,11 @@ |
| 84447 | 85351 | const char *zType, /* "idx" or "tbl" */ |
| 84448 | 85352 | const char *zName /* Name of index or table */ |
| 84449 | 85353 | ){ |
| 84450 | 85354 | int i; |
| 84451 | 85355 | const char *zDbName = pParse->db->aDb[iDb].zName; |
| 84452 | | - for(i=1; i<=3; i++){ |
| 85356 | + for(i=1; i<=4; i++){ |
| 84453 | 85357 | char zTab[24]; |
| 84454 | 85358 | sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); |
| 84455 | 85359 | if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ |
| 84456 | 85360 | sqlite3NestedParse(pParse, |
| 84457 | 85361 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| | @@ -85289,11 +86193,11 @@ |
| 85289 | 86193 | |
| 85290 | 86194 | /* Gather the complete text of the CREATE INDEX statement into |
| 85291 | 86195 | ** the zStmt variable |
| 85292 | 86196 | */ |
| 85293 | 86197 | if( pStart ){ |
| 85294 | | - int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; |
| 86198 | + int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; |
| 85295 | 86199 | if( pName->z[n-1]==';' ) n--; |
| 85296 | 86200 | /* A named index with an explicit CREATE INDEX statement */ |
| 85297 | 86201 | zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", |
| 85298 | 86202 | onError==OE_None ? "" : " UNIQUE", n, pName->z); |
| 85299 | 86203 | }else{ |
| | @@ -88926,13 +89830,13 @@ |
| 88926 | 89830 | } |
| 88927 | 89831 | static void groupConcatFinalize(sqlite3_context *context){ |
| 88928 | 89832 | StrAccum *pAccum; |
| 88929 | 89833 | pAccum = sqlite3_aggregate_context(context, 0); |
| 88930 | 89834 | if( pAccum ){ |
| 88931 | | - if( pAccum->tooBig ){ |
| 89835 | + if( pAccum->accError==STRACCUM_TOOBIG ){ |
| 88932 | 89836 | sqlite3_result_error_toobig(context); |
| 88933 | | - }else if( pAccum->mallocFailed ){ |
| 89837 | + }else if( pAccum->accError==STRACCUM_NOMEM ){ |
| 88934 | 89838 | sqlite3_result_error_nomem(context); |
| 88935 | 89839 | }else{ |
| 88936 | 89840 | sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, |
| 88937 | 89841 | sqlite3_free); |
| 88938 | 89842 | } |
| | @@ -89118,10 +90022,13 @@ |
| 89118 | 90022 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 89119 | 90023 | } |
| 89120 | 90024 | sqlite3RegisterDateTimeFunctions(); |
| 89121 | 90025 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 89122 | 90026 | sqlite3AlterFunctions(); |
| 90027 | +#endif |
| 90028 | +#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) |
| 90029 | + sqlite3AnalyzeFunctions(); |
| 89123 | 90030 | #endif |
| 89124 | 90031 | } |
| 89125 | 90032 | |
| 89126 | 90033 | /************** End of func.c ************************************************/ |
| 89127 | 90034 | /************** Begin file fkey.c ********************************************/ |
| | @@ -93834,10 +94741,40 @@ |
| 93834 | 94741 | sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); |
| 93835 | 94742 | sqlite3VdbeSetNumCols(v, 1); |
| 93836 | 94743 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); |
| 93837 | 94744 | sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); |
| 93838 | 94745 | } |
| 94746 | + |
| 94747 | + |
| 94748 | +/* |
| 94749 | +** Set the safety_level and pager flags for pager iDb. Or if iDb<0 |
| 94750 | +** set these values for all pagers. |
| 94751 | +*/ |
| 94752 | +#ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 94753 | +static void setAllPagerFlags(sqlite3 *db){ |
| 94754 | + if( db->autoCommit ){ |
| 94755 | + Db *pDb = db->aDb; |
| 94756 | + int n = db->nDb; |
| 94757 | + assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); |
| 94758 | + assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); |
| 94759 | + assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); |
| 94760 | + assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) |
| 94761 | + == PAGER_FLAGS_MASK ); |
| 94762 | + assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); |
| 94763 | + while( (n--) > 0 ){ |
| 94764 | + if( pDb->pBt ){ |
| 94765 | + sqlite3BtreeSetPagerFlags(pDb->pBt, |
| 94766 | + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); |
| 94767 | + } |
| 94768 | + pDb++; |
| 94769 | + } |
| 94770 | + } |
| 94771 | +} |
| 94772 | +#else |
| 94773 | +# define setAllPagerFlags(X) /* no-op */ |
| 94774 | +#endif |
| 94775 | + |
| 93839 | 94776 | |
| 93840 | 94777 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS |
| 93841 | 94778 | /* |
| 93842 | 94779 | ** Check to see if zRight and zLeft refer to a pragma that queries |
| 93843 | 94780 | ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. |
| | @@ -93853,10 +94790,11 @@ |
| 93853 | 94790 | { "count_changes", SQLITE_CountRows }, |
| 93854 | 94791 | { "empty_result_callbacks", SQLITE_NullCallback }, |
| 93855 | 94792 | { "legacy_file_format", SQLITE_LegacyFileFmt }, |
| 93856 | 94793 | { "fullfsync", SQLITE_FullFSync }, |
| 93857 | 94794 | { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, |
| 94795 | + { "cache_spill", SQLITE_CacheSpill }, |
| 93858 | 94796 | { "reverse_unordered_selects", SQLITE_ReverseOrder }, |
| 93859 | 94797 | { "query_only", SQLITE_QueryOnly }, |
| 93860 | 94798 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 93861 | 94799 | { "automatic_index", SQLITE_AutoIndex }, |
| 93862 | 94800 | #endif |
| | @@ -94307,11 +95245,11 @@ |
| 94307 | 95245 | */ |
| 94308 | 95246 | if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 94309 | 95247 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 94310 | 95248 | i64 iLimit = -2; |
| 94311 | 95249 | if( zRight ){ |
| 94312 | | - sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); |
| 95250 | + sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 94313 | 95251 | if( iLimit<-1 ) iLimit = -1; |
| 94314 | 95252 | } |
| 94315 | 95253 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 94316 | 95254 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 94317 | 95255 | }else |
| | @@ -94441,14 +95379,15 @@ |
| 94441 | 95379 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 94442 | 95380 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 94443 | 95381 | */ |
| 94444 | 95382 | if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 94445 | 95383 | sqlite3_int64 sz; |
| 95384 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 94446 | 95385 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 94447 | 95386 | if( zRight ){ |
| 94448 | 95387 | int ii; |
| 94449 | | - sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8); |
| 95388 | + sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 94450 | 95389 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 94451 | 95390 | if( pId2->n==0 ) db->szMmap = sz; |
| 94452 | 95391 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 94453 | 95392 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 94454 | 95393 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| | @@ -94455,12 +95394,13 @@ |
| 94455 | 95394 | } |
| 94456 | 95395 | } |
| 94457 | 95396 | } |
| 94458 | 95397 | sz = -1; |
| 94459 | 95398 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 94460 | | -#if SQLITE_MAX_MMAP_SIZE==0 |
| 95399 | +#else |
| 94461 | 95400 | sz = 0; |
| 95401 | + rc = SQLITE_OK; |
| 94462 | 95402 | #endif |
| 94463 | 95403 | if( rc==SQLITE_OK ){ |
| 94464 | 95404 | returnSingleInt(pParse, "mmap_size", sz); |
| 94465 | 95405 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 94466 | 95406 | pParse->nErr++; |
| | @@ -94643,19 +95583,19 @@ |
| 94643 | 95583 | if( !db->autoCommit ){ |
| 94644 | 95584 | sqlite3ErrorMsg(pParse, |
| 94645 | 95585 | "Safety level may not be changed inside a transaction"); |
| 94646 | 95586 | }else{ |
| 94647 | 95587 | pDb->safety_level = getSafetyLevel(zRight,0,1)+1; |
| 95588 | + setAllPagerFlags(db); |
| 94648 | 95589 | } |
| 94649 | 95590 | } |
| 94650 | 95591 | }else |
| 94651 | 95592 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
| 94652 | 95593 | |
| 94653 | 95594 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS |
| 94654 | 95595 | if( flagPragma(pParse, zLeft, zRight) ){ |
| 94655 | | - /* The flagPragma() subroutine also generates any necessary code |
| 94656 | | - ** there is nothing more to do here */ |
| 95596 | + setAllPagerFlags(db); |
| 94657 | 95597 | }else |
| 94658 | 95598 | #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ |
| 94659 | 95599 | |
| 94660 | 95600 | #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS |
| 94661 | 95601 | /* |
| | @@ -95482,21 +96422,10 @@ |
| 95482 | 96422 | #endif |
| 95483 | 96423 | |
| 95484 | 96424 | |
| 95485 | 96425 | {/* Empty ELSE clause */} |
| 95486 | 96426 | |
| 95487 | | - /* |
| 95488 | | - ** Reset the safety level, in case the fullfsync flag or synchronous |
| 95489 | | - ** setting changed. |
| 95490 | | - */ |
| 95491 | | -#ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 95492 | | - if( db->autoCommit ){ |
| 95493 | | - sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, |
| 95494 | | - (db->flags&SQLITE_FullFSync)!=0, |
| 95495 | | - (db->flags&SQLITE_CkptFullFSync)!=0); |
| 95496 | | - } |
| 95497 | | -#endif |
| 95498 | 96427 | pragma_out: |
| 95499 | 96428 | sqlite3DbFree(db, zLeft); |
| 95500 | 96429 | sqlite3DbFree(db, zRight); |
| 95501 | 96430 | } |
| 95502 | 96431 | |
| | @@ -102619,11 +103548,11 @@ |
| 102619 | 103548 | ** space. |
| 102620 | 103549 | */ |
| 102621 | 103550 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 102622 | 103551 | assert( pTab!=0 ); |
| 102623 | 103552 | if( !pTab->pSelect ){ |
| 102624 | | - sqlite3_value *pValue; |
| 103553 | + sqlite3_value *pValue = 0; |
| 102625 | 103554 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 102626 | 103555 | Column *pCol = &pTab->aCol[i]; |
| 102627 | 103556 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); |
| 102628 | 103557 | assert( i<pTab->nCol ); |
| 102629 | 103558 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, |
| | @@ -104395,14 +105324,13 @@ |
| 104395 | 105324 | /* |
| 104396 | 105325 | ** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans |
| 104397 | 105326 | ** array. Return the error code for the first error that occurs, or |
| 104398 | 105327 | ** SQLITE_OK if all xSync operations are successful. |
| 104399 | 105328 | ** |
| 104400 | | -** Set *pzErrmsg to point to a buffer that should be released using |
| 104401 | | -** sqlite3DbFree() containing an error message, if one is available. |
| 105329 | +** If an error message is available, leave it in p->zErrMsg. |
| 104402 | 105330 | */ |
| 104403 | | -SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ |
| 105331 | +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ |
| 104404 | 105332 | int i; |
| 104405 | 105333 | int rc = SQLITE_OK; |
| 104406 | 105334 | VTable **aVTrans = db->aVTrans; |
| 104407 | 105335 | |
| 104408 | 105336 | db->aVTrans = 0; |
| | @@ -104409,13 +105337,11 @@ |
| 104409 | 105337 | for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
| 104410 | 105338 | int (*x)(sqlite3_vtab *); |
| 104411 | 105339 | sqlite3_vtab *pVtab = aVTrans[i]->pVtab; |
| 104412 | 105340 | if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ |
| 104413 | 105341 | rc = x(pVtab); |
| 104414 | | - sqlite3DbFree(db, *pzErrmsg); |
| 104415 | | - *pzErrmsg = pVtab->zErrMsg; |
| 104416 | | - pVtab->zErrMsg = 0; |
| 105342 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 104417 | 105343 | } |
| 104418 | 105344 | } |
| 104419 | 105345 | db->aVTrans = aVTrans; |
| 104420 | 105346 | return rc; |
| 104421 | 105347 | } |
| | @@ -104776,10 +105702,11 @@ |
| 104776 | 105702 | int iIdxCur; /* The VDBE cursor used to access pIdx */ |
| 104777 | 105703 | int addrBrk; /* Jump here to break out of the loop */ |
| 104778 | 105704 | int addrNxt; /* Jump here to start the next IN combination */ |
| 104779 | 105705 | int addrCont; /* Jump here to continue with the next loop cycle */ |
| 104780 | 105706 | int addrFirst; /* First instruction of interior of the loop */ |
| 105707 | + int addrBody; /* Beginning of the body of this loop */ |
| 104781 | 105708 | u8 iFrom; /* Which entry in the FROM clause */ |
| 104782 | 105709 | u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ |
| 104783 | 105710 | int p1, p2; /* Operands of the opcode used to ends the loop */ |
| 104784 | 105711 | union { /* Information that depends on pWLoop->wsFlags */ |
| 104785 | 105712 | struct { |
| | @@ -104971,11 +105898,11 @@ |
| 104971 | 105898 | #define TERM_CODED 0x04 /* This term is already coded */ |
| 104972 | 105899 | #define TERM_COPIED 0x08 /* Has a child */ |
| 104973 | 105900 | #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ |
| 104974 | 105901 | #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ |
| 104975 | 105902 | #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ |
| 104976 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 105903 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 104977 | 105904 | # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ |
| 104978 | 105905 | #else |
| 104979 | 105906 | # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ |
| 104980 | 105907 | #endif |
| 104981 | 105908 | |
| | @@ -105077,10 +106004,14 @@ |
| 105077 | 106004 | WhereInfo *pWInfo; /* Information about this WHERE */ |
| 105078 | 106005 | WhereClause *pWC; /* WHERE clause terms */ |
| 105079 | 106006 | ExprList *pOrderBy; /* ORDER BY clause */ |
| 105080 | 106007 | WhereLoop *pNew; /* Template WhereLoop */ |
| 105081 | 106008 | WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ |
| 106009 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 106010 | + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ |
| 106011 | + int nRecValid; /* Number of valid fields currently in pRec */ |
| 106012 | +#endif |
| 105082 | 106013 | }; |
| 105083 | 106014 | |
| 105084 | 106015 | /* |
| 105085 | 106016 | ** The WHERE clause processing routine has two halves. The |
| 105086 | 106017 | ** first part does the start of the WHERE loop and the second |
| | @@ -105890,12 +106821,14 @@ |
| 105890 | 106821 | /* |
| 105891 | 106822 | ** If the pBase expression originated in the ON or USING clause of |
| 105892 | 106823 | ** a join, then transfer the appropriate markings over to derived. |
| 105893 | 106824 | */ |
| 105894 | 106825 | static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ |
| 105895 | | - pDerived->flags |= pBase->flags & EP_FromJoin; |
| 105896 | | - pDerived->iRightJoinTable = pBase->iRightJoinTable; |
| 106826 | + if( pDerived ){ |
| 106827 | + pDerived->flags |= pBase->flags & EP_FromJoin; |
| 106828 | + pDerived->iRightJoinTable = pBase->iRightJoinTable; |
| 106829 | + } |
| 105897 | 106830 | } |
| 105898 | 106831 | |
| 105899 | 106832 | #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) |
| 105900 | 106833 | /* |
| 105901 | 106834 | ** Analyze a term that consists of two or more OR-connected |
| | @@ -106348,10 +107281,11 @@ |
| 106348 | 107281 | Expr *pNewExpr; |
| 106349 | 107282 | int idxNew; |
| 106350 | 107283 | pNewExpr = sqlite3PExpr(pParse, ops[i], |
| 106351 | 107284 | sqlite3ExprDup(db, pExpr->pLeft, 0), |
| 106352 | 107285 | sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); |
| 107286 | + transferJoinMarkings(pNewExpr, pExpr); |
| 106353 | 107287 | idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); |
| 106354 | 107288 | testcase( idxNew==0 ); |
| 106355 | 107289 | exprAnalyze(pSrc, pWC, idxNew); |
| 106356 | 107290 | pTerm = &pWC->a[idxTerm]; |
| 106357 | 107291 | pWC->a[idxNew].iParent = idxTerm; |
| | @@ -106415,17 +107349,19 @@ |
| 106415 | 107349 | sCollSeqName.n = 6; |
| 106416 | 107350 | pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); |
| 106417 | 107351 | pNewExpr1 = sqlite3PExpr(pParse, TK_GE, |
| 106418 | 107352 | sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName), |
| 106419 | 107353 | pStr1, 0); |
| 107354 | + transferJoinMarkings(pNewExpr1, pExpr); |
| 106420 | 107355 | idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); |
| 106421 | 107356 | testcase( idxNew1==0 ); |
| 106422 | 107357 | exprAnalyze(pSrc, pWC, idxNew1); |
| 106423 | 107358 | pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); |
| 106424 | 107359 | pNewExpr2 = sqlite3PExpr(pParse, TK_LT, |
| 106425 | 107360 | sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName), |
| 106426 | 107361 | pStr2, 0); |
| 107362 | + transferJoinMarkings(pNewExpr2, pExpr); |
| 106427 | 107363 | idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); |
| 106428 | 107364 | testcase( idxNew2==0 ); |
| 106429 | 107365 | exprAnalyze(pSrc, pWC, idxNew2); |
| 106430 | 107366 | pTerm = &pWC->a[idxTerm]; |
| 106431 | 107367 | if( isComplete ){ |
| | @@ -106471,11 +107407,11 @@ |
| 106471 | 107407 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106472 | 107408 | } |
| 106473 | 107409 | } |
| 106474 | 107410 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 106475 | 107411 | |
| 106476 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 107412 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 106477 | 107413 | /* When sqlite_stat3 histogram data is available an operator of the |
| 106478 | 107414 | ** form "x IS NOT NULL" can sometimes be evaluated more efficiently |
| 106479 | 107415 | ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a |
| 106480 | 107416 | ** virtual term of that form. |
| 106481 | 107417 | ** |
| | @@ -106511,11 +107447,11 @@ |
| 106511 | 107447 | pTerm->nChild = 1; |
| 106512 | 107448 | pTerm->wtFlags |= TERM_COPIED; |
| 106513 | 107449 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106514 | 107450 | } |
| 106515 | 107451 | } |
| 106516 | | -#endif /* SQLITE_ENABLE_STAT */ |
| 107452 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 106517 | 107453 | |
| 106518 | 107454 | /* Prevent ON clause terms of a LEFT JOIN from being used to drive |
| 106519 | 107455 | ** an index for tables to the left of the join. |
| 106520 | 107456 | */ |
| 106521 | 107457 | pTerm->prereqRight |= extraRight; |
| | @@ -107079,155 +108015,84 @@ |
| 107079 | 108015 | return pParse->nErr; |
| 107080 | 108016 | } |
| 107081 | 108017 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 107082 | 108018 | |
| 107083 | 108019 | |
| 107084 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108020 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107085 | 108021 | /* |
| 107086 | 108022 | ** Estimate the location of a particular key among all keys in an |
| 107087 | 108023 | ** index. Store the results in aStat as follows: |
| 107088 | 108024 | ** |
| 107089 | 108025 | ** aStat[0] Est. number of rows less than pVal |
| 107090 | 108026 | ** aStat[1] Est. number of rows equal to pVal |
| 107091 | 108027 | ** |
| 107092 | 108028 | ** Return SQLITE_OK on success. |
| 107093 | 108029 | */ |
| 107094 | | -static int whereKeyStats( |
| 108030 | +static void whereKeyStats( |
| 107095 | 108031 | Parse *pParse, /* Database connection */ |
| 107096 | 108032 | Index *pIdx, /* Index to consider domain of */ |
| 107097 | | - sqlite3_value *pVal, /* Value to consider */ |
| 108033 | + UnpackedRecord *pRec, /* Vector of values to consider */ |
| 107098 | 108034 | int roundUp, /* Round up if true. Round down if false */ |
| 107099 | 108035 | tRowcnt *aStat /* OUT: stats written here */ |
| 107100 | 108036 | ){ |
| 107101 | | - tRowcnt n; |
| 107102 | | - IndexSample *aSample; |
| 107103 | | - int i, eType; |
| 107104 | | - int isEq = 0; |
| 107105 | | - i64 v; |
| 107106 | | - double r, rS; |
| 107107 | | - |
| 107108 | | - assert( roundUp==0 || roundUp==1 ); |
| 108037 | + IndexSample *aSample = pIdx->aSample; |
| 108038 | + int iCol = pRec->nField-1; /* Index of required stats in anEq[] etc. */ |
| 108039 | + int iMin = 0; /* Smallest sample not yet tested */ |
| 108040 | + int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ |
| 108041 | + int iTest; /* Next sample to test */ |
| 108042 | + int res; /* Result of comparison operation */ |
| 108043 | + |
| 107109 | 108044 | assert( pIdx->nSample>0 ); |
| 107110 | | - if( pVal==0 ) return SQLITE_ERROR; |
| 107111 | | - n = pIdx->aiRowEst[0]; |
| 107112 | | - aSample = pIdx->aSample; |
| 107113 | | - eType = sqlite3_value_type(pVal); |
| 107114 | | - |
| 107115 | | - if( eType==SQLITE_INTEGER ){ |
| 107116 | | - v = sqlite3_value_int64(pVal); |
| 107117 | | - r = (i64)v; |
| 107118 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107119 | | - if( aSample[i].eType==SQLITE_NULL ) continue; |
| 107120 | | - if( aSample[i].eType>=SQLITE_TEXT ) break; |
| 107121 | | - if( aSample[i].eType==SQLITE_INTEGER ){ |
| 107122 | | - if( aSample[i].u.i>=v ){ |
| 107123 | | - isEq = aSample[i].u.i==v; |
| 107124 | | - break; |
| 107125 | | - } |
| 107126 | | - }else{ |
| 107127 | | - assert( aSample[i].eType==SQLITE_FLOAT ); |
| 107128 | | - if( aSample[i].u.r>=r ){ |
| 107129 | | - isEq = aSample[i].u.r==r; |
| 107130 | | - break; |
| 107131 | | - } |
| 107132 | | - } |
| 107133 | | - } |
| 107134 | | - }else if( eType==SQLITE_FLOAT ){ |
| 107135 | | - r = sqlite3_value_double(pVal); |
| 107136 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107137 | | - if( aSample[i].eType==SQLITE_NULL ) continue; |
| 107138 | | - if( aSample[i].eType>=SQLITE_TEXT ) break; |
| 107139 | | - if( aSample[i].eType==SQLITE_FLOAT ){ |
| 107140 | | - rS = aSample[i].u.r; |
| 107141 | | - }else{ |
| 107142 | | - rS = aSample[i].u.i; |
| 107143 | | - } |
| 107144 | | - if( rS>=r ){ |
| 107145 | | - isEq = rS==r; |
| 107146 | | - break; |
| 107147 | | - } |
| 107148 | | - } |
| 107149 | | - }else if( eType==SQLITE_NULL ){ |
| 107150 | | - i = 0; |
| 107151 | | - if( aSample[0].eType==SQLITE_NULL ) isEq = 1; |
| 107152 | | - }else{ |
| 107153 | | - assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); |
| 107154 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107155 | | - if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){ |
| 107156 | | - break; |
| 107157 | | - } |
| 107158 | | - } |
| 107159 | | - if( i<pIdx->nSample ){ |
| 107160 | | - sqlite3 *db = pParse->db; |
| 107161 | | - CollSeq *pColl; |
| 107162 | | - const u8 *z; |
| 107163 | | - if( eType==SQLITE_BLOB ){ |
| 107164 | | - z = (const u8 *)sqlite3_value_blob(pVal); |
| 107165 | | - pColl = db->pDfltColl; |
| 107166 | | - assert( pColl->enc==SQLITE_UTF8 ); |
| 107167 | | - }else{ |
| 107168 | | - pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl); |
| 107169 | | - /* If the collating sequence was unavailable, we should have failed |
| 107170 | | - ** long ago and never reached this point. But we'll check just to |
| 107171 | | - ** be doubly sure. */ |
| 107172 | | - if( NEVER(pColl==0) ) return SQLITE_ERROR; |
| 107173 | | - z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); |
| 107174 | | - if( !z ){ |
| 107175 | | - return SQLITE_NOMEM; |
| 107176 | | - } |
| 107177 | | - assert( z && pColl && pColl->xCmp ); |
| 107178 | | - } |
| 107179 | | - n = sqlite3ValueBytes(pVal, pColl->enc); |
| 107180 | | - |
| 107181 | | - for(; i<pIdx->nSample; i++){ |
| 107182 | | - int c; |
| 107183 | | - int eSampletype = aSample[i].eType; |
| 107184 | | - if( eSampletype<eType ) continue; |
| 107185 | | - if( eSampletype!=eType ) break; |
| 107186 | | -#ifndef SQLITE_OMIT_UTF16 |
| 107187 | | - if( pColl->enc!=SQLITE_UTF8 ){ |
| 107188 | | - int nSample; |
| 107189 | | - char *zSample = sqlite3Utf8to16( |
| 107190 | | - db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample |
| 107191 | | - ); |
| 107192 | | - if( !zSample ){ |
| 107193 | | - assert( db->mallocFailed ); |
| 107194 | | - return SQLITE_NOMEM; |
| 107195 | | - } |
| 107196 | | - c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); |
| 107197 | | - sqlite3DbFree(db, zSample); |
| 107198 | | - }else |
| 107199 | | -#endif |
| 107200 | | - { |
| 107201 | | - c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); |
| 107202 | | - } |
| 107203 | | - if( c>=0 ){ |
| 107204 | | - if( c==0 ) isEq = 1; |
| 107205 | | - break; |
| 107206 | | - } |
| 107207 | | - } |
| 107208 | | - } |
| 107209 | | - } |
| 108045 | + assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); |
| 108046 | + do{ |
| 108047 | + iTest = (iMin+i)/2; |
| 108048 | + res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); |
| 108049 | + if( res<0 ){ |
| 108050 | + iMin = iTest+1; |
| 108051 | + }else{ |
| 108052 | + i = iTest; |
| 108053 | + } |
| 108054 | + }while( res && iMin<i ); |
| 108055 | + |
| 108056 | +#ifdef SQLITE_DEBUG |
| 108057 | + /* The following assert statements check that the binary search code |
| 108058 | + ** above found the right answer. This block serves no purpose other |
| 108059 | + ** than to invoke the asserts. */ |
| 108060 | + if( res==0 ){ |
| 108061 | + /* If (res==0) is true, then sample $i must be equal to pRec */ |
| 108062 | + assert( i<pIdx->nSample ); |
| 108063 | + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) |
| 108064 | + || pParse->db->mallocFailed ); |
| 108065 | + }else{ |
| 108066 | + /* Otherwise, pRec must be smaller than sample $i and larger than |
| 108067 | + ** sample ($i-1). */ |
| 108068 | + assert( i==pIdx->nSample |
| 108069 | + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 |
| 108070 | + || pParse->db->mallocFailed ); |
| 108071 | + assert( i==0 |
| 108072 | + || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 |
| 108073 | + || pParse->db->mallocFailed ); |
| 108074 | + } |
| 108075 | +#endif /* ifdef SQLITE_DEBUG */ |
| 107210 | 108076 | |
| 107211 | 108077 | /* At this point, aSample[i] is the first sample that is greater than |
| 107212 | 108078 | ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less |
| 107213 | | - ** than pVal. If aSample[i]==pVal, then isEq==1. |
| 108079 | + ** than pVal. If aSample[i]==pVal, then res==0. |
| 107214 | 108080 | */ |
| 107215 | | - if( isEq ){ |
| 107216 | | - assert( i<pIdx->nSample ); |
| 107217 | | - aStat[0] = aSample[i].nLt; |
| 107218 | | - aStat[1] = aSample[i].nEq; |
| 108081 | + if( res==0 ){ |
| 108082 | + aStat[0] = aSample[i].anLt[iCol]; |
| 108083 | + aStat[1] = aSample[i].anEq[iCol]; |
| 107219 | 108084 | }else{ |
| 107220 | 108085 | tRowcnt iLower, iUpper, iGap; |
| 107221 | 108086 | if( i==0 ){ |
| 107222 | 108087 | iLower = 0; |
| 107223 | | - iUpper = aSample[0].nLt; |
| 108088 | + iUpper = aSample[0].anLt[iCol]; |
| 107224 | 108089 | }else{ |
| 107225 | | - iUpper = i>=pIdx->nSample ? n : aSample[i].nLt; |
| 107226 | | - iLower = aSample[i-1].nEq + aSample[i-1].nLt; |
| 108090 | + iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; |
| 108091 | + iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 107227 | 108092 | } |
| 107228 | | - aStat[1] = pIdx->avgEq; |
| 108093 | + aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 107229 | 108094 | if( iLower>=iUpper ){ |
| 107230 | 108095 | iGap = 0; |
| 107231 | 108096 | }else{ |
| 107232 | 108097 | iGap = iUpper - iLower; |
| 107233 | 108098 | } |
| | @@ -107236,48 +108101,12 @@ |
| 107236 | 108101 | }else{ |
| 107237 | 108102 | iGap = iGap/3; |
| 107238 | 108103 | } |
| 107239 | 108104 | aStat[0] = iLower + iGap; |
| 107240 | 108105 | } |
| 107241 | | - return SQLITE_OK; |
| 107242 | | -} |
| 107243 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 107244 | | - |
| 107245 | | -/* |
| 107246 | | -** If expression pExpr represents a literal value, set *pp to point to |
| 107247 | | -** an sqlite3_value structure containing the same value, with affinity |
| 107248 | | -** aff applied to it, before returning. It is the responsibility of the |
| 107249 | | -** caller to eventually release this structure by passing it to |
| 107250 | | -** sqlite3ValueFree(). |
| 107251 | | -** |
| 107252 | | -** If the current parse is a recompile (sqlite3Reprepare()) and pExpr |
| 107253 | | -** is an SQL variable that currently has a non-NULL value bound to it, |
| 107254 | | -** create an sqlite3_value structure containing this value, again with |
| 107255 | | -** affinity aff applied to it, instead. |
| 107256 | | -** |
| 107257 | | -** If neither of the above apply, set *pp to NULL. |
| 107258 | | -** |
| 107259 | | -** If an error occurs, return an error code. Otherwise, SQLITE_OK. |
| 107260 | | -*/ |
| 107261 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 107262 | | -static int valueFromExpr( |
| 107263 | | - Parse *pParse, |
| 107264 | | - Expr *pExpr, |
| 107265 | | - u8 aff, |
| 107266 | | - sqlite3_value **pp |
| 107267 | | -){ |
| 107268 | | - if( pExpr->op==TK_VARIABLE |
| 107269 | | - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 107270 | | - ){ |
| 107271 | | - int iVar = pExpr->iColumn; |
| 107272 | | - sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); |
| 107273 | | - *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff); |
| 107274 | | - return SQLITE_OK; |
| 107275 | | - } |
| 107276 | | - return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp); |
| 107277 | | -} |
| 107278 | | -#endif |
| 108106 | +} |
| 108107 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107279 | 108108 | |
| 107280 | 108109 | /* |
| 107281 | 108110 | ** This function is used to estimate the number of rows that will be visited |
| 107282 | 108111 | ** by scanning an index for a range of values. The range may have an upper |
| 107283 | 108112 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| | @@ -107290,107 +108119,154 @@ |
| 107290 | 108119 | ** pLower pUpper |
| 107291 | 108120 | ** |
| 107292 | 108121 | ** If either of the upper or lower bound is not present, then NULL is passed in |
| 107293 | 108122 | ** place of the corresponding WhereTerm. |
| 107294 | 108123 | ** |
| 107295 | | -** The nEq parameter is passed the index of the index column subject to the |
| 107296 | | -** range constraint. Or, equivalently, the number of equality constraints |
| 107297 | | -** optimized by the proposed index scan. For example, assuming index p is |
| 107298 | | -** on t1(a, b), and the SQL query is: |
| 108124 | +** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index |
| 108125 | +** column subject to the range constraint. Or, equivalently, the number of |
| 108126 | +** equality constraints optimized by the proposed index scan. For example, |
| 108127 | +** assuming index p is on t1(a, b), and the SQL query is: |
| 107299 | 108128 | ** |
| 107300 | 108129 | ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... |
| 107301 | 108130 | ** |
| 107302 | | -** then nEq should be passed the value 1 (as the range restricted column, |
| 107303 | | -** b, is the second left-most column of the index). Or, if the query is: |
| 108131 | +** then nEq is set to 1 (as the range restricted column, b, is the second |
| 108132 | +** left-most column of the index). Or, if the query is: |
| 107304 | 108133 | ** |
| 107305 | 108134 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 107306 | 108135 | ** |
| 107307 | | -** then nEq should be passed 0. |
| 107308 | | -** |
| 107309 | | -** The returned value is an integer divisor to reduce the estimated |
| 107310 | | -** search space. A return value of 1 means that range constraints are |
| 107311 | | -** no help at all. A return value of 2 means range constraints are |
| 107312 | | -** expected to reduce the search space by half. And so forth... |
| 107313 | | -** |
| 107314 | | -** In the absence of sqlite_stat3 ANALYZE data, each range inequality |
| 107315 | | -** reduces the search space by a factor of 4. Hence a single constraint (x>?) |
| 107316 | | -** results in a return of 4 and a range constraint (x>? AND x<?) results |
| 107317 | | -** in a return of 16. |
| 108136 | +** then nEq is set to 0. |
| 108137 | +** |
| 108138 | +** When this function is called, *pnOut is set to the whereCost() of the |
| 108139 | +** number of rows that the index scan is expected to visit without |
| 108140 | +** considering the range constraints. If nEq is 0, this is the number of |
| 108141 | +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) |
| 108142 | +** to account for the range contraints pLower and pUpper. |
| 108143 | +** |
| 108144 | +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be |
| 108145 | +** used, each range inequality reduces the search space by a factor of 4. |
| 108146 | +** Hence a pair of constraints (x>? AND x<?) reduces the expected number of |
| 108147 | +** rows visited by a factor of 16. |
| 107318 | 108148 | */ |
| 107319 | 108149 | static int whereRangeScanEst( |
| 107320 | 108150 | Parse *pParse, /* Parsing & code generating context */ |
| 107321 | | - Index *p, /* The index containing the range-compared column; "x" */ |
| 107322 | | - int nEq, /* index into p->aCol[] of the range-compared column */ |
| 108151 | + WhereLoopBuilder *pBuilder, |
| 107323 | 108152 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 107324 | 108153 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 107325 | | - WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */ |
| 108154 | + WhereCost *pnOut /* IN/OUT: Number of rows visited */ |
| 107326 | 108155 | ){ |
| 107327 | 108156 | int rc = SQLITE_OK; |
| 108157 | + int nOut = (int)*pnOut; |
| 107328 | 108158 | |
| 107329 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108159 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108160 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108161 | + int nEq = pBuilder->pNew->u.btree.nEq; |
| 107330 | 108162 | |
| 107331 | | - if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){ |
| 107332 | | - sqlite3_value *pRangeVal; |
| 107333 | | - tRowcnt iLower = 0; |
| 107334 | | - tRowcnt iUpper = p->aiRowEst[0]; |
| 108163 | + if( nEq==pBuilder->nRecValid |
| 108164 | + && nEq<p->nSampleCol |
| 108165 | + && p->nSample |
| 108166 | + && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108167 | + ){ |
| 108168 | + UnpackedRecord *pRec = pBuilder->pRec; |
| 107335 | 108169 | tRowcnt a[2]; |
| 107336 | 108170 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 107337 | 108171 | |
| 108172 | + /* Variable iLower will be set to the estimate of the number of rows in |
| 108173 | + ** the index that are less than the lower bound of the range query. The |
| 108174 | + ** lower bound being the concatenation of $P and $L, where $P is the |
| 108175 | + ** key-prefix formed by the nEq values matched against the nEq left-most |
| 108176 | + ** columns of the index, and $L is the value in pLower. |
| 108177 | + ** |
| 108178 | + ** Or, if pLower is NULL or $L cannot be extracted from it (because it |
| 108179 | + ** is not a simple variable or literal value), the lower bound of the |
| 108180 | + ** range is $P. Due to a quirk in the way whereKeyStats() works, even |
| 108181 | + ** if $L is available, whereKeyStats() is called for both ($P) and |
| 108182 | + ** ($P:$L) and the larger of the two returned values used. |
| 108183 | + ** |
| 108184 | + ** Similarly, iUpper is to be set to the estimate of the number of rows |
| 108185 | + ** less than the upper bound of the range query. Where the upper bound |
| 108186 | + ** is either ($P) or ($P:$U). Again, even if $U is available, both values |
| 108187 | + ** of iUpper are requested of whereKeyStats() and the smaller used. |
| 108188 | + */ |
| 108189 | + tRowcnt iLower; |
| 108190 | + tRowcnt iUpper; |
| 108191 | + |
| 108192 | + /* Determine iLower and iUpper using ($P) only. */ |
| 108193 | + if( nEq==0 ){ |
| 108194 | + iLower = 0; |
| 108195 | + iUpper = p->aiRowEst[0]; |
| 108196 | + }else{ |
| 108197 | + /* Note: this call could be optimized away - since the same values must |
| 108198 | + ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 108199 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108200 | + iLower = a[0]; |
| 108201 | + iUpper = a[0] + a[1]; |
| 108202 | + } |
| 108203 | + |
| 108204 | + /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 107338 | 108205 | if( pLower ){ |
| 108206 | + int bOk; /* True if value is extracted from pExpr */ |
| 107339 | 108207 | Expr *pExpr = pLower->pExpr->pRight; |
| 107340 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); |
| 107341 | 108208 | assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 ); |
| 107342 | | - if( rc==SQLITE_OK |
| 107343 | | - && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK |
| 107344 | | - ){ |
| 107345 | | - iLower = a[0]; |
| 107346 | | - if( (pLower->eOperator & WO_GT)!=0 ) iLower += a[1]; |
| 107347 | | - } |
| 107348 | | - sqlite3ValueFree(pRangeVal); |
| 107349 | | - } |
| 107350 | | - if( rc==SQLITE_OK && pUpper ){ |
| 107351 | | - Expr *pExpr = pUpper->pExpr->pRight; |
| 107352 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); |
| 108209 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108210 | + if( rc==SQLITE_OK && bOk ){ |
| 108211 | + tRowcnt iNew; |
| 108212 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108213 | + iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 108214 | + if( iNew>iLower ) iLower = iNew; |
| 108215 | + } |
| 108216 | + } |
| 108217 | + |
| 108218 | + /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 108219 | + if( pUpper ){ |
| 108220 | + int bOk; /* True if value is extracted from pExpr */ |
| 108221 | + Expr *pExpr = pUpper->pExpr->pRight; |
| 107353 | 108222 | assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); |
| 107354 | | - if( rc==SQLITE_OK |
| 107355 | | - && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK |
| 107356 | | - ){ |
| 107357 | | - iUpper = a[0]; |
| 107358 | | - if( (pUpper->eOperator & WO_LE)!=0 ) iUpper += a[1]; |
| 107359 | | - } |
| 107360 | | - sqlite3ValueFree(pRangeVal); |
| 107361 | | - } |
| 108223 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108224 | + if( rc==SQLITE_OK && bOk ){ |
| 108225 | + tRowcnt iNew; |
| 108226 | + whereKeyStats(pParse, p, pRec, 1, a); |
| 108227 | + iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 108228 | + if( iNew<iUpper ) iUpper = iNew; |
| 108229 | + } |
| 108230 | + } |
| 108231 | + |
| 108232 | + pBuilder->pRec = pRec; |
| 107362 | 108233 | if( rc==SQLITE_OK ){ |
| 107363 | | - WhereCost iBase = whereCost(p->aiRowEst[0]); |
| 108234 | + WhereCost nNew; |
| 107364 | 108235 | if( iUpper>iLower ){ |
| 107365 | | - iBase -= whereCost(iUpper - iLower); |
| 108236 | + nNew = whereCost(iUpper - iLower); |
| 108237 | + }else{ |
| 108238 | + nNew = 10; assert( 10==whereCost(2) ); |
| 107366 | 108239 | } |
| 107367 | | - *pRangeDiv = iBase; |
| 107368 | | - WHERETRACE(0x100, ("range scan regions: %u..%u div=%d\n", |
| 107369 | | - (u32)iLower, (u32)iUpper, *pRangeDiv)); |
| 108240 | + if( nNew<nOut ){ |
| 108241 | + nOut = nNew; |
| 108242 | + } |
| 108243 | + *pnOut = (WhereCost)nOut; |
| 108244 | + WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n", |
| 108245 | + (u32)iLower, (u32)iUpper, nOut)); |
| 107370 | 108246 | return SQLITE_OK; |
| 107371 | 108247 | } |
| 107372 | 108248 | } |
| 107373 | 108249 | #else |
| 107374 | 108250 | UNUSED_PARAMETER(pParse); |
| 107375 | | - UNUSED_PARAMETER(p); |
| 107376 | | - UNUSED_PARAMETER(nEq); |
| 108251 | + UNUSED_PARAMETER(pBuilder); |
| 107377 | 108252 | #endif |
| 107378 | 108253 | assert( pLower || pUpper ); |
| 107379 | | - *pRangeDiv = 0; |
| 107380 | 108254 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 107381 | 108255 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 107382 | 108256 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 107383 | | - *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 108257 | + nOut -= 20; assert( 20==whereCost(4) ); |
| 107384 | 108258 | } |
| 107385 | 108259 | if( pUpper ){ |
| 107386 | | - *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 108260 | + nOut -= 20; assert( 20==whereCost(4) ); |
| 107387 | 108261 | } |
| 108262 | + if( nOut<10 ) nOut = 10; |
| 108263 | + *pnOut = (WhereCost)nOut; |
| 107388 | 108264 | return rc; |
| 107389 | 108265 | } |
| 107390 | 108266 | |
| 107391 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108267 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107392 | 108268 | /* |
| 107393 | 108269 | ** Estimate the number of rows that will be returned based on |
| 107394 | 108270 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 107395 | 108271 | ** the histogram data. This only works when x is the left-most |
| 107396 | 108272 | ** column of an index and sqlite_stat3 histogram data is available |
| | @@ -107406,41 +108282,57 @@ |
| 107406 | 108282 | ** for a UTF conversion required for comparison. The error is stored |
| 107407 | 108283 | ** in the pParse structure. |
| 107408 | 108284 | */ |
| 107409 | 108285 | static int whereEqualScanEst( |
| 107410 | 108286 | Parse *pParse, /* Parsing & code generating context */ |
| 107411 | | - Index *p, /* The index whose left-most column is pTerm */ |
| 108287 | + WhereLoopBuilder *pBuilder, |
| 107412 | 108288 | Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ |
| 107413 | 108289 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107414 | 108290 | ){ |
| 107415 | | - sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ |
| 108291 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108292 | + int nEq = pBuilder->pNew->u.btree.nEq; |
| 108293 | + UnpackedRecord *pRec = pBuilder->pRec; |
| 107416 | 108294 | u8 aff; /* Column affinity */ |
| 107417 | 108295 | int rc; /* Subfunction return code */ |
| 107418 | 108296 | tRowcnt a[2]; /* Statistics */ |
| 108297 | + int bOk; |
| 107419 | 108298 | |
| 108299 | + assert( nEq>=1 ); |
| 108300 | + assert( nEq<=(p->nColumn+1) ); |
| 107420 | 108301 | assert( p->aSample!=0 ); |
| 107421 | 108302 | assert( p->nSample>0 ); |
| 107422 | | - aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 107423 | | - if( pExpr ){ |
| 107424 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRhs); |
| 107425 | | - if( rc ) goto whereEqualScanEst_cancel; |
| 107426 | | - }else{ |
| 107427 | | - pRhs = sqlite3ValueNew(pParse->db); |
| 107428 | | - } |
| 107429 | | - if( pRhs==0 ) return SQLITE_NOTFOUND; |
| 107430 | | - rc = whereKeyStats(pParse, p, pRhs, 0, a); |
| 107431 | | - if( rc==SQLITE_OK ){ |
| 107432 | | - WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); |
| 107433 | | - *pnRow = a[1]; |
| 107434 | | - } |
| 107435 | | -whereEqualScanEst_cancel: |
| 107436 | | - sqlite3ValueFree(pRhs); |
| 108303 | + assert( pBuilder->nRecValid<nEq ); |
| 108304 | + |
| 108305 | + /* If values are not available for all fields of the index to the left |
| 108306 | + ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */ |
| 108307 | + if( pBuilder->nRecValid<(nEq-1) ){ |
| 108308 | + return SQLITE_NOTFOUND; |
| 108309 | + } |
| 108310 | + |
| 108311 | + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() |
| 108312 | + ** below would return the same value. */ |
| 108313 | + if( nEq>p->nColumn ){ |
| 108314 | + *pnRow = 1; |
| 108315 | + return SQLITE_OK; |
| 108316 | + } |
| 108317 | + |
| 108318 | + aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity; |
| 108319 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); |
| 108320 | + pBuilder->pRec = pRec; |
| 108321 | + if( rc!=SQLITE_OK ) return rc; |
| 108322 | + if( bOk==0 ) return SQLITE_NOTFOUND; |
| 108323 | + pBuilder->nRecValid = nEq; |
| 108324 | + |
| 108325 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108326 | + WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); |
| 108327 | + *pnRow = a[1]; |
| 108328 | + |
| 107437 | 108329 | return rc; |
| 107438 | 108330 | } |
| 107439 | | -#endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 108331 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107440 | 108332 | |
| 107441 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108333 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107442 | 108334 | /* |
| 107443 | 108335 | ** Estimate the number of rows that will be returned based on |
| 107444 | 108336 | ** an IN constraint where the right-hand side of the IN operator |
| 107445 | 108337 | ** is a list of values. Example: |
| 107446 | 108338 | ** |
| | @@ -107455,33 +108347,38 @@ |
| 107455 | 108347 | ** for a UTF conversion required for comparison. The error is stored |
| 107456 | 108348 | ** in the pParse structure. |
| 107457 | 108349 | */ |
| 107458 | 108350 | static int whereInScanEst( |
| 107459 | 108351 | Parse *pParse, /* Parsing & code generating context */ |
| 107460 | | - Index *p, /* The index whose left-most column is pTerm */ |
| 108352 | + WhereLoopBuilder *pBuilder, |
| 107461 | 108353 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 107462 | 108354 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107463 | 108355 | ){ |
| 108356 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108357 | + int nRecValid = pBuilder->nRecValid; |
| 107464 | 108358 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 107465 | 108359 | tRowcnt nEst; /* Number of rows for a single term */ |
| 107466 | 108360 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 107467 | 108361 | int i; /* Loop counter */ |
| 107468 | 108362 | |
| 107469 | 108363 | assert( p->aSample!=0 ); |
| 107470 | 108364 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 107471 | 108365 | nEst = p->aiRowEst[0]; |
| 107472 | | - rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst); |
| 108366 | + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 107473 | 108367 | nRowEst += nEst; |
| 108368 | + pBuilder->nRecValid = nRecValid; |
| 107474 | 108369 | } |
| 108370 | + |
| 107475 | 108371 | if( rc==SQLITE_OK ){ |
| 107476 | 108372 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 107477 | 108373 | *pnRow = nRowEst; |
| 107478 | 108374 | WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst)); |
| 107479 | 108375 | } |
| 108376 | + assert( pBuilder->nRecValid==nRecValid ); |
| 107480 | 108377 | return rc; |
| 107481 | 108378 | } |
| 107482 | | -#endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 108379 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107483 | 108380 | |
| 107484 | 108381 | /* |
| 107485 | 108382 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| 107486 | 108383 | ** if it controls a LEFT OUTER JOIN and it did not originate in the ON |
| 107487 | 108384 | ** or USING clause of that join. |
| | @@ -107715,11 +108612,11 @@ |
| 107715 | 108612 | pParse->db->mallocFailed = 1; |
| 107716 | 108613 | } |
| 107717 | 108614 | |
| 107718 | 108615 | /* Evaluate the equality constraints |
| 107719 | 108616 | */ |
| 107720 | | - assert( pIdx->nColumn>=nEq ); |
| 108617 | + assert( zAff==0 || (int)strlen(zAff)>=nEq ); |
| 107721 | 108618 | for(j=0; j<nEq; j++){ |
| 107722 | 108619 | int r1; |
| 107723 | 108620 | pTerm = pLoop->aLTerm[j]; |
| 107724 | 108621 | assert( pTerm!=0 ); |
| 107725 | 108622 | /* The following true for indices with redundant columns. |
| | @@ -107807,11 +108704,12 @@ |
| 107807 | 108704 | } |
| 107808 | 108705 | sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); |
| 107809 | 108706 | txt.db = db; |
| 107810 | 108707 | sqlite3StrAccumAppend(&txt, " (", 2); |
| 107811 | 108708 | for(i=0; i<nEq; i++){ |
| 107812 | | - explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "="); |
| 108709 | + char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName; |
| 108710 | + explainAppendTerm(&txt, i, z, "="); |
| 107813 | 108711 | } |
| 107814 | 108712 | |
| 107815 | 108713 | j = i; |
| 107816 | 108714 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 107817 | 108715 | char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName; |
| | @@ -109021,16 +109919,22 @@ |
| 109021 | 109919 | saved_nOut = pNew->nOut; |
| 109022 | 109920 | pNew->rSetup = 0; |
| 109023 | 109921 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 109024 | 109922 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 109025 | 109923 | int nIn = 0; |
| 109924 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 109925 | + int nRecValid = pBuilder->nRecValid; |
| 109926 | +#endif |
| 109927 | + if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 109928 | + && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 109929 | + ){ |
| 109930 | + continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 109931 | + } |
| 109026 | 109932 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 109027 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 109028 | | - if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){ |
| 109029 | | - continue; /* skip IS NOT NULL constraints on a NOT NULL column */ |
| 109030 | | - } |
| 109031 | | -#endif |
| 109933 | + |
| 109934 | + assert( pNew->nOut==saved_nOut ); |
| 109935 | + |
| 109032 | 109936 | pNew->wsFlags = saved_wsFlags; |
| 109033 | 109937 | pNew->u.btree.nEq = saved_nEq; |
| 109034 | 109938 | pNew->nLTerm = saved_nLTerm; |
| 109035 | 109939 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 109036 | 109940 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| | @@ -109083,29 +109987,34 @@ |
| 109083 | 109987 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 109084 | 109988 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 109085 | 109989 | } |
| 109086 | 109990 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 109087 | 109991 | /* Adjust nOut and rRun for STAT3 range values */ |
| 109088 | | - WhereCost rDiv; |
| 109089 | | - whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq, |
| 109090 | | - pBtm, pTop, &rDiv); |
| 109091 | | - pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; |
| 109092 | | - } |
| 109093 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 109094 | | - if( pNew->u.btree.nEq==1 && pProbe->nSample |
| 109095 | | - && OptimizationEnabled(db, SQLITE_Stat3) ){ |
| 109992 | + assert( pNew->nOut==saved_nOut ); |
| 109993 | + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); |
| 109994 | + } |
| 109995 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 109996 | + if( nInMul==0 |
| 109997 | + && pProbe->nSample |
| 109998 | + && pNew->u.btree.nEq<=pProbe->nSampleCol |
| 109999 | + && OptimizationEnabled(db, SQLITE_Stat3) |
| 110000 | + ){ |
| 110001 | + Expr *pExpr = pTerm->pExpr; |
| 109096 | 110002 | tRowcnt nOut = 0; |
| 109097 | 110003 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 109098 | 110004 | testcase( pTerm->eOperator & WO_EQ ); |
| 109099 | 110005 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 109100 | | - rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut); |
| 110006 | + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 109101 | 110007 | }else if( (pTerm->eOperator & WO_IN) |
| 109102 | | - && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){ |
| 109103 | | - rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut); |
| 110008 | + && !ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 110009 | + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 109104 | 110010 | } |
| 109105 | 110011 | assert( nOut==0 || rc==SQLITE_OK ); |
| 109106 | | - if( nOut ) pNew->nOut = whereCost(nOut); |
| 110012 | + if( nOut ){ |
| 110013 | + nOut = whereCost(nOut); |
| 110014 | + pNew->nOut = MIN(nOut, saved_nOut); |
| 110015 | + } |
| 109107 | 110016 | } |
| 109108 | 110017 | #endif |
| 109109 | 110018 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 109110 | 110019 | /* Each row involves a step of the index, then a binary search of |
| 109111 | 110020 | ** the main table */ |
| | @@ -109118,10 +110027,14 @@ |
| 109118 | 110027 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 109119 | 110028 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 109120 | 110029 | ){ |
| 109121 | 110030 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 109122 | 110031 | } |
| 110032 | + pNew->nOut = saved_nOut; |
| 110033 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110034 | + pBuilder->nRecValid = nRecValid; |
| 110035 | +#endif |
| 109123 | 110036 | } |
| 109124 | 110037 | pNew->prereq = saved_prereq; |
| 109125 | 110038 | pNew->u.btree.nEq = saved_nEq; |
| 109126 | 110039 | pNew->wsFlags = saved_wsFlags; |
| 109127 | 110040 | pNew->nOut = saved_nOut; |
| | @@ -109166,10 +110079,11 @@ |
| 109166 | 110079 | static Bitmask columnsInIndex(Index *pIdx){ |
| 109167 | 110080 | Bitmask m = 0; |
| 109168 | 110081 | int j; |
| 109169 | 110082 | for(j=pIdx->nColumn-1; j>=0; j--){ |
| 109170 | 110083 | int x = pIdx->aiColumn[j]; |
| 110084 | + assert( x>=0 ); |
| 109171 | 110085 | testcase( x==BMS-1 ); |
| 109172 | 110086 | testcase( x==BMS-2 ); |
| 109173 | 110087 | if( x<BMS-1 ) m |= MASKBIT(x); |
| 109174 | 110088 | } |
| 109175 | 110089 | return m; |
| | @@ -109244,10 +110158,11 @@ |
| 109244 | 110158 | pProbe = &sPk; |
| 109245 | 110159 | } |
| 109246 | 110160 | rSize = whereCost(pSrc->pTab->nRowEst); |
| 109247 | 110161 | rLogSize = estLog(rSize); |
| 109248 | 110162 | |
| 110163 | +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 109249 | 110164 | /* Automatic indexes */ |
| 109250 | 110165 | if( !pBuilder->pOrSet |
| 109251 | 110166 | && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 |
| 109252 | 110167 | && pSrc->pIndex==0 |
| 109253 | 110168 | && !pSrc->viaCoroutine |
| | @@ -109278,10 +110193,11 @@ |
| 109278 | 110193 | pNew->prereq = mExtra | pTerm->prereqRight; |
| 109279 | 110194 | rc = whereLoopInsert(pBuilder, pNew); |
| 109280 | 110195 | } |
| 109281 | 110196 | } |
| 109282 | 110197 | } |
| 110198 | +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ |
| 109283 | 110199 | |
| 109284 | 110200 | /* Loop over all indices |
| 109285 | 110201 | */ |
| 109286 | 110202 | for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ |
| 109287 | 110203 | if( pProbe->pPartIdxWhere!=0 |
| | @@ -109344,11 +110260,17 @@ |
| 109344 | 110260 | } |
| 109345 | 110261 | rc = whereLoopInsert(pBuilder, pNew); |
| 109346 | 110262 | if( rc ) break; |
| 109347 | 110263 | } |
| 109348 | 110264 | } |
| 110265 | + |
| 109349 | 110266 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| 110267 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110268 | + sqlite3Stat4ProbeFree(pBuilder->pRec); |
| 110269 | + pBuilder->nRecValid = 0; |
| 110270 | + pBuilder->pRec = 0; |
| 110271 | +#endif |
| 109350 | 110272 | |
| 109351 | 110273 | /* If there was an INDEXED BY clause, then only that one index is |
| 109352 | 110274 | ** considered. */ |
| 109353 | 110275 | if( pSrc->pIndex ) break; |
| 109354 | 110276 | } |
| | @@ -109541,10 +110463,11 @@ |
| 109541 | 110463 | |
| 109542 | 110464 | pWC = pBuilder->pWC; |
| 109543 | 110465 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 109544 | 110466 | pWCEnd = pWC->a + pWC->nTerm; |
| 109545 | 110467 | pNew = pBuilder->pNew; |
| 110468 | + memset(&sSum, 0, sizeof(sSum)); |
| 109546 | 110469 | |
| 109547 | 110470 | for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){ |
| 109548 | 110471 | if( (pTerm->eOperator & WO_OR)!=0 |
| 109549 | 110472 | && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 |
| 109550 | 110473 | ){ |
| | @@ -110226,15 +111149,19 @@ |
| 110226 | 111149 | pLoop->u.btree.nEq = 1; |
| 110227 | 111150 | /* TUNING: Cost of a rowid lookup is 10 */ |
| 110228 | 111151 | pLoop->rRun = 33; /* 33==whereCost(10) */ |
| 110229 | 111152 | }else{ |
| 110230 | 111153 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 110231 | | - if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue; |
| 111154 | + assert( pLoop->aLTermSpace==pLoop->aLTerm ); |
| 111155 | + assert( ArraySize(pLoop->aLTermSpace)==4 ); |
| 111156 | + if( pIdx->onError==OE_None |
| 111157 | + || pIdx->pPartIdxWhere!=0 |
| 111158 | + || pIdx->nColumn>ArraySize(pLoop->aLTermSpace) |
| 111159 | + ) continue; |
| 110232 | 111160 | for(j=0; j<pIdx->nColumn; j++){ |
| 110233 | 111161 | pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); |
| 110234 | 111162 | if( pTerm==0 ) break; |
| 110235 | | - whereLoopResize(pWInfo->pParse->db, pLoop, j); |
| 110236 | 111163 | pLoop->aLTerm[j] = pTerm; |
| 110237 | 111164 | } |
| 110238 | 111165 | if( j!=pIdx->nColumn ) continue; |
| 110239 | 111166 | pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; |
| 110240 | 111167 | if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ |
| | @@ -110667,15 +111594,10 @@ |
| 110667 | 111594 | assert( n<=pTab->nCol ); |
| 110668 | 111595 | } |
| 110669 | 111596 | }else{ |
| 110670 | 111597 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 110671 | 111598 | } |
| 110672 | | -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 110673 | | - if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 110674 | | - constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel); |
| 110675 | | - }else |
| 110676 | | -#endif |
| 110677 | 111599 | if( pLoop->wsFlags & WHERE_INDEXED ){ |
| 110678 | 111600 | Index *pIx = pLoop->u.btree.pIndex; |
| 110679 | 111601 | KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); |
| 110680 | 111602 | /* FIXME: As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */ |
| 110681 | 111603 | int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++; |
| | @@ -110696,11 +111618,19 @@ |
| 110696 | 111618 | ** program. |
| 110697 | 111619 | */ |
| 110698 | 111620 | notReady = ~(Bitmask)0; |
| 110699 | 111621 | for(ii=0; ii<nTabList; ii++){ |
| 110700 | 111622 | pLevel = &pWInfo->a[ii]; |
| 111623 | +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 111624 | + if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 111625 | + constructAutomaticIndex(pParse, &pWInfo->sWC, |
| 111626 | + &pTabList->a[pLevel->iFrom], notReady, pLevel); |
| 111627 | + if( db->mallocFailed ) goto whereBeginError; |
| 111628 | + } |
| 111629 | +#endif |
| 110701 | 111630 | explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags); |
| 111631 | + pLevel->addrBody = sqlite3VdbeCurrentAddr(v); |
| 110702 | 111632 | notReady = codeOneLoopStart(pWInfo, ii, notReady); |
| 110703 | 111633 | pWInfo->iContinue = pLevel->addrCont; |
| 110704 | 111634 | } |
| 110705 | 111635 | |
| 110706 | 111636 | /* Done. */ |
| | @@ -110816,13 +111746,14 @@ |
| 110816 | 111746 | } |
| 110817 | 111747 | if( pIdx && !db->mallocFailed ){ |
| 110818 | 111748 | int k, j, last; |
| 110819 | 111749 | VdbeOp *pOp; |
| 110820 | 111750 | |
| 110821 | | - pOp = sqlite3VdbeGetOp(v, pWInfo->iTop); |
| 110822 | 111751 | last = sqlite3VdbeCurrentAddr(v); |
| 110823 | | - for(k=pWInfo->iTop; k<last; k++, pOp++){ |
| 111752 | + k = pLevel->addrBody; |
| 111753 | + pOp = sqlite3VdbeGetOp(v, k); |
| 111754 | + for(; k<last; k++, pOp++){ |
| 110824 | 111755 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 110825 | 111756 | if( pOp->opcode==OP_Column ){ |
| 110826 | 111757 | for(j=0; j<pIdx->nColumn; j++){ |
| 110827 | 111758 | if( pOp->p2==pIdx->aiColumn[j] ){ |
| 110828 | 111759 | pOp->p2 = j; |
| | @@ -117967,11 +118898,11 @@ |
| 117967 | 118898 | memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); |
| 117968 | 118899 | db->autoCommit = 1; |
| 117969 | 118900 | db->nextAutovac = -1; |
| 117970 | 118901 | db->szMmap = sqlite3GlobalConfig.szMmap; |
| 117971 | 118902 | db->nextPagesize = 0; |
| 117972 | | - db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger |
| 118903 | + db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill |
| 117973 | 118904 | #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX |
| 117974 | 118905 | | SQLITE_AutoIndex |
| 117975 | 118906 | #endif |
| 117976 | 118907 | #if SQLITE_DEFAULT_FILE_FORMAT<4 |
| 117977 | 118908 | | SQLITE_LegacyFileFmt |
| | @@ -130880,11 +131811,11 @@ |
| 130880 | 131811 | while( 1 ){ |
| 130881 | 131812 | |
| 130882 | 131813 | /* The following line of code (and the "p++" below the while() loop) is |
| 130883 | 131814 | ** normally all that is required to move pointer p to the desired |
| 130884 | 131815 | ** position. The exception is if this node is being loaded from disk |
| 130885 | | - ** incrementally and pointer "p" now points to the first byte passed |
| 131816 | + ** incrementally and pointer "p" now points to the first byte past |
| 130886 | 131817 | ** the populated part of pReader->aNode[]. |
| 130887 | 131818 | */ |
| 130888 | 131819 | while( *p | c ) c = *p++ & 0x80; |
| 130889 | 131820 | assert( *p==0 ); |
| 130890 | 131821 | |
| | @@ -132267,12 +133198,12 @@ |
| 132267 | 133198 | fts3SegReaderFirstDocid(p, apSegment[i]); |
| 132268 | 133199 | } |
| 132269 | 133200 | fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp); |
| 132270 | 133201 | while( apSegment[0]->pOffsetList ){ |
| 132271 | 133202 | int j; /* Number of segments that share a docid */ |
| 132272 | | - char *pList; |
| 132273 | | - int nList; |
| 133203 | + char *pList = 0; |
| 133204 | + int nList = 0; |
| 132274 | 133205 | int nByte; |
| 132275 | 133206 | sqlite3_int64 iDocid = apSegment[0]->iDocid; |
| 132276 | 133207 | fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); |
| 132277 | 133208 | j = 1; |
| 132278 | 133209 | while( j<nMerge |
| | @@ -134554,15 +135485,15 @@ |
| 134554 | 135485 | } |
| 134555 | 135486 | } |
| 134556 | 135487 | if( pTC ) pModule->xClose(pTC); |
| 134557 | 135488 | if( rc==SQLITE_DONE ) rc = SQLITE_OK; |
| 134558 | 135489 | } |
| 135490 | + } |
| 134559 | 135491 | |
| 134560 | | - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 134561 | | - if( pDef->pList ){ |
| 134562 | | - rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134563 | | - } |
| 135492 | + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ |
| 135493 | + if( pDef->pList ){ |
| 135494 | + rc = fts3PendingListAppendVarint(&pDef->pList, 0); |
| 134564 | 135495 | } |
| 134565 | 135496 | } |
| 134566 | 135497 | } |
| 134567 | 135498 | |
| 134568 | 135499 | return rc; |
| | @@ -135341,10 +136272,11 @@ |
| 135341 | 136272 | return SQLITE_NOMEM; |
| 135342 | 136273 | } |
| 135343 | 136274 | pStr->z = zNew; |
| 135344 | 136275 | pStr->nAlloc = nAlloc; |
| 135345 | 136276 | } |
| 136277 | + assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) ); |
| 135346 | 136278 | |
| 135347 | 136279 | /* Append the data to the string buffer. */ |
| 135348 | 136280 | memcpy(&pStr->z[pStr->n], zAppend, nAppend); |
| 135349 | 136281 | pStr->n += nAppend; |
| 135350 | 136282 | pStr->z[pStr->n] = '\0'; |
| 135351 | 136283 | |