Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | integrity-check-improvements |
Files: | files | file ages | folders |
SHA1: |
549bae0856004ff65b505175460abd59 |
User & Date: | drh 2017-02-22 14:15:37.561 |
Context
2017-02-22
| ||
15:11 | Fix integrity_check so that it verifies NOT NULL constraints even for tables that have no indexes. Enhance quick_check so that it verifies NOT NULL and CHECK constraints. (check-in: 5264844b06 user: drh tags: integrity-check-improvements) | |
14:15 | Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. (check-in: 549bae0856 user: drh tags: integrity-check-improvements) | |
2017-02-21
| ||
21:24 | In sqlite3VdbeHalt(), return as soon as possible if Vdbe.magic!=VDBE_MAGIC_RUN. This makes sqlite3_reset() slightly faster in some cases. (check-in: 80adc0cb4e user: dan tags: trunk) | |
Changes
Changes to src/pragma.c.
︙ | ︙ | |||
1477 1478 1479 1480 1481 1482 1483 | Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; Index *pPrior = 0; int loopTop; int iDataCur, iIdxCur; int r1 = -1; | | | 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; Index *pPrior = 0; int loopTop; int iDataCur, iIdxCur; int r1 = -1; if( pTab->pIndex==0 && pTab->pCheck==0 ) continue; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, |
︙ | ︙ | |||
1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 | pTab->aCol[j].zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); sqlite3VdbeAddOp0(v, OP_Halt); sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeJumpHere(v, jmp3); } /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(v); if( pPk==pIdx ) continue; r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, | > > > > > > > > > > > > > > > > > > > > > > > > > | 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | pTab->aCol[j].zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); sqlite3VdbeAddOp0(v, OP_Halt); sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeJumpHere(v, jmp3); } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ int addrCkFault = sqlite3VdbeMakeLabel(v); int addrCkOk = sqlite3VdbeMakeLabel(v); ExprList *pCheck = pTab->pCheck; char *zErr; int k; pParse->iSelfTab = iDataCur; sqlite3ExprCachePush(pParse); for(k=pCheck->nExpr-1; k>0; k--){ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); } sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, SQLITE_JUMPIFNULL); sqlite3VdbeResolveLabel(v, addrCkFault); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", pTab->zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); sqlite3VdbeAddOp2(v, OP_IfPos, 1, addrCkOk); VdbeCoverage(v); sqlite3VdbeAddOp0(v, OP_Halt); sqlite3VdbeResolveLabel(v, addrCkOk); sqlite3ExprCachePop(pParse); } /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(v); if( pPk==pIdx ) continue; r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, |
︙ | ︙ |
Changes to test/check.test.
︙ | ︙ | |||
305 306 307 308 309 310 311 312 | } } {12 -22} do_test check-4.8 { execsql { PRAGMA ignore_check_constraints=ON; UPDATE t4 SET x=0, y=1; SELECT * FROM t4; } | > | > > > > < | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | } } {12 -22} do_test check-4.8 { execsql { PRAGMA ignore_check_constraints=ON; UPDATE t4 SET x=0, y=1; SELECT * FROM t4; PRAGMA integrity_check; } } {0 1 ok} do_execsql_test check-4.8.1 { PRAGMA ignore_check_constraints=OFF; PRAGMA integrity_check; } {{CHECK constraint failed in t4}} do_test check-4.9 { catchsql { UPDATE t4 SET x=0, y=2; } } {1 {CHECK constraint failed: t4}} ifcapable vacuum { do_test check_4.10 { catchsql { VACUUM |
︙ | ︙ |