SQLite

Check-in [8fa923caa1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved detection of malformed records by PRAGMA integrity_check.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | improved-integrity-check
Files: files | file ages | folders
SHA3-256: 8fa923caa1535fc9ebed0214d211fc3d09a015d78afd01f288c215a7980d25f2
User & Date: drh 2017-09-09 20:38:49.243
Context
2017-09-09
22:46
Simplification and performance improvement to sqlite3_reset(). (check-in: b6425d0170 user: drh tags: improved-integrity-check)
20:38
Improved detection of malformed records by PRAGMA integrity_check. (check-in: 8fa923caa1 user: drh tags: improved-integrity-check)
00:51
Fix harmless compiler warnings seen with MSVC. (check-in: faa22e29a5 user: mistachkin tags: trunk)
Changes
Unified Diff Show Whitespace Changes Patch
Changes to src/pragma.c.
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
        Index *pIdx, *pPk;
        Index *pPrior = 0;
        int loopTop;
        int iDataCur, iIdxCur;
        int r1 = -1;

        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
        if( pTab->pCheck==0
         && (pTab->tabFlags & TF_HasNotNull)==0
         && (pTab->pIndex==0 || isQuick)
        ){
          continue;  /* No additional checks needed for this table */
        }
        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
        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 */







<
<
<
<
<
<







1545
1546
1547
1548
1549
1550
1551






1552
1553
1554
1555
1556
1557
1558
        Index *pIdx, *pPk;
        Index *pPrior = 0;
        int loopTop;
        int iDataCur, iIdxCur;
        int r1 = -1;

        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */






        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
        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 */
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
          zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
                              pTab->aCol[j].zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v, 3);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */
        sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(v);
            int addrCkOk = sqlite3VdbeMakeLabel(v);
            char *zErr;
            int k;







<







1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
          zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
                              pTab->aCol[j].zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v, 3);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */

        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(v);
            int addrCkOk = sqlite3VdbeMakeLabel(v);
            char *zErr;
            int k;
1605
1606
1607
1608
1609
1610
1611




1612
1613
1614
1615
1616
1617
1618
1619
1620
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            integrityCheckResultRow(v, 3);
            sqlite3VdbeResolveLabel(v, addrCkOk);
            sqlite3ExprCachePop(pParse);
          }
          sqlite3ExprListDelete(db, pCheck);
        }




        /* Validate index entries for the current row */
        for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; 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,
                                       pPrior, r1);
          pPrior = pIdx;
          sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);  /* increment entry count */







>
>
>
>

|







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            integrityCheckResultRow(v, 3);
            sqlite3VdbeResolveLabel(v, addrCkOk);
            sqlite3ExprCachePop(pParse);
          }
          sqlite3ExprListDelete(db, pCheck);
        }
        if( !isQuick ){ /* Omit the remaining tests for quick_check */
          /* Sanity check on record header decoding */
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
        /* 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,
                                       pPrior, r1);
          pPrior = pIdx;
          sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);  /* increment entry count */
1651
1652
1653
1654
1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
            sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
            sqlite3VdbeGoto(v, jmp5);
            sqlite3VdbeResolveLabel(v, uniqOk);
          }
          sqlite3VdbeJumpHere(v, jmp4);
          sqlite3ResolvePartIdxLabel(pParse, jmp3);
        }

        sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
        sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
        if( !isQuick ){
          sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
            if( pPk==pIdx ) continue;







>







1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
            sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
            sqlite3VdbeGoto(v, jmp5);
            sqlite3VdbeResolveLabel(v, uniqOk);
          }
          sqlite3VdbeJumpHere(v, jmp4);
          sqlite3ResolvePartIdxLabel(pParse, jmp3);
        }
        }
        sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
        sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
        if( !isQuick ){
          sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
            if( pPk==pIdx ) continue;