Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem with the sqlite3VdbeMayAbort() assert failing following an OOM. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b3027863505fa8edf355f3f5eea4502e |
User & Date: | dan 2009-09-10 16:14:51.000 |
Context
2009-09-10
| ||
17:45 | Add assert() statement to verify that new mutexes are not allocated when the mutex subsystem is uninitialized. (check-in: 1183c53357 user: drh tags: trunk) | |
16:14 | Fix a problem with the sqlite3VdbeMayAbort() assert failing following an OOM. (check-in: b302786350 user: dan tags: trunk) | |
10:15 | Remove an ALWAYS macro around an expression that is sometimes false. (check-in: f2a9ee722c user: dan tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
134 135 136 137 138 139 140 | if( pParse->nested ) return; if( pParse->nErr ) return; /* Begin by generating some termination code at the end of the ** vdbe program */ v = sqlite3GetVdbe(pParse); | | > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | if( pParse->nested ) return; if( pParse->nErr ) return; /* Begin by generating some termination code at the end of the ** vdbe program */ v = sqlite3GetVdbe(pParse); assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ sqlite3VdbeAddOp0(v, OP_Halt); /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a ** transaction on each used database and to verify the schema cookie |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
185 186 187 188 189 190 191 | int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeDelete(Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeDelete(Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG int sqlite3VdbeAssertMayAbort(Vdbe *, int); void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); void sqlite3VdbeCountChanges(Vdbe*); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
307 308 309 310 311 312 313 | } } return pRet; } /* | | > > > | > > | | | < | > > > > > > | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | } } return pRet; } /* ** Check if the program stored in the VM associated with pParse may ** throw an ABORT exception (causing the statement, but not transaction ** to be rolled back). This condition is true if the main program or any ** sub-programs contains any of the following: ** ** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. ** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. ** * OP_Destroy ** * OP_VUpdate ** * OP_VRename ** ** Then check that the value of Parse.mayAbort is true if an ** ABORT may be thrown, or false otherwise. Return true if it does ** match, or false otherwise. This function is intended to be used as ** part of an assert statement in the compiler. Similar to: ** ** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); */ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ int hasAbort = 0; Op *pOp; VdbeOpIter sIter; memset(&sIter, 0, sizeof(sIter)); sIter.v = v; while( (pOp = opIterNext(&sIter))!=0 ){ int opcode = pOp->opcode; if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) ){ hasAbort = 1; break; } } sqlite3DbFree(v->db, sIter.apSub); /* Return true if hasAbort==mayAbort. Or if a malloc failure occured. ** If malloc failed, then the while() loop above may not have iterated ** through all opcodes and hasAbort may be set incorrectly. Return ** true for this case to prevent the assert() in the callers frame ** from failing. */ return ( v->db->mallocFailed || hasAbort==mayAbort ); } #endif /* ** Loop through the program looking for P2 values that are negative ** on jump instructions. Each such value is a label. Resolve the ** label by setting the P2 value to its correct non-zero value. |
︙ | ︙ |