Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a register allocation bug in the VDBE code generator for PRAGMA integrity_check; |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
88439a866b3b16ad7c308ebe59198662 |
User & Date: | drh 2016-03-19 00:35:02.035 |
References
2017-07-15
| ||
19:32 | • New ticket [a4e06e75a9] False-positive from "PRAGMA integrity_check". (artifact: 1cd2172770 user: drh) | |
Context
2016-03-19
| ||
14:53 | Fix test scripts sqldiff.test and rbudiff.test so that they work with the --testdir option. (check-in: 1ffe3cde03 user: dan tags: trunk) | |
00:40 | Fix a VDBE register allocation bug exposed by recent enhancements to PRAGMA integrity_check. (check-in: c73b5b9ccf user: drh tags: apple-osx) | |
00:35 | Fix a register allocation bug in the VDBE code generator for PRAGMA integrity_check; (check-in: 88439a866b user: drh tags: trunk) | |
2016-03-18
| ||
00:39 | Fix FTS5 so that it works with SQLITE_OMIT_AUTORESET. (check-in: b199637d81 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
4247 4248 4249 4250 4251 4252 4253 | /* ** Mark all temporary registers as being unavailable for reuse. */ void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nTempReg = 0; pParse->nRangeReg = 0; } | > > > > > > > > > > > > > > > > > > > > > > > | 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 | /* ** Mark all temporary registers as being unavailable for reuse. */ void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nTempReg = 0; pParse->nRangeReg = 0; } /* ** Validate that no temporary register falls within the range of ** iFirst..iLast, inclusive. This routine is only call from within assert() ** statements. */ #ifdef SQLITE_DEBUG int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ int i; if( pParse->nRangeReg>0 && pParse->iRangeReg+pParse->nRangeReg<iLast && pParse->iRangeReg>=iFirst ){ return 0; } for(i=0; i<pParse->nTempReg; i++){ if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ return 0; } } return 1; } #endif /* SQLITE_DEBUG */ |
Changes to src/pragma.c.
︙ | ︙ | |||
1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 | /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ HashElem *x; Hash *pTbls; int *aRoot; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ VdbeCoverage(v); | > > | 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 | /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ HashElem *x; Hash *pTbls; int *aRoot; int cnt = 0; int mxIdx = 0; int nIdx; if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ VdbeCoverage(v); |
︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 | */ assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; if( HasRowid(pTab) ) cnt++; | | > | | 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | */ assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; if( HasRowid(pTab) ) cnt++; for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } if( nIdx>mxIdx ) mxIdx = nIdx; } aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); if( aRoot==0 ) break; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ aRoot[cnt++] = pIdx->tnum; } } aRoot[cnt] = 0; /* Make sure sufficient number of registers have been allocated */ pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); sqlite3VdbeChangeP5(v, (u8)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), |
︙ | ︙ | |||
1510 1511 1512 1513 1514 1515 1516 | sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ } | | > | 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ } assert( pParse->nMem>=8+j ); assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; j<pTab->nCol; j++){ char *zErr; int jmp2, jmp3; if( j==pTab->iPKey ) continue; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 | int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); int sqlite3GetTempReg(Parse*); void sqlite3ReleaseTempReg(Parse*,int); int sqlite3GetTempRange(Parse*,int); void sqlite3ReleaseTempRange(Parse*,int,int); void sqlite3ClearTempRegCache(Parse*); Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); | > > > | 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 | int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); int sqlite3GetTempReg(Parse*); void sqlite3ReleaseTempReg(Parse*,int); int sqlite3GetTempRange(Parse*,int); void sqlite3ReleaseTempRange(Parse*,int,int); void sqlite3ClearTempRegCache(Parse*); #ifdef SQLITE_DEBUG int sqlite3NoTempsInRange(Parse*,int,int); #endif Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); |
︙ | ︙ |