| | @@ -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.3. 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.3" |
| 226 | | -#define SQLITE_VERSION_NUMBER 3008004 |
| 227 | | -#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3" |
| 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,32 +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) || \ |
| 8455 | +#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 8450 | 8456 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
| 8451 | 8457 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
| 8452 | | - defined(__arm__) |
| 8458 | + defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) |
| 8459 | +# define SQLITE_BYTEORDER 1234 |
| 8453 | 8460 | # define SQLITE_BIGENDIAN 0 |
| 8454 | 8461 | # define SQLITE_LITTLEENDIAN 1 |
| 8455 | 8462 | # define SQLITE_UTF16NATIVE SQLITE_UTF16LE |
| 8456 | | -#elif defined(sparc) || defined(__ppc__) |
| 8463 | +#endif |
| 8464 | +#if (defined(sparc) || defined(__ppc__)) \ |
| 8465 | + && !defined(SQLITE_RUNTIME_BYTEORDER) |
| 8466 | +# define SQLITE_BYTEORDER 4321 |
| 8457 | 8467 | # define SQLITE_BIGENDIAN 1 |
| 8458 | 8468 | # define SQLITE_LITTLEENDIAN 0 |
| 8459 | 8469 | # define SQLITE_UTF16NATIVE SQLITE_UTF16BE |
| 8460 | | -#else |
| 8470 | +#endif |
| 8471 | +#if !defined(SQLITE_BYTEORDER) |
| 8472 | +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ |
| 8461 | 8473 | # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) |
| 8462 | 8474 | # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) |
| 8463 | | -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8475 | +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8464 | 8476 | #endif |
| 8465 | 8477 | |
| 8466 | 8478 | /* |
| 8467 | 8479 | ** Constants for the largest and smallest possible 64-bit signed integers. |
| 8468 | 8480 | ** These macros are designed to work correctly on both 32-bit and 64-bit |
| | @@ -8825,10 +8837,11 @@ |
| 8825 | 8837 | #define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ |
| 8826 | 8838 | #define BTREE_BLOBKEY 2 /* Table has keys only - no data */ |
| 8827 | 8839 | |
| 8828 | 8840 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); |
| 8829 | 8841 | SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); |
| 8842 | +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); |
| 8830 | 8843 | SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); |
| 8831 | 8844 | |
| 8832 | 8845 | SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); |
| 8833 | 8846 | SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); |
| 8834 | 8847 | |
| | @@ -8899,11 +8912,11 @@ |
| 8899 | 8912 | |
| 8900 | 8913 | SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); |
| 8901 | 8914 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 8902 | 8915 | |
| 8903 | 8916 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8904 | | -SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); |
| 8917 | +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); |
| 8905 | 8918 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8906 | 8919 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8907 | 8920 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 8908 | 8921 | |
| 8909 | 8922 | #ifndef NDEBUG |
| | @@ -9142,11 +9155,11 @@ |
| 9142 | 9155 | #define OP_Next 9 |
| 9143 | 9156 | #define OP_AggStep 10 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 9144 | 9157 | #define OP_Checkpoint 11 |
| 9145 | 9158 | #define OP_JournalMode 12 |
| 9146 | 9159 | #define OP_Vacuum 13 |
| 9147 | | -#define OP_VFilter 14 /* synopsis: iPlan=r[P3] zPlan='P4' */ |
| 9160 | +#define OP_VFilter 14 /* synopsis: iplan=r[P3] zplan='P4' */ |
| 9148 | 9161 | #define OP_VUpdate 15 /* synopsis: data=r[P3@P2] */ |
| 9149 | 9162 | #define OP_Goto 16 |
| 9150 | 9163 | #define OP_Gosub 17 |
| 9151 | 9164 | #define OP_Return 18 |
| 9152 | 9165 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| | @@ -9169,11 +9182,11 @@ |
| 9169 | 9182 | #define OP_CollSeq 36 |
| 9170 | 9183 | #define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ |
| 9171 | 9184 | #define OP_MustBeInt 38 |
| 9172 | 9185 | #define OP_RealAffinity 39 |
| 9173 | 9186 | #define OP_Permutation 40 |
| 9174 | | -#define OP_Compare 41 |
| 9187 | +#define OP_Compare 41 /* synopsis: r[P1@P3] <-> r[P2@P3] */ |
| 9175 | 9188 | #define OP_Jump 42 |
| 9176 | 9189 | #define OP_Once 43 |
| 9177 | 9190 | #define OP_If 44 |
| 9178 | 9191 | #define OP_IfNot 45 |
| 9179 | 9192 | #define OP_Column 46 /* synopsis: r[P3]=PX */ |
| | @@ -9196,11 +9209,11 @@ |
| 9196 | 9209 | #define OP_Seek 63 /* synopsis: intkey=r[P2] */ |
| 9197 | 9210 | #define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */ |
| 9198 | 9211 | #define OP_NotFound 65 /* synopsis: key=r[P3@P4] */ |
| 9199 | 9212 | #define OP_Found 66 /* synopsis: key=r[P3@P4] */ |
| 9200 | 9213 | #define OP_NotExists 67 /* synopsis: intkey=r[P3] */ |
| 9201 | | -#define OP_Sequence 68 /* synopsis: r[P2]=rowid */ |
| 9214 | +#define OP_Sequence 68 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 9202 | 9215 | #define OP_NewRowid 69 /* synopsis: r[P2]=rowid */ |
| 9203 | 9216 | #define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9204 | 9217 | #define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9205 | 9218 | #define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9206 | 9219 | #define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */ |
| | @@ -9244,51 +9257,52 @@ |
| 9244 | 9257 | #define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */ |
| 9245 | 9258 | #define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */ |
| 9246 | 9259 | #define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */ |
| 9247 | 9260 | #define OP_Destroy 114 |
| 9248 | 9261 | #define OP_Clear 115 |
| 9249 | | -#define OP_CreateIndex 116 /* synopsis: r[P2]=root iDb=P1 */ |
| 9250 | | -#define OP_CreateTable 117 /* synopsis: r[P2]=root iDb=P1 */ |
| 9251 | | -#define OP_ParseSchema 118 |
| 9252 | | -#define OP_LoadAnalysis 119 |
| 9253 | | -#define OP_DropTable 120 |
| 9254 | | -#define OP_DropIndex 121 |
| 9255 | | -#define OP_DropTrigger 122 |
| 9256 | | -#define OP_IntegrityCk 123 |
| 9257 | | -#define OP_RowSetAdd 124 /* synopsis: rowset(P1)=r[P2] */ |
| 9258 | | -#define OP_RowSetRead 125 /* synopsis: r[P3]=rowset(P1) */ |
| 9259 | | -#define OP_RowSetTest 126 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9260 | | -#define OP_Program 127 |
| 9261 | | -#define OP_Param 128 |
| 9262 | | -#define OP_FkCounter 129 /* synopsis: fkctr[P1]+=P2 */ |
| 9263 | | -#define OP_FkIfZero 130 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9264 | | -#define OP_MemMax 131 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9265 | | -#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]) */ |
| 9266 | 9279 | #define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9267 | | -#define OP_IfNeg 134 /* synopsis: if r[P1]<0 goto P2 */ |
| 9268 | | -#define OP_IfZero 135 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9269 | | -#define OP_AggFinal 136 /* synopsis: accum=r[P1] N=P2 */ |
| 9270 | | -#define OP_IncrVacuum 137 |
| 9271 | | -#define OP_Expire 138 |
| 9272 | | -#define OP_TableLock 139 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9273 | | -#define OP_VBegin 140 |
| 9274 | | -#define OP_VCreate 141 |
| 9275 | | -#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 |
| 9276 | 9289 | #define OP_ToText 143 /* same as TK_TO_TEXT */ |
| 9277 | 9290 | #define OP_ToBlob 144 /* same as TK_TO_BLOB */ |
| 9278 | 9291 | #define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */ |
| 9279 | 9292 | #define OP_ToInt 146 /* same as TK_TO_INT */ |
| 9280 | 9293 | #define OP_ToReal 147 /* same as TK_TO_REAL */ |
| 9281 | | -#define OP_VOpen 148 |
| 9282 | | -#define OP_VColumn 149 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9283 | | -#define OP_VNext 150 |
| 9284 | | -#define OP_VRename 151 |
| 9285 | | -#define OP_Pagecount 152 |
| 9286 | | -#define OP_MaxPgcnt 153 |
| 9287 | | -#define OP_Init 154 /* synopsis: Start at P2 */ |
| 9288 | | -#define OP_Noop 155 |
| 9289 | | -#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 |
| 9290 | 9304 | |
| 9291 | 9305 | |
| 9292 | 9306 | /* Properties such as "out2" or "jump" that are specified in |
| 9293 | 9307 | ** comments following the "case" for each opcode in the vdbe.c |
| 9294 | 9308 | ** are encoded into bitvectors as follows: |
| | @@ -9313,16 +9327,16 @@ |
| 9313 | 9327 | /* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\ |
| 9314 | 9328 | /* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\ |
| 9315 | 9329 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\ |
| 9316 | 9330 | /* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\ |
| 9317 | 9331 | /* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\ |
| 9318 | | -/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00,\ |
| 9319 | | -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15, 0x01,\ |
| 9320 | | -/* 128 */ 0x02, 0x00, 0x01, 0x08, 0x05, 0x02, 0x05, 0x05,\ |
| 9321 | | -/* 136 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\ |
| 9322 | | -/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00,\ |
| 9323 | | -/* 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,} |
| 9324 | 9338 | |
| 9325 | 9339 | /************** End of opcodes.h *********************************************/ |
| 9326 | 9340 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9327 | 9341 | |
| 9328 | 9342 | /* |
| | @@ -9375,14 +9389,14 @@ |
| 9375 | 9389 | #ifndef SQLITE_OMIT_TRACE |
| 9376 | 9390 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 9377 | 9391 | #endif |
| 9378 | 9392 | |
| 9379 | 9393 | SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 9380 | | -SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int); |
| 9394 | +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int); |
| 9381 | 9395 | SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); |
| 9382 | 9396 | |
| 9383 | | -typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int); |
| 9397 | +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int); |
| 9384 | 9398 | SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); |
| 9385 | 9399 | |
| 9386 | 9400 | #ifndef SQLITE_OMIT_TRIGGER |
| 9387 | 9401 | SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); |
| 9388 | 9402 | #endif |
| | @@ -11004,10 +11018,11 @@ |
| 11004 | 11018 | */ |
| 11005 | 11019 | struct UnpackedRecord { |
| 11006 | 11020 | KeyInfo *pKeyInfo; /* Collation and sort-order information */ |
| 11007 | 11021 | u16 nField; /* Number of entries in apMem[] */ |
| 11008 | 11022 | i8 default_rc; /* Comparison result if keys are equal */ |
| 11023 | + u8 isCorrupt; /* Corruption detected by xRecordCompare() */ |
| 11009 | 11024 | Mem *aMem; /* Values */ |
| 11010 | 11025 | int r1; /* Value to return if (lhs > rhs) */ |
| 11011 | 11026 | int r2; /* Value to return if (rhs < lhs) */ |
| 11012 | 11027 | }; |
| 11013 | 11028 | |
| | @@ -11270,12 +11285,12 @@ |
| 11270 | 11285 | #define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 11271 | 11286 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11272 | 11287 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| 11273 | 11288 | #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ |
| 11274 | 11289 | #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ |
| 11275 | | -#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */ |
| 11276 | | - /* 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 */ |
| 11277 | 11292 | #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ |
| 11278 | 11293 | #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ |
| 11279 | 11294 | #define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ |
| 11280 | 11295 | #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ |
| 11281 | 11296 | #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ |
| | @@ -11335,11 +11350,10 @@ |
| 11335 | 11350 | ** of the result column in the form: DATABASE.TABLE.COLUMN. This later |
| 11336 | 11351 | ** form is used for name resolution with nested FROM clauses. |
| 11337 | 11352 | */ |
| 11338 | 11353 | struct ExprList { |
| 11339 | 11354 | int nExpr; /* Number of expressions on the list */ |
| 11340 | | - int iECursor; /* VDBE Cursor associated with this ExprList */ |
| 11341 | 11355 | struct ExprList_item { /* For each expression in the list */ |
| 11342 | 11356 | Expr *pExpr; /* The list of expressions */ |
| 11343 | 11357 | char *zName; /* Token associated with this expression */ |
| 11344 | 11358 | char *zSpan; /* Original text of the expression */ |
| 11345 | 11359 | u8 sortOrder; /* 1 for DESC or 0 for ASC */ |
| | @@ -11559,11 +11573,11 @@ |
| 11559 | 11573 | struct Select { |
| 11560 | 11574 | ExprList *pEList; /* The fields of the result */ |
| 11561 | 11575 | u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ |
| 11562 | 11576 | u16 selFlags; /* Various SF_* values */ |
| 11563 | 11577 | int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ |
| 11564 | | - int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ |
| 11578 | + int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ |
| 11565 | 11579 | u64 nSelectRow; /* Estimated number of result rows */ |
| 11566 | 11580 | SrcList *pSrc; /* The FROM clause */ |
| 11567 | 11581 | Expr *pWhere; /* The WHERE clause */ |
| 11568 | 11582 | ExprList *pGroupBy; /* The GROUP BY clause */ |
| 11569 | 11583 | Expr *pHaving; /* The HAVING clause */ |
| | @@ -11583,13 +11597,13 @@ |
| 11583 | 11597 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 11584 | 11598 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 11585 | 11599 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 11586 | 11600 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 11587 | 11601 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 11588 | | -#define SF_UseSorter 0x0040 /* Sort using a sorter */ |
| 11602 | + /* 0x0040 NOT USED */ |
| 11589 | 11603 | #define SF_Values 0x0080 /* Synthesized from VALUES clause */ |
| 11590 | | -#define SF_Materialize 0x0100 /* NOT USED */ |
| 11604 | + /* 0x0100 NOT USED */ |
| 11591 | 11605 | #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ |
| 11592 | 11606 | #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ |
| 11593 | 11607 | #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ |
| 11594 | 11608 | #define SF_Compound 0x1000 /* Part of a compound query */ |
| 11595 | 11609 | |
| | @@ -11638,17 +11652,19 @@ |
| 11638 | 11652 | ** of the co-routine is stored in register pDest->iSDParm |
| 11639 | 11653 | ** and the result row is stored in pDest->nDest registers |
| 11640 | 11654 | ** starting with pDest->iSdst. |
| 11641 | 11655 | ** |
| 11642 | 11656 | ** SRT_Table Store results in temporary table pDest->iSDParm. |
| 11643 | | -** This is like SRT_EphemTab except that the table |
| 11644 | | -** 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. |
| 11645 | 11661 | ** |
| 11646 | | -** SRT_DistTable Store results in a temporary table pDest->iSDParm. |
| 11662 | +** SRT_DistFifo Store results in a temporary table pDest->iSDParm. |
| 11647 | 11663 | ** But also use temporary table pDest->iSDParm+1 as |
| 11648 | 11664 | ** a record of all prior results and ignore any duplicate |
| 11649 | | -** rows. Name means: "Distinct Table". |
| 11665 | +** rows. Name means: "Distinct Fifo". |
| 11650 | 11666 | ** |
| 11651 | 11667 | ** SRT_Queue Store results in priority queue pDest->iSDParm (really |
| 11652 | 11668 | ** an index). Append a sequence number so that all entries |
| 11653 | 11669 | ** are distinct. |
| 11654 | 11670 | ** |
| | @@ -11658,23 +11674,24 @@ |
| 11658 | 11674 | */ |
| 11659 | 11675 | #define SRT_Union 1 /* Store result as keys in an index */ |
| 11660 | 11676 | #define SRT_Except 2 /* Remove result from a UNION index */ |
| 11661 | 11677 | #define SRT_Exists 3 /* Store 1 if the result is not empty */ |
| 11662 | 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 */ |
| 11663 | 11683 | |
| 11664 | 11684 | /* The ORDER BY clause is ignored for all of the above */ |
| 11665 | | -#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard) |
| 11666 | | - |
| 11667 | | -#define SRT_Output 5 /* Output each row of result */ |
| 11668 | | -#define SRT_Mem 6 /* Store result in a memory cell */ |
| 11669 | | -#define SRT_Set 7 /* Store results as keys in an index */ |
| 11670 | | -#define SRT_EphemTab 8 /* Create transient tab and store like SRT_Table */ |
| 11671 | | -#define SRT_Coroutine 9 /* Generate a single row of result */ |
| 11672 | | -#define SRT_Table 10 /* Store result as data with an automatic rowid */ |
| 11673 | | -#define SRT_DistTable 11 /* Like SRT_Table, but unique results only */ |
| 11674 | | -#define SRT_Queue 12 /* Store result in an queue */ |
| 11675 | | -#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 */ |
| 11676 | 11693 | |
| 11677 | 11694 | /* |
| 11678 | 11695 | ** An instance of this object describes where to put of the results of |
| 11679 | 11696 | ** a SELECT statement. |
| 11680 | 11697 | */ |
| | @@ -11768,12 +11785,10 @@ |
| 11768 | 11785 | int rc; /* Return code from execution */ |
| 11769 | 11786 | u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ |
| 11770 | 11787 | u8 checkSchema; /* Causes schema cookie check after an error */ |
| 11771 | 11788 | u8 nested; /* Number of nested calls to the parser/code generator */ |
| 11772 | 11789 | u8 nTempReg; /* Number of temporary registers in aTempReg[] */ |
| 11773 | | - u8 nColCache; /* Number of entries in aColCache[] */ |
| 11774 | | - u8 iColCache; /* Next entry in aColCache[] to replace */ |
| 11775 | 11790 | u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ |
| 11776 | 11791 | u8 mayAbort; /* True if statement may throw an ABORT exception */ |
| 11777 | 11792 | u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ |
| 11778 | 11793 | u8 okConstFactor; /* OK to factor out constants */ |
| 11779 | 11794 | int aTempReg[8]; /* Holding area for temporary registers */ |
| | @@ -12459,11 +12474,11 @@ |
| 12459 | 12474 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 12460 | 12475 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| 12461 | 12476 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); |
| 12462 | 12477 | SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); |
| 12463 | 12478 | SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); |
| 12464 | | -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); |
| 12479 | +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); |
| 12465 | 12480 | SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); |
| 12466 | 12481 | SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); |
| 12467 | 12482 | SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); |
| 12468 | 12483 | SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); |
| 12469 | 12484 | SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); |
| | @@ -12669,11 +12684,11 @@ |
| 12669 | 12684 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 12670 | 12685 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 12671 | 12686 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 12672 | 12687 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 12673 | 12688 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
| 12674 | | -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*); |
| 12689 | +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*); |
| 12675 | 12690 | SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); |
| 12676 | 12691 | SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); |
| 12677 | 12692 | SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); |
| 12678 | 12693 | SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); |
| 12679 | 12694 | SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); |
| | @@ -13754,10 +13769,11 @@ |
| 13754 | 13769 | u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13755 | 13770 | i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13756 | 13771 | u8 nullRow; /* True if pointing to a row with no data */ |
| 13757 | 13772 | u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13758 | 13773 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13774 | + Bool isEphemeral:1; /* True for an ephemeral table */ |
| 13759 | 13775 | Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13760 | 13776 | Bool isTable:1; /* True if a table requiring integer keys */ |
| 13761 | 13777 | Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13762 | 13778 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13763 | 13779 | i64 seqCount; /* Sequence counter */ |
| | @@ -14073,11 +14089,11 @@ |
| 14073 | 14089 | SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); |
| 14074 | 14090 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); |
| 14075 | 14091 | SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); |
| 14076 | 14092 | |
| 14077 | 14093 | int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); |
| 14078 | | -SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*); |
| 14094 | +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); |
| 14079 | 14095 | SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); |
| 14080 | 14096 | SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); |
| 14081 | 14097 | SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); |
| 14082 | 14098 | SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); |
| 14083 | 14099 | SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); |
| | @@ -14119,10 +14135,11 @@ |
| 14119 | 14135 | SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); |
| 14120 | 14136 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); |
| 14121 | 14137 | SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); |
| 14122 | 14138 | |
| 14123 | 14139 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 14140 | +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); |
| 14124 | 14141 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 14125 | 14142 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); |
| 14126 | 14143 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); |
| 14127 | 14144 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); |
| 14128 | 14145 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); |
| | @@ -17858,11 +17875,11 @@ |
| 17858 | 17875 | |
| 17859 | 17876 | /* Make sure mem5.aiFreelist[iLogsize] contains at least one free |
| 17860 | 17877 | ** block. If not, then split a block of the next larger power of |
| 17861 | 17878 | ** two in order to create a new free block of size iLogsize. |
| 17862 | 17879 | */ |
| 17863 | | - for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){} |
| 17880 | + for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){} |
| 17864 | 17881 | if( iBin>LOGMAX ){ |
| 17865 | 17882 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 17866 | 17883 | sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); |
| 17867 | 17884 | return 0; |
| 17868 | 17885 | } |
| | @@ -20168,24 +20185,10 @@ |
| 20168 | 20185 | *val = (*val - d)*10.0; |
| 20169 | 20186 | return (char)digit; |
| 20170 | 20187 | } |
| 20171 | 20188 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 20172 | 20189 | |
| 20173 | | -/* |
| 20174 | | -** Append N space characters to the given string buffer. |
| 20175 | | -*/ |
| 20176 | | -SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){ |
| 20177 | | - static const char zSpaces[] = " "; |
| 20178 | | - while( N>=(int)sizeof(zSpaces)-1 ){ |
| 20179 | | - sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1); |
| 20180 | | - N -= sizeof(zSpaces)-1; |
| 20181 | | - } |
| 20182 | | - if( N>0 ){ |
| 20183 | | - sqlite3StrAccumAppend(pAccum, zSpaces, N); |
| 20184 | | - } |
| 20185 | | -} |
| 20186 | | - |
| 20187 | 20190 | /* |
| 20188 | 20191 | ** Set the StrAccum object to an error mode. |
| 20189 | 20192 | */ |
| 20190 | 20193 | static void setStrAccumError(StrAccum *p, u8 eError){ |
| 20191 | 20194 | p->accError = eError; |
| | @@ -20271,15 +20274,13 @@ |
| 20271 | 20274 | }else{ |
| 20272 | 20275 | bArgList = useIntern = 0; |
| 20273 | 20276 | } |
| 20274 | 20277 | for(; (c=(*fmt))!=0; ++fmt){ |
| 20275 | 20278 | if( c!='%' ){ |
| 20276 | | - int amt; |
| 20277 | 20279 | bufpt = (char *)fmt; |
| 20278 | | - amt = 1; |
| 20279 | | - while( (c=(*++fmt))!='%' && c!=0 ) amt++; |
| 20280 | | - sqlite3StrAccumAppend(pAccum, bufpt, amt); |
| 20280 | + while( (c=(*++fmt))!='%' && c!=0 ){}; |
| 20281 | + sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); |
| 20281 | 20282 | if( c==0 ) break; |
| 20282 | 20283 | } |
| 20283 | 20284 | if( (c=(*++fmt))==0 ){ |
| 20284 | 20285 | sqlite3StrAccumAppend(pAccum, "%", 1); |
| 20285 | 20286 | break; |
| | @@ -20456,14 +20457,12 @@ |
| 20456 | 20457 | } |
| 20457 | 20458 | *(--bufpt) = zOrd[x*2+1]; |
| 20458 | 20459 | *(--bufpt) = zOrd[x*2]; |
| 20459 | 20460 | } |
| 20460 | 20461 | { |
| 20461 | | - register const char *cset; /* Use registers for speed */ |
| 20462 | | - register int base; |
| 20463 | | - cset = &aDigits[infop->charset]; |
| 20464 | | - base = infop->base; |
| 20462 | + const char *cset = &aDigits[infop->charset]; |
| 20463 | + u8 base = infop->base; |
| 20465 | 20464 | do{ /* Convert to ascii */ |
| 20466 | 20465 | *(--bufpt) = cset[longvalue%base]; |
| 20467 | 20466 | longvalue = longvalue/base; |
| 20468 | 20467 | }while( longvalue>0 ); |
| 20469 | 20468 | } |
| | @@ -20763,77 +20762,102 @@ |
| 20763 | 20762 | /* |
| 20764 | 20763 | ** The text of the conversion is pointed to by "bufpt" and is |
| 20765 | 20764 | ** "length" characters long. The field width is "width". Do |
| 20766 | 20765 | ** the output. |
| 20767 | 20766 | */ |
| 20768 | | - if( !flag_leftjustify ){ |
| 20769 | | - register int nspace; |
| 20770 | | - nspace = width-length; |
| 20771 | | - if( nspace>0 ){ |
| 20772 | | - sqlite3AppendSpace(pAccum, nspace); |
| 20773 | | - } |
| 20774 | | - } |
| 20775 | | - if( length>0 ){ |
| 20776 | | - sqlite3StrAccumAppend(pAccum, bufpt, length); |
| 20777 | | - } |
| 20778 | | - if( flag_leftjustify ){ |
| 20779 | | - register int nspace; |
| 20780 | | - nspace = width-length; |
| 20781 | | - if( nspace>0 ){ |
| 20782 | | - sqlite3AppendSpace(pAccum, nspace); |
| 20783 | | - } |
| 20784 | | - } |
| 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 | + |
| 20785 | 20772 | if( zExtra ) sqlite3_free(zExtra); |
| 20786 | 20773 | }/* End for loop over the format string */ |
| 20787 | 20774 | } /* End of function */ |
| 20788 | 20775 | |
| 20789 | 20776 | /* |
| 20790 | | -** 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. |
| 20791 | 20850 | */ |
| 20792 | 20851 | SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
| 20793 | 20852 | assert( z!=0 ); |
| 20794 | 20853 | assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 20795 | 20854 | assert( N>=0 ); |
| 20796 | 20855 | assert( p->accError==0 || p->nAlloc==0 ); |
| 20797 | 20856 | if( p->nChar+N >= p->nAlloc ){ |
| 20798 | | - char *zNew; |
| 20799 | | - if( p->accError ){ |
| 20800 | | - testcase(p->accError==STRACCUM_TOOBIG); |
| 20801 | | - testcase(p->accError==STRACCUM_NOMEM); |
| 20802 | | - return; |
| 20803 | | - } |
| 20804 | | - if( !p->useMalloc ){ |
| 20805 | | - N = p->nAlloc - p->nChar - 1; |
| 20806 | | - setStrAccumError(p, STRACCUM_TOOBIG); |
| 20807 | | - if( N<=0 ){ |
| 20808 | | - return; |
| 20809 | | - } |
| 20810 | | - }else{ |
| 20811 | | - char *zOld = (p->zText==p->zBase ? 0 : p->zText); |
| 20812 | | - i64 szNew = p->nChar; |
| 20813 | | - szNew += N + 1; |
| 20814 | | - if( szNew > p->mxAlloc ){ |
| 20815 | | - sqlite3StrAccumReset(p); |
| 20816 | | - setStrAccumError(p, STRACCUM_TOOBIG); |
| 20817 | | - return; |
| 20818 | | - }else{ |
| 20819 | | - p->nAlloc = (int)szNew; |
| 20820 | | - } |
| 20821 | | - if( p->useMalloc==1 ){ |
| 20822 | | - zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); |
| 20823 | | - }else{ |
| 20824 | | - zNew = sqlite3_realloc(zOld, p->nAlloc); |
| 20825 | | - } |
| 20826 | | - if( zNew ){ |
| 20827 | | - if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 20828 | | - p->zText = zNew; |
| 20829 | | - }else{ |
| 20830 | | - sqlite3StrAccumReset(p); |
| 20831 | | - setStrAccumError(p, STRACCUM_NOMEM); |
| 20832 | | - return; |
| 20833 | | - } |
| 20834 | | - } |
| 20857 | + enlargeAndAppend(p,z,N); |
| 20858 | + return; |
| 20835 | 20859 | } |
| 20836 | 20860 | assert( p->zText ); |
| 20837 | 20861 | memcpy(&p->zText[p->nChar], z, N); |
| 20838 | 20862 | p->nChar += N; |
| 20839 | 20863 | } |
| | @@ -23337,11 +23361,11 @@ |
| 23337 | 23361 | /* 9 */ "Next" OpHelp(""), |
| 23338 | 23362 | /* 10 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 23339 | 23363 | /* 11 */ "Checkpoint" OpHelp(""), |
| 23340 | 23364 | /* 12 */ "JournalMode" OpHelp(""), |
| 23341 | 23365 | /* 13 */ "Vacuum" OpHelp(""), |
| 23342 | | - /* 14 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"), |
| 23366 | + /* 14 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), |
| 23343 | 23367 | /* 15 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 23344 | 23368 | /* 16 */ "Goto" OpHelp(""), |
| 23345 | 23369 | /* 17 */ "Gosub" OpHelp(""), |
| 23346 | 23370 | /* 18 */ "Return" OpHelp(""), |
| 23347 | 23371 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), |
| | @@ -23364,11 +23388,11 @@ |
| 23364 | 23388 | /* 36 */ "CollSeq" OpHelp(""), |
| 23365 | 23389 | /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 23366 | 23390 | /* 38 */ "MustBeInt" OpHelp(""), |
| 23367 | 23391 | /* 39 */ "RealAffinity" OpHelp(""), |
| 23368 | 23392 | /* 40 */ "Permutation" OpHelp(""), |
| 23369 | | - /* 41 */ "Compare" OpHelp(""), |
| 23393 | + /* 41 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), |
| 23370 | 23394 | /* 42 */ "Jump" OpHelp(""), |
| 23371 | 23395 | /* 43 */ "Once" OpHelp(""), |
| 23372 | 23396 | /* 44 */ "If" OpHelp(""), |
| 23373 | 23397 | /* 45 */ "IfNot" OpHelp(""), |
| 23374 | 23398 | /* 46 */ "Column" OpHelp("r[P3]=PX"), |
| | @@ -23391,11 +23415,11 @@ |
| 23391 | 23415 | /* 63 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23392 | 23416 | /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23393 | 23417 | /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23394 | 23418 | /* 66 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23395 | 23419 | /* 67 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23396 | | - /* 68 */ "Sequence" OpHelp("r[P2]=rowid"), |
| 23420 | + /* 68 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 23397 | 23421 | /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23398 | 23422 | /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 23399 | 23423 | /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 23400 | 23424 | /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 23401 | 23425 | /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| | @@ -23439,51 +23463,52 @@ |
| 23439 | 23463 | /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 23440 | 23464 | /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 23441 | 23465 | /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 23442 | 23466 | /* 114 */ "Destroy" OpHelp(""), |
| 23443 | 23467 | /* 115 */ "Clear" OpHelp(""), |
| 23444 | | - /* 116 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23445 | | - /* 117 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23446 | | - /* 118 */ "ParseSchema" OpHelp(""), |
| 23447 | | - /* 119 */ "LoadAnalysis" OpHelp(""), |
| 23448 | | - /* 120 */ "DropTable" OpHelp(""), |
| 23449 | | - /* 121 */ "DropIndex" OpHelp(""), |
| 23450 | | - /* 122 */ "DropTrigger" OpHelp(""), |
| 23451 | | - /* 123 */ "IntegrityCk" OpHelp(""), |
| 23452 | | - /* 124 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23453 | | - /* 125 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23454 | | - /* 126 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23455 | | - /* 127 */ "Program" OpHelp(""), |
| 23456 | | - /* 128 */ "Param" OpHelp(""), |
| 23457 | | - /* 129 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23458 | | - /* 130 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23459 | | - /* 131 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23460 | | - /* 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])"), |
| 23461 | 23485 | /* 133 */ "Real" OpHelp("r[P2]=P4"), |
| 23462 | | - /* 134 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23463 | | - /* 135 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 23464 | | - /* 136 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23465 | | - /* 137 */ "IncrVacuum" OpHelp(""), |
| 23466 | | - /* 138 */ "Expire" OpHelp(""), |
| 23467 | | - /* 139 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23468 | | - /* 140 */ "VBegin" OpHelp(""), |
| 23469 | | - /* 141 */ "VCreate" OpHelp(""), |
| 23470 | | - /* 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(""), |
| 23471 | 23495 | /* 143 */ "ToText" OpHelp(""), |
| 23472 | 23496 | /* 144 */ "ToBlob" OpHelp(""), |
| 23473 | 23497 | /* 145 */ "ToNumeric" OpHelp(""), |
| 23474 | 23498 | /* 146 */ "ToInt" OpHelp(""), |
| 23475 | 23499 | /* 147 */ "ToReal" OpHelp(""), |
| 23476 | | - /* 148 */ "VOpen" OpHelp(""), |
| 23477 | | - /* 149 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23478 | | - /* 150 */ "VNext" OpHelp(""), |
| 23479 | | - /* 151 */ "VRename" OpHelp(""), |
| 23480 | | - /* 152 */ "Pagecount" OpHelp(""), |
| 23481 | | - /* 153 */ "MaxPgcnt" OpHelp(""), |
| 23482 | | - /* 154 */ "Init" OpHelp("Start at P2"), |
| 23483 | | - /* 155 */ "Noop" OpHelp(""), |
| 23484 | | - /* 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(""), |
| 23485 | 23510 | }; |
| 23486 | 23511 | return azName[i]; |
| 23487 | 23512 | } |
| 23488 | 23513 | #endif |
| 23489 | 23514 | |
| | @@ -24019,10 +24044,11 @@ |
| 24019 | 24044 | return geteuid() ? 0 : fchown(fd,uid,gid); |
| 24020 | 24045 | } |
| 24021 | 24046 | |
| 24022 | 24047 | /* Forward reference */ |
| 24023 | 24048 | static int openDirectory(const char*, int*); |
| 24049 | +static int unixGetpagesize(void); |
| 24024 | 24050 | |
| 24025 | 24051 | /* |
| 24026 | 24052 | ** Many system calls are accessed through pointer-to-functions so that |
| 24027 | 24053 | ** they may be overridden at runtime to facilitate fault injection during |
| 24028 | 24054 | ** testing and sandboxing. The following array holds the names and pointers |
| | @@ -24141,10 +24167,13 @@ |
| 24141 | 24167 | #else |
| 24142 | 24168 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 24143 | 24169 | #endif |
| 24144 | 24170 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 24145 | 24171 | #endif |
| 24172 | + |
| 24173 | + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, |
| 24174 | +#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) |
| 24146 | 24175 | |
| 24147 | 24176 | }; /* End of the overrideable system calls */ |
| 24148 | 24177 | |
| 24149 | 24178 | /* |
| 24150 | 24179 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -27801,10 +27830,40 @@ |
| 27801 | 27830 | #endif |
| 27802 | 27831 | |
| 27803 | 27832 | return rc; |
| 27804 | 27833 | } |
| 27805 | 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 | +} |
| 27806 | 27865 | |
| 27807 | 27866 | /* |
| 27808 | 27867 | ** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0. |
| 27809 | 27868 | ** |
| 27810 | 27869 | ** This is not a VFS shared-memory method; it is a utility function called |
| | @@ -27812,14 +27871,15 @@ |
| 27812 | 27871 | */ |
| 27813 | 27872 | static void unixShmPurge(unixFile *pFd){ |
| 27814 | 27873 | unixShmNode *p = pFd->pInode->pShmNode; |
| 27815 | 27874 | assert( unixMutexHeld() ); |
| 27816 | 27875 | if( p && p->nRef==0 ){ |
| 27876 | + int nShmPerMap = unixShmRegionPerMap(); |
| 27817 | 27877 | int i; |
| 27818 | 27878 | assert( p->pInode==pFd->pInode ); |
| 27819 | 27879 | sqlite3_mutex_free(p->mutex); |
| 27820 | | - for(i=0; i<p->nRegion; i++){ |
| 27880 | + for(i=0; i<p->nRegion; i+=nShmPerMap){ |
| 27821 | 27881 | if( p->h>=0 ){ |
| 27822 | 27882 | osMunmap(p->apRegion[i], p->szRegion); |
| 27823 | 27883 | }else{ |
| 27824 | 27884 | sqlite3_free(p->apRegion[i]); |
| 27825 | 27885 | } |
| | @@ -28022,10 +28082,12 @@ |
| 28022 | 28082 | ){ |
| 28023 | 28083 | unixFile *pDbFd = (unixFile*)fd; |
| 28024 | 28084 | unixShm *p; |
| 28025 | 28085 | unixShmNode *pShmNode; |
| 28026 | 28086 | int rc = SQLITE_OK; |
| 28087 | + int nShmPerMap = unixShmRegionPerMap(); |
| 28088 | + int nReqRegion; |
| 28027 | 28089 | |
| 28028 | 28090 | /* If the shared-memory file has not yet been opened, open it now. */ |
| 28029 | 28091 | if( pDbFd->pShm==0 ){ |
| 28030 | 28092 | rc = unixOpenSharedMemory(pDbFd); |
| 28031 | 28093 | if( rc!=SQLITE_OK ) return rc; |
| | @@ -28037,13 +28099,16 @@ |
| 28037 | 28099 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 28038 | 28100 | assert( pShmNode->pInode==pDbFd->pInode ); |
| 28039 | 28101 | assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); |
| 28040 | 28102 | assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); |
| 28041 | 28103 | |
| 28042 | | - 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 ){ |
| 28043 | 28108 | char **apNew; /* New apRegion[] array */ |
| 28044 | | - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ |
| 28109 | + int nByte = nReqRegion*szRegion; /* Minimum required file size */ |
| 28045 | 28110 | struct stat sStat; /* Used by fstat() */ |
| 28046 | 28111 | |
| 28047 | 28112 | pShmNode->szRegion = szRegion; |
| 28048 | 28113 | |
| 28049 | 28114 | if( pShmNode->h>=0 ){ |
| | @@ -28088,21 +28153,23 @@ |
| 28088 | 28153 | } |
| 28089 | 28154 | } |
| 28090 | 28155 | |
| 28091 | 28156 | /* Map the requested memory region into this processes address space. */ |
| 28092 | 28157 | apNew = (char **)sqlite3_realloc( |
| 28093 | | - pShmNode->apRegion, (iRegion+1)*sizeof(char *) |
| 28158 | + pShmNode->apRegion, nReqRegion*sizeof(char *) |
| 28094 | 28159 | ); |
| 28095 | 28160 | if( !apNew ){ |
| 28096 | 28161 | rc = SQLITE_IOERR_NOMEM; |
| 28097 | 28162 | goto shmpage_out; |
| 28098 | 28163 | } |
| 28099 | 28164 | pShmNode->apRegion = apNew; |
| 28100 | | - while(pShmNode->nRegion<=iRegion){ |
| 28165 | + while( pShmNode->nRegion<nReqRegion ){ |
| 28166 | + int nMap = szRegion*nShmPerMap; |
| 28167 | + int i; |
| 28101 | 28168 | void *pMem; |
| 28102 | 28169 | if( pShmNode->h>=0 ){ |
| 28103 | | - pMem = osMmap(0, szRegion, |
| 28170 | + pMem = osMmap(0, nMap, |
| 28104 | 28171 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 28105 | 28172 | MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion |
| 28106 | 28173 | ); |
| 28107 | 28174 | if( pMem==MAP_FAILED ){ |
| 28108 | 28175 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| | @@ -28114,12 +28181,15 @@ |
| 28114 | 28181 | rc = SQLITE_NOMEM; |
| 28115 | 28182 | goto shmpage_out; |
| 28116 | 28183 | } |
| 28117 | 28184 | memset(pMem, 0, szRegion); |
| 28118 | 28185 | } |
| 28119 | | - pShmNode->apRegion[pShmNode->nRegion] = pMem; |
| 28120 | | - 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; |
| 28121 | 28191 | } |
| 28122 | 28192 | } |
| 28123 | 28193 | |
| 28124 | 28194 | shmpage_out: |
| 28125 | 28195 | if( pShmNode->nRegion>iRegion ){ |
| | @@ -28329,23 +28399,10 @@ |
| 28329 | 28399 | pFd->mmapSize = 0; |
| 28330 | 28400 | pFd->mmapSizeActual = 0; |
| 28331 | 28401 | } |
| 28332 | 28402 | } |
| 28333 | 28403 | |
| 28334 | | -/* |
| 28335 | | -** Return the system page size. |
| 28336 | | -*/ |
| 28337 | | -static int unixGetPagesize(void){ |
| 28338 | | -#if HAVE_MREMAP |
| 28339 | | - return 512; |
| 28340 | | -#elif defined(_BSD_SOURCE) |
| 28341 | | - return getpagesize(); |
| 28342 | | -#else |
| 28343 | | - return (int)sysconf(_SC_PAGESIZE); |
| 28344 | | -#endif |
| 28345 | | -} |
| 28346 | | - |
| 28347 | 28404 | /* |
| 28348 | 28405 | ** Attempt to set the size of the memory mapping maintained by file |
| 28349 | 28406 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 28350 | 28407 | ** |
| 28351 | 28408 | ** If successful, this function sets the following variables: |
| | @@ -28378,12 +28435,16 @@ |
| 28378 | 28435 | assert( MAP_FAILED!=0 ); |
| 28379 | 28436 | |
| 28380 | 28437 | if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; |
| 28381 | 28438 | |
| 28382 | 28439 | if( pOrig ){ |
| 28383 | | - const int szSyspage = unixGetPagesize(); |
| 28440 | +#if HAVE_MREMAP |
| 28441 | + i64 nReuse = pFd->mmapSize; |
| 28442 | +#else |
| 28443 | + const int szSyspage = osGetpagesize(); |
| 28384 | 28444 | i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); |
| 28445 | +#endif |
| 28385 | 28446 | u8 *pReq = &pOrig[nReuse]; |
| 28386 | 28447 | |
| 28387 | 28448 | /* Unmap any pages of the existing mapping that cannot be reused. */ |
| 28388 | 28449 | if( nReuse!=nOrig ){ |
| 28389 | 28450 | osMunmap(pReq, nOrig-nReuse); |
| | @@ -31125,11 +31186,11 @@ |
| 31125 | 31186 | }; |
| 31126 | 31187 | unsigned int i; /* Loop counter */ |
| 31127 | 31188 | |
| 31128 | 31189 | /* Double-check that the aSyscall[] array has been constructed |
| 31129 | 31190 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 31130 | | - assert( ArraySize(aSyscall)==24 ); |
| 31191 | + assert( ArraySize(aSyscall)==25 ); |
| 31131 | 31192 | |
| 31132 | 31193 | /* Register all VFSes defined in the aVfs[] array */ |
| 31133 | 31194 | for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |
| 31134 | 31195 | sqlite3_vfs_register(&aVfs[i], i==0); |
| 31135 | 31196 | } |
| | @@ -50379,31 +50440,34 @@ |
| 50379 | 50440 | struct BtCursor { |
| 50380 | 50441 | Btree *pBtree; /* The Btree to which this cursor belongs */ |
| 50381 | 50442 | BtShared *pBt; /* The BtShared this cursor points to */ |
| 50382 | 50443 | BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ |
| 50383 | 50444 | struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ |
| 50384 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 50385 | 50445 | Pgno *aOverflow; /* Cache of overflow page locations */ |
| 50386 | | -#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 */ |
| 50387 | 50449 | Pgno pgnoRoot; /* The root page of this tree */ |
| 50388 | | - CellInfo info; /* A parse of the cell we are pointing at */ |
| 50389 | | - i64 nKey; /* Size of pKey, or last integer key */ |
| 50390 | | - void *pKey; /* Saved key that was cursor's last known position */ |
| 50450 | + int nOvflAlloc; /* Allocated size of aOverflow[] array */ |
| 50391 | 50451 | int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ |
| 50392 | | - u8 wrFlag; /* True if writable */ |
| 50393 | | - u8 atLast; /* Cursor pointing to the last entry */ |
| 50394 | | - u8 validNKey; /* True if info.nKey is valid */ |
| 50452 | + u8 curFlags; /* zero or more BTCF_* flags defined below */ |
| 50395 | 50453 | u8 eState; /* One of the CURSOR_XXX constants (see below) */ |
| 50396 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 50397 | | - u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ |
| 50398 | | -#endif |
| 50399 | 50454 | u8 hints; /* As configured by CursorSetHints() */ |
| 50400 | 50455 | i16 iPage; /* Index of current page in apPage */ |
| 50401 | 50456 | u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ |
| 50402 | 50457 | MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ |
| 50403 | 50458 | }; |
| 50404 | 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 | + |
| 50405 | 50469 | /* |
| 50406 | 50470 | ** Potential values for BtCursor.eState. |
| 50407 | 50471 | ** |
| 50408 | 50472 | ** CURSOR_INVALID: |
| 50409 | 50473 | ** Cursor does not point to a valid entry. This can happen (for example) |
| | @@ -51270,20 +51334,15 @@ |
| 51270 | 51334 | static int cursorHoldsMutex(BtCursor *p){ |
| 51271 | 51335 | return sqlite3_mutex_held(p->pBt->mutex); |
| 51272 | 51336 | } |
| 51273 | 51337 | #endif |
| 51274 | 51338 | |
| 51275 | | - |
| 51276 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 51277 | 51339 | /* |
| 51278 | | -** 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. |
| 51279 | 51342 | */ |
| 51280 | | -static void invalidateOverflowCache(BtCursor *pCur){ |
| 51281 | | - assert( cursorHoldsMutex(pCur) ); |
| 51282 | | - sqlite3_free(pCur->aOverflow); |
| 51283 | | - pCur->aOverflow = 0; |
| 51284 | | -} |
| 51343 | +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) |
| 51285 | 51344 | |
| 51286 | 51345 | /* |
| 51287 | 51346 | ** Invalidate the overflow page-list cache for all cursors opened |
| 51288 | 51347 | ** on the shared btree structure pBt. |
| 51289 | 51348 | */ |
| | @@ -51293,10 +51352,11 @@ |
| 51293 | 51352 | for(p=pBt->pCursor; p; p=p->pNext){ |
| 51294 | 51353 | invalidateOverflowCache(p); |
| 51295 | 51354 | } |
| 51296 | 51355 | } |
| 51297 | 51356 | |
| 51357 | +#ifndef SQLITE_OMIT_INCRBLOB |
| 51298 | 51358 | /* |
| 51299 | 51359 | ** This function is called before modifying the contents of a table |
| 51300 | 51360 | ** to invalidate any incrblob cursors that are open on the |
| 51301 | 51361 | ** row or one of the rows being modified. |
| 51302 | 51362 | ** |
| | @@ -51315,20 +51375,18 @@ |
| 51315 | 51375 | ){ |
| 51316 | 51376 | BtCursor *p; |
| 51317 | 51377 | BtShared *pBt = pBtree->pBt; |
| 51318 | 51378 | assert( sqlite3BtreeHoldsMutex(pBtree) ); |
| 51319 | 51379 | for(p=pBt->pCursor; p; p=p->pNext){ |
| 51320 | | - if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){ |
| 51380 | + if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){ |
| 51321 | 51381 | p->eState = CURSOR_INVALID; |
| 51322 | 51382 | } |
| 51323 | 51383 | } |
| 51324 | 51384 | } |
| 51325 | 51385 | |
| 51326 | 51386 | #else |
| 51327 | | - /* Stub functions when INCRBLOB is omitted */ |
| 51328 | | - #define invalidateOverflowCache(x) |
| 51329 | | - #define invalidateAllOverflowCache(x) |
| 51387 | + /* Stub function when INCRBLOB is omitted */ |
| 51330 | 51388 | #define invalidateIncrblobCursors(x,y,z) |
| 51331 | 51389 | #endif /* SQLITE_OMIT_INCRBLOB */ |
| 51332 | 51390 | |
| 51333 | 51391 | /* |
| 51334 | 51392 | ** Set bit pgno of the BtShared.pHasContent bitvec. This is called |
| | @@ -51570,24 +51628,36 @@ |
| 51570 | 51628 | ** Determine whether or not a cursor has moved from the position it |
| 51571 | 51629 | ** was last placed at. Cursors can move when the row they are pointing |
| 51572 | 51630 | ** at is deleted out from under them. |
| 51573 | 51631 | ** |
| 51574 | 51632 | ** This routine returns an error code if something goes wrong. The |
| 51575 | | -** 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. |
| 51576 | 51642 | */ |
| 51577 | 51643 | SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ |
| 51578 | 51644 | int rc; |
| 51579 | 51645 | |
| 51646 | + if( pCur->eState==CURSOR_VALID ){ |
| 51647 | + *pHasMoved = 0; |
| 51648 | + return SQLITE_OK; |
| 51649 | + } |
| 51580 | 51650 | rc = restoreCursorPosition(pCur); |
| 51581 | 51651 | if( rc ){ |
| 51582 | | - *pHasMoved = 1; |
| 51652 | + *pHasMoved = 2; |
| 51583 | 51653 | return rc; |
| 51584 | 51654 | } |
| 51585 | 51655 | if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){ |
| 51656 | + *pHasMoved = 2; |
| 51657 | + }else{ |
| 51586 | 51658 | *pHasMoved = 1; |
| 51587 | | - }else{ |
| 51588 | | - *pHasMoved = 0; |
| 51589 | 51659 | } |
| 51590 | 51660 | return SQLITE_OK; |
| 51591 | 51661 | } |
| 51592 | 51662 | |
| 51593 | 51663 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| | @@ -53375,11 +53445,12 @@ |
| 53375 | 53445 | */ |
| 53376 | 53446 | static int countValidCursors(BtShared *pBt, int wrOnly){ |
| 53377 | 53447 | BtCursor *pCur; |
| 53378 | 53448 | int r = 0; |
| 53379 | 53449 | for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ |
| 53380 | | - 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++; |
| 53381 | 53452 | } |
| 53382 | 53453 | return r; |
| 53383 | 53454 | } |
| 53384 | 53455 | #endif |
| 53385 | 53456 | |
| | @@ -54450,11 +54521,12 @@ |
| 54450 | 54521 | pCur->pgnoRoot = (Pgno)iTable; |
| 54451 | 54522 | pCur->iPage = -1; |
| 54452 | 54523 | pCur->pKeyInfo = pKeyInfo; |
| 54453 | 54524 | pCur->pBtree = p; |
| 54454 | 54525 | pCur->pBt = pBt; |
| 54455 | | - pCur->wrFlag = (u8)wrFlag; |
| 54526 | + assert( wrFlag==0 || wrFlag==BTCF_WriteFlag ); |
| 54527 | + pCur->curFlags = wrFlag; |
| 54456 | 54528 | pCur->pNext = pBt->pCursor; |
| 54457 | 54529 | if( pCur->pNext ){ |
| 54458 | 54530 | pCur->pNext->pPrev = pCur; |
| 54459 | 54531 | } |
| 54460 | 54532 | pBt->pCursor = pCur; |
| | @@ -54520,11 +54592,11 @@ |
| 54520 | 54592 | } |
| 54521 | 54593 | for(i=0; i<=pCur->iPage; i++){ |
| 54522 | 54594 | releasePage(pCur->apPage[i]); |
| 54523 | 54595 | } |
| 54524 | 54596 | unlockBtreeIfUnused(pBt); |
| 54525 | | - invalidateOverflowCache(pCur); |
| 54597 | + sqlite3DbFree(pBtree->db, pCur->aOverflow); |
| 54526 | 54598 | /* sqlite3_free(pCur); */ |
| 54527 | 54599 | sqlite3BtreeLeave(pBtree); |
| 54528 | 54600 | } |
| 54529 | 54601 | return SQLITE_OK; |
| 54530 | 54602 | } |
| | @@ -54559,22 +54631,22 @@ |
| 54559 | 54631 | /* Use a real function in MSVC to work around bugs in that compiler. */ |
| 54560 | 54632 | static void getCellInfo(BtCursor *pCur){ |
| 54561 | 54633 | if( pCur->info.nSize==0 ){ |
| 54562 | 54634 | int iPage = pCur->iPage; |
| 54563 | 54635 | btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); |
| 54564 | | - pCur->validNKey = 1; |
| 54636 | + pCur->curFlags |= BTCF_ValidNKey; |
| 54565 | 54637 | }else{ |
| 54566 | 54638 | assertCellInfo(pCur); |
| 54567 | 54639 | } |
| 54568 | 54640 | } |
| 54569 | 54641 | #else /* if not _MSC_VER */ |
| 54570 | 54642 | /* Use a macro in all other compilers so that the function is inlined */ |
| 54571 | 54643 | #define getCellInfo(pCur) \ |
| 54572 | 54644 | if( pCur->info.nSize==0 ){ \ |
| 54573 | 54645 | int iPage = pCur->iPage; \ |
| 54574 | | - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ |
| 54575 | | - pCur->validNKey = 1; \ |
| 54646 | + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ |
| 54647 | + pCur->curFlags |= BTCF_ValidNKey; \ |
| 54576 | 54648 | }else{ \ |
| 54577 | 54649 | assertCellInfo(pCur); \ |
| 54578 | 54650 | } |
| 54579 | 54651 | #endif /* _MSC_VER */ |
| 54580 | 54652 | |
| | @@ -54741,26 +54813,28 @@ |
| 54741 | 54813 | return SQLITE_OK; |
| 54742 | 54814 | } |
| 54743 | 54815 | |
| 54744 | 54816 | /* |
| 54745 | 54817 | ** This function is used to read or overwrite payload information |
| 54746 | | -** for the entry that the pCur cursor is pointing to. If the eOp |
| 54747 | | -** parameter is 0, this is a read operation (data copied into |
| 54748 | | -** buffer pBuf). If it is non-zero, a write (data copied from |
| 54749 | | -** 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. |
| 54750 | 54824 | ** |
| 54751 | 54825 | ** A total of "amt" bytes are read or written beginning at "offset". |
| 54752 | 54826 | ** Data is read to or from the buffer pBuf. |
| 54753 | 54827 | ** |
| 54754 | 54828 | ** The content being read or written might appear on the main page |
| 54755 | 54829 | ** or be scattered out on multiple overflow pages. |
| 54756 | 54830 | ** |
| 54757 | | -** If the BtCursor.isIncrblobHandle flag is set, and the current |
| 54758 | | -** cursor entry uses one or more overflow pages, this function |
| 54759 | | -** allocates space for and lazily popluates the overflow page-list |
| 54760 | | -** cache array (BtCursor.aOverflow). Subsequent calls use this |
| 54761 | | -** 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. |
| 54762 | 54836 | ** |
| 54763 | 54837 | ** Once an overflow page-list cache has been allocated, it may be |
| 54764 | 54838 | ** invalidated if some other cursor writes to the same table, or if |
| 54765 | 54839 | ** the cursor is moved to a different row. Additionally, in auto-vacuum |
| 54766 | 54840 | ** mode, the following events may invalidate an overflow page-list cache. |
| | @@ -54780,19 +54854,26 @@ |
| 54780 | 54854 | int rc = SQLITE_OK; |
| 54781 | 54855 | u32 nKey; |
| 54782 | 54856 | int iIdx = 0; |
| 54783 | 54857 | MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ |
| 54784 | 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 |
| 54785 | 54862 | |
| 54786 | 54863 | assert( pPage ); |
| 54787 | 54864 | assert( pCur->eState==CURSOR_VALID ); |
| 54788 | 54865 | assert( pCur->aiIdx[pCur->iPage]<pPage->nCell ); |
| 54789 | 54866 | assert( cursorHoldsMutex(pCur) ); |
| 54867 | + assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ |
| 54790 | 54868 | |
| 54791 | 54869 | getCellInfo(pCur); |
| 54792 | 54870 | aPayload = pCur->info.pCell + pCur->info.nHeader; |
| 54793 | 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 |
| 54794 | 54875 | |
| 54795 | 54876 | if( NEVER(offset+amt > nKey+pCur->info.nData) |
| 54796 | 54877 | || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] |
| 54797 | 54878 | ){ |
| 54798 | 54879 | /* Trying to read or write past the end of the data is an error */ |
| | @@ -54803,11 +54884,11 @@ |
| 54803 | 54884 | if( offset<pCur->info.nLocal ){ |
| 54804 | 54885 | int a = amt; |
| 54805 | 54886 | if( a+offset>pCur->info.nLocal ){ |
| 54806 | 54887 | a = pCur->info.nLocal - offset; |
| 54807 | 54888 | } |
| 54808 | | - rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); |
| 54889 | + rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); |
| 54809 | 54890 | offset = 0; |
| 54810 | 54891 | pBuf += a; |
| 54811 | 54892 | amt -= a; |
| 54812 | 54893 | }else{ |
| 54813 | 54894 | offset -= pCur->info.nLocal; |
| | @@ -54817,62 +54898,72 @@ |
| 54817 | 54898 | const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ |
| 54818 | 54899 | Pgno nextPage; |
| 54819 | 54900 | |
| 54820 | 54901 | nextPage = get4byte(&aPayload[pCur->info.nLocal]); |
| 54821 | 54902 | |
| 54822 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54823 | | - /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] |
| 54824 | | - ** has not been allocated, allocate it now. The array is sized at |
| 54825 | | - ** one entry for each overflow page in the overflow chain. The |
| 54826 | | - ** page number of the first overflow page is stored in aOverflow[0], |
| 54827 | | - ** etc. A value of 0 in the aOverflow[] array means "not yet known" |
| 54828 | | - ** (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). |
| 54829 | 54910 | */ |
| 54830 | | - if( pCur->isIncrblobHandle && !pCur->aOverflow ){ |
| 54911 | + if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ |
| 54831 | 54912 | int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; |
| 54832 | | - pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); |
| 54833 | | - /* nOvfl is always positive. If it were zero, fetchPayload would have |
| 54834 | | - ** been used instead of this routine. */ |
| 54835 | | - if( ALWAYS(nOvfl) && !pCur->aOverflow ){ |
| 54836 | | - 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; |
| 54837 | 54927 | } |
| 54838 | 54928 | } |
| 54839 | 54929 | |
| 54840 | 54930 | /* If the overflow page-list cache has been allocated and the |
| 54841 | 54931 | ** entry for the first required overflow page is valid, skip |
| 54842 | 54932 | ** directly to it. |
| 54843 | 54933 | */ |
| 54844 | | - if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){ |
| 54934 | + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){ |
| 54845 | 54935 | iIdx = (offset/ovflSize); |
| 54846 | 54936 | nextPage = pCur->aOverflow[iIdx]; |
| 54847 | 54937 | offset = (offset%ovflSize); |
| 54848 | 54938 | } |
| 54849 | | -#endif |
| 54850 | 54939 | |
| 54851 | 54940 | for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ |
| 54852 | 54941 | |
| 54853 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54854 | 54942 | /* If required, populate the overflow page-list cache. */ |
| 54855 | | - if( pCur->aOverflow ){ |
| 54943 | + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ |
| 54856 | 54944 | assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); |
| 54857 | 54945 | pCur->aOverflow[iIdx] = nextPage; |
| 54858 | 54946 | } |
| 54859 | | -#endif |
| 54860 | 54947 | |
| 54861 | 54948 | if( offset>=ovflSize ){ |
| 54862 | 54949 | /* The only reason to read this page is to obtain the page |
| 54863 | 54950 | ** number for the next page in the overflow chain. The page |
| 54864 | 54951 | ** data is not required. So first try to lookup the overflow |
| 54865 | 54952 | ** page-list cache, if any, then fall back to the getOverflowPage() |
| 54866 | 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. |
| 54867 | 54957 | */ |
| 54868 | | -#ifndef SQLITE_OMIT_INCRBLOB |
| 54869 | | - if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ |
| 54958 | + assert( eOp!=2 ); |
| 54959 | + assert( pCur->curFlags & BTCF_ValidOvfl ); |
| 54960 | + if( pCur->aOverflow[iIdx+1] ){ |
| 54870 | 54961 | nextPage = pCur->aOverflow[iIdx+1]; |
| 54871 | | - } else |
| 54872 | | -#endif |
| 54962 | + }else{ |
| 54873 | 54963 | rc = getOverflowPage(pBt, nextPage, 0, &nextPage); |
| 54964 | + } |
| 54874 | 54965 | offset -= ovflSize; |
| 54875 | 54966 | }else{ |
| 54876 | 54967 | /* Need to read this page properly. It contains some of the |
| 54877 | 54968 | ** range of data that is being read (eOp==0) or written (eOp!=0). |
| 54878 | 54969 | */ |
| | @@ -54890,17 +54981,19 @@ |
| 54890 | 54981 | ** 1) this is a read operation, and |
| 54891 | 54982 | ** 2) data is required from the start of this overflow page, and |
| 54892 | 54983 | ** 3) the database is file-backed, and |
| 54893 | 54984 | ** 4) there is no open write-transaction, and |
| 54894 | 54985 | ** 5) the database is not a WAL database, |
| 54986 | + ** 6) all data from the page is being read. |
| 54895 | 54987 | ** |
| 54896 | 54988 | ** then data can be read directly from the database file into the |
| 54897 | 54989 | ** output buffer, bypassing the page-cache altogether. This speeds |
| 54898 | 54990 | ** up loading large records that span many overflow pages. |
| 54899 | 54991 | */ |
| 54900 | | - if( eOp==0 /* (1) */ |
| 54992 | + if( (eOp&0x01)==0 /* (1) */ |
| 54901 | 54993 | && offset==0 /* (2) */ |
| 54994 | + && (bEnd || a==ovflSize) /* (6) */ |
| 54902 | 54995 | && pBt->inTransaction==TRANS_READ /* (4) */ |
| 54903 | 54996 | && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ |
| 54904 | 54997 | && pBt->pPage1->aData[19]==0x01 /* (5) */ |
| 54905 | 54998 | ){ |
| 54906 | 54999 | u8 aSave[4]; |
| | @@ -54913,16 +55006,16 @@ |
| 54913 | 55006 | #endif |
| 54914 | 55007 | |
| 54915 | 55008 | { |
| 54916 | 55009 | DbPage *pDbPage; |
| 54917 | 55010 | rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, |
| 54918 | | - (eOp==0 ? PAGER_GET_READONLY : 0) |
| 55011 | + ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) |
| 54919 | 55012 | ); |
| 54920 | 55013 | if( rc==SQLITE_OK ){ |
| 54921 | 55014 | aPayload = sqlite3PagerGetData(pDbPage); |
| 54922 | 55015 | nextPage = get4byte(aPayload); |
| 54923 | | - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); |
| 55016 | + rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); |
| 54924 | 55017 | sqlite3PagerUnref(pDbPage); |
| 54925 | 55018 | offset = 0; |
| 54926 | 55019 | } |
| 54927 | 55020 | } |
| 54928 | 55021 | amt -= a; |
| | @@ -55012,14 +55105,17 @@ |
| 55012 | 55105 | assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); |
| 55013 | 55106 | assert( pCur->eState==CURSOR_VALID ); |
| 55014 | 55107 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 55015 | 55108 | assert( cursorHoldsMutex(pCur) ); |
| 55016 | 55109 | assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); |
| 55110 | + assert( pCur->info.nSize>0 ); |
| 55111 | +#if 0 |
| 55017 | 55112 | if( pCur->info.nSize==0 ){ |
| 55018 | 55113 | btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], |
| 55019 | 55114 | &pCur->info); |
| 55020 | 55115 | } |
| 55116 | +#endif |
| 55021 | 55117 | *pAmt = pCur->info.nLocal; |
| 55022 | 55118 | return (void*)(pCur->info.pCell + pCur->info.nHeader); |
| 55023 | 55119 | } |
| 55024 | 55120 | |
| 55025 | 55121 | |
| | @@ -55066,18 +55162,18 @@ |
| 55066 | 55162 | assert( pCur->iPage>=0 ); |
| 55067 | 55163 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ |
| 55068 | 55164 | return SQLITE_CORRUPT_BKPT; |
| 55069 | 55165 | } |
| 55070 | 55166 | rc = getAndInitPage(pBt, newPgno, &pNewPage, |
| 55071 | | - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 55167 | + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); |
| 55072 | 55168 | if( rc ) return rc; |
| 55073 | 55169 | pCur->apPage[i+1] = pNewPage; |
| 55074 | 55170 | pCur->aiIdx[i+1] = 0; |
| 55075 | 55171 | pCur->iPage++; |
| 55076 | 55172 | |
| 55077 | 55173 | pCur->info.nSize = 0; |
| 55078 | | - pCur->validNKey = 0; |
| 55174 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55079 | 55175 | if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ |
| 55080 | 55176 | return SQLITE_CORRUPT_BKPT; |
| 55081 | 55177 | } |
| 55082 | 55178 | return SQLITE_OK; |
| 55083 | 55179 | } |
| | @@ -55131,11 +55227,11 @@ |
| 55131 | 55227 | testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); |
| 55132 | 55228 | |
| 55133 | 55229 | releasePage(pCur->apPage[pCur->iPage]); |
| 55134 | 55230 | pCur->iPage--; |
| 55135 | 55231 | pCur->info.nSize = 0; |
| 55136 | | - pCur->validNKey = 0; |
| 55232 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55137 | 55233 | } |
| 55138 | 55234 | |
| 55139 | 55235 | /* |
| 55140 | 55236 | ** Move the cursor to point to the root page of its b-tree structure. |
| 55141 | 55237 | ** |
| | @@ -55178,11 +55274,11 @@ |
| 55178 | 55274 | }else if( pCur->pgnoRoot==0 ){ |
| 55179 | 55275 | pCur->eState = CURSOR_INVALID; |
| 55180 | 55276 | return SQLITE_OK; |
| 55181 | 55277 | }else{ |
| 55182 | 55278 | rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], |
| 55183 | | - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 55279 | + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); |
| 55184 | 55280 | if( rc!=SQLITE_OK ){ |
| 55185 | 55281 | pCur->eState = CURSOR_INVALID; |
| 55186 | 55282 | return rc; |
| 55187 | 55283 | } |
| 55188 | 55284 | pCur->iPage = 0; |
| | @@ -55205,12 +55301,11 @@ |
| 55205 | 55301 | return SQLITE_CORRUPT_BKPT; |
| 55206 | 55302 | } |
| 55207 | 55303 | |
| 55208 | 55304 | pCur->aiIdx[0] = 0; |
| 55209 | 55305 | pCur->info.nSize = 0; |
| 55210 | | - pCur->atLast = 0; |
| 55211 | | - pCur->validNKey = 0; |
| 55306 | + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55212 | 55307 | |
| 55213 | 55308 | if( pRoot->nCell>0 ){ |
| 55214 | 55309 | pCur->eState = CURSOR_VALID; |
| 55215 | 55310 | }else if( !pRoot->leaf ){ |
| 55216 | 55311 | Pgno subpage; |
| | @@ -55269,11 +55364,11 @@ |
| 55269 | 55364 | rc = moveToChild(pCur, pgno); |
| 55270 | 55365 | } |
| 55271 | 55366 | if( rc==SQLITE_OK ){ |
| 55272 | 55367 | pCur->aiIdx[pCur->iPage] = pPage->nCell-1; |
| 55273 | 55368 | pCur->info.nSize = 0; |
| 55274 | | - pCur->validNKey = 0; |
| 55369 | + pCur->curFlags &= ~BTCF_ValidNKey; |
| 55275 | 55370 | } |
| 55276 | 55371 | return rc; |
| 55277 | 55372 | } |
| 55278 | 55373 | |
| 55279 | 55374 | /* Move the cursor to the first entry in the table. Return SQLITE_OK |
| | @@ -55308,11 +55403,11 @@ |
| 55308 | 55403 | |
| 55309 | 55404 | assert( cursorHoldsMutex(pCur) ); |
| 55310 | 55405 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 55311 | 55406 | |
| 55312 | 55407 | /* If the cursor already points to the last entry, this is a no-op. */ |
| 55313 | | - if( CURSOR_VALID==pCur->eState && pCur->atLast ){ |
| 55408 | + if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ |
| 55314 | 55409 | #ifdef SQLITE_DEBUG |
| 55315 | 55410 | /* This block serves to assert() that the cursor really does point |
| 55316 | 55411 | ** to the last entry in the b-tree. */ |
| 55317 | 55412 | int ii; |
| 55318 | 55413 | for(ii=0; ii<pCur->iPage; ii++){ |
| | @@ -55331,11 +55426,16 @@ |
| 55331 | 55426 | *pRes = 1; |
| 55332 | 55427 | }else{ |
| 55333 | 55428 | assert( pCur->eState==CURSOR_VALID ); |
| 55334 | 55429 | *pRes = 0; |
| 55335 | 55430 | rc = moveToRightmost(pCur); |
| 55336 | | - 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 | + |
| 55337 | 55437 | } |
| 55338 | 55438 | } |
| 55339 | 55439 | return rc; |
| 55340 | 55440 | } |
| 55341 | 55441 | |
| | @@ -55382,25 +55482,26 @@ |
| 55382 | 55482 | assert( pRes ); |
| 55383 | 55483 | assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); |
| 55384 | 55484 | |
| 55385 | 55485 | /* If the cursor is already positioned at the point we are trying |
| 55386 | 55486 | ** to move to, then just return without doing any work */ |
| 55387 | | - if( pCur->eState==CURSOR_VALID && pCur->validNKey |
| 55487 | + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 |
| 55388 | 55488 | && pCur->apPage[0]->intKey |
| 55389 | 55489 | ){ |
| 55390 | 55490 | if( pCur->info.nKey==intKey ){ |
| 55391 | 55491 | *pRes = 0; |
| 55392 | 55492 | return SQLITE_OK; |
| 55393 | 55493 | } |
| 55394 | | - if( pCur->atLast && pCur->info.nKey<intKey ){ |
| 55494 | + if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){ |
| 55395 | 55495 | *pRes = -1; |
| 55396 | 55496 | return SQLITE_OK; |
| 55397 | 55497 | } |
| 55398 | 55498 | } |
| 55399 | 55499 | |
| 55400 | 55500 | if( pIdxKey ){ |
| 55401 | 55501 | xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); |
| 55502 | + pIdxKey->isCorrupt = 0; |
| 55402 | 55503 | assert( pIdxKey->default_rc==1 |
| 55403 | 55504 | || pIdxKey->default_rc==0 |
| 55404 | 55505 | || pIdxKey->default_rc==-1 |
| 55405 | 55506 | ); |
| 55406 | 55507 | }else{ |
| | @@ -55455,11 +55556,11 @@ |
| 55455 | 55556 | }else if( nCellKey>intKey ){ |
| 55456 | 55557 | upr = idx-1; |
| 55457 | 55558 | if( lwr>upr ){ c = +1; break; } |
| 55458 | 55559 | }else{ |
| 55459 | 55560 | assert( nCellKey==intKey ); |
| 55460 | | - pCur->validNKey = 1; |
| 55561 | + pCur->curFlags |= BTCF_ValidNKey; |
| 55461 | 55562 | pCur->info.nKey = nCellKey; |
| 55462 | 55563 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55463 | 55564 | if( !pPage->leaf ){ |
| 55464 | 55565 | lwr = idx; |
| 55465 | 55566 | goto moveto_next_layer; |
| | @@ -55512,27 +55613,29 @@ |
| 55512 | 55613 | if( pCellKey==0 ){ |
| 55513 | 55614 | rc = SQLITE_NOMEM; |
| 55514 | 55615 | goto moveto_finish; |
| 55515 | 55616 | } |
| 55516 | 55617 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55517 | | - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); |
| 55618 | + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); |
| 55518 | 55619 | if( rc ){ |
| 55519 | 55620 | sqlite3_free(pCellKey); |
| 55520 | 55621 | goto moveto_finish; |
| 55521 | 55622 | } |
| 55522 | 55623 | c = xRecordCompare(nCell, pCellKey, pIdxKey, 0); |
| 55523 | 55624 | sqlite3_free(pCellKey); |
| 55524 | 55625 | } |
| 55626 | + assert( pIdxKey->isCorrupt==0 || c==0 ); |
| 55525 | 55627 | if( c<0 ){ |
| 55526 | 55628 | lwr = idx+1; |
| 55527 | 55629 | }else if( c>0 ){ |
| 55528 | 55630 | upr = idx-1; |
| 55529 | 55631 | }else{ |
| 55530 | 55632 | assert( c==0 ); |
| 55531 | 55633 | *pRes = 0; |
| 55532 | 55634 | rc = SQLITE_OK; |
| 55533 | 55635 | pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55636 | + if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT; |
| 55534 | 55637 | goto moveto_finish; |
| 55535 | 55638 | } |
| 55536 | 55639 | if( lwr>upr ) break; |
| 55537 | 55640 | assert( lwr+upr>=0 ); |
| 55538 | 55641 | idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ |
| | @@ -55557,11 +55660,11 @@ |
| 55557 | 55660 | rc = moveToChild(pCur, chldPg); |
| 55558 | 55661 | if( rc ) break; |
| 55559 | 55662 | } |
| 55560 | 55663 | moveto_finish: |
| 55561 | 55664 | pCur->info.nSize = 0; |
| 55562 | | - pCur->validNKey = 0; |
| 55665 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55563 | 55666 | return rc; |
| 55564 | 55667 | } |
| 55565 | 55668 | |
| 55566 | 55669 | |
| 55567 | 55670 | /* |
| | @@ -55602,10 +55705,11 @@ |
| 55602 | 55705 | assert( cursorHoldsMutex(pCur) ); |
| 55603 | 55706 | assert( pRes!=0 ); |
| 55604 | 55707 | assert( *pRes==0 || *pRes==1 ); |
| 55605 | 55708 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 55606 | 55709 | if( pCur->eState!=CURSOR_VALID ){ |
| 55710 | + invalidateOverflowCache(pCur); |
| 55607 | 55711 | rc = restoreCursorPosition(pCur); |
| 55608 | 55712 | if( rc!=SQLITE_OK ){ |
| 55609 | 55713 | *pRes = 0; |
| 55610 | 55714 | return rc; |
| 55611 | 55715 | } |
| | @@ -55635,11 +55739,11 @@ |
| 55635 | 55739 | ** only happen if the database is corrupt in such a way as to link the |
| 55636 | 55740 | ** page into more than one b-tree structure. */ |
| 55637 | 55741 | testcase( idx>pPage->nCell ); |
| 55638 | 55742 | |
| 55639 | 55743 | pCur->info.nSize = 0; |
| 55640 | | - pCur->validNKey = 0; |
| 55744 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55641 | 55745 | if( idx>=pPage->nCell ){ |
| 55642 | 55746 | if( !pPage->leaf ){ |
| 55643 | 55747 | rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); |
| 55644 | 55748 | if( rc ){ |
| 55645 | 55749 | *pRes = 0; |
| | @@ -55696,11 +55800,11 @@ |
| 55696 | 55800 | |
| 55697 | 55801 | assert( cursorHoldsMutex(pCur) ); |
| 55698 | 55802 | assert( pRes!=0 ); |
| 55699 | 55803 | assert( *pRes==0 || *pRes==1 ); |
| 55700 | 55804 | assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); |
| 55701 | | - pCur->atLast = 0; |
| 55805 | + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl); |
| 55702 | 55806 | if( pCur->eState!=CURSOR_VALID ){ |
| 55703 | 55807 | if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ |
| 55704 | 55808 | rc = btreeRestoreCursorPosition(pCur); |
| 55705 | 55809 | if( rc!=SQLITE_OK ){ |
| 55706 | 55810 | *pRes = 0; |
| | @@ -55741,11 +55845,11 @@ |
| 55741 | 55845 | return SQLITE_OK; |
| 55742 | 55846 | } |
| 55743 | 55847 | moveToParent(pCur); |
| 55744 | 55848 | } |
| 55745 | 55849 | pCur->info.nSize = 0; |
| 55746 | | - pCur->validNKey = 0; |
| 55850 | + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); |
| 55747 | 55851 | |
| 55748 | 55852 | pCur->aiIdx[pCur->iPage]--; |
| 55749 | 55853 | pPage = pCur->apPage[pCur->iPage]; |
| 55750 | 55854 | if( pPage->intKey && !pPage->leaf ){ |
| 55751 | 55855 | rc = sqlite3BtreePrevious(pCur, pRes); |
| | @@ -57766,11 +57870,11 @@ |
| 57766 | 57870 | assert( pCur->skipNext!=SQLITE_OK ); |
| 57767 | 57871 | return pCur->skipNext; |
| 57768 | 57872 | } |
| 57769 | 57873 | |
| 57770 | 57874 | assert( cursorHoldsMutex(pCur) ); |
| 57771 | | - assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE |
| 57875 | + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE |
| 57772 | 57876 | && (pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 57773 | 57877 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); |
| 57774 | 57878 | |
| 57775 | 57879 | /* Assert that the caller has been consistent. If this cursor was opened |
| 57776 | 57880 | ** expecting an index b-tree, then the caller should be inserting blob |
| | @@ -57799,11 +57903,11 @@ |
| 57799 | 57903 | invalidateIncrblobCursors(p, nKey, 0); |
| 57800 | 57904 | |
| 57801 | 57905 | /* If the cursor is currently on the last row and we are appending a |
| 57802 | 57906 | ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto() |
| 57803 | 57907 | ** call */ |
| 57804 | | - if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){ |
| 57908 | + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){ |
| 57805 | 57909 | loc = -1; |
| 57806 | 57910 | } |
| 57807 | 57911 | } |
| 57808 | 57912 | |
| 57809 | 57913 | if( !loc ){ |
| | @@ -57852,11 +57956,11 @@ |
| 57852 | 57956 | insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); |
| 57853 | 57957 | assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); |
| 57854 | 57958 | |
| 57855 | 57959 | /* If no error has occurred and pPage has an overflow cell, call balance() |
| 57856 | 57960 | ** to redistribute the cells within the tree. Since balance() may move |
| 57857 | | - ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey |
| 57961 | + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey |
| 57858 | 57962 | ** variables. |
| 57859 | 57963 | ** |
| 57860 | 57964 | ** Previous versions of SQLite called moveToRoot() to move the cursor |
| 57861 | 57965 | ** back to the root page as balance() used to invalidate the contents |
| 57862 | 57966 | ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, |
| | @@ -57872,11 +57976,11 @@ |
| 57872 | 57976 | ** larger than the largest existing key, it is possible to insert the |
| 57873 | 57977 | ** row without seeking the cursor. This can be a big performance boost. |
| 57874 | 57978 | */ |
| 57875 | 57979 | pCur->info.nSize = 0; |
| 57876 | 57980 | if( rc==SQLITE_OK && pPage->nOverflow ){ |
| 57877 | | - pCur->validNKey = 0; |
| 57981 | + pCur->curFlags &= ~(BTCF_ValidNKey); |
| 57878 | 57982 | rc = balance(pCur); |
| 57879 | 57983 | |
| 57880 | 57984 | /* Must make sure nOverflow is reset to zero even if the balance() |
| 57881 | 57985 | ** fails. Internal data structure corruption will result otherwise. |
| 57882 | 57986 | ** Also, set the cursor state to invalid. This stops saveCursorPosition() |
| | @@ -57904,11 +58008,11 @@ |
| 57904 | 58008 | int iCellDepth; /* Depth of node containing pCell */ |
| 57905 | 58009 | |
| 57906 | 58010 | assert( cursorHoldsMutex(pCur) ); |
| 57907 | 58011 | assert( pBt->inTransaction==TRANS_WRITE ); |
| 57908 | 58012 | assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 57909 | | - assert( pCur->wrFlag ); |
| 58013 | + assert( pCur->curFlags & BTCF_WriteFlag ); |
| 57910 | 58014 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); |
| 57911 | 58015 | assert( !hasReadConflicts(p, pCur->pgnoRoot) ); |
| 57912 | 58016 | |
| 57913 | 58017 | if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) |
| 57914 | 58018 | || NEVER(pCur->eState!=CURSOR_VALID) |
| | @@ -58248,10 +58352,19 @@ |
| 58248 | 58352 | rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); |
| 58249 | 58353 | } |
| 58250 | 58354 | sqlite3BtreeLeave(p); |
| 58251 | 58355 | return rc; |
| 58252 | 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 | +} |
| 58253 | 58366 | |
| 58254 | 58367 | /* |
| 58255 | 58368 | ** Erase all information in a table and add the root of the table to |
| 58256 | 58369 | ** the freelist. Except, the root of the principle table (the one on |
| 58257 | 58370 | ** page 1) is never added to the freelist. |
| | @@ -59208,11 +59321,11 @@ |
| 59208 | 59321 | */ |
| 59209 | 59322 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ |
| 59210 | 59323 | int rc; |
| 59211 | 59324 | assert( cursorHoldsMutex(pCsr) ); |
| 59212 | 59325 | assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); |
| 59213 | | - assert( pCsr->isIncrblobHandle ); |
| 59326 | + assert( pCsr->curFlags & BTCF_Incrblob ); |
| 59214 | 59327 | |
| 59215 | 59328 | rc = restoreCursorPosition(pCsr); |
| 59216 | 59329 | if( rc!=SQLITE_OK ){ |
| 59217 | 59330 | return rc; |
| 59218 | 59331 | } |
| | @@ -59237,11 +59350,11 @@ |
| 59237 | 59350 | ** (b) there is a read/write transaction open, |
| 59238 | 59351 | ** (c) the connection holds a write-lock on the table (if required), |
| 59239 | 59352 | ** (d) there are no conflicting read-locks, and |
| 59240 | 59353 | ** (e) the cursor points at a valid row of an intKey table. |
| 59241 | 59354 | */ |
| 59242 | | - if( !pCsr->wrFlag ){ |
| 59355 | + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ |
| 59243 | 59356 | return SQLITE_READONLY; |
| 59244 | 59357 | } |
| 59245 | 59358 | assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 |
| 59246 | 59359 | && pCsr->pBt->inTransaction==TRANS_WRITE ); |
| 59247 | 59360 | assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); |
| | @@ -59250,24 +59363,14 @@ |
| 59250 | 59363 | |
| 59251 | 59364 | return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); |
| 59252 | 59365 | } |
| 59253 | 59366 | |
| 59254 | 59367 | /* |
| 59255 | | -** Set a flag on this cursor to cache the locations of pages from the |
| 59256 | | -** overflow list for the current row. This is used by cursors opened |
| 59257 | | -** for incremental blob IO only. |
| 59258 | | -** |
| 59259 | | -** This function sets a flag only. The actual page location cache |
| 59260 | | -** (stored in BtCursor.aOverflow[]) is allocated and used by function |
| 59261 | | -** accessPayload() (the worker function for sqlite3BtreeData() and |
| 59262 | | -** sqlite3BtreePutData()). |
| 59368 | +** Mark this cursor as an incremental blob cursor. |
| 59263 | 59369 | */ |
| 59264 | | -SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ |
| 59265 | | - assert( cursorHoldsMutex(pCur) ); |
| 59266 | | - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 59267 | | - invalidateOverflowCache(pCur); |
| 59268 | | - pCur->isIncrblobHandle = 1; |
| 59370 | +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ |
| 59371 | + pCur->curFlags |= BTCF_Incrblob; |
| 59269 | 59372 | } |
| 59270 | 59373 | #endif |
| 59271 | 59374 | |
| 59272 | 59375 | /* |
| 59273 | 59376 | ** Set both the "read version" (single byte at byte offset 18) and |
| | @@ -61634,11 +61737,11 @@ |
| 61634 | 61737 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ |
| 61635 | 61738 | Parse *p = v->pParse; |
| 61636 | 61739 | int j = -1-x; |
| 61637 | 61740 | assert( v->magic==VDBE_MAGIC_INIT ); |
| 61638 | 61741 | assert( j<p->nLabel ); |
| 61639 | | - if( j>=0 && p->aLabel ){ |
| 61742 | + if( ALWAYS(j>=0) && p->aLabel ){ |
| 61640 | 61743 | p->aLabel[j] = v->nOp; |
| 61641 | 61744 | } |
| 61642 | 61745 | p->iFixedOp = v->nOp - 1; |
| 61643 | 61746 | } |
| 61644 | 61747 | |
| | @@ -62141,11 +62244,13 @@ |
| 62141 | 62244 | assert( addr<p->nOp ); |
| 62142 | 62245 | if( addr<0 ){ |
| 62143 | 62246 | addr = p->nOp - 1; |
| 62144 | 62247 | } |
| 62145 | 62248 | pOp = &p->aOp[addr]; |
| 62146 | | - 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 ); |
| 62147 | 62252 | freeP4(db, pOp->p4type, pOp->p4.p); |
| 62148 | 62253 | pOp->p4.p = 0; |
| 62149 | 62254 | if( n==P4_INT32 ){ |
| 62150 | 62255 | /* Note: this cast is safe, because the origin data point was an int |
| 62151 | 62256 | ** that was cast to a (const char *). */ |
| | @@ -64091,11 +64196,11 @@ |
| 64091 | 64196 | int hasMoved; |
| 64092 | 64197 | int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); |
| 64093 | 64198 | if( rc ) return rc; |
| 64094 | 64199 | if( hasMoved ){ |
| 64095 | 64200 | p->cacheStatus = CACHE_STALE; |
| 64096 | | - p->nullRow = 1; |
| 64201 | + if( hasMoved==2 ) p->nullRow = 1; |
| 64097 | 64202 | } |
| 64098 | 64203 | } |
| 64099 | 64204 | return SQLITE_OK; |
| 64100 | 64205 | } |
| 64101 | 64206 | |
| | @@ -64761,14 +64866,17 @@ |
| 64761 | 64866 | ** determined that the first fields of the keys are equal. |
| 64762 | 64867 | ** |
| 64763 | 64868 | ** Key1 and Key2 do not have to contain the same number of fields. If all |
| 64764 | 64869 | ** fields that appear in both keys are equal, then pPKey2->default_rc is |
| 64765 | 64870 | ** returned. |
| 64871 | +** |
| 64872 | +** If database corruption is discovered, set pPKey2->isCorrupt to non-zero |
| 64873 | +** and return 0. |
| 64766 | 64874 | */ |
| 64767 | 64875 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare( |
| 64768 | 64876 | int nKey1, const void *pKey1, /* Left key */ |
| 64769 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 64877 | + UnpackedRecord *pPKey2, /* Right key */ |
| 64770 | 64878 | int bSkip /* If true, skip the first field */ |
| 64771 | 64879 | ){ |
| 64772 | 64880 | u32 d1; /* Offset into aKey[] of next data element */ |
| 64773 | 64881 | int i; /* Index of next field to compare */ |
| 64774 | 64882 | u32 szHdr1; /* Size of record header in bytes */ |
| | @@ -64790,11 +64898,14 @@ |
| 64790 | 64898 | i = 1; |
| 64791 | 64899 | pRhs++; |
| 64792 | 64900 | }else{ |
| 64793 | 64901 | idx1 = getVarint32(aKey1, szHdr1); |
| 64794 | 64902 | d1 = szHdr1; |
| 64795 | | - if( d1>(unsigned)nKey1 ) return 1; /* Corruption */ |
| 64903 | + if( d1>(unsigned)nKey1 ){ |
| 64904 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 64905 | + return 0; /* Corruption */ |
| 64906 | + } |
| 64796 | 64907 | i = 0; |
| 64797 | 64908 | } |
| 64798 | 64909 | |
| 64799 | 64910 | VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ |
| 64800 | 64911 | assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField |
| | @@ -64867,11 +64978,12 @@ |
| 64867 | 64978 | }else{ |
| 64868 | 64979 | mem1.n = (serial_type - 12) / 2; |
| 64869 | 64980 | testcase( (d1+mem1.n)==(unsigned)nKey1 ); |
| 64870 | 64981 | testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); |
| 64871 | 64982 | if( (d1+mem1.n) > (unsigned)nKey1 ){ |
| 64872 | | - rc = 1; /* Corruption */ |
| 64983 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 64984 | + return 0; /* Corruption */ |
| 64873 | 64985 | }else if( pKeyInfo->aColl[i] ){ |
| 64874 | 64986 | mem1.enc = pKeyInfo->enc; |
| 64875 | 64987 | mem1.db = pKeyInfo->db; |
| 64876 | 64988 | mem1.flags = MEM_Str; |
| 64877 | 64989 | mem1.z = (char*)&aKey1[d1]; |
| | @@ -64893,11 +65005,12 @@ |
| 64893 | 65005 | }else{ |
| 64894 | 65006 | int nStr = (serial_type - 12) / 2; |
| 64895 | 65007 | testcase( (d1+nStr)==(unsigned)nKey1 ); |
| 64896 | 65008 | testcase( (d1+nStr+1)==(unsigned)nKey1 ); |
| 64897 | 65009 | if( (d1+nStr) > (unsigned)nKey1 ){ |
| 64898 | | - rc = 1; /* Corruption */ |
| 65010 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 65011 | + return 0; /* Corruption */ |
| 64899 | 65012 | }else{ |
| 64900 | 65013 | int nCmp = MIN(nStr, pRhs->n); |
| 64901 | 65014 | rc = memcmp(&aKey1[d1], pRhs->z, nCmp); |
| 64902 | 65015 | if( rc==0 ) rc = nStr - pRhs->n; |
| 64903 | 65016 | } |
| | @@ -64946,14 +65059,17 @@ |
| 64946 | 65059 | /* |
| 64947 | 65060 | ** This function is an optimized version of sqlite3VdbeRecordCompare() |
| 64948 | 65061 | ** that (a) the first field of pPKey2 is an integer, and (b) the |
| 64949 | 65062 | ** size-of-header varint at the start of (pKey1/nKey1) fits in a single |
| 64950 | 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. |
| 64951 | 65067 | */ |
| 64952 | 65068 | static int vdbeRecordCompareInt( |
| 64953 | 65069 | int nKey1, const void *pKey1, /* Left key */ |
| 64954 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 65070 | + UnpackedRecord *pPKey2, /* Right key */ |
| 64955 | 65071 | int bSkip /* Ignored */ |
| 64956 | 65072 | ){ |
| 64957 | 65073 | const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; |
| 64958 | 65074 | int serial_type = ((const u8*)pKey1)[1]; |
| 64959 | 65075 | int res; |
| | @@ -64962,10 +65078,11 @@ |
| 64962 | 65078 | i64 v = pPKey2->aMem[0].u.i; |
| 64963 | 65079 | i64 lhs; |
| 64964 | 65080 | UNUSED_PARAMETER(bSkip); |
| 64965 | 65081 | |
| 64966 | 65082 | assert( bSkip==0 ); |
| 65083 | + assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); |
| 64967 | 65084 | switch( serial_type ){ |
| 64968 | 65085 | case 1: { /* 1-byte signed integer */ |
| 64969 | 65086 | lhs = ONE_BYTE_INT(aKey); |
| 64970 | 65087 | testcase( lhs<0 ); |
| 64971 | 65088 | break; |
| | @@ -65046,11 +65163,11 @@ |
| 65046 | 65163 | ** uses the collation sequence BINARY and (c) that the size-of-header varint |
| 65047 | 65164 | ** at the start of (pKey1/nKey1) fits in a single byte. |
| 65048 | 65165 | */ |
| 65049 | 65166 | static int vdbeRecordCompareString( |
| 65050 | 65167 | int nKey1, const void *pKey1, /* Left key */ |
| 65051 | | - const UnpackedRecord *pPKey2, /* Right key */ |
| 65168 | + UnpackedRecord *pPKey2, /* Right key */ |
| 65052 | 65169 | int bSkip |
| 65053 | 65170 | ){ |
| 65054 | 65171 | const u8 *aKey1 = (const u8*)pKey1; |
| 65055 | 65172 | int serial_type; |
| 65056 | 65173 | int res; |
| | @@ -65067,11 +65184,14 @@ |
| 65067 | 65184 | int nCmp; |
| 65068 | 65185 | int nStr; |
| 65069 | 65186 | int szHdr = aKey1[0]; |
| 65070 | 65187 | |
| 65071 | 65188 | nStr = (serial_type-12) / 2; |
| 65072 | | - if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */ |
| 65189 | + if( (szHdr + nStr) > nKey1 ){ |
| 65190 | + pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT; |
| 65191 | + return 0; /* Corruption */ |
| 65192 | + } |
| 65073 | 65193 | nCmp = MIN( pPKey2->aMem[0].n, nStr ); |
| 65074 | 65194 | res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); |
| 65075 | 65195 | |
| 65076 | 65196 | if( res==0 ){ |
| 65077 | 65197 | res = nStr - pPKey2->aMem[0].n; |
| | @@ -65232,11 +65352,11 @@ |
| 65232 | 65352 | ** is ignored as well. Hence, this routine only compares the prefixes |
| 65233 | 65353 | ** of the keys prior to the final rowid, not the entire key. |
| 65234 | 65354 | */ |
| 65235 | 65355 | SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( |
| 65236 | 65356 | VdbeCursor *pC, /* The cursor to compare against */ |
| 65237 | | - const UnpackedRecord *pUnpacked, /* Unpacked version of key */ |
| 65357 | + UnpackedRecord *pUnpacked, /* Unpacked version of key */ |
| 65238 | 65358 | int *res /* Write the comparison result here */ |
| 65239 | 65359 | ){ |
| 65240 | 65360 | i64 nCellKey = 0; |
| 65241 | 65361 | int rc; |
| 65242 | 65362 | BtCursor *pCur = pC->pCursor; |
| | @@ -67322,10 +67442,33 @@ |
| 67322 | 67442 | u8 affinity, |
| 67323 | 67443 | u8 enc |
| 67324 | 67444 | ){ |
| 67325 | 67445 | applyAffinity((Mem *)pVal, affinity, enc); |
| 67326 | 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 | +} |
| 67327 | 67470 | |
| 67328 | 67471 | #ifdef SQLITE_DEBUG |
| 67329 | 67472 | /* |
| 67330 | 67473 | ** Write a nice string representation of the contents of cell pMem |
| 67331 | 67474 | ** into buffer zBuf, length nBuf. |
| | @@ -68182,14 +68325,15 @@ |
| 68182 | 68325 | } |
| 68183 | 68326 | |
| 68184 | 68327 | /* Opcode: Move P1 P2 P3 * * |
| 68185 | 68328 | ** Synopsis: r[P2@P3]=r[P1@P3] |
| 68186 | 68329 | ** |
| 68187 | | -** Move the values in register P1..P1+P3 over into |
| 68188 | | -** 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 |
| 68189 | 68332 | ** left holding a NULL. It is an error for register ranges |
| 68190 | | -** 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. |
| 68191 | 68335 | */ |
| 68192 | 68336 | case OP_Move: { |
| 68193 | 68337 | char *zMalloc; /* Holding variable for allocated memory */ |
| 68194 | 68338 | int n; /* Number of registers left to copy */ |
| 68195 | 68339 | int p1; /* Register to copy from */ |
| | @@ -68196,11 +68340,11 @@ |
| 68196 | 68340 | int p2; /* Register to copy to */ |
| 68197 | 68341 | |
| 68198 | 68342 | n = pOp->p3; |
| 68199 | 68343 | p1 = pOp->p1; |
| 68200 | 68344 | p2 = pOp->p2; |
| 68201 | | - assert( n>=0 && p1>0 && p2>0 ); |
| 68345 | + assert( n>0 && p1>0 && p2>0 ); |
| 68202 | 68346 | assert( p1+n<=p2 || p2+n<=p1 ); |
| 68203 | 68347 | |
| 68204 | 68348 | pIn1 = &aMem[p1]; |
| 68205 | 68349 | pOut = &aMem[p2]; |
| 68206 | 68350 | do{ |
| | @@ -68220,11 +68364,11 @@ |
| 68220 | 68364 | pIn1->xDel = 0; |
| 68221 | 68365 | pIn1->zMalloc = zMalloc; |
| 68222 | 68366 | REGISTER_TRACE(p2++, pOut); |
| 68223 | 68367 | pIn1++; |
| 68224 | 68368 | pOut++; |
| 68225 | | - }while( n-- ); |
| 68369 | + }while( --n ); |
| 68226 | 68370 | break; |
| 68227 | 68371 | } |
| 68228 | 68372 | |
| 68229 | 68373 | /* Opcode: Copy P1 P2 P3 * * |
| 68230 | 68374 | ** Synopsis: r[P2@P3+1]=r[P1@P3+1] |
| | @@ -68452,24 +68596,26 @@ |
| 68452 | 68596 | case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ |
| 68453 | 68597 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ |
| 68454 | 68598 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ |
| 68455 | 68599 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
| 68456 | 68600 | char bIntint; /* Started out as two integer operands */ |
| 68457 | | - 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 */ |
| 68458 | 68604 | i64 iA; /* Integer value of left operand */ |
| 68459 | 68605 | i64 iB; /* Integer value of right operand */ |
| 68460 | 68606 | double rA; /* Real value of left operand */ |
| 68461 | 68607 | double rB; /* Real value of right operand */ |
| 68462 | 68608 | |
| 68463 | 68609 | pIn1 = &aMem[pOp->p1]; |
| 68464 | | - applyNumericAffinity(pIn1); |
| 68610 | + type1 = numericType(pIn1); |
| 68465 | 68611 | pIn2 = &aMem[pOp->p2]; |
| 68466 | | - applyNumericAffinity(pIn2); |
| 68612 | + type2 = numericType(pIn2); |
| 68467 | 68613 | pOut = &aMem[pOp->p3]; |
| 68468 | 68614 | flags = pIn1->flags | pIn2->flags; |
| 68469 | 68615 | if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 68470 | | - if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ |
| 68616 | + if( (type1 & type2 & MEM_Int)!=0 ){ |
| 68471 | 68617 | iA = pIn1->u.i; |
| 68472 | 68618 | iB = pIn2->u.i; |
| 68473 | 68619 | bIntint = 1; |
| 68474 | 68620 | switch( pOp->opcode ){ |
| 68475 | 68621 | case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; |
| | @@ -68521,11 +68667,11 @@ |
| 68521 | 68667 | if( sqlite3IsNaN(rB) ){ |
| 68522 | 68668 | goto arithmetic_result_is_null; |
| 68523 | 68669 | } |
| 68524 | 68670 | pOut->r = rB; |
| 68525 | 68671 | MemSetTypeFlag(pOut, MEM_Real); |
| 68526 | | - if( (flags & MEM_Real)==0 && !bIntint ){ |
| 68672 | + if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ |
| 68527 | 68673 | sqlite3VdbeIntegerAffinity(pOut); |
| 68528 | 68674 | } |
| 68529 | 68675 | #endif |
| 68530 | 68676 | } |
| 68531 | 68677 | break; |
| | @@ -69097,10 +69243,11 @@ |
| 69097 | 69243 | aPermute = pOp->p4.ai; |
| 69098 | 69244 | break; |
| 69099 | 69245 | } |
| 69100 | 69246 | |
| 69101 | 69247 | /* Opcode: Compare P1 P2 P3 P4 P5 |
| 69248 | +** Synopsis: r[P1@P3] <-> r[P2@P3] |
| 69102 | 69249 | ** |
| 69103 | 69250 | ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this |
| 69104 | 69251 | ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of |
| 69105 | 69252 | ** the comparison for use by the next OP_Jump instruct. |
| 69106 | 69253 | ** |
| | @@ -70432,10 +70579,11 @@ |
| 70432 | 70579 | assert( pOp->p1>=0 ); |
| 70433 | 70580 | assert( pOp->p2>=0 ); |
| 70434 | 70581 | pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 70435 | 70582 | if( pCx==0 ) goto no_mem; |
| 70436 | 70583 | pCx->nullRow = 1; |
| 70584 | + pCx->isEphemeral = 1; |
| 70437 | 70585 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, |
| 70438 | 70586 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| 70439 | 70587 | if( rc==SQLITE_OK ){ |
| 70440 | 70588 | rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); |
| 70441 | 70589 | } |
| | @@ -70922,11 +71070,11 @@ |
| 70922 | 71070 | pC->seekResult = res; |
| 70923 | 71071 | break; |
| 70924 | 71072 | } |
| 70925 | 71073 | |
| 70926 | 71074 | /* Opcode: Sequence P1 P2 * * * |
| 70927 | | -** Synopsis: r[P2]=rowid |
| 71075 | +** Synopsis: r[P2]=cursor[P1].ctr++ |
| 70928 | 71076 | ** |
| 70929 | 71077 | ** Find the next available sequence number for cursor P1. |
| 70930 | 71078 | ** Write the sequence number into register P2. |
| 70931 | 71079 | ** The sequence number on the cursor is incremented after this |
| 70932 | 71080 | ** instruction. |
| | @@ -71613,10 +71761,11 @@ |
| 71613 | 71761 | VdbeCursor *pC; |
| 71614 | 71762 | int res; |
| 71615 | 71763 | |
| 71616 | 71764 | pC = p->apCsr[pOp->p1]; |
| 71617 | 71765 | assert( isSorter(pC) ); |
| 71766 | + res = 0; |
| 71618 | 71767 | rc = sqlite3VdbeSorterNext(db, pC, &res); |
| 71619 | 71768 | goto next_tail; |
| 71620 | 71769 | case OP_PrevIfOpen: /* jump */ |
| 71621 | 71770 | case OP_NextIfOpen: /* jump */ |
| 71622 | 71771 | if( p->apCsr[pOp->p1]==0 ) break; |
| | @@ -71970,10 +72119,33 @@ |
| 71970 | 72119 | aMem[pOp->p3].u.i += nChange; |
| 71971 | 72120 | } |
| 71972 | 72121 | } |
| 71973 | 72122 | break; |
| 71974 | 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 | +} |
| 71975 | 72147 | |
| 71976 | 72148 | /* Opcode: CreateTable P1 P2 * * * |
| 71977 | 72149 | ** Synopsis: r[P2]=root iDb=P1 |
| 71978 | 72150 | ** |
| 71979 | 72151 | ** Allocate a new table in the main database file if P1==0 or in the |
| | @@ -72977,11 +73149,11 @@ |
| 72977 | 73149 | } |
| 72978 | 73150 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 72979 | 73151 | |
| 72980 | 73152 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 72981 | 73153 | /* Opcode: VFilter P1 P2 P3 P4 * |
| 72982 | | -** Synopsis: iPlan=r[P3] zPlan='P4' |
| 73154 | +** Synopsis: iplan=r[P3] zplan='P4' |
| 72983 | 73155 | ** |
| 72984 | 73156 | ** P1 is a cursor opened using VOpen. P2 is an address to jump to if |
| 72985 | 73157 | ** the filtered result set is empty. |
| 72986 | 73158 | ** |
| 72987 | 73159 | ** P4 is either NULL or a string that was generated by the xBestIndex |
| | @@ -73545,13 +73717,11 @@ |
| 73545 | 73717 | p->pStmt = 0; |
| 73546 | 73718 | }else{ |
| 73547 | 73719 | p->iOffset = pC->aType[p->iCol + pC->nField]; |
| 73548 | 73720 | p->nByte = sqlite3VdbeSerialTypeLen(type); |
| 73549 | 73721 | p->pCsr = pC->pCursor; |
| 73550 | | - sqlite3BtreeEnterCursor(p->pCsr); |
| 73551 | | - sqlite3BtreeCacheOverflow(p->pCsr); |
| 73552 | | - sqlite3BtreeLeaveCursor(p->pCsr); |
| 73722 | + sqlite3BtreeIncrblobCursor(p->pCsr); |
| 73553 | 73723 | } |
| 73554 | 73724 | } |
| 73555 | 73725 | |
| 73556 | 73726 | if( rc==SQLITE_ROW ){ |
| 73557 | 73727 | rc = SQLITE_OK; |
| | @@ -74440,28 +74610,45 @@ |
| 74440 | 74610 | for(p=pRecord; p; p=pNext){ |
| 74441 | 74611 | pNext = p->pNext; |
| 74442 | 74612 | sqlite3DbFree(db, p); |
| 74443 | 74613 | } |
| 74444 | 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 | + |
| 74445 | 74642 | |
| 74446 | 74643 | /* |
| 74447 | 74644 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 74448 | 74645 | */ |
| 74449 | 74646 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ |
| 74450 | 74647 | VdbeSorter *pSorter = pCsr->pSorter; |
| 74451 | 74648 | if( pSorter ){ |
| 74452 | | - if( pSorter->aIter ){ |
| 74453 | | - int i; |
| 74454 | | - for(i=0; i<pSorter->nTree; i++){ |
| 74455 | | - vdbeSorterIterZero(db, &pSorter->aIter[i]); |
| 74456 | | - } |
| 74457 | | - sqlite3DbFree(db, pSorter->aIter); |
| 74458 | | - } |
| 74459 | | - if( pSorter->pTemp1 ){ |
| 74460 | | - sqlite3OsCloseFree(pSorter->pTemp1); |
| 74461 | | - } |
| 74462 | | - vdbeSorterRecordFree(db, pSorter->pRecord); |
| 74649 | + sqlite3VdbeSorterReset(db, pSorter); |
| 74463 | 74650 | sqlite3DbFree(db, pSorter->pUnpacked); |
| 74464 | 74651 | sqlite3DbFree(db, pSorter); |
| 74465 | 74652 | pCsr->pSorter = 0; |
| 74466 | 74653 | } |
| 74467 | 74654 | } |
| | @@ -74893,18 +75080,59 @@ |
| 74893 | 75080 | VdbeSorter *pSorter = pCsr->pSorter; |
| 74894 | 75081 | int rc; /* Return code */ |
| 74895 | 75082 | |
| 74896 | 75083 | if( pSorter->aTree ){ |
| 74897 | 75084 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| 74898 | | - int i; /* Index of aTree[] to recalculate */ |
| 74899 | | - |
| 74900 | 75085 | rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 74901 | | - for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ |
| 74902 | | - 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); |
| 74903 | 75133 | } |
| 74904 | | - |
| 74905 | | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 74906 | 75134 | }else{ |
| 74907 | 75135 | SorterRecord *pFree = pSorter->pRecord; |
| 74908 | 75136 | pSorter->pRecord = pFree->pNext; |
| 74909 | 75137 | pFree->pNext = 0; |
| 74910 | 75138 | vdbeSorterRecordFree(db, pFree); |
| | @@ -77136,10 +77364,11 @@ |
| 77136 | 77364 | ** SELECT * FROM t1 WHERE (select a from t1); |
| 77137 | 77365 | */ |
| 77138 | 77366 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ |
| 77139 | 77367 | int op; |
| 77140 | 77368 | pExpr = sqlite3ExprSkipCollate(pExpr); |
| 77369 | + if( pExpr->flags & EP_Generic ) return SQLITE_AFF_NONE; |
| 77141 | 77370 | op = pExpr->op; |
| 77142 | 77371 | if( op==TK_SELECT ){ |
| 77143 | 77372 | assert( pExpr->flags&EP_xIsSelect ); |
| 77144 | 77373 | return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); |
| 77145 | 77374 | } |
| | @@ -77168,11 +77397,15 @@ |
| 77168 | 77397 | ** implements the COLLATE operator. |
| 77169 | 77398 | ** |
| 77170 | 77399 | ** If a memory allocation error occurs, that fact is recorded in pParse->db |
| 77171 | 77400 | ** and the pExpr parameter is returned unchanged. |
| 77172 | 77401 | */ |
| 77173 | | -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 | +){ |
| 77174 | 77407 | if( pCollName->n>0 ){ |
| 77175 | 77408 | Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); |
| 77176 | 77409 | if( pNew ){ |
| 77177 | 77410 | pNew->pLeft = pExpr; |
| 77178 | 77411 | pNew->flags |= EP_Collate|EP_Skip; |
| | @@ -77221,10 +77454,11 @@ |
| 77221 | 77454 | sqlite3 *db = pParse->db; |
| 77222 | 77455 | CollSeq *pColl = 0; |
| 77223 | 77456 | Expr *p = pExpr; |
| 77224 | 77457 | while( p ){ |
| 77225 | 77458 | int op = p->op; |
| 77459 | + if( p->flags & EP_Generic ) break; |
| 77226 | 77460 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 77227 | 77461 | p = p->pLeft; |
| 77228 | 77462 | continue; |
| 77229 | 77463 | } |
| 77230 | 77464 | if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ |
| | @@ -78052,11 +78286,10 @@ |
| 78052 | 78286 | struct ExprList_item *pItem, *pOldItem; |
| 78053 | 78287 | int i; |
| 78054 | 78288 | if( p==0 ) return 0; |
| 78055 | 78289 | pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); |
| 78056 | 78290 | if( pNew==0 ) return 0; |
| 78057 | | - pNew->iECursor = 0; |
| 78058 | 78291 | pNew->nExpr = i = p->nExpr; |
| 78059 | 78292 | if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){} |
| 78060 | 78293 | pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) ); |
| 78061 | 78294 | if( pItem==0 ){ |
| 78062 | 78295 | sqlite3DbFree(db, pNew); |
| | @@ -78165,11 +78398,10 @@ |
| 78165 | 78398 | pNew->iLimit = 0; |
| 78166 | 78399 | pNew->iOffset = 0; |
| 78167 | 78400 | pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; |
| 78168 | 78401 | pNew->addrOpenEphm[0] = -1; |
| 78169 | 78402 | pNew->addrOpenEphm[1] = -1; |
| 78170 | | - pNew->addrOpenEphm[2] = -1; |
| 78171 | 78403 | pNew->nSelectRow = p->nSelectRow; |
| 78172 | 78404 | pNew->pWith = withDup(db, p->pWith); |
| 78173 | 78405 | return pNew; |
| 78174 | 78406 | } |
| 78175 | 78407 | #else |
| | @@ -78733,11 +78965,10 @@ |
| 78733 | 78965 | eType = IN_INDEX_EPH; |
| 78734 | 78966 | if( prNotFound ){ |
| 78735 | 78967 | *prNotFound = rMayHaveNull = ++pParse->nMem; |
| 78736 | 78968 | sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); |
| 78737 | 78969 | }else{ |
| 78738 | | - testcase( pParse->nQueryLoop>0 ); |
| 78739 | 78970 | pParse->nQueryLoop = 0; |
| 78740 | 78971 | if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 78741 | 78972 | eType = IN_INDEX_ROWID; |
| 78742 | 78973 | } |
| 78743 | 78974 | } |
| | @@ -78983,11 +79214,11 @@ |
| 78983 | 79214 | } |
| 78984 | 79215 | |
| 78985 | 79216 | if( testAddr>=0 ){ |
| 78986 | 79217 | sqlite3VdbeJumpHere(v, testAddr); |
| 78987 | 79218 | } |
| 78988 | | - sqlite3ExprCachePop(pParse, 1); |
| 79219 | + sqlite3ExprCachePop(pParse); |
| 78989 | 79220 | |
| 78990 | 79221 | return rReg; |
| 78991 | 79222 | } |
| 78992 | 79223 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| 78993 | 79224 | |
| | @@ -79118,11 +79349,11 @@ |
| 79118 | 79349 | */ |
| 79119 | 79350 | sqlite3VdbeJumpHere(v, j1); |
| 79120 | 79351 | } |
| 79121 | 79352 | } |
| 79122 | 79353 | sqlite3ReleaseTempReg(pParse, r1); |
| 79123 | | - sqlite3ExprCachePop(pParse, 1); |
| 79354 | + sqlite3ExprCachePop(pParse); |
| 79124 | 79355 | VdbeComment((v, "end IN expr")); |
| 79125 | 79356 | } |
| 79126 | 79357 | #endif /* SQLITE_OMIT_SUBQUERY */ |
| 79127 | 79358 | |
| 79128 | 79359 | /* |
| | @@ -79301,19 +79532,18 @@ |
| 79301 | 79532 | #endif |
| 79302 | 79533 | } |
| 79303 | 79534 | |
| 79304 | 79535 | /* |
| 79305 | 79536 | ** Remove from the column cache any entries that were added since the |
| 79306 | | -** the previous N Push operations. In other words, restore the cache |
| 79307 | | -** 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. |
| 79308 | 79539 | */ |
| 79309 | | -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){ |
| 79540 | +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ |
| 79310 | 79541 | int i; |
| 79311 | 79542 | struct yColCache *p; |
| 79312 | | - assert( N>0 ); |
| 79313 | | - assert( pParse->iCacheLevel>=N ); |
| 79314 | | - pParse->iCacheLevel -= N; |
| 79543 | + assert( pParse->iCacheLevel>=1 ); |
| 79544 | + pParse->iCacheLevel--; |
| 79315 | 79545 | #ifdef SQLITE_DEBUG |
| 79316 | 79546 | if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ |
| 79317 | 79547 | printf("POP to %d\n", pParse->iCacheLevel); |
| 79318 | 79548 | } |
| 79319 | 79549 | #endif |
| | @@ -79438,11 +79668,11 @@ |
| 79438 | 79668 | */ |
| 79439 | 79669 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ |
| 79440 | 79670 | int i; |
| 79441 | 79671 | struct yColCache *p; |
| 79442 | 79672 | assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); |
| 79443 | | - sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1); |
| 79673 | + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); |
| 79444 | 79674 | for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ |
| 79445 | 79675 | int x = p->iReg; |
| 79446 | 79676 | if( x>=iFrom && x<iFrom+nReg ){ |
| 79447 | 79677 | p->iReg += iTo-iFrom; |
| 79448 | 79678 | } |
| | @@ -79787,11 +80017,11 @@ |
| 79787 | 80017 | sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce); |
| 79788 | 80018 | VdbeCoverage(v); |
| 79789 | 80019 | sqlite3ExprCacheRemove(pParse, target, 1); |
| 79790 | 80020 | sqlite3ExprCachePush(pParse); |
| 79791 | 80021 | sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target); |
| 79792 | | - sqlite3ExprCachePop(pParse, 1); |
| 80022 | + sqlite3ExprCachePop(pParse); |
| 79793 | 80023 | } |
| 79794 | 80024 | sqlite3VdbeResolveLabel(v, endCoalesce); |
| 79795 | 80025 | break; |
| 79796 | 80026 | } |
| 79797 | 80027 | |
| | @@ -79839,13 +80069,13 @@ |
| 79839 | 80069 | pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); |
| 79840 | 80070 | } |
| 79841 | 80071 | } |
| 79842 | 80072 | |
| 79843 | 80073 | sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ |
| 79844 | | - sqlite3ExprCodeExprList(pParse, pFarg, r1, |
| 80074 | + sqlite3ExprCodeExprList(pParse, pFarg, r1, |
| 79845 | 80075 | SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); |
| 79846 | | - sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ |
| 80076 | + sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ |
| 79847 | 80077 | }else{ |
| 79848 | 80078 | r1 = 0; |
| 79849 | 80079 | } |
| 79850 | 80080 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 79851 | 80081 | /* Possibly overload the function if the first argument is |
| | @@ -80061,17 +80291,17 @@ |
| 80061 | 80291 | testcase( pTest->op==TK_COLUMN ); |
| 80062 | 80292 | sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); |
| 80063 | 80293 | testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); |
| 80064 | 80294 | sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); |
| 80065 | 80295 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); |
| 80066 | | - sqlite3ExprCachePop(pParse, 1); |
| 80296 | + sqlite3ExprCachePop(pParse); |
| 80067 | 80297 | sqlite3VdbeResolveLabel(v, nextCase); |
| 80068 | 80298 | } |
| 80069 | 80299 | if( (nExpr&1)!=0 ){ |
| 80070 | 80300 | sqlite3ExprCachePush(pParse); |
| 80071 | 80301 | sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); |
| 80072 | | - sqlite3ExprCachePop(pParse, 1); |
| 80302 | + sqlite3ExprCachePop(pParse); |
| 80073 | 80303 | }else{ |
| 80074 | 80304 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| 80075 | 80305 | } |
| 80076 | 80306 | assert( db->mallocFailed || pParse->nErr>0 |
| 80077 | 80307 | || pParse->iCacheLevel==iCacheLevel ); |
| | @@ -80646,19 +80876,19 @@ |
| 80646 | 80876 | testcase( jumpIfNull==0 ); |
| 80647 | 80877 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); |
| 80648 | 80878 | sqlite3ExprCachePush(pParse); |
| 80649 | 80879 | sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80650 | 80880 | sqlite3VdbeResolveLabel(v, d2); |
| 80651 | | - sqlite3ExprCachePop(pParse, 1); |
| 80881 | + sqlite3ExprCachePop(pParse); |
| 80652 | 80882 | break; |
| 80653 | 80883 | } |
| 80654 | 80884 | case TK_OR: { |
| 80655 | 80885 | testcase( jumpIfNull==0 ); |
| 80656 | 80886 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); |
| 80657 | 80887 | sqlite3ExprCachePush(pParse); |
| 80658 | 80888 | sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80659 | | - sqlite3ExprCachePop(pParse, 1); |
| 80889 | + sqlite3ExprCachePop(pParse); |
| 80660 | 80890 | break; |
| 80661 | 80891 | } |
| 80662 | 80892 | case TK_NOT: { |
| 80663 | 80893 | testcase( jumpIfNull==0 ); |
| 80664 | 80894 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); |
| | @@ -80800,21 +81030,21 @@ |
| 80800 | 81030 | case TK_AND: { |
| 80801 | 81031 | testcase( jumpIfNull==0 ); |
| 80802 | 81032 | sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); |
| 80803 | 81033 | sqlite3ExprCachePush(pParse); |
| 80804 | 81034 | sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80805 | | - sqlite3ExprCachePop(pParse, 1); |
| 81035 | + sqlite3ExprCachePop(pParse); |
| 80806 | 81036 | break; |
| 80807 | 81037 | } |
| 80808 | 81038 | case TK_OR: { |
| 80809 | 81039 | int d2 = sqlite3VdbeMakeLabel(v); |
| 80810 | 81040 | testcase( jumpIfNull==0 ); |
| 80811 | 81041 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); |
| 80812 | 81042 | sqlite3ExprCachePush(pParse); |
| 80813 | 81043 | sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); |
| 80814 | 81044 | sqlite3VdbeResolveLabel(v, d2); |
| 80815 | | - sqlite3ExprCachePop(pParse, 1); |
| 81045 | + sqlite3ExprCachePop(pParse); |
| 80816 | 81046 | break; |
| 80817 | 81047 | } |
| 80818 | 81048 | case TK_NOT: { |
| 80819 | 81049 | testcase( jumpIfNull==0 ); |
| 80820 | 81050 | sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); |
| | @@ -90339,11 +90569,11 @@ |
| 90339 | 90569 | ** resolve that label. |
| 90340 | 90570 | */ |
| 90341 | 90571 | SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ |
| 90342 | 90572 | if( iLabel ){ |
| 90343 | 90573 | sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); |
| 90344 | | - sqlite3ExprCachePop(pParse, 1); |
| 90574 | + sqlite3ExprCachePop(pParse); |
| 90345 | 90575 | } |
| 90346 | 90576 | } |
| 90347 | 90577 | |
| 90348 | 90578 | /************** End of delete.c **********************************************/ |
| 90349 | 90579 | /************** Begin file func.c ********************************************/ |
| | @@ -98740,11 +98970,11 @@ |
| 98740 | 98970 | sqlite3VdbeChangeP5(v, (u8)i); |
| 98741 | 98971 | addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); |
| 98742 | 98972 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| 98743 | 98973 | sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), |
| 98744 | 98974 | P4_DYNAMIC); |
| 98745 | | - sqlite3VdbeAddOp2(v, OP_Move, 2, 4); |
| 98975 | + sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); |
| 98746 | 98976 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); |
| 98747 | 98977 | sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); |
| 98748 | 98978 | sqlite3VdbeJumpHere(v, addr); |
| 98749 | 98979 | |
| 98750 | 98980 | /* Make sure all the indices are constructed correctly. |
| | @@ -100078,10 +100308,38 @@ |
| 100078 | 100308 | ************************************************************************* |
| 100079 | 100309 | ** This file contains C code routines that are called by the parser |
| 100080 | 100310 | ** to handle SELECT statements in SQLite. |
| 100081 | 100311 | */ |
| 100082 | 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 */ |
| 100083 | 100341 | |
| 100084 | 100342 | /* |
| 100085 | 100343 | ** Delete all the content of a Select structure but do not deallocate |
| 100086 | 100344 | ** the select structure itself. |
| 100087 | 100345 | */ |
| | @@ -100151,11 +100409,10 @@ |
| 100151 | 100409 | pNew->pLimit = pLimit; |
| 100152 | 100410 | pNew->pOffset = pOffset; |
| 100153 | 100411 | assert( pOffset==0 || pLimit!=0 ); |
| 100154 | 100412 | pNew->addrOpenEphm[0] = -1; |
| 100155 | 100413 | pNew->addrOpenEphm[1] = -1; |
| 100156 | | - pNew->addrOpenEphm[2] = -1; |
| 100157 | 100414 | if( db->mallocFailed ) { |
| 100158 | 100415 | clearSelect(db, pNew); |
| 100159 | 100416 | if( pNew!=&standin ) sqlite3DbFree(db, pNew); |
| 100160 | 100417 | pNew = 0; |
| 100161 | 100418 | }else{ |
| | @@ -100483,38 +100740,79 @@ |
| 100483 | 100740 | } |
| 100484 | 100741 | } |
| 100485 | 100742 | return 0; |
| 100486 | 100743 | } |
| 100487 | 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 | + |
| 100488 | 100753 | /* |
| 100489 | | -** Insert code into "v" that will push the record on the top of the |
| 100490 | | -** stack into the sorter. |
| 100754 | +** Insert code into "v" that will push the record in register regData |
| 100755 | +** into the sorter. |
| 100491 | 100756 | */ |
| 100492 | 100757 | static void pushOntoSorter( |
| 100493 | 100758 | Parse *pParse, /* Parser context */ |
| 100494 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 100759 | + SortCtx *pSort, /* Information about the ORDER BY clause */ |
| 100495 | 100760 | Select *pSelect, /* The whole SELECT statement */ |
| 100496 | 100761 | int regData /* Register holding data to be sorted */ |
| 100497 | 100762 | ){ |
| 100498 | 100763 | Vdbe *v = pParse->pVdbe; |
| 100499 | | - int nExpr = pOrderBy->nExpr; |
| 100764 | + int nExpr = pSort->pOrderBy->nExpr; |
| 100500 | 100765 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 100501 | 100766 | int regRecord = sqlite3GetTempReg(pParse); |
| 100767 | + int nOBSat = pSort->nOBSat; |
| 100502 | 100768 | int op; |
| 100503 | 100769 | sqlite3ExprCacheClear(pParse); |
| 100504 | | - sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 100505 | | - sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 100770 | + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0); |
| 100771 | + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); |
| 100506 | 100772 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 100507 | | - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 100508 | | - 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 ){ |
| 100509 | 100805 | op = OP_SorterInsert; |
| 100510 | 100806 | }else{ |
| 100511 | 100807 | op = OP_IdxInsert; |
| 100512 | 100808 | } |
| 100513 | | - sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); |
| 100514 | | - sqlite3ReleaseTempReg(pParse, regRecord); |
| 100515 | | - 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 | + } |
| 100516 | 100814 | if( pSelect->iLimit ){ |
| 100517 | 100815 | int addr1, addr2; |
| 100518 | 100816 | int iLimit; |
| 100519 | 100817 | if( pSelect->iOffset ){ |
| 100520 | 100818 | iLimit = pSelect->iOffset+1; |
| | @@ -100523,12 +100821,12 @@ |
| 100523 | 100821 | } |
| 100524 | 100822 | addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v); |
| 100525 | 100823 | sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); |
| 100526 | 100824 | addr2 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 100527 | 100825 | sqlite3VdbeJumpHere(v, addr1); |
| 100528 | | - sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); |
| 100529 | | - sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); |
| 100826 | + sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); |
| 100827 | + sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); |
| 100530 | 100828 | sqlite3VdbeJumpHere(v, addr2); |
| 100531 | 100829 | } |
| 100532 | 100830 | } |
| 100533 | 100831 | |
| 100534 | 100832 | /* |
| | @@ -100537,11 +100835,11 @@ |
| 100537 | 100835 | static void codeOffset( |
| 100538 | 100836 | Vdbe *v, /* Generate code into this VM */ |
| 100539 | 100837 | int iOffset, /* Register holding the offset counter */ |
| 100540 | 100838 | int iContinue /* Jump here to skip the current record */ |
| 100541 | 100839 | ){ |
| 100542 | | - if( iOffset>0 && iContinue!=0 ){ |
| 100840 | + if( iOffset>0 ){ |
| 100543 | 100841 | int addr; |
| 100544 | 100842 | sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); |
| 100545 | 100843 | addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v); |
| 100546 | 100844 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); |
| 100547 | 100845 | VdbeComment((v, "skip OFFSET records")); |
| | @@ -100598,23 +100896,10 @@ |
| 100598 | 100896 | return 0; |
| 100599 | 100897 | } |
| 100600 | 100898 | } |
| 100601 | 100899 | #endif |
| 100602 | 100900 | |
| 100603 | | -/* |
| 100604 | | -** An instance of the following object is used to record information about |
| 100605 | | -** how to process the DISTINCT keyword, to simplify passing that information |
| 100606 | | -** into the selectInnerLoop() routine. |
| 100607 | | -*/ |
| 100608 | | -typedef struct DistinctCtx DistinctCtx; |
| 100609 | | -struct DistinctCtx { |
| 100610 | | - u8 isTnct; /* True if the DISTINCT keyword is present */ |
| 100611 | | - u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ |
| 100612 | | - int tabTnct; /* Ephemeral table used for DISTINCT processing */ |
| 100613 | | - int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ |
| 100614 | | -}; |
| 100615 | | - |
| 100616 | 100901 | /* |
| 100617 | 100902 | ** This routine generates the code for the inside of the inner loop |
| 100618 | 100903 | ** of a SELECT. |
| 100619 | 100904 | ** |
| 100620 | 100905 | ** If srcTab is negative, then the pEList expressions |
| | @@ -100625,11 +100910,11 @@ |
| 100625 | 100910 | static void selectInnerLoop( |
| 100626 | 100911 | Parse *pParse, /* The parser context */ |
| 100627 | 100912 | Select *p, /* The complete select statement being coded */ |
| 100628 | 100913 | ExprList *pEList, /* List of values being extracted */ |
| 100629 | 100914 | int srcTab, /* Pull data from this table */ |
| 100630 | | - ExprList *pOrderBy, /* If not NULL, sort results using this key */ |
| 100915 | + SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ |
| 100631 | 100916 | DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ |
| 100632 | 100917 | SelectDest *pDest, /* How to dispose of the results */ |
| 100633 | 100918 | int iContinue, /* Jump here to continue with next row */ |
| 100634 | 100919 | int iBreak /* Jump here to break out of the inner loop */ |
| 100635 | 100920 | ){ |
| | @@ -100642,11 +100927,13 @@ |
| 100642 | 100927 | int nResultCol; /* Number of result columns */ |
| 100643 | 100928 | |
| 100644 | 100929 | assert( v ); |
| 100645 | 100930 | assert( pEList!=0 ); |
| 100646 | 100931 | hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; |
| 100647 | | - if( pOrderBy==0 && !hasDistinct ){ |
| 100932 | + if( pSort && pSort->pOrderBy==0 ) pSort = 0; |
| 100933 | + if( pSort==0 && !hasDistinct ){ |
| 100934 | + assert( iContinue!=0 ); |
| 100648 | 100935 | codeOffset(v, p->iOffset, iContinue); |
| 100649 | 100936 | } |
| 100650 | 100937 | |
| 100651 | 100938 | /* Pull the requested columns. |
| 100652 | 100939 | */ |
| | @@ -100732,11 +101019,11 @@ |
| 100732 | 101019 | assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); |
| 100733 | 101020 | codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult); |
| 100734 | 101021 | break; |
| 100735 | 101022 | } |
| 100736 | 101023 | } |
| 100737 | | - if( pOrderBy==0 ){ |
| 101024 | + if( pSort==0 ){ |
| 100738 | 101025 | codeOffset(v, p->iOffset, iContinue); |
| 100739 | 101026 | } |
| 100740 | 101027 | } |
| 100741 | 101028 | |
| 100742 | 101029 | switch( eDest ){ |
| | @@ -100763,32 +101050,33 @@ |
| 100763 | 101050 | } |
| 100764 | 101051 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
| 100765 | 101052 | |
| 100766 | 101053 | /* Store the result as data using a unique key. |
| 100767 | 101054 | */ |
| 100768 | | - case SRT_DistTable: |
| 101055 | + case SRT_Fifo: |
| 101056 | + case SRT_DistFifo: |
| 100769 | 101057 | case SRT_Table: |
| 100770 | 101058 | case SRT_EphemTab: { |
| 100771 | 101059 | int r1 = sqlite3GetTempReg(pParse); |
| 100772 | 101060 | testcase( eDest==SRT_Table ); |
| 100773 | 101061 | testcase( eDest==SRT_EphemTab ); |
| 100774 | 101062 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 100775 | 101063 | #ifndef SQLITE_OMIT_CTE |
| 100776 | | - if( eDest==SRT_DistTable ){ |
| 100777 | | - /* 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 |
| 100778 | 101066 | ** on an ephemeral index. If the current row is already present |
| 100779 | 101067 | ** in the index, do not write it to the output. If not, add the |
| 100780 | 101068 | ** current row to the index and proceed with writing it to the |
| 100781 | 101069 | ** output table as well. */ |
| 100782 | 101070 | int addr = sqlite3VdbeCurrentAddr(v) + 4; |
| 100783 | 101071 | sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); |
| 100784 | 101072 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); |
| 100785 | | - assert( pOrderBy==0 ); |
| 101073 | + assert( pSort==0 ); |
| 100786 | 101074 | } |
| 100787 | 101075 | #endif |
| 100788 | | - if( pOrderBy ){ |
| 100789 | | - pushOntoSorter(pParse, pOrderBy, p, r1); |
| 101076 | + if( pSort ){ |
| 101077 | + pushOntoSorter(pParse, pSort, p, r1); |
| 100790 | 101078 | }else{ |
| 100791 | 101079 | int r2 = sqlite3GetTempReg(pParse); |
| 100792 | 101080 | sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); |
| 100793 | 101081 | sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); |
| 100794 | 101082 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| | @@ -100805,16 +101093,16 @@ |
| 100805 | 101093 | */ |
| 100806 | 101094 | case SRT_Set: { |
| 100807 | 101095 | assert( nResultCol==1 ); |
| 100808 | 101096 | pDest->affSdst = |
| 100809 | 101097 | sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); |
| 100810 | | - if( pOrderBy ){ |
| 101098 | + if( pSort ){ |
| 100811 | 101099 | /* At first glance you would think we could optimize out the |
| 100812 | 101100 | ** ORDER BY in this case since the order of entries in the set |
| 100813 | 101101 | ** does not matter. But there might be a LIMIT clause, in which |
| 100814 | 101102 | ** case the order does matter */ |
| 100815 | | - pushOntoSorter(pParse, pOrderBy, p, regResult); |
| 101103 | + pushOntoSorter(pParse, pSort, p, regResult); |
| 100816 | 101104 | }else{ |
| 100817 | 101105 | int r1 = sqlite3GetTempReg(pParse); |
| 100818 | 101106 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); |
| 100819 | 101107 | sqlite3ExprCacheAffinityChange(pParse, regResult, 1); |
| 100820 | 101108 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); |
| | @@ -100835,12 +101123,12 @@ |
| 100835 | 101123 | ** store the results in the appropriate memory cell and break out |
| 100836 | 101124 | ** of the scan loop. |
| 100837 | 101125 | */ |
| 100838 | 101126 | case SRT_Mem: { |
| 100839 | 101127 | assert( nResultCol==1 ); |
| 100840 | | - if( pOrderBy ){ |
| 100841 | | - pushOntoSorter(pParse, pOrderBy, p, regResult); |
| 101128 | + if( pSort ){ |
| 101129 | + pushOntoSorter(pParse, pSort, p, regResult); |
| 100842 | 101130 | }else{ |
| 100843 | 101131 | sqlite3ExprCodeMove(pParse, regResult, iParm, 1); |
| 100844 | 101132 | /* The LIMIT clause will jump out of the loop for us */ |
| 100845 | 101133 | } |
| 100846 | 101134 | break; |
| | @@ -100849,14 +101137,14 @@ |
| 100849 | 101137 | |
| 100850 | 101138 | case SRT_Coroutine: /* Send data to a co-routine */ |
| 100851 | 101139 | case SRT_Output: { /* Return the results */ |
| 100852 | 101140 | testcase( eDest==SRT_Coroutine ); |
| 100853 | 101141 | testcase( eDest==SRT_Output ); |
| 100854 | | - if( pOrderBy ){ |
| 101142 | + if( pSort ){ |
| 100855 | 101143 | int r1 = sqlite3GetTempReg(pParse); |
| 100856 | 101144 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); |
| 100857 | | - pushOntoSorter(pParse, pOrderBy, p, r1); |
| 101145 | + pushOntoSorter(pParse, pSort, p, r1); |
| 100858 | 101146 | sqlite3ReleaseTempReg(pParse, r1); |
| 100859 | 101147 | }else if( eDest==SRT_Coroutine ){ |
| 100860 | 101148 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 100861 | 101149 | }else{ |
| 100862 | 101150 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); |
| | @@ -100929,11 +101217,11 @@ |
| 100929 | 101217 | |
| 100930 | 101218 | /* Jump to the end of the loop if the LIMIT is reached. Except, if |
| 100931 | 101219 | ** there is a sorter, in which case the sorter has already limited |
| 100932 | 101220 | ** the output for us. |
| 100933 | 101221 | */ |
| 100934 | | - if( pOrderBy==0 && p->iLimit ){ |
| 101222 | + if( pSort==0 && p->iLimit ){ |
| 100935 | 101223 | sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); |
| 100936 | 101224 | } |
| 100937 | 101225 | } |
| 100938 | 101226 | |
| 100939 | 101227 | /* |
| | @@ -101000,27 +101288,32 @@ |
| 101000 | 101288 | ** |
| 101001 | 101289 | ** Space to hold the KeyInfo structure is obtain from malloc. The calling |
| 101002 | 101290 | ** function is responsible for seeing that this structure is eventually |
| 101003 | 101291 | ** freed. |
| 101004 | 101292 | */ |
| 101005 | | -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 | +){ |
| 101006 | 101299 | int nExpr; |
| 101007 | 101300 | KeyInfo *pInfo; |
| 101008 | 101301 | struct ExprList_item *pItem; |
| 101009 | 101302 | sqlite3 *db = pParse->db; |
| 101010 | 101303 | int i; |
| 101011 | 101304 | |
| 101012 | 101305 | nExpr = pList->nExpr; |
| 101013 | | - pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra, 1); |
| 101306 | + pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1); |
| 101014 | 101307 | if( pInfo ){ |
| 101015 | 101308 | assert( sqlite3KeyInfoIsWriteable(pInfo) ); |
| 101016 | | - for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){ |
| 101309 | + for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){ |
| 101017 | 101310 | CollSeq *pColl; |
| 101018 | 101311 | pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); |
| 101019 | 101312 | if( !pColl ) pColl = db->pDfltColl; |
| 101020 | | - pInfo->aColl[i] = pColl; |
| 101021 | | - pInfo->aSortOrder[i] = pItem->sortOrder; |
| 101313 | + pInfo->aColl[i-iStart] = pColl; |
| 101314 | + pInfo->aSortOrder[i-iStart] = pItem->sortOrder; |
| 101022 | 101315 | } |
| 101023 | 101316 | } |
| 101024 | 101317 | return pInfo; |
| 101025 | 101318 | } |
| 101026 | 101319 | |
| | @@ -101118,50 +101411,60 @@ |
| 101118 | 101411 | ** routine generates the code needed to do that. |
| 101119 | 101412 | */ |
| 101120 | 101413 | static void generateSortTail( |
| 101121 | 101414 | Parse *pParse, /* Parsing context */ |
| 101122 | 101415 | Select *p, /* The SELECT statement */ |
| 101123 | | - Vdbe *v, /* Generate code into this VDBE */ |
| 101416 | + SortCtx *pSort, /* Information on the ORDER BY clause */ |
| 101124 | 101417 | int nColumn, /* Number of columns of data */ |
| 101125 | 101418 | SelectDest *pDest /* Write the sorted results here */ |
| 101126 | 101419 | ){ |
| 101420 | + Vdbe *v = pParse->pVdbe; /* The prepared statement */ |
| 101127 | 101421 | int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ |
| 101128 | 101422 | int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ |
| 101129 | 101423 | int addr; |
| 101424 | + int addrOnce = 0; |
| 101130 | 101425 | int iTab; |
| 101131 | 101426 | int pseudoTab = 0; |
| 101132 | | - ExprList *pOrderBy = p->pOrderBy; |
| 101133 | | - |
| 101427 | + ExprList *pOrderBy = pSort->pOrderBy; |
| 101134 | 101428 | int eDest = pDest->eDest; |
| 101135 | 101429 | int iParm = pDest->iSDParm; |
| 101136 | | - |
| 101137 | 101430 | int regRow; |
| 101138 | 101431 | int regRowid; |
| 101432 | + int nKey; |
| 101139 | 101433 | |
| 101140 | | - 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; |
| 101141 | 101441 | regRow = sqlite3GetTempReg(pParse); |
| 101142 | 101442 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 101143 | 101443 | pseudoTab = pParse->nTab++; |
| 101144 | 101444 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 101145 | 101445 | regRowid = 0; |
| 101146 | 101446 | }else{ |
| 101147 | 101447 | regRowid = sqlite3GetTempReg(pParse); |
| 101148 | 101448 | } |
| 101149 | | - if( p->selFlags & SF_UseSorter ){ |
| 101449 | + nKey = pOrderBy->nExpr - pSort->nOBSat; |
| 101450 | + if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 101150 | 101451 | int regSortOut = ++pParse->nMem; |
| 101151 | 101452 | int ptab2 = pParse->nTab++; |
| 101152 | | - sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); |
| 101453 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, nKey+2); |
| 101454 | + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 101153 | 101455 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 101154 | 101456 | VdbeCoverage(v); |
| 101155 | 101457 | codeOffset(v, p->iOffset, addrContinue); |
| 101156 | 101458 | sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 101157 | | - sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); |
| 101459 | + sqlite3VdbeAddOp3(v, OP_Column, ptab2, nKey+1, regRow); |
| 101158 | 101460 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 101159 | 101461 | }else{ |
| 101462 | + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); |
| 101160 | 101463 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); |
| 101161 | 101464 | codeOffset(v, p->iOffset, addrContinue); |
| 101162 | | - sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); |
| 101465 | + sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow); |
| 101163 | 101466 | } |
| 101164 | 101467 | switch( eDest ){ |
| 101165 | 101468 | case SRT_Table: |
| 101166 | 101469 | case SRT_EphemTab: { |
| 101167 | 101470 | testcase( eDest==SRT_Table ); |
| | @@ -101212,15 +101515,16 @@ |
| 101212 | 101515 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 101213 | 101516 | |
| 101214 | 101517 | /* The bottom of the loop |
| 101215 | 101518 | */ |
| 101216 | 101519 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 101217 | | - if( p->selFlags & SF_UseSorter ){ |
| 101520 | + if( pSort->sortFlags & SORTFLAG_UseSorter ){ |
| 101218 | 101521 | sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); |
| 101219 | 101522 | }else{ |
| 101220 | 101523 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); |
| 101221 | 101524 | } |
| 101525 | + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); |
| 101222 | 101526 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 101223 | 101527 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 101224 | 101528 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 101225 | 101529 | } |
| 101226 | 101530 | } |
| | @@ -101898,11 +102202,11 @@ |
| 101898 | 102202 | int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ |
| 101899 | 102203 | int iCurrent = 0; /* The Current table */ |
| 101900 | 102204 | int regCurrent; /* Register holding Current table */ |
| 101901 | 102205 | int iQueue; /* The Queue table */ |
| 101902 | 102206 | int iDistinct = 0; /* To ensure unique results if UNION */ |
| 101903 | | - int eDest = SRT_Table; /* How to write to Queue */ |
| 102207 | + int eDest = SRT_Fifo; /* How to write to Queue */ |
| 101904 | 102208 | SelectDest destQueue; /* SelectDest targetting the Queue table */ |
| 101905 | 102209 | int i; /* Loop counter */ |
| 101906 | 102210 | int rc; /* Result code */ |
| 101907 | 102211 | ExprList *pOrderBy; /* The ORDER BY clause */ |
| 101908 | 102212 | Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ |
| | @@ -101930,17 +102234,17 @@ |
| 101930 | 102234 | } |
| 101931 | 102235 | } |
| 101932 | 102236 | |
| 101933 | 102237 | /* Allocate cursors numbers for Queue and Distinct. The cursor number for |
| 101934 | 102238 | ** the Distinct table must be exactly one greater than Queue in order |
| 101935 | | - ** for the SRT_DistTable and SRT_DistQueue destinations to work. */ |
| 102239 | + ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ |
| 101936 | 102240 | iQueue = pParse->nTab++; |
| 101937 | 102241 | if( p->op==TK_UNION ){ |
| 101938 | | - eDest = pOrderBy ? SRT_DistQueue : SRT_DistTable; |
| 102242 | + eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; |
| 101939 | 102243 | iDistinct = pParse->nTab++; |
| 101940 | 102244 | }else{ |
| 101941 | | - eDest = pOrderBy ? SRT_Queue : SRT_Table; |
| 102245 | + eDest = pOrderBy ? SRT_Queue : SRT_Fifo; |
| 101942 | 102246 | } |
| 101943 | 102247 | sqlite3SelectDestInit(&destQueue, eDest, iQueue); |
| 101944 | 102248 | |
| 101945 | 102249 | /* Allocate cursors for Current, Queue, and Distinct. */ |
| 101946 | 102250 | regCurrent = ++pParse->nMem; |
| | @@ -102002,10 +102306,11 @@ |
| 102002 | 102306 | /* Keep running the loop until the Queue is empty */ |
| 102003 | 102307 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); |
| 102004 | 102308 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 102005 | 102309 | |
| 102006 | 102310 | end_of_recursive_query: |
| 102311 | + sqlite3ExprListDelete(pParse->db, p->pOrderBy); |
| 102007 | 102312 | p->pOrderBy = pOrderBy; |
| 102008 | 102313 | p->pLimit = pLimit; |
| 102009 | 102314 | p->pOffset = pOffset; |
| 102010 | 102315 | return; |
| 102011 | 102316 | } |
| | @@ -104373,11 +104678,11 @@ |
| 104373 | 104678 | if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ |
| 104374 | 104679 | sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " |
| 104375 | 104680 | "argument"); |
| 104376 | 104681 | pFunc->iDistinct = -1; |
| 104377 | 104682 | }else{ |
| 104378 | | - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0); |
| 104683 | + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); |
| 104379 | 104684 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, |
| 104380 | 104685 | (char*)pKeyInfo, P4_KEYINFO); |
| 104381 | 104686 | } |
| 104382 | 104687 | } |
| 104383 | 104688 | } |
| | @@ -104528,16 +104833,15 @@ |
| 104528 | 104833 | Vdbe *v; /* The virtual machine under construction */ |
| 104529 | 104834 | int isAgg; /* True for select lists like "count(*)" */ |
| 104530 | 104835 | ExprList *pEList; /* List of columns to extract. */ |
| 104531 | 104836 | SrcList *pTabList; /* List of tables to select from */ |
| 104532 | 104837 | Expr *pWhere; /* The WHERE clause. May be NULL */ |
| 104533 | | - ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ |
| 104534 | 104838 | ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ |
| 104535 | 104839 | Expr *pHaving; /* The HAVING clause. May be NULL */ |
| 104536 | 104840 | int rc = 1; /* Value to return from this function */ |
| 104537 | | - int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ |
| 104538 | 104841 | DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ |
| 104842 | + SortCtx sSort; /* Info on how to code the ORDER BY clause */ |
| 104539 | 104843 | AggInfo sAggInfo; /* Information used by aggregate queries */ |
| 104540 | 104844 | int iEnd; /* Address of the end of the query */ |
| 104541 | 104845 | sqlite3 *db; /* The database connection */ |
| 104542 | 104846 | |
| 104543 | 104847 | #ifndef SQLITE_OMIT_EXPLAIN |
| | @@ -104550,21 +104854,28 @@ |
| 104550 | 104854 | return 1; |
| 104551 | 104855 | } |
| 104552 | 104856 | if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; |
| 104553 | 104857 | memset(&sAggInfo, 0, sizeof(sAggInfo)); |
| 104554 | 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 ); |
| 104555 | 104863 | if( IgnorableOrderby(pDest) ){ |
| 104556 | 104864 | assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || |
| 104557 | | - 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); |
| 104558 | 104868 | /* If ORDER BY makes no difference in the output then neither does |
| 104559 | 104869 | ** DISTINCT so it can be removed too. */ |
| 104560 | 104870 | sqlite3ExprListDelete(db, p->pOrderBy); |
| 104561 | 104871 | p->pOrderBy = 0; |
| 104562 | 104872 | p->selFlags &= ~SF_Distinct; |
| 104563 | 104873 | } |
| 104564 | 104874 | sqlite3SelectPrep(pParse, p, 0); |
| 104565 | | - pOrderBy = p->pOrderBy; |
| 104875 | + memset(&sSort, 0, sizeof(sSort)); |
| 104876 | + sSort.pOrderBy = p->pOrderBy; |
| 104566 | 104877 | pTabList = p->pSrc; |
| 104567 | 104878 | pEList = p->pEList; |
| 104568 | 104879 | if( pParse->nErr || db->mallocFailed ){ |
| 104569 | 104880 | goto select_end; |
| 104570 | 104881 | } |
| | @@ -104682,11 +104993,11 @@ |
| 104682 | 104993 | goto select_end; |
| 104683 | 104994 | } |
| 104684 | 104995 | pParse->nHeight -= sqlite3SelectExprHeight(p); |
| 104685 | 104996 | pTabList = p->pSrc; |
| 104686 | 104997 | if( !IgnorableOrderby(pDest) ){ |
| 104687 | | - pOrderBy = p->pOrderBy; |
| 104998 | + sSort.pOrderBy = p->pOrderBy; |
| 104688 | 104999 | } |
| 104689 | 105000 | } |
| 104690 | 105001 | pEList = p->pEList; |
| 104691 | 105002 | #endif |
| 104692 | 105003 | pWhere = p->pWhere; |
| | @@ -104709,13 +105020,13 @@ |
| 104709 | 105020 | ** will cause elements to come out in the correct order. This is |
| 104710 | 105021 | ** an optimization - the correct answer should result regardless. |
| 104711 | 105022 | ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER |
| 104712 | 105023 | ** to disable this optimization for testing purposes. |
| 104713 | 105024 | */ |
| 104714 | | - if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0 |
| 105025 | + if( sqlite3ExprListCompare(p->pGroupBy, sSort.pOrderBy, -1)==0 |
| 104715 | 105026 | && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ |
| 104716 | | - pOrderBy = 0; |
| 105027 | + sSort.pOrderBy = 0; |
| 104717 | 105028 | } |
| 104718 | 105029 | |
| 104719 | 105030 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 104720 | 105031 | ** if the select-list is the same as the ORDER BY list, then this query |
| 104721 | 105032 | ** can be rewritten as a GROUP BY. In other words, this: |
| | @@ -104730,16 +105041,16 @@ |
| 104730 | 105041 | ** used for both the ORDER BY and DISTINCT processing. As originally |
| 104731 | 105042 | ** written the query must use a temp-table for at least one of the ORDER |
| 104732 | 105043 | ** BY and DISTINCT, and an index or separate temp-table for the other. |
| 104733 | 105044 | */ |
| 104734 | 105045 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct |
| 104735 | | - && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0 |
| 105046 | + && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 |
| 104736 | 105047 | ){ |
| 104737 | 105048 | p->selFlags &= ~SF_Distinct; |
| 104738 | 105049 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 104739 | 105050 | pGroupBy = p->pGroupBy; |
| 104740 | | - pOrderBy = 0; |
| 105051 | + sSort.pOrderBy = 0; |
| 104741 | 105052 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 104742 | 105053 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 104743 | 105054 | ** original setting of the SF_Distinct flag, not the current setting */ |
| 104744 | 105055 | assert( sDistinct.isTnct ); |
| 104745 | 105056 | } |
| | @@ -104749,20 +105060,20 @@ |
| 104749 | 105060 | ** extracted in pre-sorted order. If that is the case, then the |
| 104750 | 105061 | ** OP_OpenEphemeral instruction will be changed to an OP_Noop once |
| 104751 | 105062 | ** we figure out that the sorting index is not needed. The addrSortIndex |
| 104752 | 105063 | ** variable is used to facilitate that change. |
| 104753 | 105064 | */ |
| 104754 | | - if( pOrderBy ){ |
| 105065 | + if( sSort.pOrderBy ){ |
| 104755 | 105066 | KeyInfo *pKeyInfo; |
| 104756 | | - pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 0); |
| 104757 | | - pOrderBy->iECursor = pParse->nTab++; |
| 104758 | | - p->addrOpenEphm[2] = addrSortIndex = |
| 105067 | + pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0); |
| 105068 | + sSort.iECursor = pParse->nTab++; |
| 105069 | + sSort.addrSortIndex = |
| 104759 | 105070 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 104760 | | - pOrderBy->iECursor, pOrderBy->nExpr+2, 0, |
| 105071 | + sSort.iECursor, sSort.pOrderBy->nExpr+2, 0, |
| 104761 | 105072 | (char*)pKeyInfo, P4_KEYINFO); |
| 104762 | 105073 | }else{ |
| 104763 | | - addrSortIndex = -1; |
| 105074 | + sSort.addrSortIndex = -1; |
| 104764 | 105075 | } |
| 104765 | 105076 | |
| 104766 | 105077 | /* If the output is destined for a temporary table, open that table. |
| 104767 | 105078 | */ |
| 104768 | 105079 | if( pDest->eDest==SRT_EphemTab ){ |
| | @@ -104772,22 +105083,22 @@ |
| 104772 | 105083 | /* Set the limiter. |
| 104773 | 105084 | */ |
| 104774 | 105085 | iEnd = sqlite3VdbeMakeLabel(v); |
| 104775 | 105086 | p->nSelectRow = LARGEST_INT64; |
| 104776 | 105087 | computeLimitRegisters(pParse, p, iEnd); |
| 104777 | | - if( p->iLimit==0 && addrSortIndex>=0 ){ |
| 104778 | | - sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; |
| 104779 | | - 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; |
| 104780 | 105091 | } |
| 104781 | 105092 | |
| 104782 | 105093 | /* Open a virtual index to use for the distinct set. |
| 104783 | 105094 | */ |
| 104784 | 105095 | if( p->selFlags & SF_Distinct ){ |
| 104785 | 105096 | sDistinct.tabTnct = pParse->nTab++; |
| 104786 | 105097 | sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 104787 | 105098 | sDistinct.tabTnct, 0, 0, |
| 104788 | | - (char*)keyInfoFromExprList(pParse, p->pEList, 0), |
| 105099 | + (char*)keyInfoFromExprList(pParse, p->pEList,0,0), |
| 104789 | 105100 | P4_KEYINFO); |
| 104790 | 105101 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 104791 | 105102 | sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; |
| 104792 | 105103 | }else{ |
| 104793 | 105104 | sDistinct.eTnctType = WHERE_DISTINCT_NOOP; |
| | @@ -104796,32 +105107,36 @@ |
| 104796 | 105107 | if( !isAgg && pGroupBy==0 ){ |
| 104797 | 105108 | /* No aggregate functions and no GROUP BY clause */ |
| 104798 | 105109 | u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); |
| 104799 | 105110 | |
| 104800 | 105111 | /* Begin the database scan. */ |
| 104801 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList, |
| 104802 | | - wctrlFlags, 0); |
| 105112 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, |
| 105113 | + p->pEList, wctrlFlags, 0); |
| 104803 | 105114 | if( pWInfo==0 ) goto select_end; |
| 104804 | 105115 | if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ |
| 104805 | 105116 | p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); |
| 104806 | 105117 | } |
| 104807 | 105118 | if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ |
| 104808 | 105119 | sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); |
| 104809 | 105120 | } |
| 104810 | | - 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 | + } |
| 104811 | 105127 | |
| 104812 | 105128 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| 104813 | 105129 | ** instruction ended up not being needed, then change the OP_OpenEphemeral |
| 104814 | 105130 | ** into an OP_Noop. |
| 104815 | 105131 | */ |
| 104816 | | - if( addrSortIndex>=0 && pOrderBy==0 ){ |
| 104817 | | - sqlite3VdbeChangeToNoop(v, addrSortIndex); |
| 104818 | | - p->addrOpenEphm[2] = -1; |
| 105132 | + if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ |
| 105133 | + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); |
| 104819 | 105134 | } |
| 104820 | 105135 | |
| 104821 | 105136 | /* Use the standard inner loop. */ |
| 104822 | | - selectInnerLoop(pParse, p, pEList, -1, pOrderBy, &sDistinct, pDest, |
| 105137 | + selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, |
| 104823 | 105138 | sqlite3WhereContinueLabel(pWInfo), |
| 104824 | 105139 | sqlite3WhereBreakLabel(pWInfo)); |
| 104825 | 105140 | |
| 104826 | 105141 | /* End the database scan loop. |
| 104827 | 105142 | */ |
| | @@ -104873,11 +105188,11 @@ |
| 104873 | 105188 | sNC.pAggInfo = &sAggInfo; |
| 104874 | 105189 | sAggInfo.mnReg = pParse->nMem+1; |
| 104875 | 105190 | sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; |
| 104876 | 105191 | sAggInfo.pGroupBy = pGroupBy; |
| 104877 | 105192 | sqlite3ExprAnalyzeAggList(&sNC, pEList); |
| 104878 | | - sqlite3ExprAnalyzeAggList(&sNC, pOrderBy); |
| 105193 | + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); |
| 104879 | 105194 | if( pHaving ){ |
| 104880 | 105195 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); |
| 104881 | 105196 | } |
| 104882 | 105197 | sAggInfo.nAccumulator = sAggInfo.nColumn; |
| 104883 | 105198 | for(i=0; i<sAggInfo.nFunc; i++){ |
| | @@ -104907,11 +105222,11 @@ |
| 104907 | 105222 | ** implement it. Allocate that sorting index now. If it turns out |
| 104908 | 105223 | ** that we do not need it after all, the OP_SorterOpen instruction |
| 104909 | 105224 | ** will be converted into a Noop. |
| 104910 | 105225 | */ |
| 104911 | 105226 | sAggInfo.sortingIdx = pParse->nTab++; |
| 104912 | | - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0); |
| 105227 | + pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0); |
| 104913 | 105228 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, |
| 104914 | 105229 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 104915 | 105230 | 0, (char*)pKeyInfo, P4_KEYINFO); |
| 104916 | 105231 | |
| 104917 | 105232 | /* Initialize memory locations used by GROUP BY aggregate processing |
| | @@ -104936,14 +105251,14 @@ |
| 104936 | 105251 | ** This might involve two separate loops with an OP_Sort in between, or |
| 104937 | 105252 | ** it might be a single loop that uses an index to extract information |
| 104938 | 105253 | ** in the right order to begin with. |
| 104939 | 105254 | */ |
| 104940 | 105255 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 104941 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 105256 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, |
| 104942 | 105257 | WHERE_GROUPBY, 0); |
| 104943 | 105258 | if( pWInfo==0 ) goto select_end; |
| 104944 | | - if( sqlite3WhereIsOrdered(pWInfo) ){ |
| 105259 | + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 104945 | 105260 | /* The optimizer is able to deliver rows in group by order so |
| 104946 | 105261 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 104947 | 105262 | ** cancelled later because we still need to use the pKeyInfo |
| 104948 | 105263 | */ |
| 104949 | 105264 | groupBySort = 0; |
| | @@ -105090,11 +105405,11 @@ |
| 105090 | 105405 | sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); |
| 105091 | 105406 | VdbeComment((v, "Groupby result generator entry point")); |
| 105092 | 105407 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 105093 | 105408 | finalizeAggFunctions(pParse, &sAggInfo); |
| 105094 | 105409 | sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); |
| 105095 | | - selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy, |
| 105410 | + selectInnerLoop(pParse, p, p->pEList, -1, &sSort, |
| 105096 | 105411 | &sDistinct, pDest, |
| 105097 | 105412 | addrOutputRow+1, addrSetAbort); |
| 105098 | 105413 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 105099 | 105414 | VdbeComment((v, "end groupby result generator")); |
| 105100 | 105415 | |
| | @@ -105222,20 +105537,20 @@ |
| 105222 | 105537 | sqlite3ExprListDelete(db, pDel); |
| 105223 | 105538 | goto select_end; |
| 105224 | 105539 | } |
| 105225 | 105540 | updateAccumulator(pParse, &sAggInfo); |
| 105226 | 105541 | assert( pMinMax==0 || pMinMax->nExpr==1 ); |
| 105227 | | - if( sqlite3WhereIsOrdered(pWInfo) ){ |
| 105542 | + if( sqlite3WhereIsOrdered(pWInfo)>0 ){ |
| 105228 | 105543 | sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo)); |
| 105229 | 105544 | VdbeComment((v, "%s() by index", |
| 105230 | 105545 | (flag==WHERE_ORDERBY_MIN?"min":"max"))); |
| 105231 | 105546 | } |
| 105232 | 105547 | sqlite3WhereEnd(pWInfo); |
| 105233 | 105548 | finalizeAggFunctions(pParse, &sAggInfo); |
| 105234 | 105549 | } |
| 105235 | 105550 | |
| 105236 | | - pOrderBy = 0; |
| 105551 | + sSort.pOrderBy = 0; |
| 105237 | 105552 | sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); |
| 105238 | 105553 | selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, |
| 105239 | 105554 | pDest, addrEnd, addrEnd); |
| 105240 | 105555 | sqlite3ExprListDelete(db, pDel); |
| 105241 | 105556 | } |
| | @@ -105248,13 +105563,13 @@ |
| 105248 | 105563 | } |
| 105249 | 105564 | |
| 105250 | 105565 | /* If there is an ORDER BY clause, then we need to sort the results |
| 105251 | 105566 | ** and send them to the callback one by one. |
| 105252 | 105567 | */ |
| 105253 | | - if( pOrderBy ){ |
| 105254 | | - explainTempTable(pParse, "ORDER BY"); |
| 105255 | | - 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); |
| 105256 | 105571 | } |
| 105257 | 105572 | |
| 105258 | 105573 | /* Jump here to skip this query |
| 105259 | 105574 | */ |
| 105260 | 105575 | sqlite3VdbeResolveLabel(v, iEnd); |
| | @@ -109088,11 +109403,11 @@ |
| 109088 | 109403 | Index *pIndex; /* Index used, or NULL */ |
| 109089 | 109404 | } btree; |
| 109090 | 109405 | struct { /* Information for virtual tables */ |
| 109091 | 109406 | int idxNum; /* Index number */ |
| 109092 | 109407 | u8 needFree; /* True if sqlite3_free(idxStr) is needed */ |
| 109093 | | - u8 isOrdered; /* True if satisfies ORDER BY */ |
| 109408 | + i8 isOrdered; /* True if satisfies ORDER BY */ |
| 109094 | 109409 | u16 omitMask; /* Terms that may be omitted */ |
| 109095 | 109410 | char *idxStr; /* Index identifier string */ |
| 109096 | 109411 | } vtab; |
| 109097 | 109412 | } u; |
| 109098 | 109413 | u32 wsFlags; /* WHERE_* flags describing the plan */ |
| | @@ -109150,12 +109465,11 @@ |
| 109150 | 109465 | struct WherePath { |
| 109151 | 109466 | Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ |
| 109152 | 109467 | Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ |
| 109153 | 109468 | LogEst nRow; /* Estimated number of rows generated by this path */ |
| 109154 | 109469 | LogEst rCost; /* Total cost of this path */ |
| 109155 | | - u8 isOrdered; /* True if this path satisfies ORDER BY */ |
| 109156 | | - u8 isOrderedValid; /* True if the isOrdered field is valid */ |
| 109470 | + i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ |
| 109157 | 109471 | WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ |
| 109158 | 109472 | }; |
| 109159 | 109473 | |
| 109160 | 109474 | /* |
| 109161 | 109475 | ** The query generator uses an array of instances of this structure to |
| | @@ -109365,11 +109679,11 @@ |
| 109365 | 109679 | ExprList *pResultSet; /* Result set. DISTINCT operates on these */ |
| 109366 | 109680 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 109367 | 109681 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 109368 | 109682 | LogEst nRowOut; /* Estimated number of output rows */ |
| 109369 | 109683 | u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 109370 | | - u8 bOBSat; /* ORDER BY satisfied by indices */ |
| 109684 | + i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 109371 | 109685 | u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 109372 | 109686 | u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 109373 | 109687 | u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 109374 | 109688 | u8 nLevel; /* Number of nested loop */ |
| 109375 | 109689 | int iTop; /* The very beginning of the WHERE loop */ |
| | @@ -109449,18 +109763,19 @@ |
| 109449 | 109763 | /* |
| 109450 | 109764 | ** Return TRUE if the WHERE clause returns rows in ORDER BY order. |
| 109451 | 109765 | ** Return FALSE if the output needs to be sorted. |
| 109452 | 109766 | */ |
| 109453 | 109767 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ |
| 109454 | | - return pWInfo->bOBSat!=0; |
| 109768 | + return pWInfo->nOBSat; |
| 109455 | 109769 | } |
| 109456 | 109770 | |
| 109457 | 109771 | /* |
| 109458 | 109772 | ** Return the VDBE address or label to jump to in order to continue |
| 109459 | 109773 | ** immediately with the next row of a WHERE clause. |
| 109460 | 109774 | */ |
| 109461 | 109775 | SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ |
| 109776 | + assert( pWInfo->iContinue!=0 ); |
| 109462 | 109777 | return pWInfo->iContinue; |
| 109463 | 109778 | } |
| 109464 | 109779 | |
| 109465 | 109780 | /* |
| 109466 | 109781 | ** Return the VDBE address or label to jump to in order to break |
| | @@ -112250,11 +112565,11 @@ |
| 112250 | 112565 | } |
| 112251 | 112566 | pLevel->op = OP_VNext; |
| 112252 | 112567 | pLevel->p1 = iCur; |
| 112253 | 112568 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 112254 | 112569 | sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); |
| 112255 | | - sqlite3ExprCachePop(pParse, 1); |
| 112570 | + sqlite3ExprCachePop(pParse); |
| 112256 | 112571 | }else |
| 112257 | 112572 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 112258 | 112573 | |
| 112259 | 112574 | if( (pLoop->wsFlags & WHERE_IPK)!=0 |
| 112260 | 112575 | && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 |
| | @@ -112446,12 +112761,15 @@ |
| 112446 | 112761 | ** a single iteration. This means that the first row returned |
| 112447 | 112762 | ** should not have a NULL value stored in 'x'. If column 'x' is |
| 112448 | 112763 | ** the first one after the nEq equality constraints in the index, |
| 112449 | 112764 | ** this requires some special handling. |
| 112450 | 112765 | */ |
| 112766 | + assert( pWInfo->pOrderBy==0 |
| 112767 | + || pWInfo->pOrderBy->nExpr==1 |
| 112768 | + || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 ); |
| 112451 | 112769 | if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 |
| 112452 | | - && (pWInfo->bOBSat!=0) |
| 112770 | + && pWInfo->nOBSat>0 |
| 112453 | 112771 | && (pIdx->nKeyCol>nEq) |
| 112454 | 112772 | ){ |
| 112455 | 112773 | assert( pLoop->u.btree.nSkip==0 ); |
| 112456 | 112774 | bSeekPastNull = 1; |
| 112457 | 112775 | nExtraReg = 1; |
| | @@ -112618,12 +112936,11 @@ |
| 112618 | 112936 | pLevel->op = OP_Prev; |
| 112619 | 112937 | }else{ |
| 112620 | 112938 | pLevel->op = OP_Next; |
| 112621 | 112939 | } |
| 112622 | 112940 | pLevel->p1 = iIdxCur; |
| 112623 | | - assert( (WHERE_UNQ_WANTED>>16)==1 ); |
| 112624 | | - pLevel->p3 = (pLoop->wsFlags>>16)&1; |
| 112941 | + pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; |
| 112625 | 112942 | if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ |
| 112626 | 112943 | pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 112627 | 112944 | }else{ |
| 112628 | 112945 | assert( pLevel->p5==0 ); |
| 112629 | 112946 | } |
| | @@ -113117,10 +113434,141 @@ |
| 113117 | 113434 | whereLoopDelete(db, p); |
| 113118 | 113435 | } |
| 113119 | 113436 | sqlite3DbFree(db, pWInfo); |
| 113120 | 113437 | } |
| 113121 | 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 | +} |
| 113122 | 113570 | |
| 113123 | 113571 | /* |
| 113124 | 113572 | ** Insert or replace a WhereLoop entry using the template supplied. |
| 113125 | 113573 | ** |
| 113126 | 113574 | ** An existing WhereLoop entry might be overwritten if the new template |
| | @@ -113127,29 +113575,27 @@ |
| 113127 | 113575 | ** is better and has fewer dependencies. Or the template will be ignored |
| 113128 | 113576 | ** and no insert will occur if an existing WhereLoop is faster and has |
| 113129 | 113577 | ** fewer dependencies than the template. Otherwise a new WhereLoop is |
| 113130 | 113578 | ** added based on the template. |
| 113131 | 113579 | ** |
| 113132 | | -** 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 |
| 113133 | 113581 | ** prerequisites and rRun and nOut costs of the N best loops. That |
| 113134 | 113582 | ** information is gathered in the pBuilder->pOrSet object. This special |
| 113135 | 113583 | ** processing mode is used only for OR clause processing. |
| 113136 | 113584 | ** |
| 113137 | 113585 | ** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we |
| 113138 | 113586 | ** still might overwrite similar loops with the new template if the |
| 113139 | | -** template is better. Loops may be overwritten if the following |
| 113587 | +** new template is better. Loops may be overwritten if the following |
| 113140 | 113588 | ** conditions are met: |
| 113141 | 113589 | ** |
| 113142 | 113590 | ** (1) They have the same iTab. |
| 113143 | 113591 | ** (2) They have the same iSortIdx. |
| 113144 | 113592 | ** (3) The template has same or fewer dependencies than the current loop |
| 113145 | 113593 | ** (4) The template has the same or lower cost than the current loop |
| 113146 | | -** (5) The template uses more terms of the same index but has no additional |
| 113147 | | -** dependencies |
| 113148 | 113594 | */ |
| 113149 | 113595 | static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ |
| 113150 | | - WhereLoop **ppPrev, *p, *pNext = 0; |
| 113596 | + WhereLoop **ppPrev, *p; |
| 113151 | 113597 | WhereInfo *pWInfo = pBuilder->pWInfo; |
| 113152 | 113598 | sqlite3 *db = pWInfo->pParse->db; |
| 113153 | 113599 | |
| 113154 | 113600 | /* If pBuilder->pOrSet is defined, then only keep track of the costs |
| 113155 | 113601 | ** and prereqs. |
| | @@ -113168,68 +113614,27 @@ |
| 113168 | 113614 | } |
| 113169 | 113615 | #endif |
| 113170 | 113616 | return SQLITE_OK; |
| 113171 | 113617 | } |
| 113172 | 113618 | |
| 113173 | | - /* Search for an existing WhereLoop to overwrite, or which takes |
| 113174 | | - ** priority over pTemplate. |
| 113619 | + /* Look for an existing WhereLoop to replace with pTemplate |
| 113175 | 113620 | */ |
| 113176 | | - for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){ |
| 113177 | | - if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ |
| 113178 | | - /* If either the iTab or iSortIdx values for two WhereLoop are different |
| 113179 | | - ** then those WhereLoops need to be considered separately. Neither is |
| 113180 | | - ** a candidate to replace the other. */ |
| 113181 | | - continue; |
| 113182 | | - } |
| 113183 | | - /* In the current implementation, the rSetup value is either zero |
| 113184 | | - ** or the cost of building an automatic index (NlogN) and the NlogN |
| 113185 | | - ** is the same for compatible WhereLoops. */ |
| 113186 | | - assert( p->rSetup==0 || pTemplate->rSetup==0 |
| 113187 | | - || p->rSetup==pTemplate->rSetup ); |
| 113188 | | - |
| 113189 | | - /* whereLoopAddBtree() always generates and inserts the automatic index |
| 113190 | | - ** case first. Hence compatible candidate WhereLoops never have a larger |
| 113191 | | - ** rSetup. Call this SETUP-INVARIANT */ |
| 113192 | | - assert( p->rSetup>=pTemplate->rSetup ); |
| 113193 | | - |
| 113194 | | - if( (p->prereq & pTemplate->prereq)==p->prereq |
| 113195 | | - && p->rSetup<=pTemplate->rSetup |
| 113196 | | - && p->rRun<=pTemplate->rRun |
| 113197 | | - && p->nOut<=pTemplate->nOut |
| 113198 | | - ){ |
| 113199 | | - /* This branch taken when p is equal or better than pTemplate in |
| 113200 | | - ** all of (1) dependencies (2) setup-cost, (3) run-cost, and |
| 113201 | | - ** (4) number of output rows. */ |
| 113202 | | - assert( p->rSetup==pTemplate->rSetup ); |
| 113203 | | - if( p->prereq==pTemplate->prereq |
| 113204 | | - && p->nLTerm<pTemplate->nLTerm |
| 113205 | | - && (p->wsFlags & pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 113206 | | - && (p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 113207 | | - || pTemplate->rRun+p->nLTerm<=p->rRun+pTemplate->nLTerm) |
| 113208 | | - ){ |
| 113209 | | - /* Overwrite an existing WhereLoop with an similar one that uses |
| 113210 | | - ** more terms of the index */ |
| 113211 | | - pNext = p->pNextLoop; |
| 113212 | | - break; |
| 113213 | | - }else{ |
| 113214 | | - /* pTemplate is not helpful. |
| 113215 | | - ** Return without changing or adding anything */ |
| 113216 | | - goto whereLoopInsert_noop; |
| 113217 | | - } |
| 113218 | | - } |
| 113219 | | - if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 113220 | | - && p->rRun>=pTemplate->rRun |
| 113221 | | - && p->nOut>=pTemplate->nOut |
| 113222 | | - ){ |
| 113223 | | - /* Overwrite an existing WhereLoop with a better one: one that is |
| 113224 | | - ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost |
| 113225 | | - ** or (4) number of output rows, and is no worse in any of those |
| 113226 | | - ** categories. */ |
| 113227 | | - assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ |
| 113228 | | - pNext = p->pNextLoop; |
| 113229 | | - break; |
| 113230 | | - } |
| 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; |
| 113231 | 113636 | } |
| 113232 | 113637 | |
| 113233 | 113638 | /* If we reach this point it means that either p[] should be overwritten |
| 113234 | 113639 | ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new |
| 113235 | 113640 | ** WhereLoop and insert it. |
| | @@ -113243,34 +113648,44 @@ |
| 113243 | 113648 | sqlite3DebugPrintf("ins-new: "); |
| 113244 | 113649 | whereLoopPrint(pTemplate, pBuilder->pWC); |
| 113245 | 113650 | } |
| 113246 | 113651 | #endif |
| 113247 | 113652 | if( p==0 ){ |
| 113248 | | - 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)); |
| 113249 | 113655 | if( p==0 ) return SQLITE_NOMEM; |
| 113250 | 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 | + } |
| 113251 | 113678 | } |
| 113252 | 113679 | whereLoopXfer(db, p, pTemplate); |
| 113253 | | - p->pNextLoop = pNext; |
| 113254 | | - *ppPrev = p; |
| 113255 | 113680 | if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ |
| 113256 | 113681 | Index *pIndex = p->u.btree.pIndex; |
| 113257 | 113682 | if( pIndex && pIndex->tnum==0 ){ |
| 113258 | 113683 | p->u.btree.pIndex = 0; |
| 113259 | 113684 | } |
| 113260 | 113685 | } |
| 113261 | 113686 | return SQLITE_OK; |
| 113262 | | - |
| 113263 | | - /* Jump here if the insert is a no-op */ |
| 113264 | | -whereLoopInsert_noop: |
| 113265 | | -#if WHERETRACE_ENABLED /* 0x8 */ |
| 113266 | | - if( sqlite3WhereTrace & 0x8 ){ |
| 113267 | | - sqlite3DebugPrintf("ins-noop: "); |
| 113268 | | - whereLoopPrint(pTemplate, pBuilder->pWC); |
| 113269 | | - } |
| 113270 | | -#endif |
| 113271 | | - return SQLITE_OK; |
| 113272 | 113687 | } |
| 113273 | 113688 | |
| 113274 | 113689 | /* |
| 113275 | 113690 | ** Adjust the WhereLoop.nOut value downward to account for terms of the |
| 113276 | 113691 | ** WHERE clause that reference the loop but which are not used by an |
| | @@ -113420,10 +113835,12 @@ |
| 113420 | 113835 | nIn = 46; assert( 46==sqlite3LogEst(25) ); |
| 113421 | 113836 | }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ |
| 113422 | 113837 | /* "x IN (value, value, ...)" */ |
| 113423 | 113838 | nIn = sqlite3LogEst(pExpr->x.pList->nExpr); |
| 113424 | 113839 | } |
| 113840 | + assert( nIn>0 ); /* RHS always has 2 or more terms... The parser |
| 113841 | + ** changes "x IN (?)" into "x=?". */ |
| 113425 | 113842 | pNew->rRun += nIn; |
| 113426 | 113843 | pNew->u.btree.nEq++; |
| 113427 | 113844 | pNew->nOut = nRowEst + nInMul + nIn; |
| 113428 | 113845 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| 113429 | 113846 | assert( |
| | @@ -113733,22 +114150,38 @@ |
| 113733 | 114150 | && sqlite3GlobalConfig.bUseCis |
| 113734 | 114151 | && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) |
| 113735 | 114152 | ) |
| 113736 | 114153 | ){ |
| 113737 | 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); |
| 113738 | 114159 | if( m==0 ){ |
| 113739 | 114160 | /* TUNING: Cost of a covering index scan is K*(N + log2(N)). |
| 113740 | 114161 | ** + The extra factor K of between 1.1 and 3.0 that depends |
| 113741 | 114162 | ** on the relative sizes of the table and the index. K |
| 113742 | 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. |
| 113743 | 114181 | */ |
| 113744 | | - pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 + |
| 113745 | | - (15*pProbe->szIdxRow)/pTab->szTabRow; |
| 113746 | | - }else{ |
| 113747 | | - /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) |
| 113748 | | - ** which we will simplify to just N*log2(N) */ |
| 113749 | | - pNew->rRun = rSize + rLogSize; |
| 114182 | + pNew->rRun += rLogSize; |
| 113750 | 114183 | } |
| 113751 | 114184 | whereLoopOutputAdjust(pWC, pNew); |
| 113752 | 114185 | rc = whereLoopInsert(pBuilder, pNew); |
| 113753 | 114186 | pNew->nOut = rSize; |
| 113754 | 114187 | if( rc ) break; |
| | @@ -113916,12 +114349,12 @@ |
| 113916 | 114349 | assert( pNew->nLTerm<=pNew->nLSlot ); |
| 113917 | 114350 | pNew->u.vtab.idxNum = pIdxInfo->idxNum; |
| 113918 | 114351 | pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; |
| 113919 | 114352 | pIdxInfo->needToFreeIdxStr = 0; |
| 113920 | 114353 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; |
| 113921 | | - pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) |
| 113922 | | - && pIdxInfo->orderByConsumed); |
| 114354 | + pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? |
| 114355 | + pIdxInfo->nOrderBy : 0); |
| 113923 | 114356 | pNew->rSetup = 0; |
| 113924 | 114357 | pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); |
| 113925 | 114358 | pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); |
| 113926 | 114359 | whereLoopInsert(pBuilder, pNew); |
| 113927 | 114360 | if( pNew->u.vtab.needFree ){ |
| | @@ -114078,25 +114511,25 @@ |
| 114078 | 114511 | } |
| 114079 | 114512 | |
| 114080 | 114513 | /* |
| 114081 | 114514 | ** Examine a WherePath (with the addition of the extra WhereLoop of the 5th |
| 114082 | 114515 | ** parameters) to see if it outputs rows in the requested ORDER BY |
| 114083 | | -** (or GROUP BY) without requiring a separate sort operation. Return: |
| 114516 | +** (or GROUP BY) without requiring a separate sort operation. Return N: |
| 114084 | 114517 | ** |
| 114085 | | -** 0: ORDER BY is not satisfied. Sorting required |
| 114086 | | -** 1: ORDER BY is satisfied. Omit sorting |
| 114087 | | -** -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. |
| 114088 | 114521 | ** |
| 114089 | 114522 | ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as |
| 114090 | 114523 | ** strict. With GROUP BY and DISTINCT the only requirement is that |
| 114091 | 114524 | ** equivalent rows appear immediately adjacent to one another. GROUP BY |
| 114092 | 114525 | ** and DISTINT do not require rows to appear in any particular order as long |
| 114093 | 114526 | ** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT |
| 114094 | 114527 | ** the pOrderBy terms can be matched in any order. With ORDER BY, the |
| 114095 | 114528 | ** pOrderBy terms must be matched in strict left-to-right order. |
| 114096 | 114529 | */ |
| 114097 | | -static int wherePathSatisfiesOrderBy( |
| 114530 | +static i8 wherePathSatisfiesOrderBy( |
| 114098 | 114531 | WhereInfo *pWInfo, /* The WHERE clause */ |
| 114099 | 114532 | ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ |
| 114100 | 114533 | WherePath *pPath, /* The WherePath to check */ |
| 114101 | 114534 | u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */ |
| 114102 | 114535 | u16 nLoop, /* Number of entries in pPath->aLoop[] */ |
| | @@ -114276,28 +114709,28 @@ |
| 114276 | 114709 | if( !pColl ) pColl = db->pDfltColl; |
| 114277 | 114710 | if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; |
| 114278 | 114711 | } |
| 114279 | 114712 | isMatch = 1; |
| 114280 | 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 | + } |
| 114281 | 114725 | } |
| 114282 | 114726 | if( isMatch ){ |
| 114283 | 114727 | if( iColumn<0 ){ |
| 114284 | 114728 | testcase( distinctColumns==0 ); |
| 114285 | 114729 | distinctColumns = 1; |
| 114286 | 114730 | } |
| 114287 | 114731 | obSat |= MASKBIT(i); |
| 114288 | | - if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ |
| 114289 | | - /* Make sure the sort order is compatible in an ORDER BY clause. |
| 114290 | | - ** Sort order is irrelevant for a GROUP BY clause. */ |
| 114291 | | - if( revSet ){ |
| 114292 | | - if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) return 0; |
| 114293 | | - }else{ |
| 114294 | | - rev = revIdx ^ pOrderBy->a[i].sortOrder; |
| 114295 | | - if( rev ) *pRevMask |= MASKBIT(iLoop); |
| 114296 | | - revSet = 1; |
| 114297 | | - } |
| 114298 | | - } |
| 114299 | 114732 | }else{ |
| 114300 | 114733 | /* No match found */ |
| 114301 | 114734 | if( j==0 || j<nKeyCol ){ |
| 114302 | 114735 | testcase( isOrderDistinct!=0 ); |
| 114303 | 114736 | isOrderDistinct = 0; |
| | @@ -114325,12 +114758,18 @@ |
| 114325 | 114758 | obSat |= MASKBIT(i); |
| 114326 | 114759 | } |
| 114327 | 114760 | } |
| 114328 | 114761 | } |
| 114329 | 114762 | } /* End the loop over all WhereLoops from outer-most down to inner-most */ |
| 114330 | | - if( obSat==obDone ) return 1; |
| 114331 | | - 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 | + } |
| 114332 | 114771 | return -1; |
| 114333 | 114772 | } |
| 114334 | 114773 | |
| 114335 | 114774 | #ifdef WHERETRACE_ENABLED |
| 114336 | 114775 | /* For debugging use only: */ |
| | @@ -114363,15 +114802,15 @@ |
| 114363 | 114802 | Parse *pParse; /* Parsing context */ |
| 114364 | 114803 | sqlite3 *db; /* The database connection */ |
| 114365 | 114804 | int iLoop; /* Loop counter over the terms of the join */ |
| 114366 | 114805 | int ii, jj; /* Loop counters */ |
| 114367 | 114806 | int mxI = 0; /* Index of next entry to replace */ |
| 114807 | + int nOrderBy; /* Number of ORDER BY clause terms */ |
| 114368 | 114808 | LogEst rCost; /* Cost of a path */ |
| 114369 | 114809 | LogEst nOut; /* Number of outputs */ |
| 114370 | 114810 | LogEst mxCost = 0; /* Maximum cost of a set of paths */ |
| 114371 | 114811 | LogEst mxOut = 0; /* Maximum nOut value on the set of paths */ |
| 114372 | | - LogEst rSortCost; /* Cost to do a sort */ |
| 114373 | 114812 | int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ |
| 114374 | 114813 | WherePath *aFrom; /* All nFrom paths at the previous level */ |
| 114375 | 114814 | WherePath *aTo; /* The nTo best paths at the current level */ |
| 114376 | 114815 | WherePath *pFrom; /* An element of aFrom[] that we are working on */ |
| 114377 | 114816 | WherePath *pTo; /* An element of aTo[] that we are working on */ |
| | @@ -114409,20 +114848,16 @@ |
| 114409 | 114848 | aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) ); |
| 114410 | 114849 | nFrom = 1; |
| 114411 | 114850 | |
| 114412 | 114851 | /* Precompute the cost of sorting the final result set, if the caller |
| 114413 | 114852 | ** to sqlite3WhereBegin() was concerned about sorting */ |
| 114414 | | - rSortCost = 0; |
| 114415 | 114853 | if( pWInfo->pOrderBy==0 || nRowEst==0 ){ |
| 114416 | | - aFrom[0].isOrderedValid = 1; |
| 114854 | + aFrom[0].isOrdered = 0; |
| 114855 | + nOrderBy = 0; |
| 114417 | 114856 | }else{ |
| 114418 | | - /* TUNING: Estimated cost of sorting is 48*N*log2(N) where N is the |
| 114419 | | - ** number of output rows. The 48 is the expected size of a row to sort. |
| 114420 | | - ** FIXME: compute a better estimate of the 48 multiplier based on the |
| 114421 | | - ** result set expressions. */ |
| 114422 | | - rSortCost = nRowEst + estLog(nRowEst); |
| 114423 | | - WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost)); |
| 114857 | + aFrom[0].isOrdered = -1; |
| 114858 | + nOrderBy = pWInfo->pOrderBy->nExpr; |
| 114424 | 114859 | } |
| 114425 | 114860 | |
| 114426 | 114861 | /* Compute successively longer WherePaths using the previous generation |
| 114427 | 114862 | ** of WherePaths as the basis for the next. Keep track of the mxChoice |
| 114428 | 114863 | ** best paths at each generation */ |
| | @@ -114430,43 +114865,56 @@ |
| 114430 | 114865 | nTo = 0; |
| 114431 | 114866 | for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){ |
| 114432 | 114867 | for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ |
| 114433 | 114868 | Bitmask maskNew; |
| 114434 | 114869 | Bitmask revMask = 0; |
| 114435 | | - u8 isOrderedValid = pFrom->isOrderedValid; |
| 114436 | | - u8 isOrdered = pFrom->isOrdered; |
| 114870 | + i8 isOrdered = pFrom->isOrdered; |
| 114437 | 114871 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; |
| 114438 | 114872 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| 114439 | 114873 | /* At this point, pWLoop is a candidate to be the next loop. |
| 114440 | 114874 | ** Compute its cost */ |
| 114441 | 114875 | rCost = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 114442 | 114876 | rCost = sqlite3LogEstAdd(rCost, pFrom->rCost); |
| 114443 | 114877 | nOut = pFrom->nRow + pWLoop->nOut; |
| 114444 | 114878 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 114445 | | - if( !isOrderedValid ){ |
| 114446 | | - switch( wherePathSatisfiesOrderBy(pWInfo, |
| 114879 | + if( isOrdered<0 ){ |
| 114880 | + isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 114447 | 114881 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 114448 | | - iLoop, pWLoop, &revMask) ){ |
| 114449 | | - case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */ |
| 114450 | | - isOrdered = 1; |
| 114451 | | - isOrderedValid = 1; |
| 114452 | | - break; |
| 114453 | | - case 0: /* No. pFrom+pWLoop will require a separate sort */ |
| 114454 | | - isOrdered = 0; |
| 114455 | | - isOrderedValid = 1; |
| 114456 | | - rCost = sqlite3LogEstAdd(rCost, rSortCost); |
| 114457 | | - break; |
| 114458 | | - default: /* Cannot tell yet. Try again on the next iteration */ |
| 114459 | | - 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); |
| 114460 | 114908 | } |
| 114461 | 114909 | }else{ |
| 114462 | 114910 | revMask = pFrom->revLoop; |
| 114463 | 114911 | } |
| 114464 | 114912 | /* Check to see if pWLoop should be added to the mxChoice best so far */ |
| 114465 | 114913 | for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ |
| 114466 | 114914 | if( pTo->maskLoop==maskNew |
| 114467 | | - && pTo->isOrderedValid==isOrderedValid |
| 114915 | + && ((pTo->isOrdered^isOrdered)&80)==0 |
| 114468 | 114916 | && ((pTo->rCost<=rCost && pTo->nRow<=nOut) || |
| 114469 | 114917 | (pTo->rCost>=rCost && pTo->nRow>=nOut)) |
| 114470 | 114918 | ){ |
| 114471 | 114919 | testcase( jj==nTo-1 ); |
| 114472 | 114920 | break; |
| | @@ -114476,11 +114924,11 @@ |
| 114476 | 114924 | if( nTo>=mxChoice && rCost>=mxCost ){ |
| 114477 | 114925 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114478 | 114926 | if( sqlite3WhereTrace&0x4 ){ |
| 114479 | 114927 | sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n", |
| 114480 | 114928 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114481 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114929 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114482 | 114930 | } |
| 114483 | 114931 | #endif |
| 114484 | 114932 | continue; |
| 114485 | 114933 | } |
| 114486 | 114934 | /* Add a new Path to the aTo[] set */ |
| | @@ -114494,24 +114942,24 @@ |
| 114494 | 114942 | pTo = &aTo[jj]; |
| 114495 | 114943 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114496 | 114944 | if( sqlite3WhereTrace&0x4 ){ |
| 114497 | 114945 | sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n", |
| 114498 | 114946 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114499 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114947 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114500 | 114948 | } |
| 114501 | 114949 | #endif |
| 114502 | 114950 | }else{ |
| 114503 | 114951 | if( pTo->rCost<=rCost && pTo->nRow<=nOut ){ |
| 114504 | 114952 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114505 | 114953 | if( sqlite3WhereTrace&0x4 ){ |
| 114506 | 114954 | sqlite3DebugPrintf( |
| 114507 | 114955 | "Skip %s cost=%-3d,%3d order=%c", |
| 114508 | 114956 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114509 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114957 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114510 | 114958 | sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n", |
| 114511 | 114959 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114512 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114960 | + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); |
| 114513 | 114961 | } |
| 114514 | 114962 | #endif |
| 114515 | 114963 | testcase( pTo->rCost==rCost ); |
| 114516 | 114964 | continue; |
| 114517 | 114965 | } |
| | @@ -114520,23 +114968,22 @@ |
| 114520 | 114968 | #ifdef WHERETRACE_ENABLED /* 0x4 */ |
| 114521 | 114969 | if( sqlite3WhereTrace&0x4 ){ |
| 114522 | 114970 | sqlite3DebugPrintf( |
| 114523 | 114971 | "Update %s cost=%-3d,%3d order=%c", |
| 114524 | 114972 | wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 114525 | | - isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 114973 | + isOrdered>=0 ? isOrdered+'0' : '?'); |
| 114526 | 114974 | sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n", |
| 114527 | 114975 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114528 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114976 | + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); |
| 114529 | 114977 | } |
| 114530 | 114978 | #endif |
| 114531 | 114979 | } |
| 114532 | 114980 | /* pWLoop is a winner. Add it to the set of best so far */ |
| 114533 | 114981 | pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; |
| 114534 | 114982 | pTo->revLoop = revMask; |
| 114535 | 114983 | pTo->nRow = nOut; |
| 114536 | 114984 | pTo->rCost = rCost; |
| 114537 | | - pTo->isOrderedValid = isOrderedValid; |
| 114538 | 114985 | pTo->isOrdered = isOrdered; |
| 114539 | 114986 | memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); |
| 114540 | 114987 | pTo->aLoop[iLoop] = pWLoop; |
| 114541 | 114988 | if( nTo>=mxChoice ){ |
| 114542 | 114989 | mxI = 0; |
| | @@ -114557,12 +115004,12 @@ |
| 114557 | 115004 | if( sqlite3WhereTrace>=2 ){ |
| 114558 | 115005 | sqlite3DebugPrintf("---- after round %d ----\n", iLoop); |
| 114559 | 115006 | for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){ |
| 114560 | 115007 | sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", |
| 114561 | 115008 | wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 114562 | | - pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 114563 | | - if( pTo->isOrderedValid && pTo->isOrdered ){ |
| 115009 | + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); |
| 115010 | + if( pTo->isOrdered>0 ){ |
| 114564 | 115011 | sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); |
| 114565 | 115012 | }else{ |
| 114566 | 115013 | sqlite3DebugPrintf("\n"); |
| 114567 | 115014 | } |
| 114568 | 115015 | } |
| | @@ -114601,17 +115048,22 @@ |
| 114601 | 115048 | && nRowEst |
| 114602 | 115049 | ){ |
| 114603 | 115050 | Bitmask notUsed; |
| 114604 | 115051 | int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, |
| 114605 | 115052 | WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); |
| 114606 | | - if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115053 | + if( rc==pWInfo->pResultSet->nExpr ){ |
| 115054 | + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115055 | + } |
| 114607 | 115056 | } |
| 114608 | | - if( pFrom->isOrdered ){ |
| 115057 | + if( pWInfo->pOrderBy ){ |
| 114609 | 115058 | if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ |
| 114610 | | - pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115059 | + if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ |
| 115060 | + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 115061 | + } |
| 114611 | 115062 | }else{ |
| 114612 | | - pWInfo->bOBSat = 1; |
| 115063 | + pWInfo->nOBSat = pFrom->isOrdered; |
| 115064 | + if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; |
| 114613 | 115065 | pWInfo->revMask = pFrom->revLoop; |
| 114614 | 115066 | } |
| 114615 | 115067 | } |
| 114616 | 115068 | pWInfo->nRowOut = pFrom->nRow; |
| 114617 | 115069 | |
| | @@ -114692,11 +115144,11 @@ |
| 114692 | 115144 | pLoop->nOut = (LogEst)1; |
| 114693 | 115145 | pWInfo->a[0].pWLoop = pLoop; |
| 114694 | 115146 | pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); |
| 114695 | 115147 | pWInfo->a[0].iTabCur = iCur; |
| 114696 | 115148 | pWInfo->nRowOut = 1; |
| 114697 | | - if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1; |
| 115149 | + if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; |
| 114698 | 115150 | if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114699 | 115151 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 114700 | 115152 | } |
| 114701 | 115153 | #ifdef SQLITE_DEBUG |
| 114702 | 115154 | pLoop->cId = '0'; |
| | @@ -114796,11 +115248,11 @@ |
| 114796 | 115248 | */ |
| 114797 | 115249 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 114798 | 115250 | Parse *pParse, /* The parser context */ |
| 114799 | 115251 | SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ |
| 114800 | 115252 | Expr *pWhere, /* The WHERE clause */ |
| 114801 | | - ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ |
| 115253 | + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ |
| 114802 | 115254 | ExprList *pResultSet, /* Result set of the query */ |
| 114803 | 115255 | u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ |
| 114804 | 115256 | int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ |
| 114805 | 115257 | ){ |
| 114806 | 115258 | int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ |
| | @@ -114818,10 +115270,14 @@ |
| 114818 | 115270 | |
| 114819 | 115271 | |
| 114820 | 115272 | /* Variable initialization */ |
| 114821 | 115273 | db = pParse->db; |
| 114822 | 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; |
| 114823 | 115279 | sWLB.pOrderBy = pOrderBy; |
| 114824 | 115280 | |
| 114825 | 115281 | /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 114826 | 115282 | ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 114827 | 115283 | if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ |
| | @@ -114862,11 +115318,11 @@ |
| 114862 | 115318 | pWInfo->nLevel = nTabList; |
| 114863 | 115319 | pWInfo->pParse = pParse; |
| 114864 | 115320 | pWInfo->pTabList = pTabList; |
| 114865 | 115321 | pWInfo->pOrderBy = pOrderBy; |
| 114866 | 115322 | pWInfo->pResultSet = pResultSet; |
| 114867 | | - pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
| 115323 | + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); |
| 114868 | 115324 | pWInfo->wctrlFlags = wctrlFlags; |
| 114869 | 115325 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 114870 | 115326 | pMaskSet = &pWInfo->sMaskSet; |
| 114871 | 115327 | sWLB.pWInfo = pWInfo; |
| 114872 | 115328 | sWLB.pWC = &pWInfo->sWC; |
| | @@ -114896,11 +115352,11 @@ |
| 114896 | 115352 | } |
| 114897 | 115353 | |
| 114898 | 115354 | /* Special case: No FROM clause |
| 114899 | 115355 | */ |
| 114900 | 115356 | if( nTabList==0 ){ |
| 114901 | | - if( pOrderBy ) pWInfo->bOBSat = 1; |
| 115357 | + if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; |
| 114902 | 115358 | if( wctrlFlags & WHERE_WANT_DISTINCT ){ |
| 114903 | 115359 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 114904 | 115360 | } |
| 114905 | 115361 | } |
| 114906 | 115362 | |
| | @@ -115007,12 +115463,12 @@ |
| 115007 | 115463 | } |
| 115008 | 115464 | #ifdef WHERETRACE_ENABLED /* !=0 */ |
| 115009 | 115465 | if( sqlite3WhereTrace ){ |
| 115010 | 115466 | int ii; |
| 115011 | 115467 | sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); |
| 115012 | | - if( pWInfo->bOBSat ){ |
| 115013 | | - sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask); |
| 115468 | + if( pWInfo->nOBSat>0 ){ |
| 115469 | + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); |
| 115014 | 115470 | } |
| 115015 | 115471 | switch( pWInfo->eDistinct ){ |
| 115016 | 115472 | case WHERE_DISTINCT_UNIQUE: { |
| 115017 | 115473 | sqlite3DebugPrintf(" DISTINCT=unique"); |
| 115018 | 115474 | break; |
| | @@ -118238,10 +118694,37 @@ |
| 118238 | 118694 | ** simplify to constants 0 (false) and 1 (true), respectively, |
| 118239 | 118695 | ** regardless of the value of expr1. |
| 118240 | 118696 | */ |
| 118241 | 118697 | yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy328]); |
| 118242 | 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); |
| 118243 | 118726 | }else{ |
| 118244 | 118727 | yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); |
| 118245 | 118728 | if( yygotominor.yy346.pExpr ){ |
| 118246 | 118729 | yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; |
| 118247 | 118730 | sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); |
| | @@ -120858,10 +121341,11 @@ |
| 120858 | 121341 | Table *pTab = (Table *)sqliteHashData(p); |
| 120859 | 121342 | if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); |
| 120860 | 121343 | } |
| 120861 | 121344 | } |
| 120862 | 121345 | } |
| 121346 | + sqlite3VtabUnlockList(db); |
| 120863 | 121347 | sqlite3BtreeLeaveAll(db); |
| 120864 | 121348 | #else |
| 120865 | 121349 | UNUSED_PARAMETER(db); |
| 120866 | 121350 | #endif |
| 120867 | 121351 | } |
| | @@ -123261,10 +123745,26 @@ |
| 123261 | 123745 | case SQLITE_TESTCTRL_ALWAYS: { |
| 123262 | 123746 | int x = va_arg(ap,int); |
| 123263 | 123747 | rc = ALWAYS(x); |
| 123264 | 123748 | break; |
| 123265 | 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 | + } |
| 123266 | 123766 | |
| 123267 | 123767 | /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) |
| 123268 | 123768 | ** |
| 123269 | 123769 | ** Set the nReserve size to N for the main database on the database |
| 123270 | 123770 | ** connection db. |
| | @@ -124597,11 +125097,11 @@ |
| 124597 | 125097 | char *zReadExprlist; |
| 124598 | 125098 | char *zWriteExprlist; |
| 124599 | 125099 | |
| 124600 | 125100 | int nNodeSize; /* Soft limit for node size */ |
| 124601 | 125101 | u8 bFts4; /* True for FTS4, false for FTS3 */ |
| 124602 | | - u8 bHasStat; /* True if %_stat table exists */ |
| 125102 | + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ |
| 124603 | 125103 | u8 bHasDocsize; /* True if %_docsize table exists */ |
| 124604 | 125104 | u8 bDescIdx; /* True if doclists are in reverse order */ |
| 124605 | 125105 | u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ |
| 124606 | 125106 | int nPgsz; /* Page size for host database */ |
| 124607 | 125107 | char *zSegmentsTbl; /* Name of %_segments table */ |
| | @@ -126089,14 +126589,11 @@ |
| 126089 | 126589 | |
| 126090 | 126590 | /* Check to see if a legacy fts3 table has been "upgraded" by the |
| 126091 | 126591 | ** addition of a %_stat table so that it can use incremental merge. |
| 126092 | 126592 | */ |
| 126093 | 126593 | if( !isFts4 && !isCreate ){ |
| 126094 | | - int rc2 = SQLITE_OK; |
| 126095 | | - fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2", |
| 126096 | | - p->zDb, p->zName); |
| 126097 | | - if( rc2==SQLITE_OK ) p->bHasStat = 1; |
| 126594 | + p->bHasStat = 2; |
| 126098 | 126595 | } |
| 126099 | 126596 | |
| 126100 | 126597 | /* Figure out the page-size for the database. This is required in order to |
| 126101 | 126598 | ** estimate the cost of loading large doclists from the database. */ |
| 126102 | 126599 | fts3DatabasePageSize(&rc, p); |
| | @@ -127999,11 +128496,38 @@ |
| 127999 | 128496 | sqlite3Fts3SegmentsClose(p); |
| 128000 | 128497 | return rc; |
| 128001 | 128498 | } |
| 128002 | 128499 | |
| 128003 | 128500 | /* |
| 128004 | | -** 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. |
| 128005 | 128529 | */ |
| 128006 | 128530 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 128007 | 128531 | Fts3Table *p = (Fts3Table*)pVtab; |
| 128008 | 128532 | UNUSED_PARAMETER(pVtab); |
| 128009 | 128533 | assert( p->pSegments==0 ); |
| | @@ -128010,11 +128534,11 @@ |
| 128010 | 128534 | assert( p->nPendingData==0 ); |
| 128011 | 128535 | assert( p->inTransaction!=1 ); |
| 128012 | 128536 | TESTONLY( p->inTransaction = 1 ); |
| 128013 | 128537 | TESTONLY( p->mxSavepoint = -1; ); |
| 128014 | 128538 | p->nLeafAdd = 0; |
| 128015 | | - return SQLITE_OK; |
| 128539 | + return fts3SetHasStat(p); |
| 128016 | 128540 | } |
| 128017 | 128541 | |
| 128018 | 128542 | /* |
| 128019 | 128543 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| 128020 | 128544 | ** the pending-terms hash-table have already been flushed into the database |
| | @@ -128259,18 +128783,24 @@ |
| 128259 | 128783 | ){ |
| 128260 | 128784 | Fts3Table *p = (Fts3Table *)pVtab; |
| 128261 | 128785 | sqlite3 *db = p->db; /* Database connection */ |
| 128262 | 128786 | int rc; /* Return Code */ |
| 128263 | 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 | + |
| 128264 | 128792 | /* As it happens, the pending terms table is always empty here. This is |
| 128265 | 128793 | ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction |
| 128266 | 128794 | ** always opens a savepoint transaction. And the xSavepoint() method |
| 128267 | 128795 | ** flushes the pending terms table. But leave the (no-op) call to |
| 128268 | 128796 | ** PendingTermsFlush() in in case that changes. |
| 128269 | 128797 | */ |
| 128270 | 128798 | assert( p->nPendingData==0 ); |
| 128271 | | - rc = sqlite3Fts3PendingTermsFlush(p); |
| 128799 | + if( rc==SQLITE_OK ){ |
| 128800 | + rc = sqlite3Fts3PendingTermsFlush(p); |
| 128801 | + } |
| 128272 | 128802 | |
| 128273 | 128803 | if( p->zContentTbl==0 ){ |
| 128274 | 128804 | fts3DbExec(&rc, db, |
| 128275 | 128805 | "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", |
| 128276 | 128806 | p->zDb, p->zName, zName |
| | @@ -139778,10 +140308,14 @@ |
| 139778 | 140308 | u32 *aSzIns = 0; /* Sizes of inserted documents */ |
| 139779 | 140309 | u32 *aSzDel = 0; /* Sizes of deleted documents */ |
| 139780 | 140310 | int nChng = 0; /* Net change in number of documents */ |
| 139781 | 140311 | int bInsertDone = 0; |
| 139782 | 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 | + |
| 139783 | 140317 | assert( p->pSegments==0 ); |
| 139784 | 140318 | assert( |
| 139785 | 140319 | nArg==1 /* DELETE operations */ |
| 139786 | 140320 | || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ |
| 139787 | 140321 | ); |
| | @@ -145159,30 +145693,36 @@ |
| 145159 | 145693 | ** This function populates the pRtree->nRowEst variable with an estimate |
| 145160 | 145694 | ** of the number of rows in the virtual table. If possible, this is based |
| 145161 | 145695 | ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. |
| 145162 | 145696 | */ |
| 145163 | 145697 | static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ |
| 145164 | | - 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; |
| 145165 | 145700 | sqlite3_stmt *p; |
| 145166 | 145701 | int rc; |
| 145167 | 145702 | i64 nRow = 0; |
| 145168 | 145703 | |
| 145169 | | - rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); |
| 145170 | | - if( rc==SQLITE_OK ){ |
| 145171 | | - sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC); |
| 145172 | | - if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); |
| 145173 | | - rc = sqlite3_finalize(p); |
| 145174 | | - }else if( rc!=SQLITE_NOMEM ){ |
| 145175 | | - rc = SQLITE_OK; |
| 145176 | | - } |
| 145177 | | - |
| 145178 | | - if( rc==SQLITE_OK ){ |
| 145179 | | - if( nRow==0 ){ |
| 145180 | | - pRtree->nRowEst = RTREE_DEFAULT_ROWEST; |
| 145181 | | - }else{ |
| 145182 | | - pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); |
| 145183 | | - } |
| 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); |
| 145184 | 145724 | } |
| 145185 | 145725 | |
| 145186 | 145726 | return rc; |
| 145187 | 145727 | } |
| 145188 | 145728 | |
| | @@ -145447,10 +145987,12 @@ |
| 145447 | 145987 | } |
| 145448 | 145988 | |
| 145449 | 145989 | if( rc==SQLITE_OK ){ |
| 145450 | 145990 | *ppVtab = (sqlite3_vtab *)pRtree; |
| 145451 | 145991 | }else{ |
| 145992 | + assert( *ppVtab==0 ); |
| 145993 | + assert( pRtree->nBusy==1 ); |
| 145452 | 145994 | rtreeRelease(pRtree); |
| 145453 | 145995 | } |
| 145454 | 145996 | return rc; |
| 145455 | 145997 | } |
| 145456 | 145998 | |
| 145457 | 145999 | |