Fossil SCM
Cherry-pick a few more bug-fixes from SQLite trunk, the same ones that are also backported to the SQLite 3.7.4.3 Cygwin build. See: [http://osdir.com/ml/sqlite-users/2014-04/msg00366.html]. For me those all are important enough so they should appear in the next SQLite release.
Commit
1b2c7acd69e74c77a63a765981934e5378816d29
Parent
a138dc97fcde6d3…
2 files changed
+2
+35
-16
+2
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -2128,14 +2128,16 @@ | ||
| 2128 | 2128 | rc = sqlite3_open(zNewDb, &newDb); |
| 2129 | 2129 | if( rc ){ |
| 2130 | 2130 | fprintf(stderr, "Cannot create output database: %s\n", |
| 2131 | 2131 | sqlite3_errmsg(newDb)); |
| 2132 | 2132 | }else{ |
| 2133 | + sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); | |
| 2133 | 2134 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); |
| 2134 | 2135 | tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); |
| 2135 | 2136 | tryToCloneSchema(p, newDb, "type!='table'", 0); |
| 2136 | 2137 | sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); |
| 2138 | + sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); | |
| 2137 | 2139 | } |
| 2138 | 2140 | sqlite3_close(newDb); |
| 2139 | 2141 | } |
| 2140 | 2142 | |
| 2141 | 2143 | /* |
| 2142 | 2144 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -2128,14 +2128,16 @@ | |
| 2128 | rc = sqlite3_open(zNewDb, &newDb); |
| 2129 | if( rc ){ |
| 2130 | fprintf(stderr, "Cannot create output database: %s\n", |
| 2131 | sqlite3_errmsg(newDb)); |
| 2132 | }else{ |
| 2133 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); |
| 2134 | tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); |
| 2135 | tryToCloneSchema(p, newDb, "type!='table'", 0); |
| 2136 | sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); |
| 2137 | } |
| 2138 | sqlite3_close(newDb); |
| 2139 | } |
| 2140 | |
| 2141 | /* |
| 2142 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -2128,14 +2128,16 @@ | |
| 2128 | rc = sqlite3_open(zNewDb, &newDb); |
| 2129 | if( rc ){ |
| 2130 | fprintf(stderr, "Cannot create output database: %s\n", |
| 2131 | sqlite3_errmsg(newDb)); |
| 2132 | }else{ |
| 2133 | sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); |
| 2134 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); |
| 2135 | tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); |
| 2136 | tryToCloneSchema(p, newDb, "type!='table'", 0); |
| 2137 | sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); |
| 2138 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); |
| 2139 | } |
| 2140 | sqlite3_close(newDb); |
| 2141 | } |
| 2142 | |
| 2143 | /* |
| 2144 |
+35
-16
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -8444,16 +8444,22 @@ | ||
| 8444 | 8444 | #ifdef SQLITE_AMALGAMATION |
| 8445 | 8445 | SQLITE_PRIVATE const int sqlite3one = 1; |
| 8446 | 8446 | #else |
| 8447 | 8447 | SQLITE_PRIVATE const int sqlite3one; |
| 8448 | 8448 | #endif |
| 8449 | -#if defined(i386) || defined(__i386__) || defined(_M_IX86)\ | |
| 8450 | - || defined(__x86_64) || defined(__x86_64__) | |
| 8449 | +#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ | |
| 8450 | + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ | |
| 8451 | + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ | |
| 8452 | + defined(__arm__) | |
| 8451 | 8453 | # define SQLITE_BIGENDIAN 0 |
| 8452 | 8454 | # define SQLITE_LITTLEENDIAN 1 |
| 8453 | 8455 | # define SQLITE_UTF16NATIVE SQLITE_UTF16LE |
| 8454 | -#else | |
| 8456 | +#elif defined(sparc) || defined(__ppc__) | |
| 8457 | +# define SQLITE_BIGENDIAN 1 | |
| 8458 | +# define SQLITE_LITTLEENDIAN 0 | |
| 8459 | +# define SQLITE_UTF16NATIVE SQLITE_UTF16BE | |
| 8460 | + | |
| 8455 | 8461 | # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) |
| 8456 | 8462 | # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) |
| 8457 | 8463 | # define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8458 | 8464 | #endif |
| 8459 | 8465 | |
| @@ -12389,11 +12395,11 @@ | ||
| 12389 | 12395 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); |
| 12390 | 12396 | |
| 12391 | 12397 | SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); |
| 12392 | 12398 | SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); |
| 12393 | 12399 | SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); |
| 12394 | -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, u8 iBatch, i64); | |
| 12400 | +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); | |
| 12395 | 12401 | SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); |
| 12396 | 12402 | |
| 12397 | 12403 | SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); |
| 12398 | 12404 | |
| 12399 | 12405 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) |
| @@ -12505,10 +12511,11 @@ | ||
| 12505 | 12511 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 12506 | 12512 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| 12507 | 12513 | SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); |
| 12508 | 12514 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); |
| 12509 | 12515 | SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); |
| 12516 | +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); | |
| 12510 | 12517 | SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, |
| 12511 | 12518 | u8,u8,int,int*); |
| 12512 | 12519 | SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); |
| 12513 | 12520 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); |
| 12514 | 12521 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); |
| @@ -38999,12 +39006,12 @@ | ||
| 38999 | 39006 | struct RowSetEntry *pEntry; /* List of entries using pRight */ |
| 39000 | 39007 | struct RowSetEntry *pLast; /* Last entry on the pEntry list */ |
| 39001 | 39008 | struct RowSetEntry *pFresh; /* Source of new entry objects */ |
| 39002 | 39009 | struct RowSetEntry *pForest; /* List of binary trees of entries */ |
| 39003 | 39010 | u16 nFresh; /* Number of objects on pFresh */ |
| 39004 | - u8 rsFlags; /* Various flags */ | |
| 39005 | - u8 iBatch; /* Current insert batch */ | |
| 39011 | + u16 rsFlags; /* Various flags */ | |
| 39012 | + int iBatch; /* Current insert batch */ | |
| 39006 | 39013 | }; |
| 39007 | 39014 | |
| 39008 | 39015 | /* |
| 39009 | 39016 | ** Allowed values for RowSet.rsFlags |
| 39010 | 39017 | */ |
| @@ -39334,11 +39341,11 @@ | ||
| 39334 | 39341 | ** |
| 39335 | 39342 | ** If this is the first test of a new batch and if there exist entires |
| 39336 | 39343 | ** on pRowSet->pEntry, then sort those entires into the forest at |
| 39337 | 39344 | ** pRowSet->pForest so that they can be tested. |
| 39338 | 39345 | */ |
| 39339 | -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ | |
| 39346 | +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ | |
| 39340 | 39347 | struct RowSetEntry *p, *pTree; |
| 39341 | 39348 | |
| 39342 | 39349 | /* This routine is never called after sqlite3RowSetNext() */ |
| 39343 | 39350 | assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); |
| 39344 | 39351 | |
| @@ -41161,16 +41168,15 @@ | ||
| 41161 | 41168 | assert( pPager->setMaster==0 ); |
| 41162 | 41169 | assert( !pagerUseWal(pPager) ); |
| 41163 | 41170 | |
| 41164 | 41171 | if( !zMaster |
| 41165 | 41172 | || pPager->journalMode==PAGER_JOURNALMODE_MEMORY |
| 41166 | - || pPager->journalMode==PAGER_JOURNALMODE_OFF | |
| 41173 | + || !isOpen(pPager->jfd) | |
| 41167 | 41174 | ){ |
| 41168 | 41175 | return SQLITE_OK; |
| 41169 | 41176 | } |
| 41170 | 41177 | pPager->setMaster = 1; |
| 41171 | - assert( isOpen(pPager->jfd) ); | |
| 41172 | 41178 | assert( pPager->journalHdr <= pPager->journalOff ); |
| 41173 | 41179 | |
| 41174 | 41180 | /* Calculate the length in bytes and the checksum of zMaster */ |
| 41175 | 41181 | for(nMaster=0; zMaster[nMaster]; nMaster++){ |
| 41176 | 41182 | cksum += zMaster[nMaster]; |
| @@ -72271,13 +72277,11 @@ | ||
| 72271 | 72277 | } |
| 72272 | 72278 | |
| 72273 | 72279 | assert( pOp->p4type==P4_INT32 ); |
| 72274 | 72280 | assert( iSet==-1 || iSet>=0 ); |
| 72275 | 72281 | if( iSet ){ |
| 72276 | - exists = sqlite3RowSetTest(pIn1->u.pRowSet, | |
| 72277 | - (u8)(iSet>=0 ? iSet & 0xf : 0xff), | |
| 72278 | - pIn3->u.i); | |
| 72282 | + exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); | |
| 72279 | 72283 | VdbeBranchTaken(exists!=0,2); |
| 72280 | 72284 | if( exists ){ |
| 72281 | 72285 | pc = pOp->p2 - 1; |
| 72282 | 72286 | break; |
| 72283 | 72287 | } |
| @@ -81470,10 +81474,11 @@ | ||
| 81470 | 81474 | unsigned const char *z; /* Pointer to token */ |
| 81471 | 81475 | int n; /* Length of token z */ |
| 81472 | 81476 | int token; /* Type of token */ |
| 81473 | 81477 | |
| 81474 | 81478 | UNUSED_PARAMETER(NotUsed); |
| 81479 | + if( zInput==0 || zOld==0 ) return; | |
| 81475 | 81480 | for(z=zInput; *z; z=z+n){ |
| 81476 | 81481 | n = sqlite3GetToken(z, &token); |
| 81477 | 81482 | if( token==TK_REFERENCES ){ |
| 81478 | 81483 | char *zParent; |
| 81479 | 81484 | do { |
| @@ -87464,11 +87469,11 @@ | ||
| 87464 | 87469 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); |
| 87465 | 87470 | regRecord = sqlite3GetTempReg(pParse); |
| 87466 | 87471 | |
| 87467 | 87472 | sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); |
| 87468 | 87473 | sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 87469 | - sqlite3VdbeResolveLabel(v, iPartIdxLabel); | |
| 87474 | + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); | |
| 87470 | 87475 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); |
| 87471 | 87476 | sqlite3VdbeJumpHere(v, addr1); |
| 87472 | 87477 | if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 87473 | 87478 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 87474 | 87479 | (char *)pKey, P4_KEYINFO); |
| @@ -90241,11 +90246,11 @@ | ||
| 90241 | 90246 | VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); |
| 90242 | 90247 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, |
| 90243 | 90248 | &iPartIdxLabel, pPrior, r1); |
| 90244 | 90249 | sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, |
| 90245 | 90250 | pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); |
| 90246 | - sqlite3VdbeResolveLabel(v, iPartIdxLabel); | |
| 90251 | + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); | |
| 90247 | 90252 | pPrior = pIdx; |
| 90248 | 90253 | } |
| 90249 | 90254 | } |
| 90250 | 90255 | |
| 90251 | 90256 | /* |
| @@ -90260,14 +90265,15 @@ | ||
| 90260 | 90265 | ** block of registers has already been deallocated by the time |
| 90261 | 90266 | ** this routine returns. |
| 90262 | 90267 | ** |
| 90263 | 90268 | ** If *piPartIdxLabel is not NULL, fill it in with a label and jump |
| 90264 | 90269 | ** to that label if pIdx is a partial index that should be skipped. |
| 90270 | +** The label should be resolved using sqlite3ResolvePartIdxLabel(). | |
| 90265 | 90271 | ** A partial index should be skipped if its WHERE clause evaluates |
| 90266 | 90272 | ** to false or null. If pIdx is not a partial index, *piPartIdxLabel |
| 90267 | 90273 | ** will be set to zero which is an empty label that is ignored by |
| 90268 | -** sqlite3VdbeResolveLabel(). | |
| 90274 | +** sqlite3ResolvePartIdxLabel(). | |
| 90269 | 90275 | ** |
| 90270 | 90276 | ** The pPrior and regPrior parameters are used to implement a cache to |
| 90271 | 90277 | ** avoid unnecessary register loads. If pPrior is not NULL, then it is |
| 90272 | 90278 | ** a pointer to a different index for which an index key has just been |
| 90273 | 90279 | ** computed into register regPrior. If the current pIdx index is generating |
| @@ -90296,10 +90302,11 @@ | ||
| 90296 | 90302 | |
| 90297 | 90303 | if( piPartIdxLabel ){ |
| 90298 | 90304 | if( pIdx->pPartIdxWhere ){ |
| 90299 | 90305 | *piPartIdxLabel = sqlite3VdbeMakeLabel(v); |
| 90300 | 90306 | pParse->iPartIdxTab = iDataCur; |
| 90307 | + sqlite3ExprCachePush(pParse); | |
| 90301 | 90308 | sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, |
| 90302 | 90309 | SQLITE_JUMPIFNULL); |
| 90303 | 90310 | }else{ |
| 90304 | 90311 | *piPartIdxLabel = 0; |
| 90305 | 90312 | } |
| @@ -90323,10 +90330,22 @@ | ||
| 90323 | 90330 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); |
| 90324 | 90331 | } |
| 90325 | 90332 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 90326 | 90333 | return regBase; |
| 90327 | 90334 | } |
| 90335 | + | |
| 90336 | +/* | |
| 90337 | +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label | |
| 90338 | +** because it was a partial index, then this routine should be called to | |
| 90339 | +** resolve that label. | |
| 90340 | +*/ | |
| 90341 | +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ | |
| 90342 | + if( iLabel ){ | |
| 90343 | + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); | |
| 90344 | + sqlite3ExprCachePop(pParse, 1); | |
| 90345 | + } | |
| 90346 | +} | |
| 90328 | 90347 | |
| 90329 | 90348 | /************** End of delete.c **********************************************/ |
| 90330 | 90349 | /************** Begin file func.c ********************************************/ |
| 90331 | 90350 | /* |
| 90332 | 90351 | ** 2002 February 23 |
| @@ -98774,11 +98793,11 @@ | ||
| 98774 | 98793 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 98775 | 98794 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 98776 | 98795 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 98777 | 98796 | sqlite3VdbeJumpHere(v, jmp4); |
| 98778 | 98797 | sqlite3VdbeJumpHere(v, jmp2); |
| 98779 | - sqlite3VdbeResolveLabel(v, jmp3); | |
| 98798 | + sqlite3ResolvePartIdxLabel(pParse, jmp3); | |
| 98780 | 98799 | } |
| 98781 | 98800 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 98782 | 98801 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 98783 | 98802 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 98784 | 98803 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, |
| 98785 | 98804 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -8444,16 +8444,22 @@ | |
| 8444 | #ifdef SQLITE_AMALGAMATION |
| 8445 | SQLITE_PRIVATE const int sqlite3one = 1; |
| 8446 | #else |
| 8447 | SQLITE_PRIVATE const int sqlite3one; |
| 8448 | #endif |
| 8449 | #if defined(i386) || defined(__i386__) || defined(_M_IX86)\ |
| 8450 | || defined(__x86_64) || defined(__x86_64__) |
| 8451 | # define SQLITE_BIGENDIAN 0 |
| 8452 | # define SQLITE_LITTLEENDIAN 1 |
| 8453 | # define SQLITE_UTF16NATIVE SQLITE_UTF16LE |
| 8454 | #else |
| 8455 | # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) |
| 8456 | # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) |
| 8457 | # define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8458 | #endif |
| 8459 | |
| @@ -12389,11 +12395,11 @@ | |
| 12389 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); |
| 12390 | |
| 12391 | SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); |
| 12392 | SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); |
| 12393 | SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); |
| 12394 | SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, u8 iBatch, i64); |
| 12395 | SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); |
| 12396 | |
| 12397 | SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); |
| 12398 | |
| 12399 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) |
| @@ -12505,10 +12511,11 @@ | |
| 12505 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 12506 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| 12507 | SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); |
| 12508 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); |
| 12509 | SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); |
| 12510 | SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, |
| 12511 | u8,u8,int,int*); |
| 12512 | SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); |
| 12513 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); |
| 12514 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); |
| @@ -38999,12 +39006,12 @@ | |
| 38999 | struct RowSetEntry *pEntry; /* List of entries using pRight */ |
| 39000 | struct RowSetEntry *pLast; /* Last entry on the pEntry list */ |
| 39001 | struct RowSetEntry *pFresh; /* Source of new entry objects */ |
| 39002 | struct RowSetEntry *pForest; /* List of binary trees of entries */ |
| 39003 | u16 nFresh; /* Number of objects on pFresh */ |
| 39004 | u8 rsFlags; /* Various flags */ |
| 39005 | u8 iBatch; /* Current insert batch */ |
| 39006 | }; |
| 39007 | |
| 39008 | /* |
| 39009 | ** Allowed values for RowSet.rsFlags |
| 39010 | */ |
| @@ -39334,11 +39341,11 @@ | |
| 39334 | ** |
| 39335 | ** If this is the first test of a new batch and if there exist entires |
| 39336 | ** on pRowSet->pEntry, then sort those entires into the forest at |
| 39337 | ** pRowSet->pForest so that they can be tested. |
| 39338 | */ |
| 39339 | SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ |
| 39340 | struct RowSetEntry *p, *pTree; |
| 39341 | |
| 39342 | /* This routine is never called after sqlite3RowSetNext() */ |
| 39343 | assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); |
| 39344 | |
| @@ -41161,16 +41168,15 @@ | |
| 41161 | assert( pPager->setMaster==0 ); |
| 41162 | assert( !pagerUseWal(pPager) ); |
| 41163 | |
| 41164 | if( !zMaster |
| 41165 | || pPager->journalMode==PAGER_JOURNALMODE_MEMORY |
| 41166 | || pPager->journalMode==PAGER_JOURNALMODE_OFF |
| 41167 | ){ |
| 41168 | return SQLITE_OK; |
| 41169 | } |
| 41170 | pPager->setMaster = 1; |
| 41171 | assert( isOpen(pPager->jfd) ); |
| 41172 | assert( pPager->journalHdr <= pPager->journalOff ); |
| 41173 | |
| 41174 | /* Calculate the length in bytes and the checksum of zMaster */ |
| 41175 | for(nMaster=0; zMaster[nMaster]; nMaster++){ |
| 41176 | cksum += zMaster[nMaster]; |
| @@ -72271,13 +72277,11 @@ | |
| 72271 | } |
| 72272 | |
| 72273 | assert( pOp->p4type==P4_INT32 ); |
| 72274 | assert( iSet==-1 || iSet>=0 ); |
| 72275 | if( iSet ){ |
| 72276 | exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 72277 | (u8)(iSet>=0 ? iSet & 0xf : 0xff), |
| 72278 | pIn3->u.i); |
| 72279 | VdbeBranchTaken(exists!=0,2); |
| 72280 | if( exists ){ |
| 72281 | pc = pOp->p2 - 1; |
| 72282 | break; |
| 72283 | } |
| @@ -81470,10 +81474,11 @@ | |
| 81470 | unsigned const char *z; /* Pointer to token */ |
| 81471 | int n; /* Length of token z */ |
| 81472 | int token; /* Type of token */ |
| 81473 | |
| 81474 | UNUSED_PARAMETER(NotUsed); |
| 81475 | for(z=zInput; *z; z=z+n){ |
| 81476 | n = sqlite3GetToken(z, &token); |
| 81477 | if( token==TK_REFERENCES ){ |
| 81478 | char *zParent; |
| 81479 | do { |
| @@ -87464,11 +87469,11 @@ | |
| 87464 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); |
| 87465 | regRecord = sqlite3GetTempReg(pParse); |
| 87466 | |
| 87467 | sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); |
| 87468 | sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 87469 | sqlite3VdbeResolveLabel(v, iPartIdxLabel); |
| 87470 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); |
| 87471 | sqlite3VdbeJumpHere(v, addr1); |
| 87472 | if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 87473 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 87474 | (char *)pKey, P4_KEYINFO); |
| @@ -90241,11 +90246,11 @@ | |
| 90241 | VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); |
| 90242 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, |
| 90243 | &iPartIdxLabel, pPrior, r1); |
| 90244 | sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, |
| 90245 | pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); |
| 90246 | sqlite3VdbeResolveLabel(v, iPartIdxLabel); |
| 90247 | pPrior = pIdx; |
| 90248 | } |
| 90249 | } |
| 90250 | |
| 90251 | /* |
| @@ -90260,14 +90265,15 @@ | |
| 90260 | ** block of registers has already been deallocated by the time |
| 90261 | ** this routine returns. |
| 90262 | ** |
| 90263 | ** If *piPartIdxLabel is not NULL, fill it in with a label and jump |
| 90264 | ** to that label if pIdx is a partial index that should be skipped. |
| 90265 | ** A partial index should be skipped if its WHERE clause evaluates |
| 90266 | ** to false or null. If pIdx is not a partial index, *piPartIdxLabel |
| 90267 | ** will be set to zero which is an empty label that is ignored by |
| 90268 | ** sqlite3VdbeResolveLabel(). |
| 90269 | ** |
| 90270 | ** The pPrior and regPrior parameters are used to implement a cache to |
| 90271 | ** avoid unnecessary register loads. If pPrior is not NULL, then it is |
| 90272 | ** a pointer to a different index for which an index key has just been |
| 90273 | ** computed into register regPrior. If the current pIdx index is generating |
| @@ -90296,10 +90302,11 @@ | |
| 90296 | |
| 90297 | if( piPartIdxLabel ){ |
| 90298 | if( pIdx->pPartIdxWhere ){ |
| 90299 | *piPartIdxLabel = sqlite3VdbeMakeLabel(v); |
| 90300 | pParse->iPartIdxTab = iDataCur; |
| 90301 | sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, |
| 90302 | SQLITE_JUMPIFNULL); |
| 90303 | }else{ |
| 90304 | *piPartIdxLabel = 0; |
| 90305 | } |
| @@ -90323,10 +90330,22 @@ | |
| 90323 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); |
| 90324 | } |
| 90325 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 90326 | return regBase; |
| 90327 | } |
| 90328 | |
| 90329 | /************** End of delete.c **********************************************/ |
| 90330 | /************** Begin file func.c ********************************************/ |
| 90331 | /* |
| 90332 | ** 2002 February 23 |
| @@ -98774,11 +98793,11 @@ | |
| 98774 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 98775 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 98776 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 98777 | sqlite3VdbeJumpHere(v, jmp4); |
| 98778 | sqlite3VdbeJumpHere(v, jmp2); |
| 98779 | sqlite3VdbeResolveLabel(v, jmp3); |
| 98780 | } |
| 98781 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 98782 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 98783 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 98784 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, |
| 98785 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -8444,16 +8444,22 @@ | |
| 8444 | #ifdef SQLITE_AMALGAMATION |
| 8445 | SQLITE_PRIVATE const int sqlite3one = 1; |
| 8446 | #else |
| 8447 | SQLITE_PRIVATE const int sqlite3one; |
| 8448 | #endif |
| 8449 | #if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 8450 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
| 8451 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
| 8452 | defined(__arm__) |
| 8453 | # define SQLITE_BIGENDIAN 0 |
| 8454 | # define SQLITE_LITTLEENDIAN 1 |
| 8455 | # define SQLITE_UTF16NATIVE SQLITE_UTF16LE |
| 8456 | #elif defined(sparc) || defined(__ppc__) |
| 8457 | # define SQLITE_BIGENDIAN 1 |
| 8458 | # define SQLITE_LITTLEENDIAN 0 |
| 8459 | # define SQLITE_UTF16NATIVE SQLITE_UTF16BE |
| 8460 | |
| 8461 | # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) |
| 8462 | # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) |
| 8463 | # define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) |
| 8464 | #endif |
| 8465 | |
| @@ -12389,11 +12395,11 @@ | |
| 12395 | SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); |
| 12396 | |
| 12397 | SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); |
| 12398 | SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); |
| 12399 | SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); |
| 12400 | SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); |
| 12401 | SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); |
| 12402 | |
| 12403 | SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); |
| 12404 | |
| 12405 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) |
| @@ -12505,10 +12511,11 @@ | |
| 12511 | SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); |
| 12512 | SQLITE_PRIVATE int sqlite3IsRowid(const char*); |
| 12513 | SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); |
| 12514 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); |
| 12515 | SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); |
| 12516 | SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); |
| 12517 | SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, |
| 12518 | u8,u8,int,int*); |
| 12519 | SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); |
| 12520 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); |
| 12521 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); |
| @@ -38999,12 +39006,12 @@ | |
| 39006 | struct RowSetEntry *pEntry; /* List of entries using pRight */ |
| 39007 | struct RowSetEntry *pLast; /* Last entry on the pEntry list */ |
| 39008 | struct RowSetEntry *pFresh; /* Source of new entry objects */ |
| 39009 | struct RowSetEntry *pForest; /* List of binary trees of entries */ |
| 39010 | u16 nFresh; /* Number of objects on pFresh */ |
| 39011 | u16 rsFlags; /* Various flags */ |
| 39012 | int iBatch; /* Current insert batch */ |
| 39013 | }; |
| 39014 | |
| 39015 | /* |
| 39016 | ** Allowed values for RowSet.rsFlags |
| 39017 | */ |
| @@ -39334,11 +39341,11 @@ | |
| 39341 | ** |
| 39342 | ** If this is the first test of a new batch and if there exist entires |
| 39343 | ** on pRowSet->pEntry, then sort those entires into the forest at |
| 39344 | ** pRowSet->pForest so that they can be tested. |
| 39345 | */ |
| 39346 | SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ |
| 39347 | struct RowSetEntry *p, *pTree; |
| 39348 | |
| 39349 | /* This routine is never called after sqlite3RowSetNext() */ |
| 39350 | assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); |
| 39351 | |
| @@ -41161,16 +41168,15 @@ | |
| 41168 | assert( pPager->setMaster==0 ); |
| 41169 | assert( !pagerUseWal(pPager) ); |
| 41170 | |
| 41171 | if( !zMaster |
| 41172 | || pPager->journalMode==PAGER_JOURNALMODE_MEMORY |
| 41173 | || !isOpen(pPager->jfd) |
| 41174 | ){ |
| 41175 | return SQLITE_OK; |
| 41176 | } |
| 41177 | pPager->setMaster = 1; |
| 41178 | assert( pPager->journalHdr <= pPager->journalOff ); |
| 41179 | |
| 41180 | /* Calculate the length in bytes and the checksum of zMaster */ |
| 41181 | for(nMaster=0; zMaster[nMaster]; nMaster++){ |
| 41182 | cksum += zMaster[nMaster]; |
| @@ -72271,13 +72277,11 @@ | |
| 72277 | } |
| 72278 | |
| 72279 | assert( pOp->p4type==P4_INT32 ); |
| 72280 | assert( iSet==-1 || iSet>=0 ); |
| 72281 | if( iSet ){ |
| 72282 | exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); |
| 72283 | VdbeBranchTaken(exists!=0,2); |
| 72284 | if( exists ){ |
| 72285 | pc = pOp->p2 - 1; |
| 72286 | break; |
| 72287 | } |
| @@ -81470,10 +81474,11 @@ | |
| 81474 | unsigned const char *z; /* Pointer to token */ |
| 81475 | int n; /* Length of token z */ |
| 81476 | int token; /* Type of token */ |
| 81477 | |
| 81478 | UNUSED_PARAMETER(NotUsed); |
| 81479 | if( zInput==0 || zOld==0 ) return; |
| 81480 | for(z=zInput; *z; z=z+n){ |
| 81481 | n = sqlite3GetToken(z, &token); |
| 81482 | if( token==TK_REFERENCES ){ |
| 81483 | char *zParent; |
| 81484 | do { |
| @@ -87464,11 +87469,11 @@ | |
| 87469 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); |
| 87470 | regRecord = sqlite3GetTempReg(pParse); |
| 87471 | |
| 87472 | sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); |
| 87473 | sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 87474 | sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); |
| 87475 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); |
| 87476 | sqlite3VdbeJumpHere(v, addr1); |
| 87477 | if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 87478 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 87479 | (char *)pKey, P4_KEYINFO); |
| @@ -90241,11 +90246,11 @@ | |
| 90246 | VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); |
| 90247 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, |
| 90248 | &iPartIdxLabel, pPrior, r1); |
| 90249 | sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, |
| 90250 | pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); |
| 90251 | sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); |
| 90252 | pPrior = pIdx; |
| 90253 | } |
| 90254 | } |
| 90255 | |
| 90256 | /* |
| @@ -90260,14 +90265,15 @@ | |
| 90265 | ** block of registers has already been deallocated by the time |
| 90266 | ** this routine returns. |
| 90267 | ** |
| 90268 | ** If *piPartIdxLabel is not NULL, fill it in with a label and jump |
| 90269 | ** to that label if pIdx is a partial index that should be skipped. |
| 90270 | ** The label should be resolved using sqlite3ResolvePartIdxLabel(). |
| 90271 | ** A partial index should be skipped if its WHERE clause evaluates |
| 90272 | ** to false or null. If pIdx is not a partial index, *piPartIdxLabel |
| 90273 | ** will be set to zero which is an empty label that is ignored by |
| 90274 | ** sqlite3ResolvePartIdxLabel(). |
| 90275 | ** |
| 90276 | ** The pPrior and regPrior parameters are used to implement a cache to |
| 90277 | ** avoid unnecessary register loads. If pPrior is not NULL, then it is |
| 90278 | ** a pointer to a different index for which an index key has just been |
| 90279 | ** computed into register regPrior. If the current pIdx index is generating |
| @@ -90296,10 +90302,11 @@ | |
| 90302 | |
| 90303 | if( piPartIdxLabel ){ |
| 90304 | if( pIdx->pPartIdxWhere ){ |
| 90305 | *piPartIdxLabel = sqlite3VdbeMakeLabel(v); |
| 90306 | pParse->iPartIdxTab = iDataCur; |
| 90307 | sqlite3ExprCachePush(pParse); |
| 90308 | sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, |
| 90309 | SQLITE_JUMPIFNULL); |
| 90310 | }else{ |
| 90311 | *piPartIdxLabel = 0; |
| 90312 | } |
| @@ -90323,10 +90330,22 @@ | |
| 90330 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); |
| 90331 | } |
| 90332 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 90333 | return regBase; |
| 90334 | } |
| 90335 | |
| 90336 | /* |
| 90337 | ** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label |
| 90338 | ** because it was a partial index, then this routine should be called to |
| 90339 | ** resolve that label. |
| 90340 | */ |
| 90341 | SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ |
| 90342 | if( iLabel ){ |
| 90343 | sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); |
| 90344 | sqlite3ExprCachePop(pParse, 1); |
| 90345 | } |
| 90346 | } |
| 90347 | |
| 90348 | /************** End of delete.c **********************************************/ |
| 90349 | /************** Begin file func.c ********************************************/ |
| 90350 | /* |
| 90351 | ** 2002 February 23 |
| @@ -98774,11 +98793,11 @@ | |
| 98793 | sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); |
| 98794 | jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); |
| 98795 | sqlite3VdbeAddOp0(v, OP_Halt); |
| 98796 | sqlite3VdbeJumpHere(v, jmp4); |
| 98797 | sqlite3VdbeJumpHere(v, jmp2); |
| 98798 | sqlite3ResolvePartIdxLabel(pParse, jmp3); |
| 98799 | } |
| 98800 | sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); |
| 98801 | sqlite3VdbeJumpHere(v, loopTop-1); |
| 98802 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 98803 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, |
| 98804 |