| | @@ -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.4.1. By combining all the individual C code files into this |
| 3 | +** version 3.8.5. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -220,13 +220,13 @@ |
| 220 | 220 | ** |
| 221 | 221 | ** See also: [sqlite3_libversion()], |
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | | -#define SQLITE_VERSION "3.8.4.1" |
| 226 | | -#define SQLITE_VERSION_NUMBER 3008004 |
| 227 | | -#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" |
| 225 | +#define SQLITE_VERSION "3.8.5" |
| 226 | +#define SQLITE_VERSION_NUMBER 3008005 |
| 227 | +#define SQLITE_SOURCE_ID "2014-04-18 22:20:31 9a5d38c79d2482a23bcfbc3ff35ca4fa269c768d" |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| | @@ -6236,11 +6236,12 @@ |
| 6236 | 6236 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 |
| 6237 | 6237 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6238 | 6238 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6239 | 6239 | #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6240 | 6240 | #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 |
| 6241 | | -#define SQLITE_TESTCTRL_LAST 21 |
| 6241 | +#define SQLITE_TESTCTRL_BYTEORDER 22 |
| 6242 | +#define SQLITE_TESTCTRL_LAST 22 |
| 6242 | 6243 | |
| 6243 | 6244 | /* |
| 6244 | 6245 | ** CAPI3REF: SQLite Runtime Status |
| 6245 | 6246 | ** |
| 6246 | 6247 | ** ^This interface is used to retrieve runtime status information |
| | @@ -8437,26 +8438,43 @@ |
| 8437 | 8438 | */ |
| 8438 | 8439 | typedef INT16_TYPE LogEst; |
| 8439 | 8440 | |
| 8440 | 8441 | /* |
| 8441 | 8442 | ** Macros to determine whether the machine is big or little endian, |
| 8442 | | -** evaluated at runtime. |
| 8443 | +** and whether or not that determination is run-time or compile-time. |
| 8444 | +** |
| 8445 | +** For best performance, an attempt is made to guess at the byte-order |
| 8446 | +** using C-preprocessor macros. If that is unsuccessful, or if |
| 8447 | +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined |
| 8448 | +** at run-time. |
| 8443 | 8449 | */ |
| 8444 | 8450 | #ifdef SQLITE_AMALGAMATION |
| 8445 | 8451 | SQLITE_PRIVATE const int sqlite3one = 1; |
| 8446 | 8452 | #else |
| 8447 | 8453 | SQLITE_PRIVATE const int sqlite3one; |
| 8448 | 8454 | #endif |
| 8449 | | -#if defined(i386) || defined(__i386__) || defined(_M_IX86)\ |
| 8450 | | - || defined(__x86_64) || defined(__x86_64__) |
| 8455 | +#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 8456 | + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
| 8457 | + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
| 8458 | + defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) |
| 8459 | +# define SQLITE_BYTEORDER 1234 |
| 8451 | 8460 | # define SQLITE_BIGENDIAN 0 |
| 8452 | 8461 | # define SQLITE_LITTLEENDIAN 1 |
| 8453 | 8462 | # define SQLITE_UTF16NATIVE SQLITE_UTF16LE |
| 8454 | | -#else |
| 8463 | +#endif |
| 8464 | +#if (defined(sparc) || defined(__ppc__)) \ |
| 8465 | + && !defined(SQLITE_RUNTIME_BYTEORDER) |
| 8466 | +# define SQLITE_BYTEORDER 4321 |
| 8467 | +# define SQLITE_BIGENDIAN 1 |
| 8468 | +# define SQLITE_LITTLEENDIAN 0 |
| 8469 | +# define SQLITE_UTF16NATIVE SQLITE_UTF16BE |
| 8470 | +#endif |
| 8471 | +#if !defined(SQLITE_BYTEORDER) |
| 8472 | +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ |
| 8455 | 8473 | # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) |
| 8456 | 8474 | # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) |
| 8457 | | -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8475 | +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8458 | 8476 | #endif |
| 8459 | 8477 | |
| 8460 | 8478 | /* |
| 8461 | 8479 | ** Constants for the largest and smallest possible 64-bit signed integers. |
| 8462 | 8480 | ** These macros are designed to work correctly on both 32-bit and 64-bit |
| | @@ -8767,11 +8785,13 @@ |
| 8767 | 8785 | #define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ |
| 8768 | 8786 | #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ |
| 8769 | 8787 | |
| 8770 | 8788 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 8771 | 8789 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 8772 | | -SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); |
| 8790 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 8791 | +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); |
| 8792 | +#endif |
| 8773 | 8793 | SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); |
| 8774 | 8794 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| 8775 | 8795 | SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); |
| 8776 | 8796 | SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); |
| 8777 | 8797 | SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); |
| | @@ -8817,10 +8837,11 @@ |
| 8817 | 8837 | #define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ |
| 8818 | 8838 | #define BTREE_BLOBKEY 2 /* Table has keys only - no data */ |
| 8819 | 8839 | |
| 8820 | 8840 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); |
| 8821 | 8841 | SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); |
| 8842 | +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); |
| 8822 | 8843 | SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); |
| 8823 | 8844 | |
| 8824 | 8845 | SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); |
| 8825 | 8846 | SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); |
| 8826 | 8847 | |
| | @@ -8891,11 +8912,11 @@ |
| 8891 | 8912 | |
| 8892 | 8913 | SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); |
| 8893 | 8914 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 8894 | 8915 | |
| 8895 | 8916 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8896 | | -SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); |
| 8917 | +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); |
| 8897 | 8918 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8898 | 8919 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8899 | 8920 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 8900 | 8921 | |
| 8901 | 8922 | #ifndef NDEBUG |
| | @@ -9134,11 +9155,11 @@ |
| 9134 | 9155 | #define OP_Next 9 |
| 9135 | 9156 | #define OP_AggStep 10 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 9136 | 9157 | #define OP_Checkpoint 11 |
| 9137 | 9158 | #define OP_JournalMode 12 |
| 9138 | 9159 | #define OP_Vacuum 13 |
| 9139 | | -#define OP_VFilter 14 /* synopsis: iPlan=r[P3] zPlan='P4' */ |
| 9160 | +#define OP_VFilter 14 /* synopsis: iplan=r[P3] zplan='P4' */ |
| 9140 | 9161 | #define OP_VUpdate 15 /* synopsis: data=r[P3@P2] */ |
| 9141 | 9162 | #define OP_Goto 16 |
| 9142 | 9163 | #define OP_Gosub 17 |
| 9143 | 9164 | #define OP_Return 18 |
| 9144 | 9165 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| | @@ -9161,11 +9182,11 @@ |
| 9161 | 9182 | #define OP_CollSeq 36 |
| 9162 | 9183 | #define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ |
| 9163 | 9184 | #define OP_MustBeInt 38 |
| 9164 | 9185 | #define OP_RealAffinity 39 |
| 9165 | 9186 | #define OP_Permutation 40 |
| 9166 | | -#define OP_Compare 41 |
| 9187 | +#define OP_Compare 41 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 9167 | 9188 | #define OP_Jump 42 |
| 9168 | 9189 | #define OP_Once 43 |
| 9169 | 9190 | #define OP_If 44 |
| 9170 | 9191 | #define OP_IfNot 45 |
| 9171 | 9192 | #define OP_Column 46 /* synopsis: r[P3]=PX */ |
| | @@ -9188,11 +9209,11 @@ |
| 9188 | 9209 | #define OP_Seek 63 /* synopsis: intkey=r[P2] */ |
| 9189 | 9210 | #define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ |
| 9190 | 9211 | #define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ |
| 9191 | 9212 | #define OP_Found 66 /* synopsis: key=r[P3@P4] */ |
| 9192 | 9213 | #define OP_NotExists 67 /* synopsis: intkey=r[P3] */ |
| 9193 | | -#define OP_Sequence 68 /* synopsis: r[P2]=rowid */ |
| 9214 | +#define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9194 | 9215 | #define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ |
| 9195 | 9216 | #define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9196 | 9217 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9197 | 9218 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9198 | 9219 | #define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ |
| | @@ -9236,51 +9257,52 @@ |
| 9236 | 9257 | #define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ |
| 9237 | 9258 | #define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ |
| 9238 | 9259 | #define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ |
| 9239 | 9260 | #define OP_Destroy 114 |
| 9240 | 9261 | #define OP_Clear 115 |
| 9241 | | -#define OP_CreateIndex 116 /* synopsis: r[P2]=root iDb=P1 */ |
| 9242 | | -#define OP_CreateTable 117 /* synopsis: r[P2]=root iDb=P1 */ |
| 9243 | | -#define OP_ParseSchema 118 |
| 9244 | | -#define OP_LoadAnalysis 119 |
| 9245 | | -#define OP_DropTable 120 |
| 9246 | | -#define OP_DropIndex 121 |
| 9247 | | -#define OP_DropTrigger 122 |
| 9248 | | -#define OP_IntegrityCk 123 |
| 9249 | | -#define OP_RowSetAdd 124 /* synopsis: rowset(P1)=r[P2] */ |
| 9250 | | -#define OP_RowSetRead 125 /* synopsis: r[P3]=rowset(P1) */ |
| 9251 | | -#define OP_RowSetTest 126 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9252 | | -#define OP_Program 127 |
| 9253 | | -#define OP_Param 128 |
| 9254 | | -#define OP_FkCounter 129 /* synopsis: fkctr[P1]+=P2 */ |
| 9255 | | -#define OP_FkIfZero 130 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9256 | | -#define OP_MemMax 131 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9257 | | -#define OP_IfPos 132 /* synopsis: if r[P1]>0 goto P2 */ |
| 9262 | +#define OP_ResetSorter 116 |
| 9263 | +#define OP_CreateIndex 117 /* synopsis: r[P2]=root iDb=P1 */ |
| 9264 | +#define OP_CreateTable 118 /* synopsis: r[P2]=root iDb=P1 */ |
| 9265 | +#define OP_ParseSchema 119 |
| 9266 | +#define OP_LoadAnalysis 120 |
| 9267 | +#define OP_DropTable 121 |
| 9268 | +#define OP_DropIndex 122 |
| 9269 | +#define OP_DropTrigger 123 |
| 9270 | +#define OP_IntegrityCk 124 |
| 9271 | +#define OP_RowSetAdd 125 /* synopsis: rowset(P1)=r[P2] */ |
| 9272 | +#define OP_RowSetRead 126 /* synopsis: r[P3]=rowset(P1) */ |
| 9273 | +#define OP_RowSetTest 127 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9274 | +#define OP_Program 128 |
| 9275 | +#define OP_Param 129 |
| 9276 | +#define OP_FkCounter 130 /* synopsis: fkctr[P1]+=P2 */ |
| 9277 | +#define OP_FkIfZero 131 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9278 | +#define OP_MemMax 132 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9258 | 9279 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9259 | | -#define OP_IfNeg 134 /* synopsis: if r[P1]<0 goto P2 */ |
| 9260 | | -#define OP_IfZero 135 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9261 | | -#define OP_AggFinal 136 /* synopsis: accum=r[P1] N=P2 */ |
| 9262 | | -#define OP_IncrVacuum 137 |
| 9263 | | -#define OP_Expire 138 |
| 9264 | | -#define OP_TableLock 139 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9265 | | -#define OP_VBegin 140 |
| 9266 | | -#define OP_VCreate 141 |
| 9267 | | -#define OP_VDestroy 142 |
| 9280 | +#define OP_IfPos 134 /* synopsis: if r[P1]>0 goto P2 */ |
| 9281 | +#define OP_IfNeg 135 /* synopsis: if r[P1]<0 goto P2 */ |
| 9282 | +#define OP_IfZero 136 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9283 | +#define OP_AggFinal 137 /* synopsis: accum=r[P1] N=P2 */ |
| 9284 | +#define OP_IncrVacuum 138 |
| 9285 | +#define OP_Expire 139 |
| 9286 | +#define OP_TableLock 140 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9287 | +#define OP_VBegin 141 |
| 9288 | +#define OP_VCreate 142 |
| 9268 | 9289 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9269 | 9290 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9270 | 9291 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9271 | 9292 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9272 | 9293 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9273 | | -#define OP_VOpen 148 |
| 9274 | | -#define OP_VColumn 149 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9275 | | -#define OP_VNext 150 |
| 9276 | | -#define OP_VRename 151 |
| 9277 | | -#define OP_Pagecount 152 |
| 9278 | | -#define OP_MaxPgcnt 153 |
| 9279 | | -#define OP_Init 154 /* synopsis: Start at P2 */ |
| 9280 | | -#define OP_Noop 155 |
| 9281 | | -#define OP_Explain 156 |
| 9294 | +#define OP_VDestroy 148 |
| 9295 | +#define OP_VOpen 149 |
| 9296 | +#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9297 | +#define OP_VNext 151 |
| 9298 | +#define OP_VRename 152 |
| 9299 | +#define OP_Pagecount 153 |
| 9300 | +#define OP_MaxPgcnt 154 |
| 9301 | +#define OP_Init 155 /* synopsis: Start at P2 */ |
| 9302 | +#define OP_Noop 156 |
| 9303 | +#define OP_Explain 157 |
| 9282 | 9304 | |
| 9283 | 9305 | |
| 9284 | 9306 | /* Properties such as "out2" or "jump" that are specified in |
| 9285 | 9307 | ** comments following the "case" for each opcode in the vdbe.c |
| 9286 | 9308 | ** are encoded into bitvectors as follows: |
| | @@ -9305,16 +9327,16 @@ |
| 9305 | 9327 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9306 | 9328 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9307 | 9329 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9308 | 9330 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ |
| 9309 | 9331 | /* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ |
| 9310 | | -/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00,\ |
| 9311 | | -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15, 0x01,\ |
| 9312 | | -/* 128 */ 0x02, 0x00, 0x01, 0x08, 0x05, 0x02, 0x05, 0x05,\ |
| 9313 | | -/* 136 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\ |
| 9314 | | -/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00,\ |
| 9315 | | -/* 152 */ 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9332 | +/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00,\ |
| 9333 | +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15,\ |
| 9334 | +/* 128 */ 0x01, 0x02, 0x00, 0x01, 0x08, 0x02, 0x05, 0x05,\ |
| 9335 | +/* 136 */ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,\ |
| 9336 | +/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01,\ |
| 9337 | +/* 152 */ 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,} |
| 9316 | 9338 | |
| 9317 | 9339 | /************** End of opcodes.h *********************************************/ |
| 9318 | 9340 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9319 | 9341 | |
| 9320 | 9342 | /* |
| | @@ -9367,14 +9389,14 @@ |
| 9367 | 9389 | #ifndef SQLITE_OMIT_TRACE |
| 9368 | 9390 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 9369 | 9391 | #endif |
| 9370 | 9392 | |
| 9371 | 9393 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 9372 | | -SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int); |
| 9394 | +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int); |
| 9373 | 9395 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); |
| 9374 | 9396 | |
| 9375 | | -typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int); |
| 9397 | +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int); |
| 9376 | 9398 | SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); |
| 9377 | 9399 | |
| 9378 | 9400 | #ifndef SQLITE_OMIT_TRIGGER |
| 9379 | 9401 | SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); |
| 9380 | 9402 | #endif |
| | @@ -10996,10 +11018,11 @@ |
| 10996 | 11018 | */ |
| 10997 | 11019 | struct UnpackedRecord { |
| 10998 | 11020 | KeyInfo *pKeyInfo; /* Collation and sort-order information */ |
| 10999 | 11021 | u16 nField; /* Number of entries in apMem[] */ |
| 11000 | 11022 | i8 default_rc; /* Comparison result if keys are equal */ |
| 11023 | + u8 isCorrupt; /* Corruption detected by xRecordCompare() */ |
| 11001 | 11024 | Mem *aMem; /* Values */ |
| 11002 | 11025 | int r1; /* Value to return if (lhs > rhs) */ |
| 11003 | 11026 | int r2; /* Value to return if (rhs < lhs) */ |
| 11004 | 11027 | }; |
| 11005 | 11028 | |
| | @@ -11262,12 +11285,12 @@ |
| 11262 | 11285 | #define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 11263 | 11286 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11264 | 11287 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| 11265 | 11288 | #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ |
| 11266 | 11289 | #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ |
| 11267 | | -#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */ |
| 11268 | | - /* unused 0x000200 */ |
| 11290 | +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ |
| 11291 | +#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ |
| 11269 | 11292 | #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ |
| 11270 | 11293 | #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ |
| 11271 | 11294 | #define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ |
| 11272 | 11295 | #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ |
| 11273 | 11296 | #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ |
| | @@ -11327,11 +11350,10 @@ |
| 11327 | 11350 | ** of the result column in the form: DATABASE.TABLE.COLUMN. This later |
| 11328 | 11351 | ** form is used for name resolution with nested FROM clauses. |
| 11329 | 11352 | */ |
| 11330 | 11353 | struct ExprList { |
| 11331 | 11354 | int nExpr; /* Number of expressions on the list */ |
| 11332 | | - int iECursor; /* VDBE Cursor associated with this ExprList */ |
| 11333 | 11355 | struct ExprList_item { /* For each expression in the list */ |
| 11334 | 11356 | Expr *pExpr; /* The list of expressions */ |
| 11335 | 11357 | char *zName; /* Token associated with this expression */ |
| 11336 | 11358 | char *zSpan; /* Original text of the expression */ |
| 11337 | 11359 | u8 sortOrder; /* 1 for DESC or 0 for ASC */ |
| | @@ -11551,11 +11573,11 @@ |
| 11551 | 11573 | struct Select { |
| 11552 | 11574 | ExprList *pEList; /* The fields of the result */ |
| 11553 | 11575 | u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ |
| 11554 | 11576 | u16 selFlags; /* Various SF_* values */ |
| 11555 | 11577 | int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ |
| 11556 | | - int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ |
| 11578 | + int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ |
| 11557 | 11579 | u64 nSelectRow; /* Estimated number of result rows */ |
| 11558 | 11580 | SrcList *pSrc; /* The FROM clause */ |
| 11559 | 11581 | Expr *pWhere; /* The WHERE clause */ |
| 11560 | 11582 | ExprList *pGroupBy; /* The GROUP BY clause */ |
| 11561 | 11583 | Expr *pHaving; /* The HAVING clause */ |
| | @@ -11575,13 +11597,13 @@ |
| 11575 | 11597 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 11576 | 11598 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 11577 | 11599 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 11578 | 11600 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 11579 | 11601 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 11580 | | -#define SF_UseSorter 0x0040 /* Sort using a sorter */ |
| 11602 | + /* 0x0040 NOT USED */ |
| 11581 | 11603 | #define SF_Values 0x0080 /* Synthesized from VALUES clause */ |
| 11582 | | -#define SF_Materialize 0x0100 /* NOT USED */ |
| 11604 | + /* 0x0100 NOT USED */ |
| 11583 | 11605 | #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ |
| 11584 | 11606 | #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ |
| 11585 | 11607 | #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ |
| 11586 | 11608 | #define SF_Compound 0x1000 /* Part of a compound query */ |
| 11587 | 11609 | |
| | @@ -11630,17 +11652,19 @@ |
| 11630 | 11652 | ** of the co-routine is stored in register pDest->iSDParm |
| 11631 | 11653 | ** and the result row is stored in pDest->nDest registers |
| 11632 | 11654 | ** starting with pDest->iSdst. |
| 11633 | 11655 | ** |
| 11634 | 11656 | ** SRT_Table Store results in temporary table pDest->iSDParm. |
| 11635 | | -** This is like SRT_EphemTab except that the table |
| 11636 | | -** is assumed to already be open. |
| 11657 | +** SRT_Fifo This is like SRT_EphemTab except that the table |
| 11658 | +** is assumed to already be open. SRT_Fifo has |
| 11659 | +** the additional property of being able to ignore |
| 11660 | +** the ORDER BY clause. |
| 11637 | 11661 | ** |
| 11638 | | -** SRT_DistTable Store results in a temporary table pDest->iSDParm. |
| 11662 | +** SRT_DistFifo Store results in a temporary table pDest->iSDParm. |
| 11639 | 11663 | ** But also use temporary table pDest->iSDParm+1 as |
| 11640 | 11664 | ** a record of all prior results and ignore any duplicate |
| 11641 | | -** rows. Name means: "Distinct Table". |
| 11665 | +** rows. Name means: "Distinct Fifo". |
| 11642 | 11666 | ** |
| 11643 | 11667 | ** SRT_Queue Store results in priority queue pDest->iSDParm (really |
| 11644 | 11668 | ** an index). Append a sequence number so that all entries |
| 11645 | 11669 | ** are distinct. |
| 11646 | 11670 | ** |
| | @@ -11650,23 +11674,24 @@ |
| 11650 | 11674 | */ |
| 11651 | 11675 | #define SRT_Union 1 /* Store result as keys in an index */ |
| 11652 | 11676 | #define SRT_Except 2 /* Remove result from a UNION index */ |
| 11653 | 11677 | #define SRT_Exists 3 /* Store 1 if the result is not empty */ |
| 11654 | 11678 | #define SRT_Discard 4 /* Do not save the results anywhere */ |
| 11679 | +#define SRT_Fifo 5 /* Store result as data with an automatic rowid */ |
| 11680 | +#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */ |
| 11681 | +#define SRT_Queue 7 /* Store result in an queue */ |
| 11682 | +#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */ |
| 11655 | 11683 | |
| 11656 | 11684 | /* The ORDER BY clause is ignored for all of the above */ |
| 11657 | | -#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard) |
| 11658 | | - |
| 11659 | | -#define SRT_Output 5 /* Output each row of result */ |
| 11660 | | -#define SRT_Mem 6 /* Store result in a memory cell */ |
| 11661 | | -#define SRT_Set 7 /* Store results as keys in an index */ |
| 11662 | | -#define SRT_EphemTab 8 /* Create transient tab and store like SRT_Table */ |
| 11663 | | -#define SRT_Coroutine 9 /* Generate a single row of result */ |
| 11664 | | -#define SRT_Table 10 /* Store result as data with an automatic rowid */ |
| 11665 | | -#define SRT_DistTable 11 /* Like SRT_Table, but unique results only */ |
| 11666 | | -#define SRT_Queue 12 /* Store result in an queue */ |
| 11667 | | -#define SRT_DistQueue 13 /* Like SRT_Queue, but unique results only */ |
| 11685 | +#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue) |
| 11686 | + |
| 11687 | +#define SRT_Output 9 /* Output each row of result */ |
| 11688 | +#define SRT_Mem 10 /* Store result in a memory cell */ |
| 11689 | +#define SRT_Set 11 /* Store results as keys in an index */ |
| 11690 | +#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */ |
| 11691 | +#define SRT_Coroutine 13 /* Generate a single row of result */ |
| 11692 | +#define SRT_Table 14 /* Store result as data with an automatic rowid */ |
| 11668 | 11693 | |
| 11669 | 11694 | /* |
| 11670 | 11695 | ** An instance of this object describes where to put of the results of |
| 11671 | 11696 | ** a SELECT statement. |
| 11672 | 11697 | */ |
| | @@ -11760,12 +11785,10 @@ |
| 11760 | 11785 | int rc; /* Return code from execution */ |
| 11761 | 11786 | u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ |
| 11762 | 11787 | u8 checkSchema; /* Causes schema cookie check after an error */ |
| 11763 | 11788 | u8 nested; /* Number of nested calls to the parser/code generator */ |
| 11764 | 11789 | u8 nTempReg; /* Number of temporary registers in aTempReg[] */ |
| 11765 | | - u8 nColCache; /* Number of entries in aColCache[] */ |
| 11766 | | - u8 iColCache; /* Next entry in aColCache[] to replace */ |
| 11767 | 11790 | u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ |
| 11768 | 11791 | u8 mayAbort; /* True if statement may throw an ABORT exception */ |
| 11769 | 11792 | u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ |
| 11770 | 11793 | u8 okConstFactor; /* OK to factor out constants */ |
| 11771 | 11794 | int aTempReg[8]; /* Holding area for temporary registers */ |
| | @@ -12387,11 +12410,11 @@ |
| 12387 | 12410 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); |
| 12388 | 12411 | |
| 12389 | 12412 | SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); |
| 12390 | 12413 | SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); |
| 12391 | 12414 | SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); |
| 12392 | | -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, u8 iBatch, i64); |
| 12415 | +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); |
| 12393 | 12416 | SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); |
| 12394 | 12417 | |
| 12395 | 12418 | SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); |
| 12396 | 12419 | |
| 12397 | 12420 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) |
| | @@ -12451,11 +12474,11 @@ |
| 12451 | 12474 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 12452 | 12475 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| 12453 | 12476 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); |
| 12454 | 12477 | SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); |
| 12455 | 12478 | SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); |
| 12456 | | -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); |
| 12479 | +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); |
| 12457 | 12480 | SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); |
| 12458 | 12481 | SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); |
| 12459 | 12482 | SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); |
| 12460 | 12483 | SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); |
| 12461 | 12484 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); |
| | @@ -12503,10 +12526,11 @@ |
| 12503 | 12526 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 12504 | 12527 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| 12505 | 12528 | SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); |
| 12506 | 12529 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); |
| 12507 | 12530 | SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); |
| 12531 | +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); |
| 12508 | 12532 | SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, |
| 12509 | 12533 | u8,u8,int,int*); |
| 12510 | 12534 | SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); |
| 12511 | 12535 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); |
| 12512 | 12536 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); |
| | @@ -12660,11 +12684,11 @@ |
| 12660 | 12684 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 12661 | 12685 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 12662 | 12686 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 12663 | 12687 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 12664 | 12688 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
| 12665 | | -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*); |
| 12689 | +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); |
| 12666 | 12690 | SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); |
| 12667 | 12691 | SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); |
| 12668 | 12692 | SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); |
| 12669 | 12693 | SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); |
| 12670 | 12694 | SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); |
| | @@ -13745,10 +13769,11 @@ |
| 13745 | 13769 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13746 | 13770 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13747 | 13771 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13748 | 13772 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13749 | 13773 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13774 | + Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13750 | 13775 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13751 | 13776 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13752 | 13777 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13753 | 13778 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13754 | 13779 | i64 seqCount; /* Sequence counter */ |
| | @@ -14064,11 +14089,11 @@ |
| 14064 | 14089 | SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); |
| 14065 | 14090 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); |
| 14066 | 14091 | SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); |
| 14067 | 14092 | |
| 14068 | 14093 | int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); |
| 14069 | | -SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*); |
| 14094 | +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); |
| 14070 | 14095 | SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); |
| 14071 | 14096 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 14072 | 14097 | SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); |
| 14073 | 14098 | SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); |
| 14074 | 14099 | SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); |
| | @@ -14110,10 +14135,11 @@ |
| 14110 | 14135 | SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); |
| 14111 | 14136 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); |
| 14112 | 14137 | SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); |
| 14113 | 14138 | |
| 14114 | 14139 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 14140 | +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); |
| 14115 | 14141 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 14116 | 14142 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); |
| 14117 | 14143 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); |
| 14118 | 14144 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); |
| 14119 | 14145 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); |
| | @@ -17849,11 +17875,11 @@ |
| 17849 | 17875 | |
| 17850 | 17876 | /* Make sure mem5.aiFreelist[iLogsize] contains at least one free |
| 17851 | 17877 | ** block. If not, then split a block of the next larger power of |
| 17852 | 17878 | ** two in order to create a new free block of size iLogsize. |
| 17853 | 17879 | */ |
| 17854 | | - for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){} |
| 17880 | + for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){} |
| 17855 | 17881 | if( iBin>LOGMAX ){ |
| 17856 | 17882 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 17857 | 17883 | sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); |
| 17858 | 17884 | return 0; |
| 17859 | 17885 | } |
| | @@ -20159,24 +20185,10 @@ |
| 20159 | 20185 | *val = (*val - d)*10.0; |
| 20160 | 20186 | return (char)digit; |
| 20161 | 20187 | } |
| 20162 | 20188 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 20163 | 20189 | |
| 20164 | | -/* |
| 20165 | | -** Append N space characters to the given string buffer. |
| 20166 | | -*/ |
| 20167 | | -SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){ |
| 20168 | | - static const char zSpaces[] = " "; |
| 20169 | | - while( N>=(int)sizeof(zSpaces)-1 ){ |
| 20170 | | - sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1); |
| 20171 | | - N -= sizeof(zSpaces)-1; |
| 20172 | | - } |
| 20173 | | - if( N>0 ){ |
| 20174 | | - sqlite3StrAccumAppend(pAccum, zSpaces, N); |
| 20175 | | - } |
| 20176 | | -} |
| 20177 | | - |
| 20178 | 20190 | /* |
| 20179 | 20191 | ** Set the StrAccum object to an error mode. |
| 20180 | 20192 | */ |
| 20181 | 20193 | static void setStrAccumError(StrAccum *p, u8 eError){ |
| 20182 | 20194 | p->accError = eError; |
| | @@ -20262,15 +20274,13 @@ |
| 20262 | 20274 | }else{ |
| 20263 | 20275 | bArgList = useIntern = 0; |
| 20264 | 20276 | } |
| 20265 | 20277 | for(; (c=(*fmt))!=0; ++fmt){ |
| 20266 | 20278 | if( c!='%' ){ |
| 20267 | | - int amt; |
| 20268 | 20279 | bufpt = (char *)fmt; |
| 20269 | | - amt = 1; |
| 20270 | | - while( (c=(*++fmt))!='%' && c!=0 ) amt++; |
| 20271 | | - sqlite3StrAccumAppend(pAccum, bufpt, amt); |
| 20280 | + while( (c=(*++fmt))!='%' && c!=0 ){}; |
| 20281 | + sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); |
| 20272 | 20282 | if( c==0 ) break; |
| 20273 | 20283 | } |
| 20274 | 20284 | if( (c=(*++fmt))==0 ){ |
| 20275 | 20285 | sqlite3StrAccumAppend(pAccum, "%", 1); |
| 20276 | 20286 | break; |
| | @@ -20447,14 +20457,12 @@ |
| 20447 | 20457 | } |
| 20448 | 20458 | *(--bufpt) = zOrd[x*2+1]; |
| 20449 | 20459 | *(--bufpt) = zOrd[x*2]; |
| 20450 | 20460 | } |
| 20451 | 20461 | { |
| 20452 | | - register const char *cset; /* Use registers for speed */ |
| 20453 | | - register int base; |
| 20454 | | - cset = &aDigits[infop->charset]; |
| 20455 | | - base = infop->base; |
| 20462 | + const char *cset = &aDigits[infop->charset]; |
| 20463 | + u8 base = infop->base; |
| 20456 | 20464 | do{ /* Convert to ascii */ |
| 20457 | 20465 | *(--bufpt) = cset[longvalue%base]; |
| 20458 | 20466 | longvalue = longvalue/base; |
| 20459 | 20467 | }while( longvalue>0 ); |
| 20460 | 20468 | } |
| | @@ -20754,77 +20762,102 @@ |
| 20754 | 20762 | /* |
| 20755 | 20763 | ** The text of the conversion is pointed to by "bufpt" and is |
| 20756 | 20764 | ** "length" characters long. The field width is "width". Do |
| 20757 | 20765 | ** the output. |
| 20758 | 20766 | */ |
| 20759 | | - if( !flag_leftjustify ){ |
| 20760 | | - register int nspace; |
| 20761 | | - nspace = width-length; |
| 20762 | | - if( nspace>0 ){ |
| 20763 | | - sqlite3AppendSpace(pAccum, nspace); |
| 20764 | | - } |
| 20765 | | - } |
| 20766 | | - if( length>0 ){ |
| 20767 | | - sqlite3StrAccumAppend(pAccum, bufpt, length); |
| 20768 | | - } |
| 20769 | | - if( flag_leftjustify ){ |
| 20770 | | - register int nspace; |
| 20771 | | - nspace = width-length; |
| 20772 | | - if( nspace>0 ){ |
| 20773 | | - sqlite3AppendSpace(pAccum, nspace); |
| 20774 | | - } |
| 20775 | | - } |
| 20767 | + width -= length; |
| 20768 | + if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width); |
| 20769 | + sqlite3StrAccumAppend(pAccum, bufpt, length); |
| 20770 | + if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width); |
| 20771 | + |
| 20776 | 20772 | if( zExtra ) sqlite3_free(zExtra); |
| 20777 | 20773 | }/* End for loop over the format string */ |
| 20778 | 20774 | } /* End of function */ |
| 20779 | 20775 | |
| 20780 | 20776 | /* |
| 20781 | | -** Append N bytes of text from z to the StrAccum object. |
| 20777 | +** Enlarge the memory allocation on a StrAccum object so that it is |
| 20778 | +** able to accept at least N more bytes of text. |
| 20779 | +** |
| 20780 | +** Return the number of bytes of text that StrAccum is able to accept |
| 20781 | +** after the attempted enlargement. The value returned might be zero. |
| 20782 | +*/ |
| 20783 | +static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ |
| 20784 | + char *zNew; |
| 20785 | + assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ |
| 20786 | + if( p->accError ){ |
| 20787 | + testcase(p->accError==STRACCUM_TOOBIG); |
| 20788 | + testcase(p->accError==STRACCUM_NOMEM); |
| 20789 | + return 0; |
| 20790 | + } |
| 20791 | + if( !p->useMalloc ){ |
| 20792 | + N = p->nAlloc - p->nChar - 1; |
| 20793 | + setStrAccumError(p, STRACCUM_TOOBIG); |
| 20794 | + return N; |
| 20795 | + }else{ |
| 20796 | + char *zOld = (p->zText==p->zBase ? 0 : p->zText); |
| 20797 | + i64 szNew = p->nChar; |
| 20798 | + szNew += N + 1; |
| 20799 | + if( szNew > p->mxAlloc ){ |
| 20800 | + sqlite3StrAccumReset(p); |
| 20801 | + setStrAccumError(p, STRACCUM_TOOBIG); |
| 20802 | + return 0; |
| 20803 | + }else{ |
| 20804 | + p->nAlloc = (int)szNew; |
| 20805 | + } |
| 20806 | + if( p->useMalloc==1 ){ |
| 20807 | + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); |
| 20808 | + }else{ |
| 20809 | + zNew = sqlite3_realloc(zOld, p->nAlloc); |
| 20810 | + } |
| 20811 | + if( zNew ){ |
| 20812 | + if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 20813 | + p->zText = zNew; |
| 20814 | + }else{ |
| 20815 | + sqlite3StrAccumReset(p); |
| 20816 | + setStrAccumError(p, STRACCUM_NOMEM); |
| 20817 | + return 0; |
| 20818 | + } |
| 20819 | + } |
| 20820 | + return N; |
| 20821 | +} |
| 20822 | + |
| 20823 | +/* |
| 20824 | +** Append N space characters to the given string buffer. |
| 20825 | +*/ |
| 20826 | +SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *p, int N){ |
| 20827 | + if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return; |
| 20828 | + while( (N--)>0 ) p->zText[p->nChar++] = ' '; |
| 20829 | +} |
| 20830 | + |
| 20831 | +/* |
| 20832 | +** The StrAccum "p" is not large enough to accept N new bytes of z[]. |
| 20833 | +** So enlarge if first, then do the append. |
| 20834 | +** |
| 20835 | +** This is a helper routine to sqlite3StrAccumAppend() that does special-case |
| 20836 | +** work (enlarging the buffer) using tail recursion, so that the |
| 20837 | +** sqlite3StrAccumAppend() routine can use fast calling semantics. |
| 20838 | +*/ |
| 20839 | +static void enlargeAndAppend(StrAccum *p, const char *z, int N){ |
| 20840 | + N = sqlite3StrAccumEnlarge(p, N); |
| 20841 | + if( N>0 ){ |
| 20842 | + memcpy(&p->zText[p->nChar], z, N); |
| 20843 | + p->nChar += N; |
| 20844 | + } |
| 20845 | +} |
| 20846 | + |
| 20847 | +/* |
| 20848 | +** Append N bytes of text from z to the StrAccum object. Increase the |
| 20849 | +** size of the memory allocation for StrAccum if necessary. |
| 20782 | 20850 | */ |
| 20783 | 20851 | SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
| 20784 | 20852 | assert( z!=0 ); |
| 20785 | 20853 | assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 20786 | 20854 | assert( N>=0 ); |
| 20787 | 20855 | assert( p->accError==0 || p->nAlloc==0 ); |
| 20788 | 20856 | if( p->nChar+N >= p->nAlloc ){ |
| 20789 | | - char *zNew; |
| 20790 | | - if( p->accError ){ |
| 20791 | | - testcase(p->accError==STRACCUM_TOOBIG); |
| 20792 | | - testcase(p->accError==STRACCUM_NOMEM); |
| 20793 | | - return; |
| 20794 | | - } |
| 20795 | | - if( !p->useMalloc ){ |
| 20796 | | - N = p->nAlloc - p->nChar - 1; |
| 20797 | | - setStrAccumError(p, STRACCUM_TOOBIG); |
| 20798 | | - if( N<=0 ){ |
| 20799 | | - return; |
| 20800 | | - } |
| 20801 | | - }else{ |
| 20802 | | - char *zOld = (p->zText==p->zBase ? 0 : p->zText); |
| 20803 | | - i64 szNew = p->nChar; |
| 20804 | | - szNew += N + 1; |
| 20805 | | - if( szNew > p->mxAlloc ){ |
| 20806 | | - sqlite3StrAccumReset(p); |
| 20807 | | - setStrAccumError(p, STRACCUM_TOOBIG); |
| 20808 | | - return; |
| 20809 | | - }else{ |
| 20810 | | - p->nAlloc = (int)szNew; |
| 20811 | | - } |
| 20812 | | - if( p->useMalloc==1 ){ |
| 20813 | | - zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); |
| 20814 | | - }else{ |
| 20815 | | - zNew = sqlite3_realloc(zOld, p->nAlloc); |
| 20816 | | - } |
| 20817 | | - if( zNew ){ |
| 20818 | | - if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 20819 | | - p->zText = zNew; |
| 20820 | | - }else{ |
| 20821 | | - sqlite3StrAccumReset(p); |
| 20822 | | - setStrAccumError(p, STRACCUM_NOMEM); |
| 20823 | | - return; |
| 20824 | | - } |
| 20825 | | - } |
| 20857 | + enlargeAndAppend(p,z,N); |
| 20858 | + return; |
| 20826 | 20859 | } |
| 20827 | 20860 | assert( p->zText ); |
| 20828 | 20861 | memcpy(&p->zText[p->nChar], z, N); |
| 20829 | 20862 | p->nChar += N; |
| 20830 | 20863 | } |
| | @@ -23328,11 +23361,11 @@ |
| 23328 | 23361 | /* 9 */ "Next" OpHelp(""), |
| 23329 | 23362 | /* 10 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 23330 | 23363 | /* 11 */ "Checkpoint" OpHelp(""), |
| 23331 | 23364 | /* 12 */ "JournalMode" OpHelp(""), |
| 23332 | 23365 | /* 13 */ "Vacuum" OpHelp(""), |
| 23333 | | - /* 14 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"), |
| 23366 | + /* 14 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), |
| 23334 | 23367 | /* 15 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 23335 | 23368 | /* 16 */ "Goto" OpHelp(""), |
| 23336 | 23369 | /* 17 */ "Gosub" OpHelp(""), |
| 23337 | 23370 | /* 18 */ "Return" OpHelp(""), |
| 23338 | 23371 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), |
| | @@ -23355,11 +23388,11 @@ |
| 23355 | 23388 | /* 36 */ "CollSeq" OpHelp(""), |
| 23356 | 23389 | /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 23357 | 23390 | /* 38 */ "MustBeInt" OpHelp(""), |
| 23358 | 23391 | /* 39 */ "RealAffinity" OpHelp(""), |
| 23359 | 23392 | /* 40 */ "Permutation" OpHelp(""), |
| 23360 | | - /* 41 */ "Compare" OpHelp(""), |
| 23393 | + /* 41 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 23361 | 23394 | /* 42 */ "Jump" OpHelp(""), |
| 23362 | 23395 | /* 43 */ "Once" OpHelp(""), |
| 23363 | 23396 | /* 44 */ "If" OpHelp(""), |
| 23364 | 23397 | /* 45 */ "IfNot" OpHelp(""), |
| 23365 | 23398 | /* 46 */ "Column" OpHelp("r[P3]=PX"), |
| | @@ -23382,11 +23415,11 @@ |
| 23382 | 23415 | /* 63 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23383 | 23416 | /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23384 | 23417 | /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23385 | 23418 | /* 66 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23386 | 23419 | /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23387 | | - /* 68 */ "Sequence" OpHelp("r[P2]=rowid"), |
| 23420 | + /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23388 | 23421 | /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23389 | 23422 | /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23390 | 23423 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23391 | 23424 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23392 | 23425 | /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| | @@ -23430,51 +23463,52 @@ |
| 23430 | 23463 | /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 23431 | 23464 | /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 23432 | 23465 | /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 23433 | 23466 | /* 114 */ "Destroy" OpHelp(""), |
| 23434 | 23467 | /* 115 */ "Clear" OpHelp(""), |
| 23435 | | - /* 116 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23436 | | - /* 117 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23437 | | - /* 118 */ "ParseSchema" OpHelp(""), |
| 23438 | | - /* 119 */ "LoadAnalysis" OpHelp(""), |
| 23439 | | - /* 120 */ "DropTable" OpHelp(""), |
| 23440 | | - /* 121 */ "DropIndex" OpHelp(""), |
| 23441 | | - /* 122 */ "DropTrigger" OpHelp(""), |
| 23442 | | - /* 123 */ "IntegrityCk" OpHelp(""), |
| 23443 | | - /* 124 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23444 | | - /* 125 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23445 | | - /* 126 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23446 | | - /* 127 */ "Program" OpHelp(""), |
| 23447 | | - /* 128 */ "Param" OpHelp(""), |
| 23448 | | - /* 129 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23449 | | - /* 130 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23450 | | - /* 131 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23451 | | - /* 132 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 23468 | + /* 116 */ "ResetSorter" OpHelp(""), |
| 23469 | + /* 117 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23470 | + /* 118 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23471 | + /* 119 */ "ParseSchema" OpHelp(""), |
| 23472 | + /* 120 */ "LoadAnalysis" OpHelp(""), |
| 23473 | + /* 121 */ "DropTable" OpHelp(""), |
| 23474 | + /* 122 */ "DropIndex" OpHelp(""), |
| 23475 | + /* 123 */ "DropTrigger" OpHelp(""), |
| 23476 | + /* 124 */ "IntegrityCk" OpHelp(""), |
| 23477 | + /* 125 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23478 | + /* 126 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23479 | + /* 127 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23480 | + /* 128 */ "Program" OpHelp(""), |
| 23481 | + /* 129 */ "Param" OpHelp(""), |
| 23482 | + /* 130 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23483 | + /* 131 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23484 | + /* 132 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23452 | 23485 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23453 | | - /* 134 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23454 | | - /* 135 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 23455 | | - /* 136 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23456 | | - /* 137 */ "IncrVacuum" OpHelp(""), |
| 23457 | | - /* 138 */ "Expire" OpHelp(""), |
| 23458 | | - /* 139 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23459 | | - /* 140 */ "VBegin" OpHelp(""), |
| 23460 | | - /* 141 */ "VCreate" OpHelp(""), |
| 23461 | | - /* 142 */ "VDestroy" OpHelp(""), |
| 23486 | + /* 134 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 23487 | + /* 135 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23488 | + /* 136 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 23489 | + /* 137 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23490 | + /* 138 */ "IncrVacuum" OpHelp(""), |
| 23491 | + /* 139 */ "Expire" OpHelp(""), |
| 23492 | + /* 140 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23493 | + /* 141 */ "VBegin" OpHelp(""), |
| 23494 | + /* 142 */ "VCreate" OpHelp(""), |
| 23462 | 23495 | /* 143 */ "ToText" OpHelp(""), |
| 23463 | 23496 | /* 144 */ "ToBlob" OpHelp(""), |
| 23464 | 23497 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23465 | 23498 | /* 146 */ "ToInt" OpHelp(""), |
| 23466 | 23499 | /* 147 */ "ToReal" OpHelp(""), |
| 23467 | | - /* 148 */ "VOpen" OpHelp(""), |
| 23468 | | - /* 149 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23469 | | - /* 150 */ "VNext" OpHelp(""), |
| 23470 | | - /* 151 */ "VRename" OpHelp(""), |
| 23471 | | - /* 152 */ "Pagecount" OpHelp(""), |
| 23472 | | - /* 153 */ "MaxPgcnt" OpHelp(""), |
| 23473 | | - /* 154 */ "Init" OpHelp("Start at P2"), |
| 23474 | | - /* 155 */ "Noop" OpHelp(""), |
| 23475 | | - /* 156 */ "Explain" OpHelp(""), |
| 23500 | + /* 148 */ "VDestroy" OpHelp(""), |
| 23501 | + /* 149 */ "VOpen" OpHelp(""), |
| 23502 | + /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23503 | + /* 151 */ "VNext" OpHelp(""), |
| 23504 | + /* 152 */ "VRename" OpHelp(""), |
| 23505 | + /* 153 */ "Pagecount" OpHelp(""), |
| 23506 | + /* 154 */ "MaxPgcnt" OpHelp(""), |
| 23507 | + /* 155 */ "Init" OpHelp("Start at P2"), |
| 23508 | + /* 156 */ "Noop" OpHelp(""), |
| 23509 | + /* 157 */ "Explain" OpHelp(""), |
| 23476 | 23510 | }; |
| 23477 | 23511 | return azName[i]; |
| 23478 | 23512 | } |
| 23479 | 23513 | #endif |
| 23480 | 23514 | |
| | @@ -24010,10 +24044,11 @@ |
| 24010 | 24044 | return geteuid() ? 0 : fchown(fd,uid,gid); |
| 24011 | 24045 | } |
| 24012 | 24046 | |
| 24013 | 24047 | /* Forward reference */ |
| 24014 | 24048 | static int openDirectory(const char*, int*); |
| 24049 | +static int unixGetpagesize(void); |
| 24015 | 24050 | |
| 24016 | 24051 | /* |
| 24017 | 24052 | ** Many system calls are accessed through pointer-to-functions so that |
| 24018 | 24053 | ** they may be overridden at runtime to facilitate fault injection during |
| 24019 | 24054 | ** testing and sandboxing. The following array holds the names and pointers |
| | @@ -24132,10 +24167,13 @@ |
| 24132 | 24167 | #else |
| 24133 | 24168 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 24134 | 24169 | #endif |
| 24135 | 24170 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 24136 | 24171 | #endif |
| 24172 | + |
| 24173 | + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, |
| 24174 | +#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) |
| 24137 | 24175 | |
| 24138 | 24176 | }; /* End of the overrideable system calls */ |
| 24139 | 24177 | |
| 24140 | 24178 | /* |
| 24141 | 24179 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -27792,10 +27830,40 @@ |
| 27792 | 27830 | #endif |
| 27793 | 27831 | |
| 27794 | 27832 | return rc; |
| 27795 | 27833 | } |
| 27796 | 27834 | |
| 27835 | +/* |
| 27836 | +** Return the system page size. |
| 27837 | +** |
| 27838 | +** This function should not be called directly by other code in this file. |
| 27839 | +** Instead, it should be called via macro osGetpagesize(). |
| 27840 | +*/ |
| 27841 | +static int unixGetpagesize(void){ |
| 27842 | +#if defined(_BSD_SOURCE) |
| 27843 | + return getpagesize(); |
| 27844 | +#else |
| 27845 | + return (int)sysconf(_SC_PAGESIZE); |
| 27846 | +#endif |
| 27847 | +} |
| 27848 | + |
| 27849 | +/* |
| 27850 | +** Return the minimum number of 32KB shm regions that should be mapped at |
| 27851 | +** a time, assuming that each mapping must be an integer multiple of the |
| 27852 | +** current system page-size. |
| 27853 | +** |
| 27854 | +** Usually, this is 1. The exception seems to be systems that are configured |
| 27855 | +** to use 64KB pages - in this case each mapping must cover at least two |
| 27856 | +** shm regions. |
| 27857 | +*/ |
| 27858 | +static int unixShmRegionPerMap(void){ |
| 27859 | + int shmsz = 32*1024; /* SHM region size */ |
| 27860 | + int pgsz = osGetpagesize(); /* System page size */ |
| 27861 | + assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ |
| 27862 | + if( pgsz<shmsz ) return 1; |
| 27863 | + return pgsz/shmsz; |
| 27864 | +} |
| 27797 | 27865 | |
| 27798 | 27866 | /* |
| 27799 | 27867 | ** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. |
| 27800 | 27868 | ** |
| 27801 | 27869 | ** This is not a VFS shared-memory method; it is a utility function called |
| | @@ -27803,14 +27871,15 @@ |
| 27803 | 27871 | */ |
| 27804 | 27872 | static void unixShmPurge(unixFile *pFd){ |
| 27805 | 27873 | unixShmNode *p = pFd->pInode->pShmNode; |
| 27806 | 27874 | assert( unixMutexHeld() ); |
| 27807 | 27875 | if( p && p->nRef==0 ){ |
| 27876 | + int nShmPerMap = unixShmRegionPerMap(); |
| 27808 | 27877 | int i; |
| 27809 | 27878 | assert( p->pInode==pFd->pInode ); |
| 27810 | 27879 | sqlite3_mutex_free(p->mutex); |
| 27811 | | - for(i=0; i<p->nRegion; i++){ |
| 27880 | + for(i=0; i<p->nRegion; i+=nShmPerMap){ |
| 27812 | 27881 | if( p->h>=0 ){ |
| 27813 | 27882 | osMunmap(p->apRegion[i], p->szRegion); |
| 27814 | 27883 | }else{ |
| 27815 | 27884 | sqlite3_free(p->apRegion[i]); |
| 27816 | 27885 | } |
| | @@ -28013,10 +28082,12 @@ |
| 28013 | 28082 | ){ |
| 28014 | 28083 | unixFile *pDbFd = (unixFile*)fd; |
| 28015 | 28084 | unixShm *p; |
| 28016 | 28085 | unixShmNode *pShmNode; |
| 28017 | 28086 | int rc = SQLITE_OK; |
| 28087 | + int nShmPerMap = unixShmRegionPerMap(); |
| 28088 | + int nReqRegion; |
| 28018 | 28089 | |
| 28019 | 28090 | /* If the shared-memory file has not yet been opened, open it now. */ |
| 28020 | 28091 | if( pDbFd->pShm==0 ){ |
| 28021 | 28092 | rc = unixOpenSharedMemory(pDbFd); |
| 28022 | 28093 | if( rc!=SQLITE_OK ) return rc; |
| | @@ -28028,13 +28099,16 @@ |
| 28028 | 28099 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 28029 | 28100 | assert( pShmNode->pInode==pDbFd->pInode ); |
| 28030 | 28101 | assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); |
| 28031 | 28102 | assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); |
| 28032 | 28103 | |
| 28033 | | - if( pShmNode->nRegion<=iRegion ){ |
| 28104 | + /* Minimum number of regions required to be mapped. */ |
| 28105 | + nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; |
| 28106 | + |
| 28107 | + if( pShmNode->nRegion<nReqRegion ){ |
| 28034 | 28108 | char **apNew; /* New apRegion[] array */ |
| 28035 | | - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ |
| 28109 | + int nByte = nReqRegion*szRegion; /* Minimum required file size */ |
| 28036 | 28110 | struct stat sStat; /* Used by fstat() */ |
| 28037 | 28111 | |
| 28038 | 28112 | pShmNode->szRegion = szRegion; |
| 28039 | 28113 | |
| 28040 | 28114 | if( pShmNode->h>=0 ){ |
| | @@ -28079,21 +28153,23 @@ |
| 28079 | 28153 | } |
| 28080 | 28154 | } |
| 28081 | 28155 | |
| 28082 | 28156 | /* Map the requested memory region into this processes address space. */ |
| 28083 | 28157 | apNew = (char **)sqlite3_realloc( |
| 28084 | | - pShmNode->apRegion, (iRegion+1)*sizeof(char *) |
| 28158 | + pShmNode->apRegion, nReqRegion*sizeof(char *) |
| 28085 | 28159 | ); |
| 28086 | 28160 | if( !apNew ){ |
| 28087 | 28161 | rc = SQLITE_IOERR_NOMEM; |
| 28088 | 28162 | goto shmpage_out; |
| 28089 | 28163 | } |
| 28090 | 28164 | pShmNode->apRegion = apNew; |
| 28091 | | - while(pShmNode->nRegion<=iRegion){ |
| 28165 | + while( pShmNode->nRegion<nReqRegion ){ |
| 28166 | + int nMap = szRegion*nShmPerMap; |
| 28167 | + int i; |
| 28092 | 28168 | void *pMem; |
| 28093 | 28169 | if( pShmNode->h>=0 ){ |
| 28094 | | - pMem = osMmap(0, szRegion, |
| 28170 | + pMem = osMmap(0, nMap, |
| 28095 | 28171 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 28096 | 28172 | MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion |
| 28097 | 28173 | ); |
| 28098 | 28174 | if( pMem==MAP_FAILED ){ |
| 28099 | 28175 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| | @@ -28105,12 +28181,15 @@ |
| 28105 | 28181 | rc = SQLITE_NOMEM; |
| 28106 | 28182 | goto shmpage_out; |
| 28107 | 28183 | } |
| 28108 | 28184 | memset(pMem, 0, szRegion); |
| 28109 | 28185 | } |
| 28110 | | - pShmNode->apRegion[pShmNode->nRegion] = pMem; |
| 28111 | | - pShmNode->nRegion++; |
| 28186 | + |
| 28187 | + for(i=0; i<nShmPerMap; i++){ |
| 28188 | + pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; |
| 28189 | + } |
| 28190 | + pShmNode->nRegion += nShmPerMap; |
| 28112 | 28191 | } |
| 28113 | 28192 | } |
| 28114 | 28193 | |
| 28115 | 28194 | shmpage_out: |
| 28116 | 28195 | if( pShmNode->nRegion>iRegion ){ |
| | @@ -28320,23 +28399,10 @@ |
| 28320 | 28399 | pFd->mmapSize = 0; |
| 28321 | 28400 | pFd->mmapSizeActual = 0; |
| 28322 | 28401 | } |
| 28323 | 28402 | } |
| 28324 | 28403 | |
| 28325 | | -/* |
| 28326 | | -** Return the system page size. |
| 28327 | | -*/ |
| 28328 | | -static int unixGetPagesize(void){ |
| 28329 | | -#if HAVE_MREMAP |
| 28330 | | - return 512; |
| 28331 | | -#elif defined(_BSD_SOURCE) |
| 28332 | | - return getpagesize(); |
| 28333 | | -#else |
| 28334 | | - return (int)sysconf(_SC_PAGESIZE); |
| 28335 | | -#endif |
| 28336 | | -} |
| 28337 | | - |
| 28338 | 28404 | /* |
| 28339 | 28405 | ** Attempt to set the size of the memory mapping maintained by file |
| 28340 | 28406 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 28341 | 28407 | ** |
| 28342 | 28408 | ** If successful, this function sets the following variables: |
| | @@ -28369,12 +28435,16 @@ |
| 28369 | 28435 | assert( MAP_FAILED!=0 ); |
| 28370 | 28436 | |
| 28371 | 28437 | if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; |
| 28372 | 28438 | |
| 28373 | 28439 | if( pOrig ){ |
| 28374 | | - const int szSyspage = unixGetPagesize(); |
| 28440 | +#if HAVE_MREMAP |
| 28441 | + i64 nReuse = pFd->mmapSize; |
| 28442 | +#else |
| 28443 | + const int szSyspage = osGetpagesize(); |
| 28375 | 28444 | i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); |
| 28445 | +#endif |
| 28376 | 28446 | u8 *pReq = &pOrig[nReuse]; |
| 28377 | 28447 | |
| 28378 | 28448 | /* Unmap any pages of the existing mapping that cannot be reused. */ |
| 28379 | 28449 | if( nReuse!=nOrig ){ |
| 28380 | 28450 | osMunmap(pReq, nOrig-nReuse); |
| | @@ -31116,11 +31186,11 @@ |
| 31116 | 31186 | }; |
| 31117 | 31187 | unsigned int i; /* Loop counter */ |
| 31118 | 31188 | |
| 31119 | 31189 | /* Double-check that the aSyscall[] array has been constructed |
| 31120 | 31190 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 31121 | | - assert( ArraySize(aSyscall)==24 ); |
| 31191 | + assert( ArraySize(aSyscall)==25 ); |
| 31122 | 31192 | |
| 31123 | 31193 | /* Register all VFSes defined in the aVfs[] array */ |
| 31124 | 31194 | for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |
| 31125 | 31195 | sqlite3_vfs_register(&aVfs[i], i==0); |
| 31126 | 31196 | } |
| | @@ -38997,12 +39067,12 @@ |
| 38997 | 39067 | struct RowSetEntry *pEntry; /* List of entries using pRight */ |
| 38998 | 39068 | struct RowSetEntry *pLast; /* Last entry on the pEntry list */ |
| 38999 | 39069 | struct RowSetEntry *pFresh; /* Source of new entry objects */ |
| 39000 | 39070 | struct RowSetEntry *pForest; /* List of binary trees of entries */ |
| 39001 | 39071 | u16 nFresh; /* Number of objects on pFresh */ |
| 39002 | | - u8 rsFlags; /* Various flags */ |
| 39003 | | - u8 iBatch; /* Current insert batch */ |
| 39072 | + u16 rsFlags; /* Various flags */ |
| 39073 | + int iBatch; /* Current insert batch */ |
| 39004 | 39074 | }; |
| 39005 | 39075 | |
| 39006 | 39076 | /* |
| 39007 | 39077 | ** Allowed values for RowSet.rsFlags |
| 39008 | 39078 | */ |
| | @@ -39332,11 +39402,11 @@ |
| 39332 | 39402 | ** |
| 39333 | 39403 | ** If this is the first test of a new batch and if there exist entires |
| 39334 | 39404 | ** on pRowSet->pEntry, then sort those entires into the forest at |
| 39335 | 39405 | ** pRowSet->pForest so that they can be tested. |
| 39336 | 39406 | */ |
| 39337 | | -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ |
| 39407 | +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ |
| 39338 | 39408 | struct RowSetEntry *p, *pTree; |
| 39339 | 39409 | |
| 39340 | 39410 | /* This routine is never called after sqlite3RowSetNext() */ |
| 39341 | 39411 | assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); |
| 39342 | 39412 | |
| | @@ -41159,16 +41229,15 @@ |
| 41159 | 41229 | assert( pPager->setMaster==0 ); |
| 41160 | 41230 | assert( !pagerUseWal(pPager) ); |
| 41161 | 41231 | |
| 41162 | 41232 | if( !zMaster |
| 41163 | 41233 | || pPager->journalMode==PAGER_JOURNALMODE_MEMORY |
| 41164 | | - || pPager->journalMode==PAGER_JOURNALMODE_OFF |
| 41234 | + || !isOpen(pPager->jfd) |
| 41165 | 41235 | ){ |
| 41166 | 41236 | return SQLITE_OK; |
| 41167 | 41237 | } |
| 41168 | 41238 | pPager->setMaster = 1; |
| 41169 | | - assert( isOpen(pPager->jfd) ); |
| 41170 | 41239 | assert( pPager->journalHdr <= pPager->journalOff ); |
| 41171 | 41240 | |
| 41172 | 41241 | /* Calculate the length in bytes and the checksum of zMaster */ |
| 41173 | 41242 | for(nMaster=0; zMaster[nMaster]; nMaster++){ |
| 41174 | 41243 | cksum += zMaster[nMaster]; |
| | @@ -50371,31 +50440,34 @@ |
| 50371 | 50440 | struct BtCursor { |
| 50372 | 50441 | Btree *pBtree; /* The Btree to which this cursor belongs */ |
| 50373 | 50442 | BtShared *pBt; /* The BtShared this cursor points to */ |
| 50374 | 50443 | BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ |
| 50375 | 50444 | struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ |
| 50376 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 50377 | 50445 | Pgno *aOverflow; /* Cache of overflow page locations */ |
| 50378 | | -#endif |
| 50446 | + CellInfo info; /* A parse of the cell we are pointing at */ |
| 50447 | + i64 nKey; /* Size of pKey, or last integer key */ |
| 50448 | + void *pKey; /* Saved key that was cursor last known position */ |
| 50379 | 50449 | Pgno pgnoRoot; /* The root page of this tree */ |
| 50380 | | - CellInfo info; /* A parse of the cell we are pointing at */ |
| 50381 | | - i64 nKey; /* Size of pKey, or last integer key */ |
| 50382 | | - void *pKey; /* Saved key that was cursor's last known position */ |
| 50450 | + int nOvflAlloc; /* Allocated size of aOverflow[] array */ |
| 50383 | 50451 | int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ |
| 50384 | | - u8 wrFlag; /* True if writable */ |
| 50385 | | - u8 atLast; /* Cursor pointing to the last entry */ |
| 50386 | | - u8 validNKey; /* True if info.nKey is valid */ |
| 50452 | + u8 curFlags; /* zero or more BTCF_* flags defined below */ |
| 50387 | 50453 | u8 eState; /* One of the CURSOR_XXX constants (see below) */ |
| 50388 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 50389 | | - u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ |
| 50390 | | -#endif |
| 50391 | 50454 | u8 hints; /* As configured by CursorSetHints() */ |
| 50392 | 50455 | i16 iPage; /* Index of current page in apPage */ |
| 50393 | 50456 | u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ |
| 50394 | 50457 | MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ |
| 50395 | 50458 | }; |
| 50396 | 50459 | |
| 50460 | +/* |
| 50461 | +** Legal values for BtCursor.curFlags |
| 50462 | +*/ |
| 50463 | +#define BTCF_WriteFlag 0x01 /* True if a write cursor */ |
| 50464 | +#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ |
| 50465 | +#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ |
| 50466 | +#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ |
| 50467 | +#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ |
| 50468 | + |
| 50397 | 50469 | /* |
| 50398 | 50470 | ** Potential values for BtCursor.eState. |
| 50399 | 50471 | ** |
| 50400 | 50472 | ** CURSOR_INVALID: |
| 50401 | 50473 | ** Cursor does not point to a valid entry. This can happen (for example) |
| | @@ -51262,20 +51334,15 @@ |
| 51262 | 51334 | static int cursorHoldsMutex(BtCursor *p){ |
| 51263 | 51335 | return sqlite3_mutex_held(p->pBt->mutex); |
| 51264 | 51336 | } |
| 51265 | 51337 | #endif |
| 51266 | 51338 | |
| 51267 | | - |
| 51268 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 51269 | 51339 | /* |
| 51270 | | -** Invalidate the overflow page-list cache for cursor pCur, if any. |
| 51340 | +** Invalidate the overflow cache of the cursor passed as the first argument. |
| 51341 | +** on the shared btree structure pBt. |
| 51271 | 51342 | */ |
| 51272 | | -static void invalidateOverflowCache(BtCursor *pCur){ |
| 51273 | | - assert( cursorHoldsMutex(pCur) ); |
| 51274 | | - sqlite3_free(pCur->aOverflow); |
| 51275 | | - pCur->aOverflow = 0; |
| 51276 | | -} |
| 51343 | +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) |
| 51277 | 51344 | |
| 51278 | 51345 | /* |
| 51279 | 51346 | ** Invalidate the overflow page-list cache for all cursors opened |
| 51280 | 51347 | ** on the shared btree structure pBt. |
| 51281 | 51348 | */ |
| | @@ -51285,10 +51352,11 @@ |
| 51285 | 51352 | for(p=pBt->pCursor; p; p=p->pNext){ |
| 51286 | 51353 | invalidateOverflowCache(p); |
| 51287 | 51354 | } |
| 51288 | 51355 | } |
| 51289 | 51356 | |
| 51357 | +#ifndef SQLITE_OMIT_INCRBLOB |
| 51290 | 51358 | /* |
| 51291 | 51359 | ** This function is called before modifying the contents of a table |
| 51292 | 51360 | ** to invalidate any incrblob cursors that are open on the |
| 51293 | 51361 | ** row or one of the rows being modified. |
| 51294 | 51362 | ** |
| | @@ -51307,20 +51375,18 @@ |
| 51307 | 51375 | ){ |
| 51308 | 51376 | BtCursor *p; |
| 51309 | 51377 | BtShared *pBt = pBtree->pBt; |
| 51310 | 51378 | assert( sqlite3BtreeHoldsMutex(pBtree) ); |
| 51311 | 51379 | for(p=pBt->pCursor; p; p=p->pNext){ |
| 51312 | | - if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){ |
| 51380 | + if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){ |
| 51313 | 51381 | p->eState = CURSOR_INVALID; |
| 51314 | 51382 | } |
| 51315 | 51383 | } |
| 51316 | 51384 | } |
| 51317 | 51385 | |
| 51318 | 51386 | #else |
| 51319 | | - /* Stub functions when INCRBLOB is omitted */ |
| 51320 | | - #define invalidateOverflowCache(x) |
| 51321 | | - #define invalidateAllOverflowCache(x) |
| 51387 | + /* Stub function when INCRBLOB is omitted */ |
| 51322 | 51388 | #define invalidateIncrblobCursors(x,y,z) |
| 51323 | 51389 | #endif /* SQLITE_OMIT_INCRBLOB */ |
| 51324 | 51390 | |
| 51325 | 51391 | /* |
| 51326 | 51392 | ** Set bit pgno of the BtShared.pHasContent bitvec. This is called |
| | @@ -51562,24 +51628,36 @@ |
| 51562 | 51628 | ** Determine whether or not a cursor has moved from the position it |
| 51563 | 51629 | ** was last placed at. Cursors can move when the row they are pointing |
| 51564 | 51630 | ** at is deleted out from under them. |
| 51565 | 51631 | ** |
| 51566 | 51632 | ** This routine returns an error code if something goes wrong. The |
| 51567 | | -** integer *pHasMoved is set to one if the cursor has moved and 0 if not. |
| 51633 | +** integer *pHasMoved is set as follows: |
| 51634 | +** |
| 51635 | +** 0: The cursor is unchanged |
| 51636 | +** 1: The cursor is still pointing at the same row, but the pointers |
| 51637 | +** returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch() |
| 51638 | +** might now be invalid because of a balance() or other change to the |
| 51639 | +** b-tree. |
| 51640 | +** 2: The cursor is no longer pointing to the row. The row might have |
| 51641 | +** been deleted out from under the cursor. |
| 51568 | 51642 | */ |
| 51569 | 51643 | SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ |
| 51570 | 51644 | int rc; |
| 51571 | 51645 | |
| 51646 | + if( pCur->eState==CURSOR_VALID ){ |
| 51647 | + *pHasMoved = 0; |
| 51648 | + return SQLITE_OK; |
| 51649 | + } |
| 51572 | 51650 | rc = restoreCursorPosition(pCur); |
| 51573 | 51651 | if( rc ){ |
| 51574 | | - *pHasMoved = 1; |
| 51652 | + *pHasMoved = 2; |
| 51575 | 51653 | return rc; |
| 51576 | 51654 | } |
| 51577 | 51655 | if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){ |
| 51656 | + *pHasMoved = 2; |
| 51657 | + }else{ |
| 51578 | 51658 | *pHasMoved = 1; |
| 51579 | | - }else{ |
| 51580 | | - *pHasMoved = 0; |
| 51581 | 51659 | } |
| 51582 | 51660 | return SQLITE_OK; |
| 51583 | 51661 | } |
| 51584 | 51662 | |
| 51585 | 51663 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| | @@ -52977,10 +53055,11 @@ |
| 52977 | 53055 | sqlite3PagerSetCachesize(pBt->pPager, mxPage); |
| 52978 | 53056 | sqlite3BtreeLeave(p); |
| 52979 | 53057 | return SQLITE_OK; |
| 52980 | 53058 | } |
| 52981 | 53059 | |
| 53060 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 52982 | 53061 | /* |
| 52983 | 53062 | ** Change the limit on the amount of the database file that may be |
| 52984 | 53063 | ** memory mapped. |
| 52985 | 53064 | */ |
| 52986 | 53065 | SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ |
| | @@ -52989,10 +53068,11 @@ |
| 52989 | 53068 | sqlite3BtreeEnter(p); |
| 52990 | 53069 | sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); |
| 52991 | 53070 | sqlite3BtreeLeave(p); |
| 52992 | 53071 | return SQLITE_OK; |
| 52993 | 53072 | } |
| 53073 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 52994 | 53074 | |
| 52995 | 53075 | /* |
| 52996 | 53076 | ** Change the way data is synced to disk in order to increase or decrease |
| 52997 | 53077 | ** how well the database resists damage due to OS crashes and power |
| 52998 | 53078 | ** failures. Level 1 is the same as asynchronous (no syncs() occur and |
| | @@ -53365,11 +53445,12 @@ |
| 53365 | 53445 | */ |
| 53366 | 53446 | static int countValidCursors(BtShared *pBt, int wrOnly){ |
| 53367 | 53447 | BtCursor *pCur; |
| 53368 | 53448 | int r = 0; |
| 53369 | 53449 | for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ |
| 53370 | | - if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; |
| 53450 | + if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) |
| 53451 | + && pCur->eState!=CURSOR_FAULT ) r++; |
| 53371 | 53452 | } |
| 53372 | 53453 | return r; |
| 53373 | 53454 | } |
| 53374 | 53455 | #endif |
| 53375 | 53456 | |
| | @@ -54440,11 +54521,12 @@ |
| 54440 | 54521 | pCur->pgnoRoot = (Pgno)iTable; |
| 54441 | 54522 | pCur->iPage = -1; |
| 54442 | 54523 | pCur->pKeyInfo = pKeyInfo; |
| 54443 | 54524 | pCur->pBtree = p; |
| 54444 | 54525 | pCur->pBt = pBt; |
| 54445 | | - pCur->wrFlag = (u8)wrFlag; |
| 54526 | + assert( wrFlag==0 || wrFlag==BTCF_WriteFlag ); |
| 54527 | + pCur->curFlags = wrFlag; |
| 54446 | 54528 | pCur->pNext = pBt->pCursor; |
| 54447 | 54529 | if( pCur->pNext ){ |
| 54448 | 54530 | pCur->pNext->pPrev = pCur; |
| 54449 | 54531 | } |
| 54450 | 54532 | pBt->pCursor = pCur; |
| | @@ -54510,11 +54592,11 @@ |
| 54510 | 54592 | } |
| 54511 | 54593 | for(i=0; i<=pCur->iPage; i++){ |
| 54512 | 54594 | releasePage(pCur->apPage[i]); |
| 54513 | 54595 | } |
| 54514 | 54596 | unlockBtreeIfUnused(pBt); |
| 54515 | | - invalidateOverflowCache(pCur); |
| 54597 | + sqlite3DbFree(pBtree->db, pCur->aOverflow); |
| 54516 | 54598 | /* sqlite3_free(pCur); */ |
| 54517 | 54599 | sqlite3BtreeLeave(pBtree); |
| 54518 | 54600 | } |
| 54519 | 54601 | return SQLITE_OK; |
| 54520 | 54602 | } |
| | @@ -54549,22 +54631,22 @@ |
| 54549 | 54631 | /* Use a real function in MSVC to work around bugs in that compiler. */ |
| 54550 | 54632 | static void getCellInfo(BtCursor *pCur){ |
| 54551 | 54633 | if( pCur->info.nSize==0 ){ |
| 54552 | 54634 | int iPage = pCur->iPage; |
| 54553 | 54635 | btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); |
| 54554 | | - pCur->validNKey = 1; |
| 54636 | + pCur->curFlags |= BTCF_ValidNKey; |
| 54555 | 54637 | }else{ |
| 54556 | 54638 | assertCellInfo(pCur); |
| 54557 | 54639 | } |
| 54558 | 54640 | } |
| 54559 | 54641 | #else /* if not _MSC_VER */ |
| 54560 | 54642 | /* Use a macro in all other compilers so that the function is inlined */ |
| 54561 | 54643 | #define getCellInfo(pCur) \ |
| 54562 | 54644 | if( pCur->info.nSize==0 ){ \ |
| 54563 | 54645 | int iPage = pCur->iPage; \ |
| 54564 | | - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ |
| 54565 | | - pCur->validNKey = 1; \ |
| 54646 | + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ |
| 54647 | + pCur->curFlags |= BTCF_ValidNKey; \ |
| 54566 | 54648 | }else{ \ |
| 54567 | 54649 | assertCellInfo(pCur); \ |
| 54568 | 54650 | } |
| 54569 | 54651 | #endif /* _MSC_VER */ |
| 54570 | 54652 | |
| | @@ -54731,26 +54813,28 @@ |
| 54731 | 54813 | return SQLITE_OK; |
| 54732 | 54814 | } |
| 54733 | 54815 | |
| 54734 | 54816 | /* |
| 54735 | 54817 | ** This function is used to read or overwrite payload information |
| 54736 | | -** for the entry that the pCur cursor is pointing to. If the eOp |
| 54737 | | -** parameter is 0, this is a read operation (data copied into |
| 54738 | | -** buffer pBuf). If it is non-zero, a write (data copied from |
| 54739 | | -** buffer pBuf). |
| 54818 | +** for the entry that the pCur cursor is pointing to. The eOp |
| 54819 | +** argument is interpreted as follows: |
| 54820 | +** |
| 54821 | +** 0: The operation is a read. Populate the overflow cache. |
| 54822 | +** 1: The operation is a write. Populate the overflow cache. |
| 54823 | +** 2: The operation is a read. Do not populate the overflow cache. |
| 54740 | 54824 | ** |
| 54741 | 54825 | ** A total of "amt" bytes are read or written beginning at "offset". |
| 54742 | 54826 | ** Data is read to or from the buffer pBuf. |
| 54743 | 54827 | ** |
| 54744 | 54828 | ** The content being read or written might appear on the main page |
| 54745 | 54829 | ** or be scattered out on multiple overflow pages. |
| 54746 | 54830 | ** |
| 54747 | | -** If the BtCursor.isIncrblobHandle flag is set, and the current |
| 54748 | | -** cursor entry uses one or more overflow pages, this function |
| 54749 | | -** allocates space for and lazily popluates the overflow page-list |
| 54750 | | -** cache array (BtCursor.aOverflow). Subsequent calls use this |
| 54751 | | -** cache to make seeking to the supplied offset more efficient. |
| 54831 | +** If the current cursor entry uses one or more overflow pages and the |
| 54832 | +** eOp argument is not 2, this function may allocate space for and lazily |
| 54833 | +** popluates the overflow page-list cache array (BtCursor.aOverflow). |
| 54834 | +** Subsequent calls use this cache to make seeking to the supplied offset |
| 54835 | +** more efficient. |
| 54752 | 54836 | ** |
| 54753 | 54837 | ** Once an overflow page-list cache has been allocated, it may be |
| 54754 | 54838 | ** invalidated if some other cursor writes to the same table, or if |
| 54755 | 54839 | ** the cursor is moved to a different row. Additionally, in auto-vacuum |
| 54756 | 54840 | ** mode, the following events may invalidate an overflow page-list cache. |
| | @@ -54770,19 +54854,26 @@ |
| 54770 | 54854 | int rc = SQLITE_OK; |
| 54771 | 54855 | u32 nKey; |
| 54772 | 54856 | int iIdx = 0; |
| 54773 | 54857 | MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ |
| 54774 | 54858 | BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ |
| 54859 | +#ifdef SQLITE_DIRECT_OVERFLOW_READ |
| 54860 | + int bEnd; /* True if reading to end of data */ |
| 54861 | +#endif |
| 54775 | 54862 | |
| 54776 | 54863 | assert( pPage ); |
| 54777 | 54864 | assert( pCur->eState==CURSOR_VALID ); |
| 54778 | 54865 | assert( pCur->aiIdx[pCur->iPage]<pPage->nCell ); |
| 54779 | 54866 | assert( cursorHoldsMutex(pCur) ); |
| 54867 | + assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ |
| 54780 | 54868 | |
| 54781 | 54869 | getCellInfo(pCur); |
| 54782 | 54870 | aPayload = pCur->info.pCell + pCur->info.nHeader; |
| 54783 | 54871 | nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); |
| 54872 | +#ifdef SQLITE_DIRECT_OVERFLOW_READ |
| 54873 | + bEnd = (offset+amt==nKey+pCur->info.nData); |
| 54874 | +#endif |
| 54784 | 54875 | |
| 54785 | 54876 | if( NEVER(offset+amt > nKey+pCur->info.nData) |
| 54786 | 54877 | || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] |
| 54787 | 54878 | ){ |
| 54788 | 54879 | /* Trying to read or write past the end of the data is an error */ |
| | @@ -54793,11 +54884,11 @@ |
| 54793 | 54884 | if( offset<pCur->info.nLocal ){ |
| 54794 | 54885 | int a = amt; |
| 54795 | 54886 | if( a+offset>pCur->info.nLocal ){ |
| 54796 | 54887 | a = pCur->info.nLocal - offset; |
| 54797 | 54888 | } |
| 54798 | | - rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); |
| 54889 | + rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); |
| 54799 | 54890 | offset = 0; |
| 54800 | 54891 | pBuf += a; |
| 54801 | 54892 | amt -= a; |
| 54802 | 54893 | }else{ |
| 54803 | 54894 | offset -= pCur->info.nLocal; |
| | @@ -54807,62 +54898,72 @@ |
| 54807 | 54898 | const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ |
| 54808 | 54899 | Pgno nextPage; |
| 54809 | 54900 | |
| 54810 | 54901 | nextPage = get4byte(&aPayload[pCur->info.nLocal]); |
| 54811 | 54902 | |
| 54812 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54813 | | - /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] |
| 54814 | | - ** has not been allocated, allocate it now. The array is sized at |
| 54815 | | - ** one entry for each overflow page in the overflow chain. The |
| 54816 | | - ** page number of the first overflow page is stored in aOverflow[0], |
| 54817 | | - ** etc. A value of 0 in the aOverflow[] array means "not yet known" |
| 54818 | | - ** (the cache is lazily populated). |
| 54903 | + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. |
| 54904 | + ** Except, do not allocate aOverflow[] for eOp==2. |
| 54905 | + ** |
| 54906 | + ** The aOverflow[] array is sized at one entry for each overflow page |
| 54907 | + ** in the overflow chain. The page number of the first overflow page is |
| 54908 | + ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array |
| 54909 | + ** means "not yet known" (the cache is lazily populated). |
| 54819 | 54910 | */ |
| 54820 | | - if( pCur->isIncrblobHandle && !pCur->aOverflow ){ |
| 54911 | + if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ |
| 54821 | 54912 | int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; |
| 54822 | | - pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); |
| 54823 | | - /* nOvfl is always positive. If it were zero, fetchPayload would have |
| 54824 | | - ** been used instead of this routine. */ |
| 54825 | | - if( ALWAYS(nOvfl) && !pCur->aOverflow ){ |
| 54826 | | - rc = SQLITE_NOMEM; |
| 54913 | + if( nOvfl>pCur->nOvflAlloc ){ |
| 54914 | + Pgno *aNew = (Pgno*)sqlite3DbRealloc( |
| 54915 | + pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno) |
| 54916 | + ); |
| 54917 | + if( aNew==0 ){ |
| 54918 | + rc = SQLITE_NOMEM; |
| 54919 | + }else{ |
| 54920 | + pCur->nOvflAlloc = nOvfl*2; |
| 54921 | + pCur->aOverflow = aNew; |
| 54922 | + } |
| 54923 | + } |
| 54924 | + if( rc==SQLITE_OK ){ |
| 54925 | + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); |
| 54926 | + pCur->curFlags |= BTCF_ValidOvfl; |
| 54827 | 54927 | } |
| 54828 | 54928 | } |
| 54829 | 54929 | |
| 54830 | 54930 | /* If the overflow page-list cache has been allocated and the |
| 54831 | 54931 | ** entry for the first required overflow page is valid, skip |
| 54832 | 54932 | ** directly to it. |
| 54833 | 54933 | */ |
| 54834 | | - if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){ |
| 54934 | + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){ |
| 54835 | 54935 | iIdx = (offset/ovflSize); |
| 54836 | 54936 | nextPage = pCur->aOverflow[iIdx]; |
| 54837 | 54937 | offset = (offset%ovflSize); |
| 54838 | 54938 | } |
| 54839 | | -#endif |
| 54840 | 54939 | |
| 54841 | 54940 | for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ |
| 54842 | 54941 | |
| 54843 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54844 | 54942 | /* If required, populate the overflow page-list cache. */ |
| 54845 | | - if( pCur->aOverflow ){ |
| 54943 | + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ |
| 54846 | 54944 | assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); |
| 54847 | 54945 | pCur->aOverflow[iIdx] = nextPage; |
| 54848 | 54946 | } |
| 54849 | | -#endif |
| 54850 | 54947 | |
| 54851 | 54948 | if( offset>=ovflSize ){ |
| 54852 | 54949 | /* The only reason to read this page is to obtain the page |
| 54853 | 54950 | ** number for the next page in the overflow chain. The page |
| 54854 | 54951 | ** data is not required. So first try to lookup the overflow |
| 54855 | 54952 | ** page-list cache, if any, then fall back to the getOverflowPage() |
| 54856 | 54953 | ** function. |
| 54954 | + ** |
| 54955 | + ** Note that the aOverflow[] array must be allocated because eOp!=2 |
| 54956 | + ** here. If eOp==2, then offset==0 and this branch is never taken. |
| 54857 | 54957 | */ |
| 54858 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54859 | | - if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ |
| 54958 | + assert( eOp!=2 ); |
| 54959 | + assert( pCur->curFlags & BTCF_ValidOvfl ); |
| 54960 | + if( pCur->aOverflow[iIdx+1] ){ |
| 54860 | 54961 | nextPage = pCur->aOverflow[iIdx+1]; |
| 54861 | | - } else |
| 54862 | | -#endif |
| 54962 | + }else{ |
| 54863 | 54963 | rc = getOverflowPage(pBt, nextPage, 0, &nextPage); |
| 54964 | + } |
| 54864 | 54965 | offset -= ovflSize; |
| 54865 | 54966 | }else{ |
| 54866 | 54967 | /* Need to read this page properly. It contains some of the |
| 54867 | 54968 | ** range of data that is being read (eOp==0) or written (eOp!=0). |
| 54868 | 54969 | */ |
| | @@ -54880,17 +54981,19 @@ |
| 54880 | 54981 | ** 1) this is a read operation, and |
| 54881 | 54982 | ** 2) data is required from the start of this overflow page, and |
| 54882 | 54983 | ** 3) the database is file-backed, and |
| 54883 | 54984 | ** 4) there is no open write-transaction, and |
| 54884 | 54985 | ** 5) the database is not a WAL database, |
| 54986 | + ** 6) all data from the page is being read. |
| 54885 | 54987 | ** |
| 54886 | 54988 | ** then data can be read directly from the database file into the |
| 54887 | 54989 | ** output buffer, bypassing the page-cache altogether. This speeds |
| 54888 | 54990 | ** up loading large records that span many overflow pages. |
| 54889 | 54991 | */ |
| 54890 | | - if( eOp==0 /* (1) */ |
| 54992 | + if( (eOp&0x01)==0 /* (1) */ |
| 54891 | 54993 | && offset==0 /* (2) */ |
| 54994 | + && (bEnd || a==ovflSize) /* (6) */ |
| 54892 | 54995 | && pBt->inTransaction==TRANS_READ /* (4) */ |
| 54893 | 54996 | && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ |
| 54894 | 54997 | && pBt->pPage1->aData[19]==0x01 /* (5) */ |
| 54895 | 54998 | ){ |
| 54896 | 54999 | u8 aSave[4]; |
| | @@ -54903,16 +55006,16 @@ |
| 54903 | 55006 | #endif |
| 54904 | 55007 | |
| 54905 | 55008 | { |
| 54906 | 55009 | DbPage *pDbPage; |
| 54907 | 55010 | rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, |
| 54908 | | - (eOp==0 ? PAGER_GET_READONLY : 0) |
| 55011 | + ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) |
| 54909 | 55012 | ); |
| 54910 | 55013 | if( rc==SQLITE_OK ){ |
| 54911 | 55014 | aPayload = sqlite3PagerGetData(pDbPage); |
| 54912 | 55015 | nextPage = get4byte(aPayload); |
| 54913 | | - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); |
| 55016 | + rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); |
| 54914 | 55017 | sqlite3PagerUnref(pDbPage); |
| 54915 | 55018 | offset = 0; |
| 54916 | 55019 | } |
| 54917 | 55020 | } |
| 54918 | 55021 | amt -= a; |
| | @@ -55002,14 +55105,17 @@ |
| 55002 | 55105 | assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); |
| 55003 | 55106 | assert( pCur->eState==CURSOR_VALID ); |
| 55004 | 55107 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 55005 | 55108 | assert( cursorHoldsMutex(pCur) ); |
| 55006 | 55109 | assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); |
| 55110 | + assert( pCur->info.nSize>0 ); |
| 55111 | +#if 0 |
| 55007 | 55112 | if( pCur->info.nSize==0 ){ |
| 55008 | 55113 | btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], |
| 55009 | 55114 | &pCur->info); |
| 55010 | 55115 | } |
| 55116 | +#endif |
| 55011 | 55117 | *pAmt = pCur->info.nLocal; |
| 55012 | 55118 | return (void*)(pCur->info.pCell + pCur->info.nHeader); |
| 55013 | 55119 | } |
| 55014 | 55120 | |
| 55015 | 55121 | |
| | @@ -55056,18 +55162,18 @@ |
| 55056 | 55162 | assert( pCur->iPage>=0 ); |
| 55057 | 55163 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ |
| 55058 | 55164 | return SQLITE_CORRUPT_BKPT; |
| 55059 | 55165 | } |
| 55060 | 55166 | rc = getAndInitPage(pBt, newPgno, &pNewPage, |
| 55061 | | - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 55167 | + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); |
| 55062 | 55168 | if( rc ) return rc; |
| 55063 | 55169 | pCur->apPage[i+1] = pNewPage; |
| 55064 | 55170 | pCur->aiIdx[i+1] = 0; |
| 55065 | 55171 | pCur->iPage++; |
| 55066 | 55172 | |
| 55067 | 55173 | pCur->info.nSize = 0; |
| 55068 | | - pCur->validNKey = 0; |
| 55174 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55069 | 55175 | if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ |
| 55070 | 55176 | return SQLITE_CORRUPT_BKPT; |
| 55071 | 55177 | } |
| 55072 | 55178 | return SQLITE_OK; |
| 55073 | 55179 | } |
| | @@ -55121,11 +55227,11 @@ |
| 55121 | 55227 | testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); |
| 55122 | 55228 | |
| 55123 | 55229 | releasePage(pCur->apPage[pCur->iPage]); |
| 55124 | 55230 | pCur->iPage--; |
| 55125 | 55231 | pCur->info.nSize = 0; |
| 55126 | | - pCur->validNKey = 0; |
| 55232 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55127 | 55233 | } |
| 55128 | 55234 | |
| 55129 | 55235 | /* |
| 55130 | 55236 | ** Move the cursor to point to the root page of its b-tree structure. |
| 55131 | 55237 | ** |
| | @@ -55168,11 +55274,11 @@ |
| 55168 | 55274 | }else if( pCur->pgnoRoot==0 ){ |
| 55169 | 55275 | pCur->eState = CURSOR_INVALID; |
| 55170 | 55276 | return SQLITE_OK; |
| 55171 | 55277 | }else{ |
| 55172 | 55278 | rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], |
| 55173 | | - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 55279 | + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); |
| 55174 | 55280 | if( rc!=SQLITE_OK ){ |
| 55175 | 55281 | pCur->eState = CURSOR_INVALID; |
| 55176 | 55282 | return rc; |
| 55177 | 55283 | } |
| 55178 | 55284 | pCur->iPage = 0; |
| | @@ -55195,12 +55301,11 @@ |
| 55195 | 55301 | return SQLITE_CORRUPT_BKPT; |
| 55196 | 55302 | } |
| 55197 | 55303 | |
| 55198 | 55304 | pCur->aiIdx[0] = 0; |
| 55199 | 55305 | pCur->info.nSize = 0; |
| 55200 | | - pCur->atLast = 0; |
| 55201 | | - pCur->validNKey = 0; |
| 55306 | + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55202 | 55307 | |
| 55203 | 55308 | if( pRoot->nCell>0 ){ |
| 55204 | 55309 | pCur->eState = CURSOR_VALID; |
| 55205 | 55310 | }else if( !pRoot->leaf ){ |
| 55206 | 55311 | Pgno subpage; |
| | @@ -55259,11 +55364,11 @@ |
| 55259 | 55364 | rc = moveToChild(pCur, pgno); |
| 55260 | 55365 | } |
| 55261 | 55366 | if( rc==SQLITE_OK ){ |
| 55262 | 55367 | pCur->aiIdx[pCur->iPage] = pPage->nCell-1; |
| 55263 | 55368 | pCur->info.nSize = 0; |
| 55264 | | - pCur->validNKey = 0; |
| 55369 | + pCur->curFlags &= ~BTCF_ValidNKey; |
| 55265 | 55370 | } |
| 55266 | 55371 | return rc; |
| 55267 | 55372 | } |
| 55268 | 55373 | |
| 55269 | 55374 | /* Move the cursor to the first entry in the table. Return SQLITE_OK |
| | @@ -55298,11 +55403,11 @@ |
| 55298 | 55403 | |
| 55299 | 55404 | assert( cursorHoldsMutex(pCur) ); |
| 55300 | 55405 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 55301 | 55406 | |
| 55302 | 55407 | /* If the cursor already points to the last entry, this is a no-op. */ |
| 55303 | | - if( CURSOR_VALID==pCur->eState && pCur->atLast ){ |
| 55408 | + if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ |
| 55304 | 55409 | #ifdef SQLITE_DEBUG |
| 55305 | 55410 | /* This block serves to assert() that the cursor really does point |
| 55306 | 55411 | ** to the last entry in the b-tree. */ |
| 55307 | 55412 | int ii; |
| 55308 | 55413 | for(ii=0; ii<pCur->iPage; ii++){ |
| | @@ -55321,11 +55426,16 @@ |
| 55321 | 55426 | *pRes = 1; |
| 55322 | 55427 | }else{ |
| 55323 | 55428 | assert( pCur->eState==CURSOR_VALID ); |
| 55324 | 55429 | *pRes = 0; |
| 55325 | 55430 | rc = moveToRightmost(pCur); |
| 55326 | | - pCur->atLast = rc==SQLITE_OK ?1:0; |
| 55431 | + if( rc==SQLITE_OK ){ |
| 55432 | + pCur->curFlags |= BTCF_AtLast; |
| 55433 | + }else{ |
| 55434 | + pCur->curFlags &= ~BTCF_AtLast; |
| 55435 | + } |
| 55436 | + |
| 55327 | 55437 | } |
| 55328 | 55438 | } |
| 55329 | 55439 | return rc; |
| 55330 | 55440 | } |
| 55331 | 55441 | |
| | @@ -55372,25 +55482,26 @@ |
| 55372 | 55482 | assert( pRes ); |
| 55373 | 55483 | assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); |
| 55374 | 55484 | |
| 55375 | 55485 | /* If the cursor is already positioned at the point we are trying |
| 55376 | 55486 | ** to move to, then just return without doing any work */ |
| 55377 | | - if( pCur->eState==CURSOR_VALID && pCur->validNKey |
| 55487 | + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 |
| 55378 | 55488 | && pCur->apPage[0]->intKey |
| 55379 | 55489 | ){ |
| 55380 | 55490 | if( pCur->info.nKey==intKey ){ |
| 55381 | 55491 | *pRes = 0; |
| 55382 | 55492 | return SQLITE_OK; |
| 55383 | 55493 | } |
| 55384 | | - if( pCur->atLast && pCur->info.nKey<intKey ){ |
| 55494 | + if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){ |
| 55385 | 55495 | *pRes = -1; |
| 55386 | 55496 | return SQLITE_OK; |
| 55387 | 55497 | } |
| 55388 | 55498 | } |
| 55389 | 55499 | |
| 55390 | 55500 | if( pIdxKey ){ |
| 55391 | 55501 | xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); |
| 55502 | + pIdxKey->isCorrupt = 0; |
| 55392 | 55503 | assert( pIdxKey->default_rc==1 |
| 55393 | 55504 | || pIdxKey->default_rc==0 |
| 55394 | 55505 | || pIdxKey->default_rc==-1 |
| 55395 | 55506 | ); |
| 55396 | 55507 | }else{ |
| | @@ -55445,11 +55556,11 @@ |
| 55445 | 55556 | }else if( nCellKey>intKey ){ |
| 55446 | 55557 | upr = idx-1; |
| 55447 | 55558 | if( lwr>upr ){ c = +1; break; } |
| 55448 | 55559 | }else{ |
| 55449 | 55560 | assert( nCellKey==intKey ); |
| 55450 | | - pCur->validNKey = 1; |
| 55561 | + pCur->curFlags |= BTCF_ValidNKey; |
| 55451 | 55562 | pCur->info.nKey = nCellKey; |
| 55452 | 55563 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55453 | 55564 | if( !pPage->leaf ){ |
| 55454 | 55565 | lwr = idx; |
| 55455 | 55566 | goto moveto_next_layer; |
| | @@ -55502,27 +55613,29 @@ |
| 55502 | 55613 | if( pCellKey==0 ){ |
| 55503 | 55614 | rc = SQLITE_NOMEM; |
| 55504 | 55615 | goto moveto_finish; |
| 55505 | 55616 | } |
| 55506 | 55617 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55507 | | - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); |
| 55618 | + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); |
| 55508 | 55619 | if( rc ){ |
| 55509 | 55620 | sqlite3_free(pCellKey); |
| 55510 | 55621 | goto moveto_finish; |
| 55511 | 55622 | } |
| 55512 | 55623 | c = xRecordCompare(nCell, pCellKey, pIdxKey, 0); |
| 55513 | 55624 | sqlite3_free(pCellKey); |
| 55514 | 55625 | } |
| 55626 | + assert( pIdxKey->isCorrupt==0 || c==0 ); |
| 55515 | 55627 | if( c<0 ){ |
| 55516 | 55628 | lwr = idx+1; |
| 55517 | 55629 | }else if( c>0 ){ |
| 55518 | 55630 | upr = idx-1; |
| 55519 | 55631 | }else{ |
| 55520 | 55632 | assert( c==0 ); |
| 55521 | 55633 | *pRes = 0; |
| 55522 | 55634 | rc = SQLITE_OK; |
| 55523 | 55635 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55636 | + if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT; |
| 55524 | 55637 | goto moveto_finish; |
| 55525 | 55638 | } |
| 55526 | 55639 | if( lwr>upr ) break; |
| 55527 | 55640 | assert( lwr+upr>=0 ); |
| 55528 | 55641 | idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ |
| | @@ -55547,11 +55660,11 @@ |
| 55547 | 55660 | rc = moveToChild(pCur, chldPg); |
| 55548 | 55661 | if( rc ) break; |
| 55549 | 55662 | } |
| 55550 | 55663 | moveto_finish: |
| 55551 | 55664 | pCur->info.nSize = 0; |
| 55552 | | - pCur->validNKey = 0; |
| 55665 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55553 | 55666 | return rc; |
| 55554 | 55667 | } |
| 55555 | 55668 | |
| 55556 | 55669 | |
| 55557 | 55670 | /* |
| | @@ -55592,10 +55705,11 @@ |
| 55592 | 55705 | assert( cursorHoldsMutex(pCur) ); |
| 55593 | 55706 | assert( pRes!=0 ); |
| 55594 | 55707 | assert( *pRes==0 || *pRes==1 ); |
| 55595 | 55708 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 55596 | 55709 | if( pCur->eState!=CURSOR_VALID ){ |
| 55710 | + invalidateOverflowCache(pCur); |
| 55597 | 55711 | rc = restoreCursorPosition(pCur); |
| 55598 | 55712 | if( rc!=SQLITE_OK ){ |
| 55599 | 55713 | *pRes = 0; |
| 55600 | 55714 | return rc; |
| 55601 | 55715 | } |
| | @@ -55625,11 +55739,11 @@ |
| 55625 | 55739 | ** only happen if the database is corrupt in such a way as to link the |
| 55626 | 55740 | ** page into more than one b-tree structure. */ |
| 55627 | 55741 | testcase( idx>pPage->nCell ); |
| 55628 | 55742 | |
| 55629 | 55743 | pCur->info.nSize = 0; |
| 55630 | | - pCur->validNKey = 0; |
| 55744 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55631 | 55745 | if( idx>=pPage->nCell ){ |
| 55632 | 55746 | if( !pPage->leaf ){ |
| 55633 | 55747 | rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); |
| 55634 | 55748 | if( rc ){ |
| 55635 | 55749 | *pRes = 0; |
| | @@ -55686,11 +55800,11 @@ |
| 55686 | 55800 | |
| 55687 | 55801 | assert( cursorHoldsMutex(pCur) ); |
| 55688 | 55802 | assert( pRes!=0 ); |
| 55689 | 55803 | assert( *pRes==0 || *pRes==1 ); |
| 55690 | 55804 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 55691 | | - pCur->atLast = 0; |
| 55805 | + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl); |
| 55692 | 55806 | if( pCur->eState!=CURSOR_VALID ){ |
| 55693 | 55807 | if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ |
| 55694 | 55808 | rc = btreeRestoreCursorPosition(pCur); |
| 55695 | 55809 | if( rc!=SQLITE_OK ){ |
| 55696 | 55810 | *pRes = 0; |
| | @@ -55731,11 +55845,11 @@ |
| 55731 | 55845 | return SQLITE_OK; |
| 55732 | 55846 | } |
| 55733 | 55847 | moveToParent(pCur); |
| 55734 | 55848 | } |
| 55735 | 55849 | pCur->info.nSize = 0; |
| 55736 | | - pCur->validNKey = 0; |
| 55850 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55737 | 55851 | |
| 55738 | 55852 | pCur->aiIdx[pCur->iPage]--; |
| 55739 | 55853 | pPage = pCur->apPage[pCur->iPage]; |
| 55740 | 55854 | if( pPage->intKey && !pPage->leaf ){ |
| 55741 | 55855 | rc = sqlite3BtreePrevious(pCur, pRes); |
| | @@ -57756,11 +57870,11 @@ |
| 57756 | 57870 | assert( pCur->skipNext!=SQLITE_OK ); |
| 57757 | 57871 | return pCur->skipNext; |
| 57758 | 57872 | } |
| 57759 | 57873 | |
| 57760 | 57874 | assert( cursorHoldsMutex(pCur) ); |
| 57761 | | - assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE |
| 57875 | + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE |
| 57762 | 57876 | && (pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 57763 | 57877 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); |
| 57764 | 57878 | |
| 57765 | 57879 | /* Assert that the caller has been consistent. If this cursor was opened |
| 57766 | 57880 | ** expecting an index b-tree, then the caller should be inserting blob |
| | @@ -57789,11 +57903,11 @@ |
| 57789 | 57903 | invalidateIncrblobCursors(p, nKey, 0); |
| 57790 | 57904 | |
| 57791 | 57905 | /* If the cursor is currently on the last row and we are appending a |
| 57792 | 57906 | ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto() |
| 57793 | 57907 | ** call */ |
| 57794 | | - if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){ |
| 57908 | + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){ |
| 57795 | 57909 | loc = -1; |
| 57796 | 57910 | } |
| 57797 | 57911 | } |
| 57798 | 57912 | |
| 57799 | 57913 | if( !loc ){ |
| | @@ -57842,11 +57956,11 @@ |
| 57842 | 57956 | insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); |
| 57843 | 57957 | assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); |
| 57844 | 57958 | |
| 57845 | 57959 | /* If no error has occurred and pPage has an overflow cell, call balance() |
| 57846 | 57960 | ** to redistribute the cells within the tree. Since balance() may move |
| 57847 | | - ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey |
| 57961 | + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey |
| 57848 | 57962 | ** variables. |
| 57849 | 57963 | ** |
| 57850 | 57964 | ** Previous versions of SQLite called moveToRoot() to move the cursor |
| 57851 | 57965 | ** back to the root page as balance() used to invalidate the contents |
| 57852 | 57966 | ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, |
| | @@ -57862,11 +57976,11 @@ |
| 57862 | 57976 | ** larger than the largest existing key, it is possible to insert the |
| 57863 | 57977 | ** row without seeking the cursor. This can be a big performance boost. |
| 57864 | 57978 | */ |
| 57865 | 57979 | pCur->info.nSize = 0; |
| 57866 | 57980 | if( rc==SQLITE_OK && pPage->nOverflow ){ |
| 57867 | | - pCur->validNKey = 0; |
| 57981 | + pCur->curFlags &= ~(BTCF_ValidNKey); |
| 57868 | 57982 | rc = balance(pCur); |
| 57869 | 57983 | |
| 57870 | 57984 | /* Must make sure nOverflow is reset to zero even if the balance() |
| 57871 | 57985 | ** fails. Internal data structure corruption will result otherwise. |
| 57872 | 57986 | ** Also, set the cursor state to invalid. This stops saveCursorPosition() |
| | @@ -57894,11 +58008,11 @@ |
| 57894 | 58008 | int iCellDepth; /* Depth of node containing pCell */ |
| 57895 | 58009 | |
| 57896 | 58010 | assert( cursorHoldsMutex(pCur) ); |
| 57897 | 58011 | assert( pBt->inTransaction==TRANS_WRITE ); |
| 57898 | 58012 | assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 57899 | | - assert( pCur->wrFlag ); |
| 58013 | + assert( pCur->curFlags & BTCF_WriteFlag ); |
| 57900 | 58014 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); |
| 57901 | 58015 | assert( !hasReadConflicts(p, pCur->pgnoRoot) ); |
| 57902 | 58016 | |
| 57903 | 58017 | if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) |
| 57904 | 58018 | || NEVER(pCur->eState!=CURSOR_VALID) |
| | @@ -58238,10 +58352,19 @@ |
| 58238 | 58352 | rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); |
| 58239 | 58353 | } |
| 58240 | 58354 | sqlite3BtreeLeave(p); |
| 58241 | 58355 | return rc; |
| 58242 | 58356 | } |
| 58357 | + |
| 58358 | +/* |
| 58359 | +** Delete all information from the single table that pCur is open on. |
| 58360 | +** |
| 58361 | +** This routine only work for pCur on an ephemeral table. |
| 58362 | +*/ |
| 58363 | +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ |
| 58364 | + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); |
| 58365 | +} |
| 58243 | 58366 | |
| 58244 | 58367 | /* |
| 58245 | 58368 | ** Erase all information in a table and add the root of the table to |
| 58246 | 58369 | ** the freelist. Except, the root of the principle table (the one on |
| 58247 | 58370 | ** page 1) is never added to the freelist. |
| | @@ -59198,11 +59321,11 @@ |
| 59198 | 59321 | */ |
| 59199 | 59322 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ |
| 59200 | 59323 | int rc; |
| 59201 | 59324 | assert( cursorHoldsMutex(pCsr) ); |
| 59202 | 59325 | assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); |
| 59203 | | - assert( pCsr->isIncrblobHandle ); |
| 59326 | + assert( pCsr->curFlags & BTCF_Incrblob ); |
| 59204 | 59327 | |
| 59205 | 59328 | rc = restoreCursorPosition(pCsr); |
| 59206 | 59329 | if( rc!=SQLITE_OK ){ |
| 59207 | 59330 | return rc; |
| 59208 | 59331 | } |
| | @@ -59227,11 +59350,11 @@ |
| 59227 | 59350 | ** (b) there is a read/write transaction open, |
| 59228 | 59351 | ** (c) the connection holds a write-lock on the table (if required), |
| 59229 | 59352 | ** (d) there are no conflicting read-locks, and |
| 59230 | 59353 | ** (e) the cursor points at a valid row of an intKey table. |
| 59231 | 59354 | */ |
| 59232 | | - if( !pCsr->wrFlag ){ |
| 59355 | + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ |
| 59233 | 59356 | return SQLITE_READONLY; |
| 59234 | 59357 | } |
| 59235 | 59358 | assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 |
| 59236 | 59359 | && pCsr->pBt->inTransaction==TRANS_WRITE ); |
| 59237 | 59360 | assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); |
| | @@ -59240,24 +59363,14 @@ |
| 59240 | 59363 | |
| 59241 | 59364 | return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); |
| 59242 | 59365 | } |
| 59243 | 59366 | |
| 59244 | 59367 | /* |
| 59245 | | -** Set a flag on this cursor to cache the locations of pages from the |
| 59246 | | -** overflow list for the current row. This is used by cursors opened |
| 59247 | | -** for incremental blob IO only. |
| 59248 | | -** |
| 59249 | | -** This function sets a flag only. The actual page location cache |
| 59250 | | -** (stored in BtCursor.aOverflow[]) is allocated and used by function |
| 59251 | | -** accessPayload() (the worker function for sqlite3BtreeData() and |
| 59252 | | -** sqlite3BtreePutData()). |
| 59368 | +** Mark this cursor as an incremental blob cursor. |
| 59253 | 59369 | */ |
| 59254 | | -SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ |
| 59255 | | - assert( cursorHoldsMutex(pCur) ); |
| 59256 | | - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 59257 | | - invalidateOverflowCache(pCur); |
| 59258 | | - pCur->isIncrblobHandle = 1; |
| 59370 | +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ |
| 59371 | + pCur->curFlags |= BTCF_Incrblob; |
| 59259 | 59372 | } |
| 59260 | 59373 | #endif |
| 59261 | 59374 | |
| 59262 | 59375 | /* |
| 59263 | 59376 | ** Set both the "read version" (single byte at byte offset 18) and |
| | @@ -61624,11 +61737,11 @@ |
| 61624 | 61737 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ |
| 61625 | 61738 | Parse *p = v->pParse; |
| 61626 | 61739 | int j = -1-x; |
| 61627 | 61740 | assert( v->magic==VDBE_MAGIC_INIT ); |
| 61628 | 61741 | assert( j<p->nLabel ); |
| 61629 | | - if( j>=0 && p->aLabel ){ |
| 61742 | + if( ALWAYS(j>=0) && p->aLabel ){ |
| 61630 | 61743 | p->aLabel[j] = v->nOp; |
| 61631 | 61744 | } |
| 61632 | 61745 | p->iFixedOp = v->nOp - 1; |
| 61633 | 61746 | } |
| 61634 | 61747 | |
| | @@ -62131,11 +62244,13 @@ |
| 62131 | 62244 | assert( addr<p->nOp ); |
| 62132 | 62245 | if( addr<0 ){ |
| 62133 | 62246 | addr = p->nOp - 1; |
| 62134 | 62247 | } |
| 62135 | 62248 | pOp = &p->aOp[addr]; |
| 62136 | | - assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 ); |
| 62249 | + assert( pOp->p4type==P4_NOTUSED |
| 62250 | + || pOp->p4type==P4_INT32 |
| 62251 | + || pOp->p4type==P4_KEYINFO ); |
| 62137 | 62252 | freeP4(db, pOp->p4type, pOp->p4.p); |
| 62138 | 62253 | pOp->p4.p = 0; |
| 62139 | 62254 | if( n==P4_INT32 ){ |
| 62140 | 62255 | /* Note: this cast is safe, because the origin data point was an int |
| 62141 | 62256 | ** that was cast to a (const char *). */ |
| | @@ -64081,11 +64196,11 @@ |
| 64081 | 64196 | int hasMoved; |
| 64082 | 64197 | int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); |
| 64083 | 64198 | if( rc ) return rc; |
| 64084 | 64199 | if( hasMoved ){ |
| 64085 | 64200 | p->cacheStatus = CACHE_STALE; |
| 64086 | | - p->nullRow = 1; |
| 64201 | + if( hasMoved==2 ) p->nullRow = 1; |
| 64087 | 64202 | } |
| 64088 | 64203 | } |
| 64089 | 64204 | return SQLITE_OK; |
| 64090 | 64205 | } |
| 64091 | 64206 | |
| | @@ -64751,14 +64866,17 @@ |
| 64751 | 64866 | ** determined that the first fields of the keys are equal. |
| 64752 | 64867 | ** |
| 64753 | 64868 | ** Key1 and Key2 do not have to contain the same number of fields. If all |
| 64754 | 64869 | ** fields that appear in both keys are equal, then pPKey2->default_rc is |
| 64755 | 64870 | ** returned. |
| 64871 | +** |
| 64872 | +** If database corruption is discovered, set pPKey2->isCorrupt to non-zero |
| 64873 | +** and return 0. |
| 64756 | 64874 | */ |
| 64757 | 64875 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare( |
| 64758 | 64876 | int nKey1, const void *pKey1, /* Left key */ |
| 64759 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 64877 | + UnpackedRecord *pPKey2, /* Right key */ |
| 64760 | 64878 | int bSkip /* If true, skip the first field */ |
| 64761 | 64879 | ){ |
| 64762 | 64880 | u32 d1; /* Offset into aKey[] of next data element */ |
| 64763 | 64881 | int i; /* Index of next field to compare */ |
| 64764 | 64882 | u32 szHdr1; /* Size of record header in bytes */ |
| | @@ -64780,10 +64898,14 @@ |
| 64780 | 64898 | i = 1; |
| 64781 | 64899 | pRhs++; |
| 64782 | 64900 | }else{ |
| 64783 | 64901 | idx1 = getVarint32(aKey1, szHdr1); |
| 64784 | 64902 | d1 = szHdr1; |
| 64903 | + if( d1>(unsigned)nKey1 ){ |
| 64904 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 64905 | + return 0; /* Corruption */ |
| 64906 | + } |
| 64785 | 64907 | i = 0; |
| 64786 | 64908 | } |
| 64787 | 64909 | |
| 64788 | 64910 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64789 | 64911 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| | @@ -64856,11 +64978,12 @@ |
| 64856 | 64978 | }else{ |
| 64857 | 64979 | mem1.n = (serial_type - 12) / 2; |
| 64858 | 64980 | testcase( (d1+mem1.n)==(unsigned)nKey1 ); |
| 64859 | 64981 | testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); |
| 64860 | 64982 | if( (d1+mem1.n) > (unsigned)nKey1 ){ |
| 64861 | | - rc = 1; /* Corruption */ |
| 64983 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 64984 | + return 0; /* Corruption */ |
| 64862 | 64985 | }else if( pKeyInfo->aColl[i] ){ |
| 64863 | 64986 | mem1.enc = pKeyInfo->enc; |
| 64864 | 64987 | mem1.db = pKeyInfo->db; |
| 64865 | 64988 | mem1.flags = MEM_Str; |
| 64866 | 64989 | mem1.z = (char*)&aKey1[d1]; |
| | @@ -64882,11 +65005,12 @@ |
| 64882 | 65005 | }else{ |
| 64883 | 65006 | int nStr = (serial_type - 12) / 2; |
| 64884 | 65007 | testcase( (d1+nStr)==(unsigned)nKey1 ); |
| 64885 | 65008 | testcase( (d1+nStr+1)==(unsigned)nKey1 ); |
| 64886 | 65009 | if( (d1+nStr) > (unsigned)nKey1 ){ |
| 64887 | | - rc = 1; /* Corruption */ |
| 65010 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 65011 | + return 0; /* Corruption */ |
| 64888 | 65012 | }else{ |
| 64889 | 65013 | int nCmp = MIN(nStr, pRhs->n); |
| 64890 | 65014 | rc = memcmp(&aKey1[d1], pRhs->z, nCmp); |
| 64891 | 65015 | if( rc==0 ) rc = nStr - pRhs->n; |
| 64892 | 65016 | } |
| | @@ -64935,14 +65059,17 @@ |
| 64935 | 65059 | /* |
| 64936 | 65060 | ** This function is an optimized version of sqlite3VdbeRecordCompare() |
| 64937 | 65061 | ** that (a) the first field of pPKey2 is an integer, and (b) the |
| 64938 | 65062 | ** size-of-header varint at the start of (pKey1/nKey1) fits in a single |
| 64939 | 65063 | ** byte (i.e. is less than 128). |
| 65064 | +** |
| 65065 | +** To avoid concerns about buffer overreads, this routine is only used |
| 65066 | +** on schemas where the maximum valid header size is 63 bytes or less. |
| 64940 | 65067 | */ |
| 64941 | 65068 | static int vdbeRecordCompareInt( |
| 64942 | 65069 | int nKey1, const void *pKey1, /* Left key */ |
| 64943 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 65070 | + UnpackedRecord *pPKey2, /* Right key */ |
| 64944 | 65071 | int bSkip /* Ignored */ |
| 64945 | 65072 | ){ |
| 64946 | 65073 | const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; |
| 64947 | 65074 | int serial_type = ((const u8*)pKey1)[1]; |
| 64948 | 65075 | int res; |
| | @@ -64951,10 +65078,11 @@ |
| 64951 | 65078 | i64 v = pPKey2->aMem[0].u.i; |
| 64952 | 65079 | i64 lhs; |
| 64953 | 65080 | UNUSED_PARAMETER(bSkip); |
| 64954 | 65081 | |
| 64955 | 65082 | assert( bSkip==0 ); |
| 65083 | + assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); |
| 64956 | 65084 | switch( serial_type ){ |
| 64957 | 65085 | case 1: { /* 1-byte signed integer */ |
| 64958 | 65086 | lhs = ONE_BYTE_INT(aKey); |
| 64959 | 65087 | testcase( lhs<0 ); |
| 64960 | 65088 | break; |
| | @@ -65035,11 +65163,11 @@ |
| 65035 | 65163 | ** uses the collation sequence BINARY and (c) that the size-of-header varint |
| 65036 | 65164 | ** at the start of (pKey1/nKey1) fits in a single byte. |
| 65037 | 65165 | */ |
| 65038 | 65166 | static int vdbeRecordCompareString( |
| 65039 | 65167 | int nKey1, const void *pKey1, /* Left key */ |
| 65040 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 65168 | + UnpackedRecord *pPKey2, /* Right key */ |
| 65041 | 65169 | int bSkip |
| 65042 | 65170 | ){ |
| 65043 | 65171 | const u8 *aKey1 = (const u8*)pKey1; |
| 65044 | 65172 | int serial_type; |
| 65045 | 65173 | int res; |
| | @@ -65056,11 +65184,14 @@ |
| 65056 | 65184 | int nCmp; |
| 65057 | 65185 | int nStr; |
| 65058 | 65186 | int szHdr = aKey1[0]; |
| 65059 | 65187 | |
| 65060 | 65188 | nStr = (serial_type-12) / 2; |
| 65061 | | - if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */ |
| 65189 | + if( (szHdr + nStr) > nKey1 ){ |
| 65190 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 65191 | + return 0; /* Corruption */ |
| 65192 | + } |
| 65062 | 65193 | nCmp = MIN( pPKey2->aMem[0].n, nStr ); |
| 65063 | 65194 | res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); |
| 65064 | 65195 | |
| 65065 | 65196 | if( res==0 ){ |
| 65066 | 65197 | res = nStr - pPKey2->aMem[0].n; |
| | @@ -65221,11 +65352,11 @@ |
| 65221 | 65352 | ** is ignored as well. Hence, this routine only compares the prefixes |
| 65222 | 65353 | ** of the keys prior to the final rowid, not the entire key. |
| 65223 | 65354 | */ |
| 65224 | 65355 | SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( |
| 65225 | 65356 | VdbeCursor *pC, /* The cursor to compare against */ |
| 65226 | | - const UnpackedRecord *pUnpacked, /* Unpacked version of key */ |
| 65357 | + UnpackedRecord *pUnpacked, /* Unpacked version of key */ |
| 65227 | 65358 | int *res /* Write the comparison result here */ |
| 65228 | 65359 | ){ |
| 65229 | 65360 | i64 nCellKey = 0; |
| 65230 | 65361 | int rc; |
| 65231 | 65362 | BtCursor *pCur = pC->pCursor; |
| | @@ -67311,10 +67442,33 @@ |
| 67311 | 67442 | u8 affinity, |
| 67312 | 67443 | u8 enc |
| 67313 | 67444 | ){ |
| 67314 | 67445 | applyAffinity((Mem *)pVal, affinity, enc); |
| 67315 | 67446 | } |
| 67447 | + |
| 67448 | +/* |
| 67449 | +** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or |
| 67450 | +** none. |
| 67451 | +** |
| 67452 | +** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. |
| 67453 | +** But it does set pMem->r and pMem->u.i appropriately. |
| 67454 | +*/ |
| 67455 | +static u16 numericType(Mem *pMem){ |
| 67456 | + if( pMem->flags & (MEM_Int|MEM_Real) ){ |
| 67457 | + return pMem->flags & (MEM_Int|MEM_Real); |
| 67458 | + } |
| 67459 | + if( pMem->flags & (MEM_Str|MEM_Blob) ){ |
| 67460 | + if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){ |
| 67461 | + return 0; |
| 67462 | + } |
| 67463 | + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ |
| 67464 | + return MEM_Int; |
| 67465 | + } |
| 67466 | + return MEM_Real; |
| 67467 | + } |
| 67468 | + return 0; |
| 67469 | +} |
| 67316 | 67470 | |
| 67317 | 67471 | #ifdef SQLITE_DEBUG |
| 67318 | 67472 | /* |
| 67319 | 67473 | ** Write a nice string representation of the contents of cell pMem |
| 67320 | 67474 | ** into buffer zBuf, length nBuf. |
| | @@ -68171,14 +68325,15 @@ |
| 68171 | 68325 | } |
| 68172 | 68326 | |
| 68173 | 68327 | /* Opcode: Move P1 P2 P3 * * |
| 68174 | 68328 | ** Synopsis: r[P2@P3]=r[P1@P3] |
| 68175 | 68329 | ** |
| 68176 | | -** Move the values in register P1..P1+P3 over into |
| 68177 | | -** registers P2..P2+P3. Registers P1..P1+P3 are |
| 68330 | +** Move the P3 values in register P1..P1+P3-1 over into |
| 68331 | +** registers P2..P2+P3-1. Registers P1..P1+P3-1 are |
| 68178 | 68332 | ** left holding a NULL. It is an error for register ranges |
| 68179 | | -** P1..P1+P3 and P2..P2+P3 to overlap. |
| 68333 | +** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error |
| 68334 | +** for P3 to be less than 1. |
| 68180 | 68335 | */ |
| 68181 | 68336 | case OP_Move: { |
| 68182 | 68337 | char *zMalloc; /* Holding variable for allocated memory */ |
| 68183 | 68338 | int n; /* Number of registers left to copy */ |
| 68184 | 68339 | int p1; /* Register to copy from */ |
| | @@ -68185,11 +68340,11 @@ |
| 68185 | 68340 | int p2; /* Register to copy to */ |
| 68186 | 68341 | |
| 68187 | 68342 | n = pOp->p3; |
| 68188 | 68343 | p1 = pOp->p1; |
| 68189 | 68344 | p2 = pOp->p2; |
| 68190 | | - assert( n>=0 && p1>0 && p2>0 ); |
| 68345 | + assert( n>0 && p1>0 && p2>0 ); |
| 68191 | 68346 | assert( p1+n<=p2 || p2+n<=p1 ); |
| 68192 | 68347 | |
| 68193 | 68348 | pIn1 = &aMem[p1]; |
| 68194 | 68349 | pOut = &aMem[p2]; |
| 68195 | 68350 | do{ |
| | @@ -68209,11 +68364,11 @@ |
| 68209 | 68364 | pIn1->xDel = 0; |
| 68210 | 68365 | pIn1->zMalloc = zMalloc; |
| 68211 | 68366 | REGISTER_TRACE(p2++, pOut); |
| 68212 | 68367 | pIn1++; |
| 68213 | 68368 | pOut++; |
| 68214 | | - }while( n-- ); |
| 68369 | + }while( --n ); |
| 68215 | 68370 | break; |
| 68216 | 68371 | } |
| 68217 | 68372 | |
| 68218 | 68373 | /* Opcode: Copy P1 P2 P3 * * |
| 68219 | 68374 | ** Synopsis: r[P2@P3+1]=r[P1@P3+1] |
| | @@ -68441,24 +68596,26 @@ |
| 68441 | 68596 | case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ |
| 68442 | 68597 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ |
| 68443 | 68598 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ |
| 68444 | 68599 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
| 68445 | 68600 | char bIntint; /* Started out as two integer operands */ |
| 68446 | | - int flags; /* Combined MEM_* flags from both inputs */ |
| 68601 | + u16 flags; /* Combined MEM_* flags from both inputs */ |
| 68602 | + u16 type1; /* Numeric type of left operand */ |
| 68603 | + u16 type2; /* Numeric type of right operand */ |
| 68447 | 68604 | i64 iA; /* Integer value of left operand */ |
| 68448 | 68605 | i64 iB; /* Integer value of right operand */ |
| 68449 | 68606 | double rA; /* Real value of left operand */ |
| 68450 | 68607 | double rB; /* Real value of right operand */ |
| 68451 | 68608 | |
| 68452 | 68609 | pIn1 = &aMem[pOp->p1]; |
| 68453 | | - applyNumericAffinity(pIn1); |
| 68610 | + type1 = numericType(pIn1); |
| 68454 | 68611 | pIn2 = &aMem[pOp->p2]; |
| 68455 | | - applyNumericAffinity(pIn2); |
| 68612 | + type2 = numericType(pIn2); |
| 68456 | 68613 | pOut = &aMem[pOp->p3]; |
| 68457 | 68614 | flags = pIn1->flags | pIn2->flags; |
| 68458 | 68615 | if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 68459 | | - if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ |
| 68616 | + if( (type1 & type2 & MEM_Int)!=0 ){ |
| 68460 | 68617 | iA = pIn1->u.i; |
| 68461 | 68618 | iB = pIn2->u.i; |
| 68462 | 68619 | bIntint = 1; |
| 68463 | 68620 | switch( pOp->opcode ){ |
| 68464 | 68621 | case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; |
| | @@ -68510,11 +68667,11 @@ |
| 68510 | 68667 | if( sqlite3IsNaN(rB) ){ |
| 68511 | 68668 | goto arithmetic_result_is_null; |
| 68512 | 68669 | } |
| 68513 | 68670 | pOut->r = rB; |
| 68514 | 68671 | MemSetTypeFlag(pOut, MEM_Real); |
| 68515 | | - if( (flags & MEM_Real)==0 && !bIntint ){ |
| 68672 | + if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ |
| 68516 | 68673 | sqlite3VdbeIntegerAffinity(pOut); |
| 68517 | 68674 | } |
| 68518 | 68675 | #endif |
| 68519 | 68676 | } |
| 68520 | 68677 | break; |
| | @@ -69086,10 +69243,11 @@ |
| 69086 | 69243 | aPermute = pOp->p4.ai; |
| 69087 | 69244 | break; |
| 69088 | 69245 | } |
| 69089 | 69246 | |
| 69090 | 69247 | /* Opcode: Compare P1 P2 P3 P4 P5 |
| 69248 | +** Synopsis: r[P1@P3] <-> r[P2@P3] |
| 69091 | 69249 | ** |
| 69092 | 69250 | ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this |
| 69093 | 69251 | ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of |
| 69094 | 69252 | ** the comparison for use by the next OP_Jump instruct. |
| 69095 | 69253 | ** |
| | @@ -70421,10 +70579,11 @@ |
| 70421 | 70579 | assert( pOp->p1>=0 ); |
| 70422 | 70580 | assert( pOp->p2>=0 ); |
| 70423 | 70581 | pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 70424 | 70582 | if( pCx==0 ) goto no_mem; |
| 70425 | 70583 | pCx->nullRow = 1; |
| 70584 | + pCx->isEphemeral = 1; |
| 70426 | 70585 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, |
| 70427 | 70586 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| 70428 | 70587 | if( rc==SQLITE_OK ){ |
| 70429 | 70588 | rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); |
| 70430 | 70589 | } |
| | @@ -70911,11 +71070,11 @@ |
| 70911 | 71070 | pC->seekResult = res; |
| 70912 | 71071 | break; |
| 70913 | 71072 | } |
| 70914 | 71073 | |
| 70915 | 71074 | /* Opcode: Sequence P1 P2 * * * |
| 70916 | | -** Synopsis: r[P2]=rowid |
| 71075 | +** Synopsis: r[P2]=cursor[P1].ctr++ |
| 70917 | 71076 | ** |
| 70918 | 71077 | ** Find the next available sequence number for cursor P1. |
| 70919 | 71078 | ** Write the sequence number into register P2. |
| 70920 | 71079 | ** The sequence number on the cursor is incremented after this |
| 70921 | 71080 | ** instruction. |
| | @@ -71602,10 +71761,11 @@ |
| 71602 | 71761 | VdbeCursor *pC; |
| 71603 | 71762 | int res; |
| 71604 | 71763 | |
| 71605 | 71764 | pC = p->apCsr[pOp->p1]; |
| 71606 | 71765 | assert( isSorter(pC) ); |
| 71766 | + res = 0; |
| 71607 | 71767 | rc = sqlite3VdbeSorterNext(db, pC, &res); |
| 71608 | 71768 | goto next_tail; |
| 71609 | 71769 | case OP_PrevIfOpen: /* jump */ |
| 71610 | 71770 | case OP_NextIfOpen: /* jump */ |
| 71611 | 71771 | if( p->apCsr[pOp->p1]==0 ) break; |
| | @@ -71959,10 +72119,33 @@ |
| 71959 | 72119 | aMem[pOp->p3].u.i += nChange; |
| 71960 | 72120 | } |
| 71961 | 72121 | } |
| 71962 | 72122 | break; |
| 71963 | 72123 | } |
| 72124 | + |
| 72125 | +/* Opcode: ResetSorter P1 * * * * |
| 72126 | +** |
| 72127 | +** Delete all contents from the ephemeral table or sorter |
| 72128 | +** that is open on cursor P1. |
| 72129 | +** |
| 72130 | +** This opcode only works for cursors used for sorting and |
| 72131 | +** opened with OP_OpenEphemeral or OP_SorterOpen. |
| 72132 | +*/ |
| 72133 | +case OP_ResetSorter: { |
| 72134 | + VdbeCursor *pC; |
| 72135 | + |
| 72136 | + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 72137 | + pC = p->apCsr[pOp->p1]; |
| 72138 | + assert( pC!=0 ); |
| 72139 | + if( pC->pSorter ){ |
| 72140 | + sqlite3VdbeSorterReset(db, pC->pSorter); |
| 72141 | + }else{ |
| 72142 | + assert( pC->isEphemeral ); |
| 72143 | + rc = sqlite3BtreeClearTableOfCursor(pC->pCursor); |
| 72144 | + } |
| 72145 | + break; |
| 72146 | +} |
| 71964 | 72147 | |
| 71965 | 72148 | /* Opcode: CreateTable P1 P2 * * * |
| 71966 | 72149 | ** Synopsis: r[P2]=root iDb=P1 |
| 71967 | 72150 | ** |
| 71968 | 72151 | ** Allocate a new table in the main database file if P1==0 or in the |
| | @@ -72266,13 +72449,11 @@ |
| 72266 | 72449 | } |
| 72267 | 72450 | |
| 72268 | 72451 | assert( pOp->p4type==P4_INT32 ); |
| 72269 | 72452 | assert( iSet==-1 || iSet>=0 ); |
| 72270 | 72453 | if( iSet ){ |
| 72271 | | - exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 72272 | | - (u8)(iSet>=0 ? iSet & 0xf : 0xff), |
| 72273 | | - pIn3->u.i); |
| 72454 | + exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); |
| 72274 | 72455 | VdbeBranchTaken(exists!=0,2); |
| 72275 | 72456 | if( exists ){ |
| 72276 | 72457 | pc = pOp->p2 - 1; |
| 72277 | 72458 | break; |
| 72278 | 72459 | } |
| | @@ -72968,11 +73149,11 @@ |
| 72968 | 73149 | } |
| 72969 | 73150 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 72970 | 73151 | |
| 72971 | 73152 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 72972 | 73153 | /* Opcode: VFilter P1 P2 P3 P4 * |
| 72973 | | -** Synopsis: iPlan=r[P3] zPlan='P4' |
| 73154 | +** Synopsis: iplan=r[P3] zplan='P4' |
| 72974 | 73155 | ** |
| 72975 | 73156 | ** P1 is a cursor opened using VOpen. P2 is an address to jump to if |
| 72976 | 73157 | ** the filtered result set is empty. |
| 72977 | 73158 | ** |
| 72978 | 73159 | ** P4 is either NULL or a string that was generated by the xBestIndex |
| | @@ -73536,13 +73717,11 @@ |
| 73536 | 73717 | p->pStmt = 0; |
| 73537 | 73718 | }else{ |
| 73538 | 73719 | p->iOffset = pC->aType[p->iCol + pC->nField]; |
| 73539 | 73720 | p->nByte = sqlite3VdbeSerialTypeLen(type); |
| 73540 | 73721 | p->pCsr = pC->pCursor; |
| 73541 | | - sqlite3BtreeEnterCursor(p->pCsr); |
| 73542 | | - sqlite3BtreeCacheOverflow(p->pCsr); |
| 73543 | | - sqlite3BtreeLeaveCursor(p->pCsr); |
| 73722 | + sqlite3BtreeIncrblobCursor(p->pCsr); |
| 73544 | 73723 | } |
| 73545 | 73724 | } |
| 73546 | 73725 | |
| 73547 | 73726 | if( rc==SQLITE_ROW ){ |
| 73548 | 73727 | rc = SQLITE_OK; |
| | @@ -74431,28 +74610,45 @@ |
| 74431 | 74610 | for(p=pRecord; p; p=pNext){ |
| 74432 | 74611 | pNext = p->pNext; |
| 74433 | 74612 | sqlite3DbFree(db, p); |
| 74434 | 74613 | } |
| 74435 | 74614 | } |
| 74615 | + |
| 74616 | +/* |
| 74617 | +** Reset a sorting cursor back to its original empty state. |
| 74618 | +*/ |
| 74619 | +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ |
| 74620 | + if( pSorter->aIter ){ |
| 74621 | + int i; |
| 74622 | + for(i=0; i<pSorter->nTree; i++){ |
| 74623 | + vdbeSorterIterZero(db, &pSorter->aIter[i]); |
| 74624 | + } |
| 74625 | + sqlite3DbFree(db, pSorter->aIter); |
| 74626 | + pSorter->aIter = 0; |
| 74627 | + } |
| 74628 | + if( pSorter->pTemp1 ){ |
| 74629 | + sqlite3OsCloseFree(pSorter->pTemp1); |
| 74630 | + pSorter->pTemp1 = 0; |
| 74631 | + } |
| 74632 | + vdbeSorterRecordFree(db, pSorter->pRecord); |
| 74633 | + pSorter->pRecord = 0; |
| 74634 | + pSorter->iWriteOff = 0; |
| 74635 | + pSorter->iReadOff = 0; |
| 74636 | + pSorter->nInMemory = 0; |
| 74637 | + pSorter->nTree = 0; |
| 74638 | + pSorter->nPMA = 0; |
| 74639 | + pSorter->aTree = 0; |
| 74640 | +} |
| 74641 | + |
| 74436 | 74642 | |
| 74437 | 74643 | /* |
| 74438 | 74644 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 74439 | 74645 | */ |
| 74440 | 74646 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ |
| 74441 | 74647 | VdbeSorter *pSorter = pCsr->pSorter; |
| 74442 | 74648 | if( pSorter ){ |
| 74443 | | - if( pSorter->aIter ){ |
| 74444 | | - int i; |
| 74445 | | - for(i=0; i<pSorter->nTree; i++){ |
| 74446 | | - vdbeSorterIterZero(db, &pSorter->aIter[i]); |
| 74447 | | - } |
| 74448 | | - sqlite3DbFree(db, pSorter->aIter); |
| 74449 | | - } |
| 74450 | | - if( pSorter->pTemp1 ){ |
| 74451 | | - sqlite3OsCloseFree(pSorter->pTemp1); |
| 74452 | | - } |
| 74453 | | - vdbeSorterRecordFree(db, pSorter->pRecord); |
| 74649 | + sqlite3VdbeSorterReset(db, pSorter); |
| 74454 | 74650 | sqlite3DbFree(db, pSorter->pUnpacked); |
| 74455 | 74651 | sqlite3DbFree(db, pSorter); |
| 74456 | 74652 | pCsr->pSorter = 0; |
| 74457 | 74653 | } |
| 74458 | 74654 | } |
| | @@ -74884,18 +75080,59 @@ |
| 74884 | 75080 | VdbeSorter *pSorter = pCsr->pSorter; |
| 74885 | 75081 | int rc; /* Return code */ |
| 74886 | 75082 | |
| 74887 | 75083 | if( pSorter->aTree ){ |
| 74888 | 75084 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| 74889 | | - int i; /* Index of aTree[] to recalculate */ |
| 74890 | | - |
| 74891 | 75085 | rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 74892 | | - for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ |
| 74893 | | - rc = vdbeSorterDoCompare(pCsr, i); |
| 75086 | + if( rc==SQLITE_OK ){ |
| 75087 | + int i; /* Index of aTree[] to recalculate */ |
| 75088 | + VdbeSorterIter *pIter1; /* First iterator to compare */ |
| 75089 | + VdbeSorterIter *pIter2; /* Second iterator to compare */ |
| 75090 | + u8 *pKey2; /* To pIter2->aKey, or 0 if record cached */ |
| 75091 | + |
| 75092 | + /* Find the first two iterators to compare. The one that was just |
| 75093 | + ** advanced (iPrev) and the one next to it in the array. */ |
| 75094 | + pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)]; |
| 75095 | + pIter2 = &pSorter->aIter[(iPrev | 0x0001)]; |
| 75096 | + pKey2 = pIter2->aKey; |
| 75097 | + |
| 75098 | + for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){ |
| 75099 | + /* Compare pIter1 and pIter2. Store the result in variable iRes. */ |
| 75100 | + int iRes; |
| 75101 | + if( pIter1->pFile==0 ){ |
| 75102 | + iRes = +1; |
| 75103 | + }else if( pIter2->pFile==0 ){ |
| 75104 | + iRes = -1; |
| 75105 | + }else{ |
| 75106 | + vdbeSorterCompare(pCsr, 0, |
| 75107 | + pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes |
| 75108 | + ); |
| 75109 | + } |
| 75110 | + |
| 75111 | + /* If pIter1 contained the smaller value, set aTree[i] to its index. |
| 75112 | + ** Then set pIter2 to the next iterator to compare to pIter1. In this |
| 75113 | + ** case there is no cache of pIter2 in pSorter->pUnpacked, so set |
| 75114 | + ** pKey2 to point to the record belonging to pIter2. |
| 75115 | + ** |
| 75116 | + ** Alternatively, if pIter2 contains the smaller of the two values, |
| 75117 | + ** set aTree[i] to its index and update pIter1. If vdbeSorterCompare() |
| 75118 | + ** was actually called above, then pSorter->pUnpacked now contains |
| 75119 | + ** a value equivalent to pIter2. So set pKey2 to NULL to prevent |
| 75120 | + ** vdbeSorterCompare() from decoding pIter2 again. */ |
| 75121 | + if( iRes<=0 ){ |
| 75122 | + pSorter->aTree[i] = (int)(pIter1 - pSorter->aIter); |
| 75123 | + pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ]; |
| 75124 | + pKey2 = pIter2->aKey; |
| 75125 | + }else{ |
| 75126 | + if( pIter1->pFile ) pKey2 = 0; |
| 75127 | + pSorter->aTree[i] = (int)(pIter2 - pSorter->aIter); |
| 75128 | + pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ]; |
| 75129 | + } |
| 75130 | + |
| 75131 | + } |
| 75132 | + *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 74894 | 75133 | } |
| 74895 | | - |
| 74896 | | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 74897 | 75134 | }else{ |
| 74898 | 75135 | SorterRecord *pFree = pSorter->pRecord; |
| 74899 | 75136 | pSorter->pRecord = pFree->pNext; |
| 74900 | 75137 | pFree->pNext = 0; |
| 74901 | 75138 | vdbeSorterRecordFree(db, pFree); |
| | @@ -77127,10 +77364,11 @@ |
| 77127 | 77364 | ** SELECT * FROM t1 WHERE (select a from t1); |
| 77128 | 77365 | */ |
| 77129 | 77366 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ |
| 77130 | 77367 | int op; |
| 77131 | 77368 | pExpr = sqlite3ExprSkipCollate(pExpr); |
| 77369 | + if( pExpr->flags & EP_Generic ) return SQLITE_AFF_NONE; |
| 77132 | 77370 | op = pExpr->op; |
| 77133 | 77371 | if( op==TK_SELECT ){ |
| 77134 | 77372 | assert( pExpr->flags&EP_xIsSelect ); |
| 77135 | 77373 | return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); |
| 77136 | 77374 | } |
| | @@ -77159,11 +77397,15 @@ |
| 77159 | 77397 | ** implements the COLLATE operator. |
| 77160 | 77398 | ** |
| 77161 | 77399 | ** If a memory allocation error occurs, that fact is recorded in pParse->db |
| 77162 | 77400 | ** and the pExpr parameter is returned unchanged. |
| 77163 | 77401 | */ |
| 77164 | | -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){ |
| 77402 | +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( |
| 77403 | + Parse *pParse, /* Parsing context */ |
| 77404 | + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ |
| 77405 | + const Token *pCollName /* Name of collating sequence */ |
| 77406 | +){ |
| 77165 | 77407 | if( pCollName->n>0 ){ |
| 77166 | 77408 | Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); |
| 77167 | 77409 | if( pNew ){ |
| 77168 | 77410 | pNew->pLeft = pExpr; |
| 77169 | 77411 | pNew->flags |= EP_Collate|EP_Skip; |
| | @@ -77212,10 +77454,11 @@ |
| 77212 | 77454 | sqlite3 *db = pParse->db; |
| 77213 | 77455 | CollSeq *pColl = 0; |
| 77214 | 77456 | Expr *p = pExpr; |
| 77215 | 77457 | while( p ){ |
| 77216 | 77458 | int op = p->op; |
| 77459 | + if( p->flags & EP_Generic ) break; |
| 77217 | 77460 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 77218 | 77461 | p = p->pLeft; |
| 77219 | 77462 | continue; |
| 77220 | 77463 | } |
| 77221 | 77464 | if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ |
| | @@ -78043,11 +78286,10 @@ |
| 78043 | 78286 | struct ExprList_item *pItem, *pOldItem; |
| 78044 | 78287 | int i; |
| 78045 | 78288 | if( p==0 ) return 0; |
| 78046 | 78289 | pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); |
| 78047 | 78290 | if( pNew==0 ) return 0; |
| 78048 | | - pNew->iECursor = 0; |
| 78049 | 78291 | pNew->nExpr = i = p->nExpr; |
| 78050 | 78292 | if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){} |
| 78051 | 78293 | pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) ); |
| 78052 | 78294 | if( pItem==0 ){ |
| 78053 | 78295 | sqlite3DbFree(db, pNew); |
| | @@ -78156,11 +78398,10 @@ |
| 78156 | 78398 | pNew->iLimit = 0; |
| 78157 | 78399 | pNew->iOffset = 0; |
| 78158 | 78400 | pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; |
| 78159 | 78401 | pNew->addrOpenEphm[0] = -1; |
| 78160 | 78402 | pNew->addrOpenEphm[1] = -1; |
| 78161 | | - pNew->addrOpenEphm[2] = -1; |
| 78162 | 78403 | pNew->nSelectRow = p->nSelectRow; |
| 78163 | 78404 | pNew->pWith = withDup(db, p->pWith); |
| 78164 | 78405 | return pNew; |
| 78165 | 78406 | } |
| 78166 | 78407 | #else |
| | @@ -78724,11 +78965,10 @@ |
| 78724 | 78965 | eType = IN_INDEX_EPH; |
| 78725 | 78966 | if( prNotFound ){ |
| 78726 | 78967 | *prNotFound = rMayHaveNull = ++pParse->nMem; |
| 78727 | 78968 | sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); |
| 78728 | 78969 | }else{ |
| 78729 | | - testcase( pParse->nQueryLoop>0 ); |
| 78730 | 78970 | pParse->nQueryLoop = 0; |
| 78731 | 78971 | if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 78732 | 78972 | eType = IN_INDEX_ROWID; |
| 78733 | 78973 | } |
| 78734 | 78974 | } |
| | @@ -78974,11 +79214,11 @@ |
| 78974 | 79214 | } |
| 78975 | 79215 | |
| 78976 | 79216 | if( testAddr>=0 ){ |
| 78977 | 79217 | sqlite3VdbeJumpHere(v, testAddr); |
| 78978 | 79218 | } |
| 78979 | | - sqlite3ExprCachePop(pParse, 1); |
| 79219 | + sqlite3ExprCachePop(pParse); |
| 78980 | 79220 | |
| 78981 | 79221 | return rReg; |
| 78982 | 79222 | } |
| 78983 | 79223 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| 78984 | 79224 | |
| | @@ -79109,11 +79349,11 @@ |
| 79109 | 79349 | */ |
| 79110 | 79350 | sqlite3VdbeJumpHere(v, j1); |
| 79111 | 79351 | } |
| 79112 | 79352 | } |
| 79113 | 79353 | sqlite3ReleaseTempReg(pParse, r1); |
| 79114 | | - sqlite3ExprCachePop(pParse, 1); |
| 79354 | + sqlite3ExprCachePop(pParse); |
| 79115 | 79355 | VdbeComment((v, "end IN expr")); |
| 79116 | 79356 | } |
| 79117 | 79357 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| 79118 | 79358 | |
| 79119 | 79359 | /* |
| | @@ -79292,19 +79532,18 @@ |
| 79292 | 79532 | #endif |
| 79293 | 79533 | } |
| 79294 | 79534 | |
| 79295 | 79535 | /* |
| 79296 | 79536 | ** Remove from the column cache any entries that were added since the |
| 79297 | | -** the previous N Push operations. In other words, restore the cache |
| 79298 | | -** to the state it was in N Pushes ago. |
| 79537 | +** the previous sqlite3ExprCachePush operation. In other words, restore |
| 79538 | +** the cache to the state it was in prior the most recent Push. |
| 79299 | 79539 | */ |
| 79300 | | -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){ |
| 79540 | +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ |
| 79301 | 79541 | int i; |
| 79302 | 79542 | struct yColCache *p; |
| 79303 | | - assert( N>0 ); |
| 79304 | | - assert( pParse->iCacheLevel>=N ); |
| 79305 | | - pParse->iCacheLevel -= N; |
| 79543 | + assert( pParse->iCacheLevel>=1 ); |
| 79544 | + pParse->iCacheLevel--; |
| 79306 | 79545 | #ifdef SQLITE_DEBUG |
| 79307 | 79546 | if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ |
| 79308 | 79547 | printf("POP to %d\n", pParse->iCacheLevel); |
| 79309 | 79548 | } |
| 79310 | 79549 | #endif |
| | @@ -79429,11 +79668,11 @@ |
| 79429 | 79668 | */ |
| 79430 | 79669 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ |
| 79431 | 79670 | int i; |
| 79432 | 79671 | struct yColCache *p; |
| 79433 | 79672 | assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); |
| 79434 | | - sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1); |
| 79673 | + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); |
| 79435 | 79674 | for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ |
| 79436 | 79675 | int x = p->iReg; |
| 79437 | 79676 | if( x>=iFrom && x<iFrom+nReg ){ |
| 79438 | 79677 | p->iReg += iTo-iFrom; |
| 79439 | 79678 | } |
| | @@ -79778,11 +80017,11 @@ |
| 79778 | 80017 | sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce); |
| 79779 | 80018 | VdbeCoverage(v); |
| 79780 | 80019 | sqlite3ExprCacheRemove(pParse, target, 1); |
| 79781 | 80020 | sqlite3ExprCachePush(pParse); |
| 79782 | 80021 | sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target); |
| 79783 | | - sqlite3ExprCachePop(pParse, 1); |
| 80022 | + sqlite3ExprCachePop(pParse); |
| 79784 | 80023 | } |
| 79785 | 80024 | sqlite3VdbeResolveLabel(v, endCoalesce); |
| 79786 | 80025 | break; |
| 79787 | 80026 | } |
| 79788 | 80027 | |
| | @@ -79830,13 +80069,13 @@ |
| 79830 | 80069 | pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); |
| 79831 | 80070 | } |
| 79832 | 80071 | } |
| 79833 | 80072 | |
| 79834 | 80073 | sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ |
| 79835 | | - sqlite3ExprCodeExprList(pParse, pFarg, r1, |
| 80074 | + sqlite3ExprCodeExprList(pParse, pFarg, r1, |
| 79836 | 80075 | SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); |
| 79837 | | - sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ |
| 80076 | + sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ |
| 79838 | 80077 | }else{ |
| 79839 | 80078 | r1 = 0; |
| 79840 | 80079 | } |
| 79841 | 80080 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 79842 | 80081 | /* Possibly overload the function if the first argument is |
| | @@ -80052,17 +80291,17 @@ |
| 80052 | 80291 | testcase( pTest->op==TK_COLUMN ); |
| 80053 | 80292 | sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); |
| 80054 | 80293 | testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); |
| 80055 | 80294 | sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); |
| 80056 | 80295 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); |
| 80057 | | - sqlite3ExprCachePop(pParse, 1); |
| 80296 | + sqlite3ExprCachePop(pParse); |
| 80058 | 80297 | sqlite3VdbeResolveLabel(v, nextCase); |
| 80059 | 80298 | } |
| 80060 | 80299 | if( (nExpr&1)!=0 ){ |
| 80061 | 80300 | sqlite3ExprCachePush(pParse); |
| 80062 | 80301 | sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); |
| 80063 | | - sqlite3ExprCachePop(pParse, 1); |
| 80302 | + sqlite3ExprCachePop(pParse); |
| 80064 | 80303 | }else{ |
| 80065 | 80304 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| 80066 | 80305 | } |
| 80067 | 80306 | assert( db->mallocFailed || pParse->nErr>0 |
| 80068 | 80307 | || pParse->iCacheLevel==iCacheLevel ); |
| | @@ -80637,19 +80876,19 @@ |
| 80637 | 80876 | testcase( jumpIfNull==0 ); |
| 80638 | 80877 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); |
| 80639 | 80878 | sqlite3ExprCachePush(pParse); |
| 80640 | 80879 | sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80641 | 80880 | sqlite3VdbeResolveLabel(v, d2); |
| 80642 | | - sqlite3ExprCachePop(pParse, 1); |
| 80881 | + sqlite3ExprCachePop(pParse); |
| 80643 | 80882 | break; |
| 80644 | 80883 | } |
| 80645 | 80884 | case TK_OR: { |
| 80646 | 80885 | testcase( jumpIfNull==0 ); |
| 80647 | 80886 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); |
| 80648 | 80887 | sqlite3ExprCachePush(pParse); |
| 80649 | 80888 | sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80650 | | - sqlite3ExprCachePop(pParse, 1); |
| 80889 | + sqlite3ExprCachePop(pParse); |
| 80651 | 80890 | break; |
| 80652 | 80891 | } |
| 80653 | 80892 | case TK_NOT: { |
| 80654 | 80893 | testcase( jumpIfNull==0 ); |
| 80655 | 80894 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); |
| | @@ -80791,21 +81030,21 @@ |
| 80791 | 81030 | case TK_AND: { |
| 80792 | 81031 | testcase( jumpIfNull==0 ); |
| 80793 | 81032 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); |
| 80794 | 81033 | sqlite3ExprCachePush(pParse); |
| 80795 | 81034 | sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80796 | | - sqlite3ExprCachePop(pParse, 1); |
| 81035 | + sqlite3ExprCachePop(pParse); |
| 80797 | 81036 | break; |
| 80798 | 81037 | } |
| 80799 | 81038 | case TK_OR: { |
| 80800 | 81039 | int d2 = sqlite3VdbeMakeLabel(v); |
| 80801 | 81040 | testcase( jumpIfNull==0 ); |
| 80802 | 81041 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); |
| 80803 | 81042 | sqlite3ExprCachePush(pParse); |
| 80804 | 81043 | sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80805 | 81044 | sqlite3VdbeResolveLabel(v, d2); |
| 80806 | | - sqlite3ExprCachePop(pParse, 1); |
| 81045 | + sqlite3ExprCachePop(pParse); |
| 80807 | 81046 | break; |
| 80808 | 81047 | } |
| 80809 | 81048 | case TK_NOT: { |
| 80810 | 81049 | testcase( jumpIfNull==0 ); |
| 80811 | 81050 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); |
| | @@ -81465,10 +81704,11 @@ |
| 81465 | 81704 | unsigned const char *z; /* Pointer to token */ |
| 81466 | 81705 | int n; /* Length of token z */ |
| 81467 | 81706 | int token; /* Type of token */ |
| 81468 | 81707 | |
| 81469 | 81708 | UNUSED_PARAMETER(NotUsed); |
| 81709 | + if( zInput==0 || zOld==0 ) return; |
| 81470 | 81710 | for(z=zInput; *z; z=z+n){ |
| 81471 | 81711 | n = sqlite3GetToken(z, &token); |
| 81472 | 81712 | if( token==TK_REFERENCES ){ |
| 81473 | 81713 | char *zParent; |
| 81474 | 81714 | do { |
| | @@ -87459,11 +87699,11 @@ |
| 87459 | 87699 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); |
| 87460 | 87700 | regRecord = sqlite3GetTempReg(pParse); |
| 87461 | 87701 | |
| 87462 | 87702 | sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); |
| 87463 | 87703 | sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 87464 | | - sqlite3VdbeResolveLabel(v, iPartIdxLabel); |
| 87704 | + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); |
| 87465 | 87705 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); |
| 87466 | 87706 | sqlite3VdbeJumpHere(v, addr1); |
| 87467 | 87707 | if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 87468 | 87708 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 87469 | 87709 | (char *)pKey, P4_KEYINFO); |
| | @@ -90236,11 +90476,11 @@ |
| 90236 | 90476 | VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); |
| 90237 | 90477 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, |
| 90238 | 90478 | &iPartIdxLabel, pPrior, r1); |
| 90239 | 90479 | sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, |
| 90240 | 90480 | pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); |
| 90241 | | - sqlite3VdbeResolveLabel(v, iPartIdxLabel); |
| 90481 | + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); |
| 90242 | 90482 | pPrior = pIdx; |
| 90243 | 90483 | } |
| 90244 | 90484 | } |
| 90245 | 90485 | |
| 90246 | 90486 | /* |
| | @@ -90255,14 +90495,15 @@ |
| 90255 | 90495 | ** block of registers has already been deallocated by the time |
| 90256 | 90496 | ** this routine returns. |
| 90257 | 90497 | ** |
| 90258 | 90498 | ** If *piPartIdxLabel is not NULL, fill it in with a label and jump |
| 90259 | 90499 | ** to that label if pIdx is a partial index that should be skipped. |
| 90500 | +** The label should be resolved using sqlite3ResolvePartIdxLabel(). |
| 90260 | 90501 | ** A partial index should be skipped if its WHERE clause evaluates |
| 90261 | 90502 | ** to false or null. If pIdx is not a partial index, *piPartIdxLabel |
| 90262 | 90503 | ** will be set to zero which is an empty label that is ignored by |
| 90263 | | -** sqlite3VdbeResolveLabel(). |
| 90504 | +** sqlite3ResolvePartIdxLabel(). |
| 90264 | 90505 | ** |
| 90265 | 90506 | ** The pPrior and regPrior parameters are used to implement a cache to |
| 90266 | 90507 | ** avoid unnecessary register loads. If pPrior is not NULL, then it is |
| 90267 | 90508 | ** a pointer to a different index for which an index key has just been |
| 90268 | 90509 | ** computed into register regPrior. If the current pIdx index is generating |
| | @@ -90291,10 +90532,11 @@ |
| 90291 | 90532 | |
| 90292 | 90533 | if( piPartIdxLabel ){ |
| 90293 | 90534 | if( pIdx->pPartIdxWhere ){ |
| 90294 | 90535 | *piPartIdxLabel = sqlite3VdbeMakeLabel(v); |
| 90295 | 90536 | pParse->iPartIdxTab = iDataCur; |
| 90537 | + sqlite3ExprCachePush(pParse); |
| 90296 | 90538 | sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, |
| 90297 | 90539 | SQLITE_JUMPIFNULL); |
| 90298 | 90540 | }else{ |
| 90299 | 90541 | *piPartIdxLabel = 0; |
| 90300 | 90542 | } |
| | @@ -90318,10 +90560,22 @@ |
| 90318 | 90560 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); |
| 90319 | 90561 | } |
| 90320 | 90562 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 90321 | 90563 | return regBase; |
| 90322 | 90564 | } |
| 90565 | + |
| 90566 | +/* |
| 90567 | +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label |
| 90568 | +** because it was a partial index, then this routine should be called to |
| 90569 | +** resolve that label. |
| 90570 | +*/ |
| 90571 | +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ |
| 90572 | + if( iLabel ){ |
| 90573 | + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); |
| 90574 | + sqlite3ExprCachePop(pParse); |
| 90575 | + } |
| 90576 | +} |
| 90323 | 90577 | |
| 90324 | 90578 | /************** End of delete.c **********************************************/ |
| 90325 | 90579 | /************** Begin file func.c ********************************************/ |
| 90326 | 90580 | /* |
| 90327 | 90581 | ** 2002 February 23 |
| | @@ -98716,11 +98970,11 @@ |
| 98716 | 98970 | sqlite3VdbeChangeP5(v, (u8)i); |
| 98717 | 98971 | addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); |
| 98718 | 98972 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| 98719 | 98973 | sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), |
| 98720 | 98974 | P4_DYNAMIC); |
| 98721 | | - sqlite3VdbeAddOp2(v, OP_Move, 2, 4); |
| 98975 | + sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); |
| 98722 | 98976 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); |
| 98723 | 98977 | sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); |
| 98724 | 98978 | sqlite3VdbeJumpHere(v, addr); |
| 98725 | 98979 | |
| 98726 | 98980 | /* Make sure all the indices are constructed correctly. |
| | @@ -98769,11 +99023,11 @@ |
| 98769 | 99023 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 98770 | 99024 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 98771 | 99025 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 98772 | 99026 | sqlite3VdbeJumpHere(v, jmp4); |
| 98773 | 99027 | sqlite3VdbeJumpHere(v, jmp2); |
| 98774 | | - sqlite3VdbeResolveLabel(v, jmp3); |
| 99028 | + sqlite3ResolvePartIdxLabel(pParse, jmp3); |
| 98775 | 99029 | } |
| 98776 | 99030 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 98777 | 99031 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 98778 | 99032 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 98779 | 99033 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, |
| | @@ -100054,10 +100308,38 @@ |
| 100054 | 100308 | ************************************************************************* |
| 100055 | 100309 | ** This file contains C code routines that are called by the parser |
| 100056 | 100310 | ** to handle SELECT statements in SQLite. |
| 100057 | 100311 | */ |
| 100058 | 100312 | |
| 100313 | +/* |
| 100314 | +** An instance of the following object is used to record information about |
| 100315 | +** how to process the DISTINCT keyword, to simplify passing that information |
| 100316 | +** into the selectInnerLoop() routine. |
| 100317 | +*/ |
| 100318 | +typedef struct DistinctCtx DistinctCtx; |
| 100319 | +struct DistinctCtx { |
| 100320 | + u8 isTnct; /* True if the DISTINCT keyword is present */ |
| 100321 | + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ |
| 100322 | + int tabTnct; /* Ephemeral table used for DISTINCT processing */ |
| 100323 | + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ |
| 100324 | +}; |
| 100325 | + |
| 100326 | +/* |
| 100327 | +** An instance of the following object is used to record information about |
| 100328 | +** the ORDER BY (or GROUP BY) clause of query is being coded. |
| 100329 | +*/ |
| 100330 | +typedef struct SortCtx SortCtx; |
| 100331 | +struct SortCtx { |
| 100332 | + ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ |
| 100333 | + int nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 100334 | + int iECursor; /* Cursor number for the sorter */ |
| 100335 | + int regReturn; /* Register holding block-output return address */ |
| 100336 | + int labelBkOut; /* Start label for the block-output subroutine */ |
| 100337 | + int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ |
| 100338 | + u8 sortFlags; /* Zero or more SORTFLAG_* bits */ |
| 100339 | +}; |
| 100340 | +#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ |
| 100059 | 100341 | |
| 100060 | 100342 | /* |
| 100061 | 100343 | ** Delete all the content of a Select structure but do not deallocate |
| 100062 | 100344 | ** the select structure itself. |
| 100063 | 100345 | */ |
| | @@ -100127,11 +100409,10 @@ |
| 100127 | 100409 | pNew->pLimit = pLimit; |
| 100128 | 100410 | pNew->pOffset = pOffset; |
| 100129 | 100411 | assert( pOffset==0 || pLimit!=0 ); |
| 100130 | 100412 | pNew->addrOpenEphm[0] = -1; |
| 100131 | 100413 | pNew->addrOpenEphm[1] = -1; |
| 100132 | | - pNew->addrOpenEphm[2] = -1; |
| 100133 | 100414 | if( db->mallocFailed ) { |
| 100134 | 100415 | clearSelect(db, pNew); |
| 100135 | 100416 | if( pNew!=&standin ) sqlite3DbFree(db, pNew); |
| 100136 | 100417 | pNew = 0; |
| 100137 | 100418 | }else{ |
| | @@ -100459,38 +100740,79 @@ |
| 100459 | 100740 | } |
| 100460 | 100741 | } |
| 100461 | 100742 | return 0; |
| 100462 | 100743 | } |
| 100463 | 100744 | |
| 100745 | +/* Forward reference */ |
| 100746 | +static KeyInfo *keyInfoFromExprList( |
| 100747 | + Parse *pParse, /* Parsing context */ |
| 100748 | + ExprList *pList, /* Form the KeyInfo object from this ExprList */ |
| 100749 | + int iStart, /* Begin with this column of pList */ |
| 100750 | + int nExtra /* Add this many extra columns to the end */ |
| 100751 | +); |
| 100752 | + |
| 100464 | 100753 | /* |
| 100465 | | -** Insert code into "v" that will push the record on the top of the |
| 100466 | | -** stack into the sorter. |
| 100754 | +** Insert code into "v" that will push the record in register regData |
| 100755 | +** into the sorter. |
| 100467 | 100756 | */ |
| 100468 | 100757 | static void pushOntoSorter( |
| 100469 | 100758 | Parse *pParse, /* Parser context */ |
| 100470 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 100759 | + SortCtx *pSort, /* Information about the ORDER BY clause */ |
| 100471 | 100760 | Select *pSelect, /* The whole SELECT statement */ |
| 100472 | 100761 | int regData /* Register holding data to be sorted */ |
| 100473 | 100762 | ){ |
| 100474 | 100763 | Vdbe *v = pParse->pVdbe; |
| 100475 | | - int nExpr = pOrderBy->nExpr; |
| 100764 | + int nExpr = pSort->pOrderBy->nExpr; |
| 100476 | 100765 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 100477 | 100766 | int regRecord = sqlite3GetTempReg(pParse); |
| 100767 | + int nOBSat = pSort->nOBSat; |
| 100478 | 100768 | int op; |
| 100479 | 100769 | sqlite3ExprCacheClear(pParse); |
| 100480 | | - sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 100481 | | - sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 100770 | + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 100771 | + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 100482 | 100772 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 100483 | | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 100484 | | - if( pSelect->selFlags & SF_UseSorter ){ |
| 100773 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat, regRecord); |
| 100774 | + if( nOBSat>0 ){ |
| 100775 | + int regPrevKey; /* The first nOBSat columns of the previous row */ |
| 100776 | + int addrFirst; /* Address of the OP_IfNot opcode */ |
| 100777 | + int addrJmp; /* Address of the OP_Jump opcode */ |
| 100778 | + VdbeOp *pOp; /* Opcode that opens the sorter */ |
| 100779 | + int nKey; /* Number of sorting key columns, including OP_Sequence */ |
| 100780 | + KeyInfo *pKI; /* Original KeyInfo on the sorter table */ |
| 100781 | + |
| 100782 | + regPrevKey = pParse->nMem+1; |
| 100783 | + pParse->nMem += pSort->nOBSat; |
| 100784 | + nKey = nExpr - pSort->nOBSat + 1; |
| 100785 | + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); VdbeCoverage(v); |
| 100786 | + sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); |
| 100787 | + pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); |
| 100788 | + if( pParse->db->mallocFailed ) return; |
| 100789 | + pOp->p2 = nKey + 1; |
| 100790 | + pKI = pOp->p4.pKeyInfo; |
| 100791 | + memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */ |
| 100792 | + sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); |
| 100793 | + pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1); |
| 100794 | + addrJmp = sqlite3VdbeCurrentAddr(v); |
| 100795 | + sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); |
| 100796 | + pSort->labelBkOut = sqlite3VdbeMakeLabel(v); |
| 100797 | + pSort->regReturn = ++pParse->nMem; |
| 100798 | + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); |
| 100799 | + sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); |
| 100800 | + sqlite3VdbeJumpHere(v, addrFirst); |
| 100801 | + sqlite3VdbeAddOp3(v, OP_Move, regBase, regPrevKey, pSort->nOBSat); |
| 100802 | + sqlite3VdbeJumpHere(v, addrJmp); |
| 100803 | + } |
| 100804 | + if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 100485 | 100805 | op = OP_SorterInsert; |
| 100486 | 100806 | }else{ |
| 100487 | 100807 | op = OP_IdxInsert; |
| 100488 | 100808 | } |
| 100489 | | - sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); |
| 100490 | | - sqlite3ReleaseTempReg(pParse, regRecord); |
| 100491 | | - sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 100809 | + sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); |
| 100810 | + if( nOBSat==0 ){ |
| 100811 | + sqlite3ReleaseTempReg(pParse, regRecord); |
| 100812 | + sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 100813 | + } |
| 100492 | 100814 | if( pSelect->iLimit ){ |
| 100493 | 100815 | int addr1, addr2; |
| 100494 | 100816 | int iLimit; |
| 100495 | 100817 | if( pSelect->iOffset ){ |
| 100496 | 100818 | iLimit = pSelect->iOffset+1; |
| | @@ -100499,12 +100821,12 @@ |
| 100499 | 100821 | } |
| 100500 | 100822 | addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v); |
| 100501 | 100823 | sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); |
| 100502 | 100824 | addr2 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 100503 | 100825 | sqlite3VdbeJumpHere(v, addr1); |
| 100504 | | - sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); |
| 100505 | | - sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); |
| 100826 | + sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); |
| 100827 | + sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); |
| 100506 | 100828 | sqlite3VdbeJumpHere(v, addr2); |
| 100507 | 100829 | } |
| 100508 | 100830 | } |
| 100509 | 100831 | |
| 100510 | 100832 | /* |
| | @@ -100513,11 +100835,11 @@ |
| 100513 | 100835 | static void codeOffset( |
| 100514 | 100836 | Vdbe *v, /* Generate code into this VM */ |
| 100515 | 100837 | int iOffset, /* Register holding the offset counter */ |
| 100516 | 100838 | int iContinue /* Jump here to skip the current record */ |
| 100517 | 100839 | ){ |
| 100518 | | - if( iOffset>0 && iContinue!=0 ){ |
| 100840 | + if( iOffset>0 ){ |
| 100519 | 100841 | int addr; |
| 100520 | 100842 | sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); |
| 100521 | 100843 | addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v); |
| 100522 | 100844 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); |
| 100523 | 100845 | VdbeComment((v, "skip OFFSET records")); |
| | @@ -100574,23 +100896,10 @@ |
| 100574 | 100896 | return 0; |
| 100575 | 100897 | } |
| 100576 | 100898 | } |
| 100577 | 100899 | #endif |
| 100578 | 100900 | |
| 100579 | | -/* |
| 100580 | | -** An instance of the following object is used to record information about |
| 100581 | | -** how to process the DISTINCT keyword, to simplify passing that information |
| 100582 | | -** into the selectInnerLoop() routine. |
| 100583 | | -*/ |
| 100584 | | -typedef struct DistinctCtx DistinctCtx; |
| 100585 | | -struct DistinctCtx { |
| 100586 | | - u8 isTnct; /* True if the DISTINCT keyword is present */ |
| 100587 | | - u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ |
| 100588 | | - int tabTnct; /* Ephemeral table used for DISTINCT processing */ |
| 100589 | | - int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ |
| 100590 | | -}; |
| 100591 | | - |
| 100592 | 100901 | /* |
| 100593 | 100902 | ** This routine generates the code for the inside of the inner loop |
| 100594 | 100903 | ** of a SELECT. |
| 100595 | 100904 | ** |
| 100596 | 100905 | ** If srcTab is negative, then the pEList expressions |
| | @@ -100601,11 +100910,11 @@ |
| 100601 | 100910 | static void selectInnerLoop( |
| 100602 | 100911 | Parse *pParse, /* The parser context */ |
| 100603 | 100912 | Select *p, /* The complete select statement being coded */ |
| 100604 | 100913 | ExprList *pEList, /* List of values being extracted */ |
| 100605 | 100914 | int srcTab, /* Pull data from this table */ |
| 100606 | | - ExprList *pOrderBy, /* If not NULL, sort results using this key */ |
| 100915 | + SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ |
| 100607 | 100916 | DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ |
| 100608 | 100917 | SelectDest *pDest, /* How to dispose of the results */ |
| 100609 | 100918 | int iContinue, /* Jump here to continue with next row */ |
| 100610 | 100919 | int iBreak /* Jump here to break out of the inner loop */ |
| 100611 | 100920 | ){ |
| | @@ -100618,11 +100927,13 @@ |
| 100618 | 100927 | int nResultCol; /* Number of result columns */ |
| 100619 | 100928 | |
| 100620 | 100929 | assert( v ); |
| 100621 | 100930 | assert( pEList!=0 ); |
| 100622 | 100931 | hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; |
| 100623 | | - if( pOrderBy==0 && !hasDistinct ){ |
| 100932 | + if( pSort && pSort->pOrderBy==0 ) pSort = 0; |
| 100933 | + if( pSort==0 && !hasDistinct ){ |
| 100934 | + assert( iContinue!=0 ); |
| 100624 | 100935 | codeOffset(v, p->iOffset, iContinue); |
| 100625 | 100936 | } |
| 100626 | 100937 | |
| 100627 | 100938 | /* Pull the requested columns. |
| 100628 | 100939 | */ |
| | @@ -100708,11 +101019,11 @@ |
| 100708 | 101019 | assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); |
| 100709 | 101020 | codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult); |
| 100710 | 101021 | break; |
| 100711 | 101022 | } |
| 100712 | 101023 | } |
| 100713 | | - if( pOrderBy==0 ){ |
| 101024 | + if( pSort==0 ){ |
| 100714 | 101025 | codeOffset(v, p->iOffset, iContinue); |
| 100715 | 101026 | } |
| 100716 | 101027 | } |
| 100717 | 101028 | |
| 100718 | 101029 | switch( eDest ){ |
| | @@ -100739,32 +101050,33 @@ |
| 100739 | 101050 | } |
| 100740 | 101051 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
| 100741 | 101052 | |
| 100742 | 101053 | /* Store the result as data using a unique key. |
| 100743 | 101054 | */ |
| 100744 | | - case SRT_DistTable: |
| 101055 | + case SRT_Fifo: |
| 101056 | + case SRT_DistFifo: |
| 100745 | 101057 | case SRT_Table: |
| 100746 | 101058 | case SRT_EphemTab: { |
| 100747 | 101059 | int r1 = sqlite3GetTempReg(pParse); |
| 100748 | 101060 | testcase( eDest==SRT_Table ); |
| 100749 | 101061 | testcase( eDest==SRT_EphemTab ); |
| 100750 | 101062 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 100751 | 101063 | #ifndef SQLITE_OMIT_CTE |
| 100752 | | - if( eDest==SRT_DistTable ){ |
| 100753 | | - /* If the destination is DistTable, then cursor (iParm+1) is open |
| 101064 | + if( eDest==SRT_DistFifo ){ |
| 101065 | + /* If the destination is DistFifo, then cursor (iParm+1) is open |
| 100754 | 101066 | ** on an ephemeral index. If the current row is already present |
| 100755 | 101067 | ** in the index, do not write it to the output. If not, add the |
| 100756 | 101068 | ** current row to the index and proceed with writing it to the |
| 100757 | 101069 | ** output table as well. */ |
| 100758 | 101070 | int addr = sqlite3VdbeCurrentAddr(v) + 4; |
| 100759 | 101071 | sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); |
| 100760 | 101072 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); |
| 100761 | | - assert( pOrderBy==0 ); |
| 101073 | + assert( pSort==0 ); |
| 100762 | 101074 | } |
| 100763 | 101075 | #endif |
| 100764 | | - if( pOrderBy ){ |
| 100765 | | - pushOntoSorter(pParse, pOrderBy, p, r1); |
| 101076 | + if( pSort ){ |
| 101077 | + pushOntoSorter(pParse, pSort, p, r1); |
| 100766 | 101078 | }else{ |
| 100767 | 101079 | int r2 = sqlite3GetTempReg(pParse); |
| 100768 | 101080 | sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); |
| 100769 | 101081 | sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); |
| 100770 | 101082 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| | @@ -100781,16 +101093,16 @@ |
| 100781 | 101093 | */ |
| 100782 | 101094 | case SRT_Set: { |
| 100783 | 101095 | assert( nResultCol==1 ); |
| 100784 | 101096 | pDest->affSdst = |
| 100785 | 101097 | sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); |
| 100786 | | - if( pOrderBy ){ |
| 101098 | + if( pSort ){ |
| 100787 | 101099 | /* At first glance you would think we could optimize out the |
| 100788 | 101100 | ** ORDER BY in this case since the order of entries in the set |
| 100789 | 101101 | ** does not matter. But there might be a LIMIT clause, in which |
| 100790 | 101102 | ** case the order does matter */ |
| 100791 | | - pushOntoSorter(pParse, pOrderBy, p, regResult); |
| 101103 | + pushOntoSorter(pParse, pSort, p, regResult); |
| 100792 | 101104 | }else{ |
| 100793 | 101105 | int r1 = sqlite3GetTempReg(pParse); |
| 100794 | 101106 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); |
| 100795 | 101107 | sqlite3ExprCacheAffinityChange(pParse, regResult, 1); |
| 100796 | 101108 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); |
| | @@ -100811,12 +101123,12 @@ |
| 100811 | 101123 | ** store the results in the appropriate memory cell and break out |
| 100812 | 101124 | ** of the scan loop. |
| 100813 | 101125 | */ |
| 100814 | 101126 | case SRT_Mem: { |
| 100815 | 101127 | assert( nResultCol==1 ); |
| 100816 | | - if( pOrderBy ){ |
| 100817 | | - pushOntoSorter(pParse, pOrderBy, p, regResult); |
| 101128 | + if( pSort ){ |
| 101129 | + pushOntoSorter(pParse, pSort, p, regResult); |
| 100818 | 101130 | }else{ |
| 100819 | 101131 | sqlite3ExprCodeMove(pParse, regResult, iParm, 1); |
| 100820 | 101132 | /* The LIMIT clause will jump out of the loop for us */ |
| 100821 | 101133 | } |
| 100822 | 101134 | break; |
| | @@ -100825,14 +101137,14 @@ |
| 100825 | 101137 | |
| 100826 | 101138 | case SRT_Coroutine: /* Send data to a co-routine */ |
| 100827 | 101139 | case SRT_Output: { /* Return the results */ |
| 100828 | 101140 | testcase( eDest==SRT_Coroutine ); |
| 100829 | 101141 | testcase( eDest==SRT_Output ); |
| 100830 | | - if( pOrderBy ){ |
| 101142 | + if( pSort ){ |
| 100831 | 101143 | int r1 = sqlite3GetTempReg(pParse); |
| 100832 | 101144 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 100833 | | - pushOntoSorter(pParse, pOrderBy, p, r1); |
| 101145 | + pushOntoSorter(pParse, pSort, p, r1); |
| 100834 | 101146 | sqlite3ReleaseTempReg(pParse, r1); |
| 100835 | 101147 | }else if( eDest==SRT_Coroutine ){ |
| 100836 | 101148 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 100837 | 101149 | }else{ |
| 100838 | 101150 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); |
| | @@ -100905,11 +101217,11 @@ |
| 100905 | 101217 | |
| 100906 | 101218 | /* Jump to the end of the loop if the LIMIT is reached. Except, if |
| 100907 | 101219 | ** there is a sorter, in which case the sorter has already limited |
| 100908 | 101220 | ** the output for us. |
| 100909 | 101221 | */ |
| 100910 | | - if( pOrderBy==0 && p->iLimit ){ |
| 101222 | + if( pSort==0 && p->iLimit ){ |
| 100911 | 101223 | sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); |
| 100912 | 101224 | } |
| 100913 | 101225 | } |
| 100914 | 101226 | |
| 100915 | 101227 | /* |
| | @@ -100976,27 +101288,32 @@ |
| 100976 | 101288 | ** |
| 100977 | 101289 | ** Space to hold the KeyInfo structure is obtain from malloc. The calling |
| 100978 | 101290 | ** function is responsible for seeing that this structure is eventually |
| 100979 | 101291 | ** freed. |
| 100980 | 101292 | */ |
| 100981 | | -static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList, int nExtra){ |
| 101293 | +static KeyInfo *keyInfoFromExprList( |
| 101294 | + Parse *pParse, /* Parsing context */ |
| 101295 | + ExprList *pList, /* Form the KeyInfo object from this ExprList */ |
| 101296 | + int iStart, /* Begin with this column of pList */ |
| 101297 | + int nExtra /* Add this many extra columns to the end */ |
| 101298 | +){ |
| 100982 | 101299 | int nExpr; |
| 100983 | 101300 | KeyInfo *pInfo; |
| 100984 | 101301 | struct ExprList_item *pItem; |
| 100985 | 101302 | sqlite3 *db = pParse->db; |
| 100986 | 101303 | int i; |
| 100987 | 101304 | |
| 100988 | 101305 | nExpr = pList->nExpr; |
| 100989 | | - pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra, 1); |
| 101306 | + pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1); |
| 100990 | 101307 | if( pInfo ){ |
| 100991 | 101308 | assert( sqlite3KeyInfoIsWriteable(pInfo) ); |
| 100992 | | - for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){ |
| 101309 | + for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){ |
| 100993 | 101310 | CollSeq *pColl; |
| 100994 | 101311 | pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); |
| 100995 | 101312 | if( !pColl ) pColl = db->pDfltColl; |
| 100996 | | - pInfo->aColl[i] = pColl; |
| 100997 | | - pInfo->aSortOrder[i] = pItem->sortOrder; |
| 101313 | + pInfo->aColl[i-iStart] = pColl; |
| 101314 | + pInfo->aSortOrder[i-iStart] = pItem->sortOrder; |
| 100998 | 101315 | } |
| 100999 | 101316 | } |
| 101000 | 101317 | return pInfo; |
| 101001 | 101318 | } |
| 101002 | 101319 | |
| | @@ -101094,50 +101411,60 @@ |
| 101094 | 101411 | ** routine generates the code needed to do that. |
| 101095 | 101412 | */ |
| 101096 | 101413 | static void generateSortTail( |
| 101097 | 101414 | Parse *pParse, /* Parsing context */ |
| 101098 | 101415 | Select *p, /* The SELECT statement */ |
| 101099 | | - Vdbe *v, /* Generate code into this VDBE */ |
| 101416 | + SortCtx *pSort, /* Information on the ORDER BY clause */ |
| 101100 | 101417 | int nColumn, /* Number of columns of data */ |
| 101101 | 101418 | SelectDest *pDest /* Write the sorted results here */ |
| 101102 | 101419 | ){ |
| 101420 | + Vdbe *v = pParse->pVdbe; /* The prepared statement */ |
| 101103 | 101421 | int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ |
| 101104 | 101422 | int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ |
| 101105 | 101423 | int addr; |
| 101424 | + int addrOnce = 0; |
| 101106 | 101425 | int iTab; |
| 101107 | 101426 | int pseudoTab = 0; |
| 101108 | | - ExprList *pOrderBy = p->pOrderBy; |
| 101109 | | - |
| 101427 | + ExprList *pOrderBy = pSort->pOrderBy; |
| 101110 | 101428 | int eDest = pDest->eDest; |
| 101111 | 101429 | int iParm = pDest->iSDParm; |
| 101112 | | - |
| 101113 | 101430 | int regRow; |
| 101114 | 101431 | int regRowid; |
| 101432 | + int nKey; |
| 101115 | 101433 | |
| 101116 | | - iTab = pOrderBy->iECursor; |
| 101434 | + if( pSort->labelBkOut ){ |
| 101435 | + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); |
| 101436 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak); |
| 101437 | + sqlite3VdbeResolveLabel(v, pSort->labelBkOut); |
| 101438 | + addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); |
| 101439 | + } |
| 101440 | + iTab = pSort->iECursor; |
| 101117 | 101441 | regRow = sqlite3GetTempReg(pParse); |
| 101118 | 101442 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 101119 | 101443 | pseudoTab = pParse->nTab++; |
| 101120 | 101444 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 101121 | 101445 | regRowid = 0; |
| 101122 | 101446 | }else{ |
| 101123 | 101447 | regRowid = sqlite3GetTempReg(pParse); |
| 101124 | 101448 | } |
| 101125 | | - if( p->selFlags & SF_UseSorter ){ |
| 101449 | + nKey = pOrderBy->nExpr - pSort->nOBSat; |
| 101450 | + if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 101126 | 101451 | int regSortOut = ++pParse->nMem; |
| 101127 | 101452 | int ptab2 = pParse->nTab++; |
| 101128 | | - sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); |
| 101453 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, nKey+2); |
| 101454 | + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 101129 | 101455 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 101130 | 101456 | VdbeCoverage(v); |
| 101131 | 101457 | codeOffset(v, p->iOffset, addrContinue); |
| 101132 | 101458 | sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 101133 | | - sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); |
| 101459 | + sqlite3VdbeAddOp3(v, OP_Column, ptab2, nKey+1, regRow); |
| 101134 | 101460 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 101135 | 101461 | }else{ |
| 101462 | + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 101136 | 101463 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 101137 | 101464 | codeOffset(v, p->iOffset, addrContinue); |
| 101138 | | - sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); |
| 101465 | + sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow); |
| 101139 | 101466 | } |
| 101140 | 101467 | switch( eDest ){ |
| 101141 | 101468 | case SRT_Table: |
| 101142 | 101469 | case SRT_EphemTab: { |
| 101143 | 101470 | testcase( eDest==SRT_Table ); |
| | @@ -101188,15 +101515,16 @@ |
| 101188 | 101515 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 101189 | 101516 | |
| 101190 | 101517 | /* The bottom of the loop |
| 101191 | 101518 | */ |
| 101192 | 101519 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 101193 | | - if( p->selFlags & SF_UseSorter ){ |
| 101520 | + if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 101194 | 101521 | sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); |
| 101195 | 101522 | }else{ |
| 101196 | 101523 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); |
| 101197 | 101524 | } |
| 101525 | + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); |
| 101198 | 101526 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 101199 | 101527 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 101200 | 101528 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 101201 | 101529 | } |
| 101202 | 101530 | } |
| | @@ -101874,11 +102202,11 @@ |
| 101874 | 102202 | int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ |
| 101875 | 102203 | int iCurrent = 0; /* The Current table */ |
| 101876 | 102204 | int regCurrent; /* Register holding Current table */ |
| 101877 | 102205 | int iQueue; /* The Queue table */ |
| 101878 | 102206 | int iDistinct = 0; /* To ensure unique results if UNION */ |
| 101879 | | - int eDest = SRT_Table; /* How to write to Queue */ |
| 102207 | + int eDest = SRT_Fifo; /* How to write to Queue */ |
| 101880 | 102208 | SelectDest destQueue; /* SelectDest targetting the Queue table */ |
| 101881 | 102209 | int i; /* Loop counter */ |
| 101882 | 102210 | int rc; /* Result code */ |
| 101883 | 102211 | ExprList *pOrderBy; /* The ORDER BY clause */ |
| 101884 | 102212 | Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ |
| | @@ -101906,17 +102234,17 @@ |
| 101906 | 102234 | } |
| 101907 | 102235 | } |
| 101908 | 102236 | |
| 101909 | 102237 | /* Allocate cursors numbers for Queue and Distinct. The cursor number for |
| 101910 | 102238 | ** the Distinct table must be exactly one greater than Queue in order |
| 101911 | | - ** for the SRT_DistTable and SRT_DistQueue destinations to work. */ |
| 102239 | + ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ |
| 101912 | 102240 | iQueue = pParse->nTab++; |
| 101913 | 102241 | if( p->op==TK_UNION ){ |
| 101914 | | - eDest = pOrderBy ? SRT_DistQueue : SRT_DistTable; |
| 102242 | + eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; |
| 101915 | 102243 | iDistinct = pParse->nTab++; |
| 101916 | 102244 | }else{ |
| 101917 | | - eDest = pOrderBy ? SRT_Queue : SRT_Table; |
| 102245 | + eDest = pOrderBy ? SRT_Queue : SRT_Fifo; |
| 101918 | 102246 | } |
| 101919 | 102247 | sqlite3SelectDestInit(&destQueue, eDest, iQueue); |
| 101920 | 102248 | |
| 101921 | 102249 | /* Allocate cursors for Current, Queue, and Distinct. */ |
| 101922 | 102250 | regCurrent = ++pParse->nMem; |
| | @@ -101978,10 +102306,11 @@ |
| 101978 | 102306 | /* Keep running the loop until the Queue is empty */ |
| 101979 | 102307 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); |
| 101980 | 102308 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 101981 | 102309 | |
| 101982 | 102310 | end_of_recursive_query: |
| 102311 | + sqlite3ExprListDelete(pParse->db, p->pOrderBy); |
| 101983 | 102312 | p->pOrderBy = pOrderBy; |
| 101984 | 102313 | p->pLimit = pLimit; |
| 101985 | 102314 | p->pOffset = pOffset; |
| 101986 | 102315 | return; |
| 101987 | 102316 | } |
| | @@ -104349,11 +104678,11 @@ |
| 104349 | 104678 | if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ |
| 104350 | 104679 | sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " |
| 104351 | 104680 | "argument"); |
| 104352 | 104681 | pFunc->iDistinct = -1; |
| 104353 | 104682 | }else{ |
| 104354 | | - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0); |
| 104683 | + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); |
| 104355 | 104684 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, |
| 104356 | 104685 | (char*)pKeyInfo, P4_KEYINFO); |
| 104357 | 104686 | } |
| 104358 | 104687 | } |
| 104359 | 104688 | } |
| | @@ -104504,16 +104833,15 @@ |
| 104504 | 104833 | Vdbe *v; /* The virtual machine under construction */ |
| 104505 | 104834 | int isAgg; /* True for select lists like "count(*)" */ |
| 104506 | 104835 | ExprList *pEList; /* List of columns to extract. */ |
| 104507 | 104836 | SrcList *pTabList; /* List of tables to select from */ |
| 104508 | 104837 | Expr *pWhere; /* The WHERE clause. May be NULL */ |
| 104509 | | - ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ |
| 104510 | 104838 | ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ |
| 104511 | 104839 | Expr *pHaving; /* The HAVING clause. May be NULL */ |
| 104512 | 104840 | int rc = 1; /* Value to return from this function */ |
| 104513 | | - int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ |
| 104514 | 104841 | DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ |
| 104842 | + SortCtx sSort; /* Info on how to code the ORDER BY clause */ |
| 104515 | 104843 | AggInfo sAggInfo; /* Information used by aggregate queries */ |
| 104516 | 104844 | int iEnd; /* Address of the end of the query */ |
| 104517 | 104845 | sqlite3 *db; /* The database connection */ |
| 104518 | 104846 | |
| 104519 | 104847 | #ifndef SQLITE_OMIT_EXPLAIN |
| | @@ -104526,21 +104854,28 @@ |
| 104526 | 104854 | return 1; |
| 104527 | 104855 | } |
| 104528 | 104856 | if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; |
| 104529 | 104857 | memset(&sAggInfo, 0, sizeof(sAggInfo)); |
| 104530 | 104858 | |
| 104859 | + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); |
| 104860 | + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); |
| 104861 | + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); |
| 104862 | + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); |
| 104531 | 104863 | if( IgnorableOrderby(pDest) ){ |
| 104532 | 104864 | assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || |
| 104533 | | - pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard); |
| 104865 | + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || |
| 104866 | + pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo || |
| 104867 | + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); |
| 104534 | 104868 | /* If ORDER BY makes no difference in the output then neither does |
| 104535 | 104869 | ** DISTINCT so it can be removed too. */ |
| 104536 | 104870 | sqlite3ExprListDelete(db, p->pOrderBy); |
| 104537 | 104871 | p->pOrderBy = 0; |
| 104538 | 104872 | p->selFlags &= ~SF_Distinct; |
| 104539 | 104873 | } |
| 104540 | 104874 | sqlite3SelectPrep(pParse, p, 0); |
| 104541 | | - pOrderBy = p->pOrderBy; |
| 104875 | + memset(&sSort, 0, sizeof(sSort)); |
| 104876 | + sSort.pOrderBy = p->pOrderBy; |
| 104542 | 104877 | pTabList = p->pSrc; |
| 104543 | 104878 | pEList = p->pEList; |
| 104544 | 104879 | if( pParse->nErr || db->mallocFailed ){ |
| 104545 | 104880 | goto select_end; |
| 104546 | 104881 | } |
| | @@ -104658,11 +104993,11 @@ |
| 104658 | 104993 | goto select_end; |
| 104659 | 104994 | } |
| 104660 | 104995 | pParse->nHeight -= sqlite3SelectExprHeight(p); |
| 104661 | 104996 | pTabList = p->pSrc; |
| 104662 | 104997 | if( !IgnorableOrderby(pDest) ){ |
| 104663 | | - pOrderBy = p->pOrderBy; |
| 104998 | + sSort.pOrderBy = p->pOrderBy; |
| 104664 | 104999 | } |
| 104665 | 105000 | } |
| 104666 | 105001 | pEList = p->pEList; |
| 104667 | 105002 | #endif |
| 104668 | 105003 | pWhere = p->pWhere; |
| | @@ -104685,13 +105020,13 @@ |
| 104685 | 105020 | ** will cause elements to come out in the correct order. This is |
| 104686 | 105021 | ** an optimization - the correct answer should result regardless. |
| 104687 | 105022 | ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER |
| 104688 | 105023 | ** to disable this optimization for testing purposes. |
| 104689 | 105024 | */ |
| 104690 | | - if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0 |
| 105025 | + if( sqlite3ExprListCompare(p->pGroupBy, sSort.pOrderBy, -1)==0 |
| 104691 | 105026 | && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ |
| 104692 | | - pOrderBy = 0; |
| 105027 | + sSort.pOrderBy = 0; |
| 104693 | 105028 | } |
| 104694 | 105029 | |
| 104695 | 105030 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 104696 | 105031 | ** if the select-list is the same as the ORDER BY list, then this query |
| 104697 | 105032 | ** can be rewritten as a GROUP BY. In other words, this: |
| | @@ -104706,16 +105041,16 @@ |
| 104706 | 105041 | ** used for both the ORDER BY and DISTINCT processing. As originally |
| 104707 | 105042 | ** written the query must use a temp-table for at least one of the ORDER |
| 104708 | 105043 | ** BY and DISTINCT, and an index or separate temp-table for the other. |
| 104709 | 105044 | */ |
| 104710 | 105045 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct |
| 104711 | | - && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0 |
| 105046 | + && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 |
| 104712 | 105047 | ){ |
| 104713 | 105048 | p->selFlags &= ~SF_Distinct; |
| 104714 | 105049 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 104715 | 105050 | pGroupBy = p->pGroupBy; |
| 104716 | | - pOrderBy = 0; |
| 105051 | + sSort.pOrderBy = 0; |
| 104717 | 105052 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 104718 | 105053 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 104719 | 105054 | ** original setting of the SF_Distinct flag, not the current setting */ |
| 104720 | 105055 | assert( sDistinct.isTnct ); |
| 104721 | 105056 | } |
| | @@ -104725,20 +105060,20 @@ |
| 104725 | 105060 | ** extracted in pre-sorted order. If that is the case, then the |
| 104726 | 105061 | ** OP_OpenEphemeral instruction will be changed to an OP_Noop once |
| 104727 | 105062 | ** we figure out that the sorting index is not needed. The addrSortIndex |
| 104728 | 105063 | ** variable is used to facilitate that change. |
| 104729 | 105064 | */ |
| 104730 | | - if( pOrderBy ){ |
| 105065 | + if( sSort.pOrderBy ){ |
| 104731 | 105066 | KeyInfo *pKeyInfo; |
| 104732 | | - pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 0); |
| 104733 | | - pOrderBy->iECursor = pParse->nTab++; |
| 104734 | | - p->addrOpenEphm[2] = addrSortIndex = |
| 105067 | + pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0); |
| 105068 | + sSort.iECursor = pParse->nTab++; |
| 105069 | + sSort.addrSortIndex = |
| 104735 | 105070 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 104736 | | - pOrderBy->iECursor, pOrderBy->nExpr+2, 0, |
| 105071 | + sSort.iECursor, sSort.pOrderBy->nExpr+2, 0, |
| 104737 | 105072 | (char*)pKeyInfo, P4_KEYINFO); |
| 104738 | 105073 | }else{ |
| 104739 | | - addrSortIndex = -1; |
| 105074 | + sSort.addrSortIndex = -1; |
| 104740 | 105075 | } |
| 104741 | 105076 | |
| 104742 | 105077 | /* If the output is destined for a temporary table, open that table. |
| 104743 | 105078 | */ |
| 104744 | 105079 | if( pDest->eDest==SRT_EphemTab ){ |
| | @@ -104748,22 +105083,22 @@ |
| 104748 | 105083 | /* Set the limiter. |
| 104749 | 105084 | */ |
| 104750 | 105085 | iEnd = sqlite3VdbeMakeLabel(v); |
| 104751 | 105086 | p->nSelectRow = LARGEST_INT64; |
| 104752 | 105087 | computeLimitRegisters(pParse, p, iEnd); |
| 104753 | | - if( p->iLimit==0 && addrSortIndex>=0 ){ |
| 104754 | | - sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; |
| 104755 | | - p->selFlags |= SF_UseSorter; |
| 105088 | + if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ |
| 105089 | + sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen; |
| 105090 | + sSort.sortFlags |= SORTFLAG_UseSorter; |
| 104756 | 105091 | } |
| 104757 | 105092 | |
| 104758 | 105093 | /* Open a virtual index to use for the distinct set. |
| 104759 | 105094 | */ |
| 104760 | 105095 | if( p->selFlags & SF_Distinct ){ |
| 104761 | 105096 | sDistinct.tabTnct = pParse->nTab++; |
| 104762 | 105097 | sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 104763 | 105098 | sDistinct.tabTnct, 0, 0, |
| 104764 | | - (char*)keyInfoFromExprList(pParse, p->pEList, 0), |
| 105099 | + (char*)keyInfoFromExprList(pParse, p->pEList,0,0), |
| 104765 | 105100 | P4_KEYINFO); |
| 104766 | 105101 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 104767 | 105102 | sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; |
| 104768 | 105103 | }else{ |
| 104769 | 105104 | sDistinct.eTnctType = WHERE_DISTINCT_NOOP; |
| | @@ -104772,32 +105107,36 @@ |
| 104772 | 105107 | if( !isAgg && pGroupBy==0 ){ |
| 104773 | 105108 | /* No aggregate functions and no GROUP BY clause */ |
| 104774 | 105109 | u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); |
| 104775 | 105110 | |
| 104776 | 105111 | /* Begin the database scan. */ |
| 104777 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList, |
| 104778 | | - wctrlFlags, 0); |
| 105112 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, |
| 105113 | + p->pEList, wctrlFlags, 0); |
| 104779 | 105114 | if( pWInfo==0 ) goto select_end; |
| 104780 | 105115 | if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ |
| 104781 | 105116 | p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); |
| 104782 | 105117 | } |
| 104783 | 105118 | if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ |
| 104784 | 105119 | sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); |
| 104785 | 105120 | } |
| 104786 | | - if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0; |
| 105121 | + if( sSort.pOrderBy ){ |
| 105122 | + sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); |
| 105123 | + if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ |
| 105124 | + sSort.pOrderBy = 0; |
| 105125 | + } |
| 105126 | + } |
| 104787 | 105127 | |
| 104788 | 105128 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| 104789 | 105129 | ** instruction ended up not being needed, then change the OP_OpenEphemeral |
| 104790 | 105130 | ** into an OP_Noop. |
| 104791 | 105131 | */ |
| 104792 | | - if( addrSortIndex>=0 && pOrderBy==0 ){ |
| 104793 | | - sqlite3VdbeChangeToNoop(v, addrSortIndex); |
| 104794 | | - p->addrOpenEphm[2] = -1; |
| 105132 | + if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ |
| 105133 | + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); |
| 104795 | 105134 | } |
| 104796 | 105135 | |
| 104797 | 105136 | /* Use the standard inner loop. */ |
| 104798 | | - selectInnerLoop(pParse, p, pEList, -1, pOrderBy, &sDistinct, pDest, |
| 105137 | + selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, |
| 104799 | 105138 | sqlite3WhereContinueLabel(pWInfo), |
| 104800 | 105139 | sqlite3WhereBreakLabel(pWInfo)); |
| 104801 | 105140 | |
| 104802 | 105141 | /* End the database scan loop. |
| 104803 | 105142 | */ |
| | @@ -104849,11 +105188,11 @@ |
| 104849 | 105188 | sNC.pAggInfo = &sAggInfo; |
| 104850 | 105189 | sAggInfo.mnReg = pParse->nMem+1; |
| 104851 | 105190 | sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; |
| 104852 | 105191 | sAggInfo.pGroupBy = pGroupBy; |
| 104853 | 105192 | sqlite3ExprAnalyzeAggList(&sNC, pEList); |
| 104854 | | - sqlite3ExprAnalyzeAggList(&sNC, pOrderBy); |
| 105193 | + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); |
| 104855 | 105194 | if( pHaving ){ |
| 104856 | 105195 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); |
| 104857 | 105196 | } |
| 104858 | 105197 | sAggInfo.nAccumulator = sAggInfo.nColumn; |
| 104859 | 105198 | for(i=0; i<sAggInfo.nFunc; i++){ |
| | @@ -104883,11 +105222,11 @@ |
| 104883 | 105222 | ** implement it. Allocate that sorting index now. If it turns out |
| 104884 | 105223 | ** that we do not need it after all, the OP_SorterOpen instruction |
| 104885 | 105224 | ** will be converted into a Noop. |
| 104886 | 105225 | */ |
| 104887 | 105226 | sAggInfo.sortingIdx = pParse->nTab++; |
| 104888 | | - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0); |
| 105227 | + pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0); |
| 104889 | 105228 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, |
| 104890 | 105229 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 104891 | 105230 | 0, (char*)pKeyInfo, P4_KEYINFO); |
| 104892 | 105231 | |
| 104893 | 105232 | /* Initialize memory locations used by GROUP BY aggregate processing |
| | @@ -104912,14 +105251,14 @@ |
| 104912 | 105251 | ** This might involve two separate loops with an OP_Sort in between, or |
| 104913 | 105252 | ** it might be a single loop that uses an index to extract information |
| 104914 | 105253 | ** in the right order to begin with. |
| 104915 | 105254 | */ |
| 104916 | 105255 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 104917 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 105256 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 104918 | 105257 | WHERE_GROUPBY, 0); |
| 104919 | 105258 | if( pWInfo==0 ) goto select_end; |
| 104920 | | - if( sqlite3WhereIsOrdered(pWInfo) ){ |
| 105259 | + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 104921 | 105260 | /* The optimizer is able to deliver rows in group by order so |
| 104922 | 105261 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 104923 | 105262 | ** cancelled later because we still need to use the pKeyInfo |
| 104924 | 105263 | */ |
| 104925 | 105264 | groupBySort = 0; |
| | @@ -105066,11 +105405,11 @@ |
| 105066 | 105405 | sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); |
| 105067 | 105406 | VdbeComment((v, "Groupby result generator entry point")); |
| 105068 | 105407 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 105069 | 105408 | finalizeAggFunctions(pParse, &sAggInfo); |
| 105070 | 105409 | sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); |
| 105071 | | - selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy, |
| 105410 | + selectInnerLoop(pParse, p, p->pEList, -1, &sSort, |
| 105072 | 105411 | &sDistinct, pDest, |
| 105073 | 105412 | addrOutputRow+1, addrSetAbort); |
| 105074 | 105413 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 105075 | 105414 | VdbeComment((v, "end groupby result generator")); |
| 105076 | 105415 | |
| | @@ -105198,20 +105537,20 @@ |
| 105198 | 105537 | sqlite3ExprListDelete(db, pDel); |
| 105199 | 105538 | goto select_end; |
| 105200 | 105539 | } |
| 105201 | 105540 | updateAccumulator(pParse, &sAggInfo); |
| 105202 | 105541 | assert( pMinMax==0 || pMinMax->nExpr==1 ); |
| 105203 | | - if( sqlite3WhereIsOrdered(pWInfo) ){ |
| 105542 | + if( sqlite3WhereIsOrdered(pWInfo)>0 ){ |
| 105204 | 105543 | sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo)); |
| 105205 | 105544 | VdbeComment((v, "%s() by index", |
| 105206 | 105545 | (flag==WHERE_ORDERBY_MIN?"min":"max"))); |
| 105207 | 105546 | } |
| 105208 | 105547 | sqlite3WhereEnd(pWInfo); |
| 105209 | 105548 | finalizeAggFunctions(pParse, &sAggInfo); |
| 105210 | 105549 | } |
| 105211 | 105550 | |
| 105212 | | - pOrderBy = 0; |
| 105551 | + sSort.pOrderBy = 0; |
| 105213 | 105552 | sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); |
| 105214 | 105553 | selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, |
| 105215 | 105554 | pDest, addrEnd, addrEnd); |
| 105216 | 105555 | sqlite3ExprListDelete(db, pDel); |
| 105217 | 105556 | } |
| | @@ -105224,13 +105563,13 @@ |
| 105224 | 105563 | } |
| 105225 | 105564 | |
| 105226 | 105565 | /* If there is an ORDER BY clause, then we need to sort the results |
| 105227 | 105566 | ** and send them to the callback one by one. |
| 105228 | 105567 | */ |
| 105229 | | - if( pOrderBy ){ |
| 105230 | | - explainTempTable(pParse, "ORDER BY"); |
| 105231 | | - generateSortTail(pParse, p, v, pEList->nExpr, pDest); |
| 105568 | + if( sSort.pOrderBy ){ |
| 105569 | + explainTempTable(pParse, sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); |
| 105570 | + generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); |
| 105232 | 105571 | } |
| 105233 | 105572 | |
| 105234 | 105573 | /* Jump here to skip this query |
| 105235 | 105574 | */ |
| 105236 | 105575 | sqlite3VdbeResolveLabel(v, iEnd); |
| | @@ -109064,11 +109403,11 @@ |
| 109064 | 109403 | Index *pIndex; /* Index used, or NULL */ |
| 109065 | 109404 | } btree; |
| 109066 | 109405 | struct { /* Information for virtual tables */ |
| 109067 | 109406 | int idxNum; /* Index number */ |
| 109068 | 109407 | u8 needFree; /* True if sqlite3_free(idxStr) is needed */ |
| 109069 | | - u8 isOrdered; /* True if satisfies ORDER BY */ |
| 109408 | + i8 isOrdered; /* True if satisfies ORDER BY */ |
| 109070 | 109409 | u16 omitMask; /* Terms that may be omitted */ |
| 109071 | 109410 | char *idxStr; /* Index identifier string */ |
| 109072 | 109411 | } vtab; |
| 109073 | 109412 | } u; |
| 109074 | 109413 | u32 wsFlags; /* WHERE_* flags describing the plan */ |
| | @@ -109126,12 +109465,11 @@ |
| 109126 | 109465 | struct WherePath { |
| 109127 | 109466 | Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ |
| 109128 | 109467 | Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ |
| 109129 | 109468 | LogEst nRow; /* Estimated number of rows generated by this path */ |
| 109130 | 109469 | LogEst rCost; /* Total cost of this path */ |
| 109131 | | - u8 isOrdered; /* True if this path satisfies ORDER BY */ |
| 109132 | | - u8 isOrderedValid; /* True if the isOrdered field is valid */ |
| 109470 | + i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ |
| 109133 | 109471 | WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ |
| 109134 | 109472 | }; |
| 109135 | 109473 | |
| 109136 | 109474 | /* |
| 109137 | 109475 | ** The query generator uses an array of instances of this structure to |
| | @@ -109341,11 +109679,11 @@ |
| 109341 | 109679 | ExprList *pResultSet; /* Result set. DISTINCT operates on these */ |
| 109342 | 109680 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 109343 | 109681 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 109344 | 109682 | LogEst nRowOut; /* Estimated number of output rows */ |
| 109345 | 109683 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 109346 | | - u8 bOBSat; /* ORDER BY satisfied by indices */ |
| 109684 | + i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 109347 | 109685 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 109348 | 109686 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 109349 | 109687 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 109350 | 109688 | u8 nLevel; /* Number of nested loop */ |
| 109351 | 109689 | int iTop; /* The very beginning of the WHERE loop */ |
| | @@ -109425,18 +109763,19 @@ |
| 109425 | 109763 | /* |
| 109426 | 109764 | ** Return TRUE if the WHERE clause returns rows in ORDER BY order. |
| 109427 | 109765 | ** Return FALSE if the output needs to be sorted. |
| 109428 | 109766 | */ |
| 109429 | 109767 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ |
| 109430 | | - return pWInfo->bOBSat!=0; |
| 109768 | + return pWInfo->nOBSat; |
| 109431 | 109769 | } |
| 109432 | 109770 | |
| 109433 | 109771 | /* |
| 109434 | 109772 | ** Return the VDBE address or label to jump to in order to continue |
| 109435 | 109773 | ** immediately with the next row of a WHERE clause. |
| 109436 | 109774 | */ |
| 109437 | 109775 | SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ |
| 109776 | + assert( pWInfo->iContinue!=0 ); |
| 109438 | 109777 | return pWInfo->iContinue; |
| 109439 | 109778 | } |
| 109440 | 109779 | |
| 109441 | 109780 | /* |
| 109442 | 109781 | ** Return the VDBE address or label to jump to in order to break |
| | @@ -112226,11 +112565,11 @@ |
| 112226 | 112565 | } |
| 112227 | 112566 | pLevel->op = OP_VNext; |
| 112228 | 112567 | pLevel->p1 = iCur; |
| 112229 | 112568 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 112230 | 112569 | sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); |
| 112231 | | - sqlite3ExprCachePop(pParse, 1); |
| 112570 | + sqlite3ExprCachePop(pParse); |
| 112232 | 112571 | }else |
| 112233 | 112572 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 112234 | 112573 | |
| 112235 | 112574 | if( (pLoop->wsFlags & WHERE_IPK)!=0 |
| 112236 | 112575 | && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 |
| | @@ -112422,12 +112761,15 @@ |
| 112422 | 112761 | ** a single iteration. This means that the first row returned |
| 112423 | 112762 | ** should not have a NULL value stored in 'x'. If column 'x' is |
| 112424 | 112763 | ** the first one after the nEq equality constraints in the index, |
| 112425 | 112764 | ** this requires some special handling. |
| 112426 | 112765 | */ |
| 112766 | + assert( pWInfo->pOrderBy==0 |
| 112767 | + || pWInfo->pOrderBy->nExpr==1 |
| 112768 | + || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 ); |
| 112427 | 112769 | if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 |
| 112428 | | - && (pWInfo->bOBSat!=0) |
| 112770 | + && pWInfo->nOBSat>0 |
| 112429 | 112771 | && (pIdx->nKeyCol>nEq) |
| 112430 | 112772 | ){ |
| 112431 | 112773 | assert( pLoop->u.btree.nSkip==0 ); |
| 112432 | 112774 | bSeekPastNull = 1; |
| 112433 | 112775 | nExtraReg = 1; |
| | @@ -112594,12 +112936,11 @@ |
| 112594 | 112936 | pLevel->op = OP_Prev; |
| 112595 | 112937 | }else{ |
| 112596 | 112938 | pLevel->op = OP_Next; |
| 112597 | 112939 | } |
| 112598 | 112940 | pLevel->p1 = iIdxCur; |
| 112599 | | - assert( (WHERE_UNQ_WANTED>>16)==1 ); |
| 112600 | | - pLevel->p3 = (pLoop->wsFlags>>16)&1; |
| 112941 | + pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; |
| 112601 | 112942 | if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ |
| 112602 | 112943 | pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 112603 | 112944 | }else{ |
| 112604 | 112945 | assert( pLevel->p5==0 ); |
| 112605 | 112946 | } |
| | @@ -113093,10 +113434,141 @@ |
| 113093 | 113434 | whereLoopDelete(db, p); |
| 113094 | 113435 | } |
| 113095 | 113436 | sqlite3DbFree(db, pWInfo); |
| 113096 | 113437 | } |
| 113097 | 113438 | } |
| 113439 | + |
| 113440 | +/* |
| 113441 | +** Return TRUE if both of the following are true: |
| 113442 | +** |
| 113443 | +** (1) X has the same or lower cost that Y |
| 113444 | +** (2) X is a proper subset of Y |
| 113445 | +** |
| 113446 | +** By "proper subset" we mean that X uses fewer WHERE clause terms |
| 113447 | +** than Y and that every WHERE clause term used by X is also used |
| 113448 | +** by Y. |
| 113449 | +** |
| 113450 | +** If X is a proper subset of Y then Y is a better choice and ought |
| 113451 | +** to have a lower cost. This routine returns TRUE when that cost |
| 113452 | +** relationship is inverted and needs to be adjusted. |
| 113453 | +*/ |
| 113454 | +static int whereLoopCheaperProperSubset( |
| 113455 | + const WhereLoop *pX, /* First WhereLoop to compare */ |
| 113456 | + const WhereLoop *pY /* Compare against this WhereLoop */ |
| 113457 | +){ |
| 113458 | + int i, j; |
| 113459 | + if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */ |
| 113460 | + if( pX->rRun >= pY->rRun ){ |
| 113461 | + if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ |
| 113462 | + if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ |
| 113463 | + } |
| 113464 | + for(j=0, i=pX->nLTerm-1; i>=0; i--){ |
| 113465 | + for(j=pY->nLTerm-1; j>=0; j--){ |
| 113466 | + if( pY->aLTerm[j]==pX->aLTerm[i] ) break; |
| 113467 | + } |
| 113468 | + if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ |
| 113469 | + } |
| 113470 | + return 1; /* All conditions meet */ |
| 113471 | +} |
| 113472 | + |
| 113473 | +/* |
| 113474 | +** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so |
| 113475 | +** that: |
| 113476 | +** |
| 113477 | +** (1) pTemplate costs less than any other WhereLoops that are a proper |
| 113478 | +** subset of pTemplate |
| 113479 | +** |
| 113480 | +** (2) pTemplate costs more than any other WhereLoops for which pTemplate |
| 113481 | +** is a proper subset. |
| 113482 | +** |
| 113483 | +** To say "WhereLoop X is a proper subset of Y" means that X uses fewer |
| 113484 | +** WHERE clause terms than Y and that every WHERE clause term used by X is |
| 113485 | +** also used by Y. |
| 113486 | +*/ |
| 113487 | +static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ |
| 113488 | + if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; |
| 113489 | + for(; p; p=p->pNextLoop){ |
| 113490 | + if( p->iTab!=pTemplate->iTab ) continue; |
| 113491 | + if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; |
| 113492 | + if( whereLoopCheaperProperSubset(p, pTemplate) ){ |
| 113493 | + /* Adjust pTemplate cost downward so that it is cheaper than its |
| 113494 | + ** subset p */ |
| 113495 | + pTemplate->rRun = p->rRun; |
| 113496 | + pTemplate->nOut = p->nOut - 1; |
| 113497 | + }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ |
| 113498 | + /* Adjust pTemplate cost upward so that it is costlier than p since |
| 113499 | + ** pTemplate is a proper subset of p */ |
| 113500 | + pTemplate->rRun = p->rRun; |
| 113501 | + pTemplate->nOut = p->nOut + 1; |
| 113502 | + } |
| 113503 | + } |
| 113504 | +} |
| 113505 | + |
| 113506 | +/* |
| 113507 | +** Search the list of WhereLoops in *ppPrev looking for one that can be |
| 113508 | +** supplanted by pTemplate. |
| 113509 | +** |
| 113510 | +** Return NULL if the WhereLoop list contains an entry that can supplant |
| 113511 | +** pTemplate, in other words if pTemplate does not belong on the list. |
| 113512 | +** |
| 113513 | +** If pX is a WhereLoop that pTemplate can supplant, then return the |
| 113514 | +** link that points to pX. |
| 113515 | +** |
| 113516 | +** If pTemplate cannot supplant any existing element of the list but needs |
| 113517 | +** to be added to the list, then return a pointer to the tail of the list. |
| 113518 | +*/ |
| 113519 | +static WhereLoop **whereLoopFindLesser( |
| 113520 | + WhereLoop **ppPrev, |
| 113521 | + const WhereLoop *pTemplate |
| 113522 | +){ |
| 113523 | + WhereLoop *p; |
| 113524 | + for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){ |
| 113525 | + if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ |
| 113526 | + /* If either the iTab or iSortIdx values for two WhereLoop are different |
| 113527 | + ** then those WhereLoops need to be considered separately. Neither is |
| 113528 | + ** a candidate to replace the other. */ |
| 113529 | + continue; |
| 113530 | + } |
| 113531 | + /* In the current implementation, the rSetup value is either zero |
| 113532 | + ** or the cost of building an automatic index (NlogN) and the NlogN |
| 113533 | + ** is the same for compatible WhereLoops. */ |
| 113534 | + assert( p->rSetup==0 || pTemplate->rSetup==0 |
| 113535 | + || p->rSetup==pTemplate->rSetup ); |
| 113536 | + |
| 113537 | + /* whereLoopAddBtree() always generates and inserts the automatic index |
| 113538 | + ** case first. Hence compatible candidate WhereLoops never have a larger |
| 113539 | + ** rSetup. Call this SETUP-INVARIANT */ |
| 113540 | + assert( p->rSetup>=pTemplate->rSetup ); |
| 113541 | + |
| 113542 | + /* If existing WhereLoop p is better than pTemplate, pTemplate can be |
| 113543 | + ** discarded. WhereLoop p is better if: |
| 113544 | + ** (1) p has no more dependencies than pTemplate, and |
| 113545 | + ** (2) p has an equal or lower cost than pTemplate |
| 113546 | + */ |
| 113547 | + if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */ |
| 113548 | + && p->rSetup<=pTemplate->rSetup /* (2a) */ |
| 113549 | + && p->rRun<=pTemplate->rRun /* (2b) */ |
| 113550 | + && p->nOut<=pTemplate->nOut /* (2c) */ |
| 113551 | + ){ |
| 113552 | + return 0; /* Discard pTemplate */ |
| 113553 | + } |
| 113554 | + |
| 113555 | + /* If pTemplate is always better than p, then cause p to be overwritten |
| 113556 | + ** with pTemplate. pTemplate is better than p if: |
| 113557 | + ** (1) pTemplate has no more dependences than p, and |
| 113558 | + ** (2) pTemplate has an equal or lower cost than p. |
| 113559 | + */ |
| 113560 | + if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ |
| 113561 | + && p->rRun>=pTemplate->rRun /* (2a) */ |
| 113562 | + && p->nOut>=pTemplate->nOut /* (2b) */ |
| 113563 | + ){ |
| 113564 | + assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ |
| 113565 | + break; /* Cause p to be overwritten by pTemplate */ |
| 113566 | + } |
| 113567 | + } |
| 113568 | + return ppPrev; |
| 113569 | +} |
| 113098 | 113570 | |
| 113099 | 113571 | /* |
| 113100 | 113572 | ** Insert or replace a WhereLoop entry using the template supplied. |
| 113101 | 113573 | ** |
| 113102 | 113574 | ** An existing WhereLoop entry might be overwritten if the new template |
| | @@ -113103,29 +113575,27 @@ |
| 113103 | 113575 | ** is better and has fewer dependencies. Or the template will be ignored |
| 113104 | 113576 | ** and no insert will occur if an existing WhereLoop is faster and has |
| 113105 | 113577 | ** fewer dependencies than the template. Otherwise a new WhereLoop is |
| 113106 | 113578 | ** added based on the template. |
| 113107 | 113579 | ** |
| 113108 | | -** If pBuilder->pOrSet is not NULL then we only care about only the |
| 113580 | +** If pBuilder->pOrSet is not NULL then we care about only the |
| 113109 | 113581 | ** prerequisites and rRun and nOut costs of the N best loops. That |
| 113110 | 113582 | ** information is gathered in the pBuilder->pOrSet object. This special |
| 113111 | 113583 | ** processing mode is used only for OR clause processing. |
| 113112 | 113584 | ** |
| 113113 | 113585 | ** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we |
| 113114 | 113586 | ** still might overwrite similar loops with the new template if the |
| 113115 | | -** template is better. Loops may be overwritten if the following |
| 113587 | +** new template is better. Loops may be overwritten if the following |
| 113116 | 113588 | ** conditions are met: |
| 113117 | 113589 | ** |
| 113118 | 113590 | ** (1) They have the same iTab. |
| 113119 | 113591 | ** (2) They have the same iSortIdx. |
| 113120 | 113592 | ** (3) The template has same or fewer dependencies than the current loop |
| 113121 | 113593 | ** (4) The template has the same or lower cost than the current loop |
| 113122 | | -** (5) The template uses more terms of the same index but has no additional |
| 113123 | | -** dependencies |
| 113124 | 113594 | */ |
| 113125 | 113595 | static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ |
| 113126 | | - WhereLoop **ppPrev, *p, *pNext = 0; |
| 113596 | + WhereLoop **ppPrev, *p; |
| 113127 | 113597 | WhereInfo *pWInfo = pBuilder->pWInfo; |
| 113128 | 113598 | sqlite3 *db = pWInfo->pParse->db; |
| 113129 | 113599 | |
| 113130 | 113600 | /* If pBuilder->pOrSet is defined, then only keep track of the costs |
| 113131 | 113601 | ** and prereqs. |
| | @@ -113144,68 +113614,27 @@ |
| 113144 | 113614 | } |
| 113145 | 113615 | #endif |
| 113146 | 113616 | return SQLITE_OK; |
| 113147 | 113617 | } |
| 113148 | 113618 | |
| 113149 | | - /* Search for an existing WhereLoop to overwrite, or which takes |
| 113150 | | - ** priority over pTemplate. |
| 113619 | + /* Look for an existing WhereLoop to replace with pTemplate |
| 113151 | 113620 | */ |
| 113152 | | - for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){ |
| 113153 | | - if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ |
| 113154 | | - /* If either the iTab or iSortIdx values for two WhereLoop are different |
| 113155 | | - ** then those WhereLoops need to be considered separately. Neither is |
| 113156 | | - ** a candidate to replace the other. */ |
| 113157 | | - continue; |
| 113158 | | - } |
| 113159 | | - /* In the current implementation, the rSetup value is either zero |
| 113160 | | - ** or the cost of building an automatic index (NlogN) and the NlogN |
| 113161 | | - ** is the same for compatible WhereLoops. */ |
| 113162 | | - assert( p->rSetup==0 || pTemplate->rSetup==0 |
| 113163 | | - || p->rSetup==pTemplate->rSetup ); |
| 113164 | | - |
| 113165 | | - /* whereLoopAddBtree() always generates and inserts the automatic index |
| 113166 | | - ** case first. Hence compatible candidate WhereLoops never have a larger |
| 113167 | | - ** rSetup. Call this SETUP-INVARIANT */ |
| 113168 | | - assert( p->rSetup>=pTemplate->rSetup ); |
| 113169 | | - |
| 113170 | | - if( (p->prereq & pTemplate->prereq)==p->prereq |
| 113171 | | - && p->rSetup<=pTemplate->rSetup |
| 113172 | | - && p->rRun<=pTemplate->rRun |
| 113173 | | - && p->nOut<=pTemplate->nOut |
| 113174 | | - ){ |
| 113175 | | - /* This branch taken when p is equal or better than pTemplate in |
| 113176 | | - ** all of (1) dependencies (2) setup-cost, (3) run-cost, and |
| 113177 | | - ** (4) number of output rows. */ |
| 113178 | | - assert( p->rSetup==pTemplate->rSetup ); |
| 113179 | | - if( p->prereq==pTemplate->prereq |
| 113180 | | - && p->nLTerm<pTemplate->nLTerm |
| 113181 | | - && (p->wsFlags & pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 113182 | | - && (p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 113183 | | - || pTemplate->rRun+p->nLTerm<=p->rRun+pTemplate->nLTerm) |
| 113184 | | - ){ |
| 113185 | | - /* Overwrite an existing WhereLoop with an similar one that uses |
| 113186 | | - ** more terms of the index */ |
| 113187 | | - pNext = p->pNextLoop; |
| 113188 | | - break; |
| 113189 | | - }else{ |
| 113190 | | - /* pTemplate is not helpful. |
| 113191 | | - ** Return without changing or adding anything */ |
| 113192 | | - goto whereLoopInsert_noop; |
| 113193 | | - } |
| 113194 | | - } |
| 113195 | | - if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 113196 | | - && p->rRun>=pTemplate->rRun |
| 113197 | | - && p->nOut>=pTemplate->nOut |
| 113198 | | - ){ |
| 113199 | | - /* Overwrite an existing WhereLoop with a better one: one that is |
| 113200 | | - ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost |
| 113201 | | - ** or (4) number of output rows, and is no worse in any of those |
| 113202 | | - ** categories. */ |
| 113203 | | - assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ |
| 113204 | | - pNext = p->pNextLoop; |
| 113205 | | - break; |
| 113206 | | - } |
| 113621 | + whereLoopAdjustCost(pWInfo->pLoops, pTemplate); |
| 113622 | + ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); |
| 113623 | + |
| 113624 | + if( ppPrev==0 ){ |
| 113625 | + /* There already exists a WhereLoop on the list that is better |
| 113626 | + ** than pTemplate, so just ignore pTemplate */ |
| 113627 | +#if WHERETRACE_ENABLED /* 0x8 */ |
| 113628 | + if( sqlite3WhereTrace & 0x8 ){ |
| 113629 | + sqlite3DebugPrintf("ins-noop: "); |
| 113630 | + whereLoopPrint(pTemplate, pBuilder->pWC); |
| 113631 | + } |
| 113632 | +#endif |
| 113633 | + return SQLITE_OK; |
| 113634 | + }else{ |
| 113635 | + p = *ppPrev; |
| 113207 | 113636 | } |
| 113208 | 113637 | |
| 113209 | 113638 | /* If we reach this point it means that either p[] should be overwritten |
| 113210 | 113639 | ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new |
| 113211 | 113640 | ** WhereLoop and insert it. |
| | @@ -113219,34 +113648,44 @@ |
| 113219 | 113648 | sqlite3DebugPrintf("ins-new: "); |
| 113220 | 113649 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 113221 | 113650 | } |
| 113222 | 113651 | #endif |
| 113223 | 113652 | if( p==0 ){ |
| 113224 | | - p = sqlite3DbMallocRaw(db, sizeof(WhereLoop)); |
| 113653 | + /* Allocate a new WhereLoop to add to the end of the list */ |
| 113654 | + *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop)); |
| 113225 | 113655 | if( p==0 ) return SQLITE_NOMEM; |
| 113226 | 113656 | whereLoopInit(p); |
| 113657 | + p->pNextLoop = 0; |
| 113658 | + }else{ |
| 113659 | + /* We will be overwriting WhereLoop p[]. But before we do, first |
| 113660 | + ** go through the rest of the list and delete any other entries besides |
| 113661 | + ** p[] that are also supplated by pTemplate */ |
| 113662 | + WhereLoop **ppTail = &p->pNextLoop; |
| 113663 | + WhereLoop *pToDel; |
| 113664 | + while( *ppTail ){ |
| 113665 | + ppTail = whereLoopFindLesser(ppTail, pTemplate); |
| 113666 | + if( NEVER(ppTail==0) ) break; |
| 113667 | + pToDel = *ppTail; |
| 113668 | + if( pToDel==0 ) break; |
| 113669 | + *ppTail = pToDel->pNextLoop; |
| 113670 | +#if WHERETRACE_ENABLED /* 0x8 */ |
| 113671 | + if( sqlite3WhereTrace & 0x8 ){ |
| 113672 | + sqlite3DebugPrintf("ins-del: "); |
| 113673 | + whereLoopPrint(pToDel, pBuilder->pWC); |
| 113674 | + } |
| 113675 | +#endif |
| 113676 | + whereLoopDelete(db, pToDel); |
| 113677 | + } |
| 113227 | 113678 | } |
| 113228 | 113679 | whereLoopXfer(db, p, pTemplate); |
| 113229 | | - p->pNextLoop = pNext; |
| 113230 | | - *ppPrev = p; |
| 113231 | 113680 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 113232 | 113681 | Index *pIndex = p->u.btree.pIndex; |
| 113233 | 113682 | if( pIndex && pIndex->tnum==0 ){ |
| 113234 | 113683 | p->u.btree.pIndex = 0; |
| 113235 | 113684 | } |
| 113236 | 113685 | } |
| 113237 | 113686 | return SQLITE_OK; |
| 113238 | | - |
| 113239 | | - /* Jump here if the insert is a no-op */ |
| 113240 | | -whereLoopInsert_noop: |
| 113241 | | -#if WHERETRACE_ENABLED /* 0x8 */ |
| 113242 | | - if( sqlite3WhereTrace & 0x8 ){ |
| 113243 | | - sqlite3DebugPrintf("ins-noop: "); |
| 113244 | | - whereLoopPrint(pTemplate, pBuilder->pWC); |
| 113245 | | - } |
| 113246 | | -#endif |
| 113247 | | - return SQLITE_OK; |
| 113248 | 113687 | } |
| 113249 | 113688 | |
| 113250 | 113689 | /* |
| 113251 | 113690 | ** Adjust the WhereLoop.nOut value downward to account for terms of the |
| 113252 | 113691 | ** WHERE clause that reference the loop but which are not used by an |
| | @@ -113396,10 +113835,12 @@ |
| 113396 | 113835 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| 113397 | 113836 | }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ |
| 113398 | 113837 | /* "x IN (value, value, ...)" */ |
| 113399 | 113838 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 113400 | 113839 | } |
| 113840 | + assert( nIn>0 ); /* RHS always has 2 or more terms... The parser |
| 113841 | + ** changes "x IN (?)" into "x=?". */ |
| 113401 | 113842 | pNew->rRun += nIn; |
| 113402 | 113843 | pNew->u.btree.nEq++; |
| 113403 | 113844 | pNew->nOut = nRowEst + nInMul + nIn; |
| 113404 | 113845 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| 113405 | 113846 | assert( |
| | @@ -113709,22 +114150,38 @@ |
| 113709 | 114150 | && sqlite3GlobalConfig.bUseCis |
| 113710 | 114151 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 113711 | 114152 | ) |
| 113712 | 114153 | ){ |
| 113713 | 114154 | pNew->iSortIdx = b ? iSortIdx : 0; |
| 114155 | + /* TUNING: The base cost of an index scan is N + log2(N). |
| 114156 | + ** The log2(N) is for the initial seek to the beginning and the N |
| 114157 | + ** is for the scan itself. */ |
| 114158 | + pNew->rRun = sqlite3LogEstAdd(rSize, rLogSize); |
| 113714 | 114159 | if( m==0 ){ |
| 113715 | 114160 | /* TUNING: Cost of a covering index scan is K*(N + log2(N)). |
| 113716 | 114161 | ** + The extra factor K of between 1.1 and 3.0 that depends |
| 113717 | 114162 | ** on the relative sizes of the table and the index. K |
| 113718 | 114163 | ** is smaller for smaller indices, thus favoring them. |
| 114164 | + ** The upper bound on K (3.0) matches the penalty factor |
| 114165 | + ** on a full table scan that tries to encourage the use of |
| 114166 | + ** indexed lookups over full scans. |
| 114167 | + */ |
| 114168 | + pNew->rRun += 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 114169 | + }else{ |
| 114170 | + /* TUNING: The cost of scanning a non-covering index is multiplied |
| 114171 | + ** by log2(N) to account for the binary search of the main table |
| 114172 | + ** that must happen for each row of the index. |
| 114173 | + ** TODO: Should there be a multiplier here, analogous to the 3x |
| 114174 | + ** multiplier for a fulltable scan or covering index scan, to |
| 114175 | + ** further discourage the use of an index scan? Or is the log2(N) |
| 114176 | + ** term sufficient discouragement? |
| 114177 | + ** TODO: What if some or all of the WHERE clause terms can be |
| 114178 | + ** computed without reference to the original table. Then the |
| 114179 | + ** penality should reduce to logK where K is the number of output |
| 114180 | + ** rows. |
| 113719 | 114181 | */ |
| 113720 | | - pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 + |
| 113721 | | - (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 113722 | | - }else{ |
| 113723 | | - /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) |
| 113724 | | - ** which we will simplify to just N*log2(N) */ |
| 113725 | | - pNew->rRun = rSize + rLogSize; |
| 114182 | + pNew->rRun += rLogSize; |
| 113726 | 114183 | } |
| 113727 | 114184 | whereLoopOutputAdjust(pWC, pNew); |
| 113728 | 114185 | rc = whereLoopInsert(pBuilder, pNew); |
| 113729 | 114186 | pNew->nOut = rSize; |
| 113730 | 114187 | if( rc ) break; |
| | @@ -113892,12 +114349,12 @@ |
| 113892 | 114349 | assert( pNew->nLTerm<=pNew->nLSlot ); |
| 113893 | 114350 | pNew->u.vtab.idxNum = pIdxInfo->idxNum; |
| 113894 | 114351 | pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; |
| 113895 | 114352 | pIdxInfo->needToFreeIdxStr = 0; |
| 113896 | 114353 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; |
| 113897 | | - pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) |
| 113898 | | - && pIdxInfo->orderByConsumed); |
| 114354 | + pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? |
| 114355 | + pIdxInfo->nOrderBy : 0); |
| 113899 | 114356 | pNew->rSetup = 0; |
| 113900 | 114357 | pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); |
| 113901 | 114358 | pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); |
| 113902 | 114359 | whereLoopInsert(pBuilder, pNew); |
| 113903 | 114360 | if( pNew->u.vtab.needFree ){ |
| | @@ -114054,25 +114511,25 @@ |
| 114054 | 114511 | } |
| 114055 | 114512 | |
| 114056 | 114513 | /* |
| 114057 | 114514 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 5th |
| 114058 | 114515 | ** parameters) to see if it outputs rows in the requested ORDER BY |
| 114059 | | -** (or GROUP BY) without requiring a separate sort operation. Return: |
| 114516 | +** (or GROUP BY) without requiring a separate sort operation. Return N: |
| 114060 | 114517 | ** |
| 114061 | | -** 0: ORDER BY is not satisfied. Sorting required |
| 114062 | | -** 1: ORDER BY is satisfied. Omit sorting |
| 114063 | | -** -1: Unknown at this time |
| 114518 | +** N>0: N terms of the ORDER BY clause are satisfied |
| 114519 | +** N==0: No terms of the ORDER BY clause are satisfied |
| 114520 | +** N<0: Unknown yet how many terms of ORDER BY might be satisfied. |
| 114064 | 114521 | ** |
| 114065 | 114522 | ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 114066 | 114523 | ** strict. With GROUP BY and DISTINCT the only requirement is that |
| 114067 | 114524 | ** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 114068 | 114525 | ** and DISTINT do not require rows to appear in any particular order as long |
| 114069 | 114526 | ** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 114070 | 114527 | ** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 114071 | 114528 | ** pOrderBy terms must be matched in strict left-to-right order. |
| 114072 | 114529 | */ |
| 114073 | | -static int wherePathSatisfiesOrderBy( |
| 114530 | +static i8 wherePathSatisfiesOrderBy( |
| 114074 | 114531 | WhereInfo *pWInfo, /* The WHERE clause */ |
| 114075 | 114532 | ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ |
| 114076 | 114533 | WherePath *pPath, /* The WherePath to check */ |
| 114077 | 114534 | u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */ |
| 114078 | 114535 | u16 nLoop, /* Number of entries in pPath->aLoop[] */ |
| | @@ -114252,28 +114709,28 @@ |
| 114252 | 114709 | if( !pColl ) pColl = db->pDfltColl; |
| 114253 | 114710 | if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; |
| 114254 | 114711 | } |
| 114255 | 114712 | isMatch = 1; |
| 114256 | 114713 | break; |
| 114714 | + } |
| 114715 | + if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 114716 | + /* Make sure the sort order is compatible in an ORDER BY clause. |
| 114717 | + ** Sort order is irrelevant for a GROUP BY clause. */ |
| 114718 | + if( revSet ){ |
| 114719 | + if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; |
| 114720 | + }else{ |
| 114721 | + rev = revIdx ^ pOrderBy->a[i].sortOrder; |
| 114722 | + if( rev ) *pRevMask |= MASKBIT(iLoop); |
| 114723 | + revSet = 1; |
| 114724 | + } |
| 114257 | 114725 | } |
| 114258 | 114726 | if( isMatch ){ |
| 114259 | 114727 | if( iColumn<0 ){ |
| 114260 | 114728 | testcase( distinctColumns==0 ); |
| 114261 | 114729 | distinctColumns = 1; |
| 114262 | 114730 | } |
| 114263 | 114731 | obSat |= MASKBIT(i); |
| 114264 | | - if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 114265 | | - /* Make sure the sort order is compatible in an ORDER BY clause. |
| 114266 | | - ** Sort order is irrelevant for a GROUP BY clause. */ |
| 114267 | | - if( revSet ){ |
| 114268 | | - if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) return 0; |
| 114269 | | - }else{ |
| 114270 | | - rev = revIdx ^ pOrderBy->a[i].sortOrder; |
| 114271 | | - if( rev ) *pRevMask |= MASKBIT(iLoop); |
| 114272 | | - revSet = 1; |
| 114273 | | - } |
| 114274 | | - } |
| 114275 | 114732 | }else{ |
| 114276 | 114733 | /* No match found */ |
| 114277 | 114734 | if( j==0 || j<nKeyCol ){ |
| 114278 | 114735 | testcase( isOrderDistinct!=0 ); |
| 114279 | 114736 | isOrderDistinct = 0; |
| | @@ -114301,12 +114758,18 @@ |
| 114301 | 114758 | obSat |= MASKBIT(i); |
| 114302 | 114759 | } |
| 114303 | 114760 | } |
| 114304 | 114761 | } |
| 114305 | 114762 | } /* End the loop over all WhereLoops from outer-most down to inner-most */ |
| 114306 | | - if( obSat==obDone ) return 1; |
| 114307 | | - if( !isOrderDistinct ) return 0; |
| 114763 | + if( obSat==obDone ) return (i8)nOrderBy; |
| 114764 | + if( !isOrderDistinct ){ |
| 114765 | + for(i=nOrderBy-1; i>0; i--){ |
| 114766 | + Bitmask m = MASKBIT(i) - 1; |
| 114767 | + if( (obSat&m)==m ) return i; |
| 114768 | + } |
| 114769 | + return 0; |
| 114770 | + } |
| 114308 | 114771 | return -1; |
| 114309 | 114772 | } |
| 114310 | 114773 | |
| 114311 | 114774 | #ifdef WHERETRACE_ENABLED |
| 114312 | 114775 | /* For debugging use only: */ |
| | @@ -114339,15 +114802,15 @@ |
| 114339 | 114802 | Parse *pParse; /* Parsing context */ |
| 114340 | 114803 | sqlite3 *db; /* The database connection */ |
| 114341 | 114804 | int iLoop; /* Loop counter over the terms of the join */ |
| 114342 | 114805 | int ii, jj; /* Loop counters */ |
| 114343 | 114806 | int mxI = 0; /* Index of next entry to replace */ |
| 114807 | + int nOrderBy; /* Number of ORDER BY clause terms */ |
| 114344 | 114808 | LogEst rCost; /* Cost of a path */ |
| 114345 | 114809 | LogEst nOut; /* Number of outputs */ |
| 114346 | 114810 | LogEst mxCost = 0; /* Maximum cost of a set of paths */ |
| 114347 | 114811 | LogEst mxOut = 0; /* Maximum nOut value on the set of paths */ |
| 114348 | | - LogEst rSortCost; /* Cost to do a sort */ |
| 114349 | 114812 | int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ |
| 114350 | 114813 | WherePath *aFrom; /* All nFrom paths at the previous level */ |
| 114351 | 114814 | WherePath *aTo; /* The nTo best paths at the current level */ |
| 114352 | 114815 | WherePath *pFrom; /* An element of aFrom[] that we are working on */ |
| 114353 | 114816 | WherePath *pTo; /* An element of aTo[] that we are working on */ |
| | @@ -114385,20 +114848,16 @@ |
| 114385 | 114848 | aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) ); |
| 114386 | 114849 | nFrom = 1; |
| 114387 | 114850 | |
| 114388 | 114851 | /* Precompute the cost of sorting the final result set, if the caller |
| 114389 | 114852 | ** to sqlite3WhereBegin() was concerned about sorting */ |
| 114390 | | - rSortCost = 0; |
| 114391 | 114853 | if( pWInfo->pOrderBy==0 || nRowEst==0 ){ |
| 114392 | | - aFrom[0].isOrderedValid = 1; |
| 114854 | + aFrom[0].isOrdered = 0; |
| 114855 | + nOrderBy = 0; |
| 114393 | 114856 | }else{ |
| 114394 | | - /* TUNING: Estimated cost of sorting is 48*N*log2(N) where N is the |
| 114395 | | - ** number of output rows. The 48 is the expected size of a row to sort. |
| 114396 | | - ** FIXME: compute a better estimate of the 48 multiplier based on the |
| 114397 | | - ** result set expressions. */ |
| 114398 | | - rSortCost = nRowEst + estLog(nRowEst); |
| 114399 | | - WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost)); |
| 114857 | + aFrom[0].isOrdered = -1; |
| 114858 | + nOrderBy = pWInfo->pOrderBy->nExpr; |
| 114400 | 114859 | } |
| 114401 | 114860 | |
| 114402 | 114861 | /* Compute successively longer WherePaths using the previous generation |
| 114403 | 114862 | ** of WherePaths as the basis for the next. Keep track of the mxChoice |
| 114404 | 114863 | ** best paths at each generation */ |
| | @@ -114406,43 +114865,56 @@ |
| 114406 | 114865 | nTo = 0; |
| 114407 | 114866 | for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){ |
| 114408 | 114867 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ |
| 114409 | 114868 | Bitmask maskNew; |
| 114410 | 114869 | Bitmask revMask = 0; |
| 114411 | | - u8 isOrderedValid = pFrom->isOrderedValid; |
| 114412 | | - u8 isOrdered = pFrom->isOrdered; |
| 114870 | + i8 isOrdered = pFrom->isOrdered; |
| 114413 | 114871 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; |
| 114414 | 114872 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| 114415 | 114873 | /* At this point, pWLoop is a candidate to be the next loop. |
| 114416 | 114874 | ** Compute its cost */ |
| 114417 | 114875 | rCost = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 114418 | 114876 | rCost = sqlite3LogEstAdd(rCost, pFrom->rCost); |
| 114419 | 114877 | nOut = pFrom->nRow + pWLoop->nOut; |
| 114420 | 114878 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 114421 | | - if( !isOrderedValid ){ |
| 114422 | | - switch( wherePathSatisfiesOrderBy(pWInfo, |
| 114879 | + if( isOrdered<0 ){ |
| 114880 | + isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 114423 | 114881 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 114424 | | - iLoop, pWLoop, &revMask) ){ |
| 114425 | | - case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */ |
| 114426 | | - isOrdered = 1; |
| 114427 | | - isOrderedValid = 1; |
| 114428 | | - break; |
| 114429 | | - case 0: /* No. pFrom+pWLoop will require a separate sort */ |
| 114430 | | - isOrdered = 0; |
| 114431 | | - isOrderedValid = 1; |
| 114432 | | - rCost = sqlite3LogEstAdd(rCost, rSortCost); |
| 114433 | | - break; |
| 114434 | | - default: /* Cannot tell yet. Try again on the next iteration */ |
| 114435 | | - break; |
| 114882 | + iLoop, pWLoop, &revMask); |
| 114883 | + if( isOrdered>=0 && isOrdered<nOrderBy ){ |
| 114884 | + /* TUNING: Estimated cost of sorting is N*log(N). |
| 114885 | + ** If the order-by clause has X terms but only the last Y terms |
| 114886 | + ** are out of order, then block-sorting will reduce the sorting |
| 114887 | + ** cost to N*log(N)*log(Y/X). The log(Y/X) term is computed |
| 114888 | + ** by rScale. |
| 114889 | + ** TODO: Should the sorting cost get a small multiplier to help |
| 114890 | + ** discourage the use of sorting and encourage the use of index |
| 114891 | + ** scans instead? |
| 114892 | + */ |
| 114893 | + LogEst rScale, rSortCost; |
| 114894 | + assert( nOrderBy>0 ); |
| 114895 | + rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66; |
| 114896 | + rSortCost = nRowEst + estLog(nRowEst) + rScale; |
| 114897 | + /* TUNING: The cost of implementing DISTINCT using a B-TREE is |
| 114898 | + ** also N*log(N) but it has a larger constant of proportionality. |
| 114899 | + ** Multiply by 3.0. */ |
| 114900 | + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114901 | + rSortCost += 16; |
| 114902 | + } |
| 114903 | + WHERETRACE(0x002, |
| 114904 | + ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", |
| 114905 | + rSortCost, (nOrderBy-isOrdered), nOrderBy, rCost, |
| 114906 | + sqlite3LogEstAdd(rCost,rSortCost))); |
| 114907 | + rCost = sqlite3LogEstAdd(rCost, rSortCost); |
| 114436 | 114908 | } |
| 114437 | 114909 | }else{ |
| 114438 | 114910 | revMask = pFrom->revLoop; |
| 114439 | 114911 | } |
| 114440 | 114912 | /* Check to see if pWLoop should be added to the mxChoice best so far */ |
| 114441 | 114913 | for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ |
| 114442 | 114914 | if( pTo->maskLoop==maskNew |
| 114443 | | - && pTo->isOrderedValid==isOrderedValid |
| 114915 | + && ((pTo->isOrdered^isOrdered)&80)==0 |
| 114444 | 114916 | && ((pTo->rCost<=rCost && pTo->nRow<=nOut) || |
| 114445 | 114917 | (pTo->rCost>=rCost && pTo->nRow>=nOut)) |
| 114446 | 114918 | ){ |
| 114447 | 114919 | testcase( jj==nTo-1 ); |
| 114448 | 114920 | break; |
| | @@ -114452,11 +114924,11 @@ |
| 114452 | 114924 | if( nTo>=mxChoice && rCost>=mxCost ){ |
| 114453 | 114925 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114454 | 114926 | if( sqlite3WhereTrace&0x4 ){ |
| 114455 | 114927 | sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n", |
| 114456 | 114928 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114457 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114929 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114458 | 114930 | } |
| 114459 | 114931 | #endif |
| 114460 | 114932 | continue; |
| 114461 | 114933 | } |
| 114462 | 114934 | /* Add a new Path to the aTo[] set */ |
| | @@ -114470,24 +114942,24 @@ |
| 114470 | 114942 | pTo = &aTo[jj]; |
| 114471 | 114943 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114472 | 114944 | if( sqlite3WhereTrace&0x4 ){ |
| 114473 | 114945 | sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n", |
| 114474 | 114946 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114475 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114947 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114476 | 114948 | } |
| 114477 | 114949 | #endif |
| 114478 | 114950 | }else{ |
| 114479 | 114951 | if( pTo->rCost<=rCost && pTo->nRow<=nOut ){ |
| 114480 | 114952 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114481 | 114953 | if( sqlite3WhereTrace&0x4 ){ |
| 114482 | 114954 | sqlite3DebugPrintf( |
| 114483 | 114955 | "Skip %s cost=%-3d,%3d order=%c", |
| 114484 | 114956 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114485 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114957 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114486 | 114958 | sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n", |
| 114487 | 114959 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114488 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114960 | + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); |
| 114489 | 114961 | } |
| 114490 | 114962 | #endif |
| 114491 | 114963 | testcase( pTo->rCost==rCost ); |
| 114492 | 114964 | continue; |
| 114493 | 114965 | } |
| | @@ -114496,23 +114968,22 @@ |
| 114496 | 114968 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114497 | 114969 | if( sqlite3WhereTrace&0x4 ){ |
| 114498 | 114970 | sqlite3DebugPrintf( |
| 114499 | 114971 | "Update %s cost=%-3d,%3d order=%c", |
| 114500 | 114972 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114501 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114973 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114502 | 114974 | sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n", |
| 114503 | 114975 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114504 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114976 | + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); |
| 114505 | 114977 | } |
| 114506 | 114978 | #endif |
| 114507 | 114979 | } |
| 114508 | 114980 | /* pWLoop is a winner. Add it to the set of best so far */ |
| 114509 | 114981 | pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; |
| 114510 | 114982 | pTo->revLoop = revMask; |
| 114511 | 114983 | pTo->nRow = nOut; |
| 114512 | 114984 | pTo->rCost = rCost; |
| 114513 | | - pTo->isOrderedValid = isOrderedValid; |
| 114514 | 114985 | pTo->isOrdered = isOrdered; |
| 114515 | 114986 | memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); |
| 114516 | 114987 | pTo->aLoop[iLoop] = pWLoop; |
| 114517 | 114988 | if( nTo>=mxChoice ){ |
| 114518 | 114989 | mxI = 0; |
| | @@ -114533,12 +115004,12 @@ |
| 114533 | 115004 | if( sqlite3WhereTrace>=2 ){ |
| 114534 | 115005 | sqlite3DebugPrintf("---- after round %d ----\n", iLoop); |
| 114535 | 115006 | for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ |
| 114536 | 115007 | sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", |
| 114537 | 115008 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114538 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114539 | | - if( pTo->isOrderedValid && pTo->isOrdered ){ |
| 115009 | + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); |
| 115010 | + if( pTo->isOrdered>0 ){ |
| 114540 | 115011 | sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); |
| 114541 | 115012 | }else{ |
| 114542 | 115013 | sqlite3DebugPrintf("\n"); |
| 114543 | 115014 | } |
| 114544 | 115015 | } |
| | @@ -114577,17 +115048,22 @@ |
| 114577 | 115048 | && nRowEst |
| 114578 | 115049 | ){ |
| 114579 | 115050 | Bitmask notUsed; |
| 114580 | 115051 | int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, |
| 114581 | 115052 | WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); |
| 114582 | | - if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115053 | + if( rc==pWInfo->pResultSet->nExpr ){ |
| 115054 | + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115055 | + } |
| 114583 | 115056 | } |
| 114584 | | - if( pFrom->isOrdered ){ |
| 115057 | + if( pWInfo->pOrderBy ){ |
| 114585 | 115058 | if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ |
| 114586 | | - pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115059 | + if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ |
| 115060 | + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115061 | + } |
| 114587 | 115062 | }else{ |
| 114588 | | - pWInfo->bOBSat = 1; |
| 115063 | + pWInfo->nOBSat = pFrom->isOrdered; |
| 115064 | + if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; |
| 114589 | 115065 | pWInfo->revMask = pFrom->revLoop; |
| 114590 | 115066 | } |
| 114591 | 115067 | } |
| 114592 | 115068 | pWInfo->nRowOut = pFrom->nRow; |
| 114593 | 115069 | |
| | @@ -114668,11 +115144,11 @@ |
| 114668 | 115144 | pLoop->nOut = (LogEst)1; |
| 114669 | 115145 | pWInfo->a[0].pWLoop = pLoop; |
| 114670 | 115146 | pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); |
| 114671 | 115147 | pWInfo->a[0].iTabCur = iCur; |
| 114672 | 115148 | pWInfo->nRowOut = 1; |
| 114673 | | - if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; |
| 115149 | + if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; |
| 114674 | 115150 | if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114675 | 115151 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 114676 | 115152 | } |
| 114677 | 115153 | #ifdef SQLITE_DEBUG |
| 114678 | 115154 | pLoop->cId = '0'; |
| | @@ -114772,11 +115248,11 @@ |
| 114772 | 115248 | */ |
| 114773 | 115249 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 114774 | 115250 | Parse *pParse, /* The parser context */ |
| 114775 | 115251 | SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ |
| 114776 | 115252 | Expr *pWhere, /* The WHERE clause */ |
| 114777 | | - ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ |
| 115253 | + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ |
| 114778 | 115254 | ExprList *pResultSet, /* Result set of the query */ |
| 114779 | 115255 | u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ |
| 114780 | 115256 | int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ |
| 114781 | 115257 | ){ |
| 114782 | 115258 | int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ |
| | @@ -114794,10 +115270,14 @@ |
| 114794 | 115270 | |
| 114795 | 115271 | |
| 114796 | 115272 | /* Variable initialization */ |
| 114797 | 115273 | db = pParse->db; |
| 114798 | 115274 | memset(&sWLB, 0, sizeof(sWLB)); |
| 115275 | + |
| 115276 | + /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ |
| 115277 | + testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); |
| 115278 | + if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; |
| 114799 | 115279 | sWLB.pOrderBy = pOrderBy; |
| 114800 | 115280 | |
| 114801 | 115281 | /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 114802 | 115282 | ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 114803 | 115283 | if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ |
| | @@ -114838,11 +115318,11 @@ |
| 114838 | 115318 | pWInfo->nLevel = nTabList; |
| 114839 | 115319 | pWInfo->pParse = pParse; |
| 114840 | 115320 | pWInfo->pTabList = pTabList; |
| 114841 | 115321 | pWInfo->pOrderBy = pOrderBy; |
| 114842 | 115322 | pWInfo->pResultSet = pResultSet; |
| 114843 | | - pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
| 115323 | + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); |
| 114844 | 115324 | pWInfo->wctrlFlags = wctrlFlags; |
| 114845 | 115325 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 114846 | 115326 | pMaskSet = &pWInfo->sMaskSet; |
| 114847 | 115327 | sWLB.pWInfo = pWInfo; |
| 114848 | 115328 | sWLB.pWC = &pWInfo->sWC; |
| | @@ -114872,11 +115352,11 @@ |
| 114872 | 115352 | } |
| 114873 | 115353 | |
| 114874 | 115354 | /* Special case: No FROM clause |
| 114875 | 115355 | */ |
| 114876 | 115356 | if( nTabList==0 ){ |
| 114877 | | - if( pOrderBy ) pWInfo->bOBSat = 1; |
| 115357 | + if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; |
| 114878 | 115358 | if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114879 | 115359 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 114880 | 115360 | } |
| 114881 | 115361 | } |
| 114882 | 115362 | |
| | @@ -114983,12 +115463,12 @@ |
| 114983 | 115463 | } |
| 114984 | 115464 | #ifdef WHERETRACE_ENABLED /* !=0 */ |
| 114985 | 115465 | if( sqlite3WhereTrace ){ |
| 114986 | 115466 | int ii; |
| 114987 | 115467 | sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); |
| 114988 | | - if( pWInfo->bOBSat ){ |
| 114989 | | - sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask); |
| 115468 | + if( pWInfo->nOBSat>0 ){ |
| 115469 | + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); |
| 114990 | 115470 | } |
| 114991 | 115471 | switch( pWInfo->eDistinct ){ |
| 114992 | 115472 | case WHERE_DISTINCT_UNIQUE: { |
| 114993 | 115473 | sqlite3DebugPrintf(" DISTINCT=unique"); |
| 114994 | 115474 | break; |
| | @@ -115266,11 +115746,11 @@ |
| 115266 | 115746 | k = pLevel->addrBody; |
| 115267 | 115747 | pOp = sqlite3VdbeGetOp(v, k); |
| 115268 | 115748 | for(; k<last; k++, pOp++){ |
| 115269 | 115749 | if( pOp->p1!=pLevel->iTabCur ) continue; |
| 115270 | 115750 | if( pOp->opcode==OP_Column ){ |
| 115271 | | - pOp->opcode = OP_SCopy; |
| 115751 | + pOp->opcode = OP_Copy; |
| 115272 | 115752 | pOp->p1 = pOp->p2 + pTabItem->regResult; |
| 115273 | 115753 | pOp->p2 = pOp->p3; |
| 115274 | 115754 | pOp->p3 = 0; |
| 115275 | 115755 | }else if( pOp->opcode==OP_Rowid ){ |
| 115276 | 115756 | pOp->opcode = OP_Null; |
| | @@ -118214,10 +118694,37 @@ |
| 118214 | 118694 | ** simplify to constants 0 (false) and 1 (true), respectively, |
| 118215 | 118695 | ** regardless of the value of expr1. |
| 118216 | 118696 | */ |
| 118217 | 118697 | yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy328]); |
| 118218 | 118698 | sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy346.pExpr); |
| 118699 | + }else if( yymsp[-1].minor.yy14->nExpr==1 ){ |
| 118700 | + /* Expressions of the form: |
| 118701 | + ** |
| 118702 | + ** expr1 IN (?1) |
| 118703 | + ** expr1 NOT IN (?2) |
| 118704 | + ** |
| 118705 | + ** with exactly one value on the RHS can be simplified to something |
| 118706 | + ** like this: |
| 118707 | + ** |
| 118708 | + ** expr1 == ?1 |
| 118709 | + ** expr1 <> ?2 |
| 118710 | + ** |
| 118711 | + ** But, the RHS of the == or <> is marked with the EP_Generic flag |
| 118712 | + ** so that it may not contribute to the computation of comparison |
| 118713 | + ** affinity or the collating sequence to use for comparison. Otherwise, |
| 118714 | + ** the semantics would be subtly different from IN or NOT IN. |
| 118715 | + */ |
| 118716 | + Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; |
| 118717 | + yymsp[-1].minor.yy14->a[0].pExpr = 0; |
| 118718 | + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); |
| 118719 | + /* pRHS cannot be NULL because a malloc error would have been detected |
| 118720 | + ** before now and control would have never reached this point */ |
| 118721 | + if( ALWAYS(pRHS) ){ |
| 118722 | + pRHS->flags &= ~EP_Collate; |
| 118723 | + pRHS->flags |= EP_Generic; |
| 118724 | + } |
| 118725 | + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy328 ? TK_NE : TK_EQ, yymsp[-4].minor.yy346.pExpr, pRHS, 0); |
| 118219 | 118726 | }else{ |
| 118220 | 118727 | yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); |
| 118221 | 118728 | if( yygotominor.yy346.pExpr ){ |
| 118222 | 118729 | yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; |
| 118223 | 118730 | sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); |
| | @@ -120834,10 +121341,11 @@ |
| 120834 | 121341 | Table *pTab = (Table *)sqliteHashData(p); |
| 120835 | 121342 | if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); |
| 120836 | 121343 | } |
| 120837 | 121344 | } |
| 120838 | 121345 | } |
| 121346 | + sqlite3VtabUnlockList(db); |
| 120839 | 121347 | sqlite3BtreeLeaveAll(db); |
| 120840 | 121348 | #else |
| 120841 | 121349 | UNUSED_PARAMETER(db); |
| 120842 | 121350 | #endif |
| 120843 | 121351 | } |
| | @@ -123237,10 +123745,26 @@ |
| 123237 | 123745 | case SQLITE_TESTCTRL_ALWAYS: { |
| 123238 | 123746 | int x = va_arg(ap,int); |
| 123239 | 123747 | rc = ALWAYS(x); |
| 123240 | 123748 | break; |
| 123241 | 123749 | } |
| 123750 | + |
| 123751 | + /* |
| 123752 | + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); |
| 123753 | + ** |
| 123754 | + ** The integer returned reveals the byte-order of the computer on which |
| 123755 | + ** SQLite is running: |
| 123756 | + ** |
| 123757 | + ** 1 big-endian, determined at run-time |
| 123758 | + ** 10 little-endian, determined at run-time |
| 123759 | + ** 432101 big-endian, determined at compile-time |
| 123760 | + ** 123410 little-endian, determined at compile-time |
| 123761 | + */ |
| 123762 | + case SQLITE_TESTCTRL_BYTEORDER: { |
| 123763 | + rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; |
| 123764 | + break; |
| 123765 | + } |
| 123242 | 123766 | |
| 123243 | 123767 | /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) |
| 123244 | 123768 | ** |
| 123245 | 123769 | ** Set the nReserve size to N for the main database on the database |
| 123246 | 123770 | ** connection db. |
| | @@ -124573,11 +125097,11 @@ |
| 124573 | 125097 | char *zReadExprlist; |
| 124574 | 125098 | char *zWriteExprlist; |
| 124575 | 125099 | |
| 124576 | 125100 | int nNodeSize; /* Soft limit for node size */ |
| 124577 | 125101 | u8 bFts4; /* True for FTS4, false for FTS3 */ |
| 124578 | | - u8 bHasStat; /* True if %_stat table exists */ |
| 125102 | + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ |
| 124579 | 125103 | u8 bHasDocsize; /* True if %_docsize table exists */ |
| 124580 | 125104 | u8 bDescIdx; /* True if doclists are in reverse order */ |
| 124581 | 125105 | u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ |
| 124582 | 125106 | int nPgsz; /* Page size for host database */ |
| 124583 | 125107 | char *zSegmentsTbl; /* Name of %_segments table */ |
| | @@ -126065,14 +126589,11 @@ |
| 126065 | 126589 | |
| 126066 | 126590 | /* Check to see if a legacy fts3 table has been "upgraded" by the |
| 126067 | 126591 | ** addition of a %_stat table so that it can use incremental merge. |
| 126068 | 126592 | */ |
| 126069 | 126593 | if( !isFts4 && !isCreate ){ |
| 126070 | | - int rc2 = SQLITE_OK; |
| 126071 | | - fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2", |
| 126072 | | - p->zDb, p->zName); |
| 126073 | | - if( rc2==SQLITE_OK ) p->bHasStat = 1; |
| 126594 | + p->bHasStat = 2; |
| 126074 | 126595 | } |
| 126075 | 126596 | |
| 126076 | 126597 | /* Figure out the page-size for the database. This is required in order to |
| 126077 | 126598 | ** estimate the cost of loading large doclists from the database. */ |
| 126078 | 126599 | fts3DatabasePageSize(&rc, p); |
| | @@ -127975,11 +128496,38 @@ |
| 127975 | 128496 | sqlite3Fts3SegmentsClose(p); |
| 127976 | 128497 | return rc; |
| 127977 | 128498 | } |
| 127978 | 128499 | |
| 127979 | 128500 | /* |
| 127980 | | -** Implementation of xBegin() method. This is a no-op. |
| 128501 | +** If it is currently unknown whether or not the FTS table has an %_stat |
| 128502 | +** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat |
| 128503 | +** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code |
| 128504 | +** if an error occurs. |
| 128505 | +*/ |
| 128506 | +static int fts3SetHasStat(Fts3Table *p){ |
| 128507 | + int rc = SQLITE_OK; |
| 128508 | + if( p->bHasStat==2 ){ |
| 128509 | + const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'"; |
| 128510 | + char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName); |
| 128511 | + if( zSql ){ |
| 128512 | + sqlite3_stmt *pStmt = 0; |
| 128513 | + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 128514 | + if( rc==SQLITE_OK ){ |
| 128515 | + int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); |
| 128516 | + rc = sqlite3_finalize(pStmt); |
| 128517 | + if( rc==SQLITE_OK ) p->bHasStat = bHasStat; |
| 128518 | + } |
| 128519 | + sqlite3_free(zSql); |
| 128520 | + }else{ |
| 128521 | + rc = SQLITE_NOMEM; |
| 128522 | + } |
| 128523 | + } |
| 128524 | + return rc; |
| 128525 | +} |
| 128526 | + |
| 128527 | +/* |
| 128528 | +** Implementation of xBegin() method. |
| 127981 | 128529 | */ |
| 127982 | 128530 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 127983 | 128531 | Fts3Table *p = (Fts3Table*)pVtab; |
| 127984 | 128532 | UNUSED_PARAMETER(pVtab); |
| 127985 | 128533 | assert( p->pSegments==0 ); |
| | @@ -127986,11 +128534,11 @@ |
| 127986 | 128534 | assert( p->nPendingData==0 ); |
| 127987 | 128535 | assert( p->inTransaction!=1 ); |
| 127988 | 128536 | TESTONLY( p->inTransaction = 1 ); |
| 127989 | 128537 | TESTONLY( p->mxSavepoint = -1; ); |
| 127990 | 128538 | p->nLeafAdd = 0; |
| 127991 | | - return SQLITE_OK; |
| 128539 | + return fts3SetHasStat(p); |
| 127992 | 128540 | } |
| 127993 | 128541 | |
| 127994 | 128542 | /* |
| 127995 | 128543 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| 127996 | 128544 | ** the pending-terms hash-table have already been flushed into the database |
| | @@ -128235,18 +128783,24 @@ |
| 128235 | 128783 | ){ |
| 128236 | 128784 | Fts3Table *p = (Fts3Table *)pVtab; |
| 128237 | 128785 | sqlite3 *db = p->db; /* Database connection */ |
| 128238 | 128786 | int rc; /* Return Code */ |
| 128239 | 128787 | |
| 128788 | + /* At this point it must be known if the %_stat table exists or not. |
| 128789 | + ** So bHasStat may not be 2. */ |
| 128790 | + rc = fts3SetHasStat(p); |
| 128791 | + |
| 128240 | 128792 | /* As it happens, the pending terms table is always empty here. This is |
| 128241 | 128793 | ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction |
| 128242 | 128794 | ** always opens a savepoint transaction. And the xSavepoint() method |
| 128243 | 128795 | ** flushes the pending terms table. But leave the (no-op) call to |
| 128244 | 128796 | ** PendingTermsFlush() in in case that changes. |
| 128245 | 128797 | */ |
| 128246 | 128798 | assert( p->nPendingData==0 ); |
| 128247 | | - rc = sqlite3Fts3PendingTermsFlush(p); |
| 128799 | + if( rc==SQLITE_OK ){ |
| 128800 | + rc = sqlite3Fts3PendingTermsFlush(p); |
| 128801 | + } |
| 128248 | 128802 | |
| 128249 | 128803 | if( p->zContentTbl==0 ){ |
| 128250 | 128804 | fts3DbExec(&rc, db, |
| 128251 | 128805 | "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", |
| 128252 | 128806 | p->zDb, p->zName, zName |
| | @@ -139754,10 +140308,14 @@ |
| 139754 | 140308 | u32 *aSzIns = 0; /* Sizes of inserted documents */ |
| 139755 | 140309 | u32 *aSzDel = 0; /* Sizes of deleted documents */ |
| 139756 | 140310 | int nChng = 0; /* Net change in number of documents */ |
| 139757 | 140311 | int bInsertDone = 0; |
| 139758 | 140312 | |
| 140313 | + /* At this point it must be known if the %_stat table exists or not. |
| 140314 | + ** So bHasStat may not be 2. */ |
| 140315 | + assert( p->bHasStat==0 || p->bHasStat==1 ); |
| 140316 | + |
| 139759 | 140317 | assert( p->pSegments==0 ); |
| 139760 | 140318 | assert( |
| 139761 | 140319 | nArg==1 /* DELETE operations */ |
| 139762 | 140320 | || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ |
| 139763 | 140321 | ); |
| | @@ -145135,30 +145693,36 @@ |
| 145135 | 145693 | ** This function populates the pRtree->nRowEst variable with an estimate |
| 145136 | 145694 | ** of the number of rows in the virtual table. If possible, this is based |
| 145137 | 145695 | ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. |
| 145138 | 145696 | */ |
| 145139 | 145697 | static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ |
| 145140 | | - const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'"; |
| 145698 | + const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; |
| 145699 | + char *zSql; |
| 145141 | 145700 | sqlite3_stmt *p; |
| 145142 | 145701 | int rc; |
| 145143 | 145702 | i64 nRow = 0; |
| 145144 | 145703 | |
| 145145 | | - rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); |
| 145146 | | - if( rc==SQLITE_OK ){ |
| 145147 | | - sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC); |
| 145148 | | - if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); |
| 145149 | | - rc = sqlite3_finalize(p); |
| 145150 | | - }else if( rc!=SQLITE_NOMEM ){ |
| 145151 | | - rc = SQLITE_OK; |
| 145152 | | - } |
| 145153 | | - |
| 145154 | | - if( rc==SQLITE_OK ){ |
| 145155 | | - if( nRow==0 ){ |
| 145156 | | - pRtree->nRowEst = RTREE_DEFAULT_ROWEST; |
| 145157 | | - }else{ |
| 145158 | | - pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); |
| 145159 | | - } |
| 145704 | + zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); |
| 145705 | + if( zSql==0 ){ |
| 145706 | + rc = SQLITE_NOMEM; |
| 145707 | + }else{ |
| 145708 | + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); |
| 145709 | + if( rc==SQLITE_OK ){ |
| 145710 | + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); |
| 145711 | + rc = sqlite3_finalize(p); |
| 145712 | + }else if( rc!=SQLITE_NOMEM ){ |
| 145713 | + rc = SQLITE_OK; |
| 145714 | + } |
| 145715 | + |
| 145716 | + if( rc==SQLITE_OK ){ |
| 145717 | + if( nRow==0 ){ |
| 145718 | + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; |
| 145719 | + }else{ |
| 145720 | + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); |
| 145721 | + } |
| 145722 | + } |
| 145723 | + sqlite3_free(zSql); |
| 145160 | 145724 | } |
| 145161 | 145725 | |
| 145162 | 145726 | return rc; |
| 145163 | 145727 | } |
| 145164 | 145728 | |
| | @@ -145423,10 +145987,12 @@ |
| 145423 | 145987 | } |
| 145424 | 145988 | |
| 145425 | 145989 | if( rc==SQLITE_OK ){ |
| 145426 | 145990 | *ppVtab = (sqlite3_vtab *)pRtree; |
| 145427 | 145991 | }else{ |
| 145992 | + assert( *ppVtab==0 ); |
| 145993 | + assert( pRtree->nBusy==1 ); |
| 145428 | 145994 | rtreeRelease(pRtree); |
| 145429 | 145995 | } |
| 145430 | 145996 | return rc; |
| 145431 | 145997 | } |
| 145432 | 145998 | |
| 145433 | 145999 | |