mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Merge support for partial integrity checks.
FossilOrigin-Name: b5443b47af95f4f0ef527bee90f186ee25faa5df197dbcc3e14d48eee095e4aa
This commit is contained in:
15
manifest
15
manifest
@ -1,13 +1,14 @@
|
|||||||
B d2aac001204621062e6cb3230ce2ac1b4545cb83b3ebb6bfebccee4d51162e97
|
B d2aac001204621062e6cb3230ce2ac1b4545cb83b3ebb6bfebccee4d51162e97
|
||||||
C Detect\sout-of-bounds\srootpage\svalues\sin\sthe\sschema.
|
C Merge\ssupport\sfor\spartial\sintegrity\schecks.
|
||||||
D 2020-07-22T21:11:10.066
|
D 2020-07-23T09:14:25.312
|
||||||
F src/analyze.c 5cffff3d355858cd22bfc6e20ac7203510d2e1cc935086eb06f4abb2f579f628
|
F src/analyze.c 5cffff3d355858cd22bfc6e20ac7203510d2e1cc935086eb06f4abb2f579f628
|
||||||
F src/btree.c a4720f51945a86379ecd962a715d6fe9de08651a67d1e6f7b4884612da83ceb5
|
F src/btree.c 312780d344ab1c205b6571ef38757c7d5ea1cec539802cdd5a508381dd71be88
|
||||||
F src/btree.h 7af72bbb4863c331c8f6753277ab40ee67d2a2125a63256d5c25489722ec162b
|
F src/btree.h 7af72bbb4863c331c8f6753277ab40ee67d2a2125a63256d5c25489722ec162b
|
||||||
F src/btreeInt.h 83166f6daeb91062b6ae9ee6247b3ad07e40eba58f3c05ba9e8dedad4ab1ea38
|
F src/btreeInt.h 83166f6daeb91062b6ae9ee6247b3ad07e40eba58f3c05ba9e8dedad4ab1ea38
|
||||||
F src/build.c 1b8436ed3ac339a0507e61b14e4bd823eb02b76a9499b2241fddc61a5ff38c1a
|
F src/build.c 1b8436ed3ac339a0507e61b14e4bd823eb02b76a9499b2241fddc61a5ff38c1a
|
||||||
F src/main.c eb8169cb49d36ef3481ed8f39459a4d1d61f07bd71ec26e6ee0b5da4ab73d49c
|
F src/main.c eb8169cb49d36ef3481ed8f39459a4d1d61f07bd71ec26e6ee0b5da4ab73d49c
|
||||||
F src/pager.c a5f65ff2cd73b8d381cc7b338cac382ca6978d578fa0b84fdaa11d3cdc3c3e18
|
F src/pager.c a5f65ff2cd73b8d381cc7b338cac382ca6978d578fa0b84fdaa11d3cdc3c3e18
|
||||||
|
F src/pragma.c bdb600be936f66b9fe69d26dfbba4528beaaf4f95c479c85b328a92484e0bf71
|
||||||
F src/prepare.c 28193f0b7fc377e14682c56b10b9dd75cf7e41eb25b8ff1ce5a4536e680e1193
|
F src/prepare.c 28193f0b7fc377e14682c56b10b9dd75cf7e41eb25b8ff1ce5a4536e680e1193
|
||||||
F src/select.c 0e75d64091200a2a8fdc02abafe176a0c2e9b2654c4cc34564f25f0b408e91de
|
F src/select.c 0e75d64091200a2a8fdc02abafe176a0c2e9b2654c4cc34564f25f0b408e91de
|
||||||
F src/sqliteInt.h ec260b2441d94ef0b5be424c323cf255ae30d23e2fb2bd1c42a3a59c2fbafedb
|
F src/sqliteInt.h ec260b2441d94ef0b5be424c323cf255ae30d23e2fb2bd1c42a3a59c2fbafedb
|
||||||
@ -23,10 +24,10 @@ F test/corruptL.test ddd255069ec87976587956c7afc1932005d7ee5eaf4fe426a8994d945b8
|
|||||||
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
|
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
|
||||||
F test/fts3corrupt4.test b352268a7092e5581b1c3fb29b7f19b424fefbc1edfd3bb9ee4eeb0d4beef970
|
F test/fts3corrupt4.test b352268a7092e5581b1c3fb29b7f19b424fefbc1edfd3bb9ee4eeb0d4beef970
|
||||||
F test/pager1.test 4fba160bf450cea19f6bf1d6483ef467545bac6405570e176c83c2c4b5d6d0d5
|
F test/pager1.test 4fba160bf450cea19f6bf1d6483ef467545bac6405570e176c83c2c4b5d6d0d5
|
||||||
|
F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8
|
||||||
F test/tester.tcl 6417cbb60c4169804e2e1b36ce1a840c9f33d0b0d97956e058f3cc49ed3904f0
|
F test/tester.tcl 6417cbb60c4169804e2e1b36ce1a840c9f33d0b0d97956e058f3cc49ed3904f0
|
||||||
F tool/showdb.c 49e810f5c414c792b5bf38cd5557ca9639713ebfef32aaff32faf7cb7ccce513
|
F tool/showdb.c 49e810f5c414c792b5bf38cd5557ca9639713ebfef32aaff32faf7cb7ccce513
|
||||||
P 4c5f3c6cacf84a36d0347790d98d82d1f584cd1537a13a2736348405c4d20367 d7dd4fc464c791915f646b1ad228697d1fa16f530fc7d0e9aa702c8df3068c65
|
P e4a92688fca31335bf15933dec10ecba04cf340ee2f726fd36d46d4c76660eee 65dd321432e8f80bc1cb11be8ca06656b41ac997a74a5eb271c797cf0fbb764e
|
||||||
R 9f768fbf5ac24d5cfc1f04bde3af2863
|
R e4d9af4b2c8b3592cb28dca1e5ada87e
|
||||||
T +closed d7dd4fc464c791915f646b1ad228697d1fa16f530fc7d0e9aa702c8df3068c65
|
|
||||||
U drh
|
U drh
|
||||||
Z 1b7e8560967702c3a371d0209708674f
|
Z 84df909394c97f14dff1300a1886c42c
|
||||||
|
@ -1 +1 @@
|
|||||||
e4a92688fca31335bf15933dec10ecba04cf340ee2f726fd36d46d4c76660eee
|
b5443b47af95f4f0ef527bee90f186ee25faa5df197dbcc3e14d48eee095e4aa
|
87
src/btree.c
87
src/btree.c
@ -10120,6 +10120,15 @@ end_of_check:
|
|||||||
** allocation errors, an error message held in memory obtained from
|
** allocation errors, an error message held in memory obtained from
|
||||||
** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
|
** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
|
||||||
** returned. If a memory allocation error occurs, NULL is returned.
|
** returned. If a memory allocation error occurs, NULL is returned.
|
||||||
|
**
|
||||||
|
** If the first entry in aRoot[] is 0, that indicates that the list of
|
||||||
|
** root pages is incomplete. This is a "partial integrity-check". This
|
||||||
|
** happens when performing an integrity check on a single table. The
|
||||||
|
** zero is skipped, of course. But in addition, the freelist checks
|
||||||
|
** and the checks to make sure every page is referenced are also skipped,
|
||||||
|
** since obviously it is not possible to know which pages are covered by
|
||||||
|
** the unverified btrees. Except, if aRoot[1] is 1, then the freelist
|
||||||
|
** checks are still performed.
|
||||||
*/
|
*/
|
||||||
char *sqlite3BtreeIntegrityCheck(
|
char *sqlite3BtreeIntegrityCheck(
|
||||||
sqlite3 *db, /* Database connection that is running the check */
|
sqlite3 *db, /* Database connection that is running the check */
|
||||||
@ -10135,6 +10144,16 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
u64 savedDbFlags = pBt->db->flags;
|
u64 savedDbFlags = pBt->db->flags;
|
||||||
char zErr[100];
|
char zErr[100];
|
||||||
VVA_ONLY( int nRef );
|
VVA_ONLY( int nRef );
|
||||||
|
int bPartial = 0; /* True if not checking all btrees */
|
||||||
|
int bCkFreelist = 1; /* True to scan the freelist */
|
||||||
|
assert( nRoot>0 );
|
||||||
|
|
||||||
|
/* aRoot[0]==0 means this is a partial check */
|
||||||
|
if( aRoot[0]==0 ){
|
||||||
|
assert( nRoot>1 );
|
||||||
|
bPartial = 1;
|
||||||
|
if( aRoot[1]!=1 ) bCkFreelist = 0;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
|
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
|
||||||
@ -10174,29 +10193,33 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
|
|
||||||
/* Check the integrity of the freelist
|
/* Check the integrity of the freelist
|
||||||
*/
|
*/
|
||||||
sCheck.zPfx = "Main freelist: ";
|
if( bCkFreelist ){
|
||||||
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
|
sCheck.zPfx = "Main freelist: ";
|
||||||
get4byte(&pBt->pPage1->aData[36]));
|
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
|
||||||
sCheck.zPfx = 0;
|
get4byte(&pBt->pPage1->aData[36]));
|
||||||
|
sCheck.zPfx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check all the tables.
|
/* Check all the tables.
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum ){
|
if( !bPartial ){
|
||||||
Pgno mx = 0;
|
if( pBt->autoVacuum ){
|
||||||
int mxInHdr;
|
Pgno mx = 0;
|
||||||
for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
|
Pgno mxInHdr;
|
||||||
mxInHdr = get4byte(&pBt->pPage1->aData[52]);
|
for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
|
||||||
if( mx!=mxInHdr ){
|
mxInHdr = get4byte(&pBt->pPage1->aData[52]);
|
||||||
|
if( mx!=mxInHdr ){
|
||||||
|
checkAppendMsg(&sCheck,
|
||||||
|
"max rootpage (%d) disagrees with header (%d)",
|
||||||
|
mx, mxInHdr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
|
||||||
checkAppendMsg(&sCheck,
|
checkAppendMsg(&sCheck,
|
||||||
"max rootpage (%d) disagrees with header (%d)",
|
"incremental_vacuum enabled with a max rootpage of zero"
|
||||||
mx, mxInHdr
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
|
|
||||||
checkAppendMsg(&sCheck,
|
|
||||||
"incremental_vacuum enabled with a max rootpage of zero"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
testcase( pBt->db->flags & SQLITE_CellSizeCk );
|
testcase( pBt->db->flags & SQLITE_CellSizeCk );
|
||||||
@ -10205,7 +10228,7 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
i64 notUsed;
|
i64 notUsed;
|
||||||
if( aRoot[i]==0 ) continue;
|
if( aRoot[i]==0 ) continue;
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum && aRoot[i]>1 ){
|
if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){
|
||||||
checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
|
checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -10215,22 +10238,24 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
|
|
||||||
/* Make sure every page in the file is referenced
|
/* Make sure every page in the file is referenced
|
||||||
*/
|
*/
|
||||||
for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
|
if( !bPartial ){
|
||||||
|
for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
|
||||||
#ifdef SQLITE_OMIT_AUTOVACUUM
|
#ifdef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( getPageReferenced(&sCheck, i)==0 ){
|
if( getPageReferenced(&sCheck, i)==0 ){
|
||||||
checkAppendMsg(&sCheck, "Page %d is never used", i);
|
checkAppendMsg(&sCheck, "Page %d is never used", i);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* If the database supports auto-vacuum, make sure no tables contain
|
/* If the database supports auto-vacuum, make sure no tables contain
|
||||||
** references to pointer-map pages.
|
** references to pointer-map pages.
|
||||||
*/
|
*/
|
||||||
if( getPageReferenced(&sCheck, i)==0 &&
|
if( getPageReferenced(&sCheck, i)==0 &&
|
||||||
(PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
|
(PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
|
||||||
checkAppendMsg(&sCheck, "Page %d is never used", i);
|
checkAppendMsg(&sCheck, "Page %d is never used", i);
|
||||||
}
|
}
|
||||||
if( getPageReferenced(&sCheck, i)!=0 &&
|
if( getPageReferenced(&sCheck, i)!=0 &&
|
||||||
(PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
|
(PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
|
||||||
checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
|
checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
32
src/pragma.c
32
src/pragma.c
@ -1526,9 +1526,22 @@ void sqlite3Pragma(
|
|||||||
** integrity_check designed to detect most database corruption
|
** integrity_check designed to detect most database corruption
|
||||||
** without the overhead of cross-checking indexes. Quick_check
|
** without the overhead of cross-checking indexes. Quick_check
|
||||||
** is linear time wherease integrity_check is O(NlogN).
|
** is linear time wherease integrity_check is O(NlogN).
|
||||||
|
**
|
||||||
|
** The maximum nubmer of errors is 100 by default. A different default
|
||||||
|
** can be specified using a numeric parameter N.
|
||||||
|
**
|
||||||
|
** Or, the parameter N can be the name of a table. In that case, only
|
||||||
|
** the one table named is verified. The freelist is only verified if
|
||||||
|
** the named table is "sqlite_schema" (or one of its aliases).
|
||||||
|
**
|
||||||
|
** All schemas are checked by default. To check just a single
|
||||||
|
** schema, use the form:
|
||||||
|
**
|
||||||
|
** PRAGMA schema.integrity_check;
|
||||||
*/
|
*/
|
||||||
case PragTyp_INTEGRITY_CHECK: {
|
case PragTyp_INTEGRITY_CHECK: {
|
||||||
int i, j, addr, mxErr;
|
int i, j, addr, mxErr;
|
||||||
|
Table *pObjTab = 0; /* Check only this one table, if not NULL */
|
||||||
|
|
||||||
int isQuick = (sqlite3Tolower(zLeft[0])=='q');
|
int isQuick = (sqlite3Tolower(zLeft[0])=='q');
|
||||||
|
|
||||||
@ -1551,9 +1564,13 @@ void sqlite3Pragma(
|
|||||||
/* Set the maximum error count */
|
/* Set the maximum error count */
|
||||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||||
if( zRight ){
|
if( zRight ){
|
||||||
sqlite3GetInt32(zRight, &mxErr);
|
if( sqlite3GetInt32(zRight, &mxErr) ){
|
||||||
if( mxErr<=0 ){
|
if( mxErr<=0 ){
|
||||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pObjTab = sqlite3LocateTable(pParse, 0, zRight,
|
||||||
|
iDb>=0 ? db->aDb[iDb].zDbSName : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
|
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
|
||||||
@ -1582,15 +1599,21 @@ void sqlite3Pragma(
|
|||||||
Table *pTab = sqliteHashData(x); /* Current table */
|
Table *pTab = sqliteHashData(x); /* Current table */
|
||||||
Index *pIdx; /* An index on pTab */
|
Index *pIdx; /* An index on pTab */
|
||||||
int nIdx; /* Number of indexes on pTab */
|
int nIdx; /* Number of indexes on pTab */
|
||||||
|
if( pObjTab && pObjTab!=pTab ) continue;
|
||||||
if( HasRowid(pTab) ) cnt++;
|
if( HasRowid(pTab) ) cnt++;
|
||||||
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
|
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
|
||||||
if( nIdx>mxIdx ) mxIdx = nIdx;
|
if( nIdx>mxIdx ) mxIdx = nIdx;
|
||||||
}
|
}
|
||||||
|
if( cnt==0 ) continue;
|
||||||
|
if( pObjTab ) cnt++;
|
||||||
aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
|
aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1));
|
||||||
if( aRoot==0 ) break;
|
if( aRoot==0 ) break;
|
||||||
for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
cnt = 0;
|
||||||
|
if( pObjTab ) aRoot[++cnt] = 0;
|
||||||
|
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||||
Table *pTab = sqliteHashData(x);
|
Table *pTab = sqliteHashData(x);
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
|
if( pObjTab && pObjTab!=pTab ) continue;
|
||||||
if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
|
if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
aRoot[++cnt] = pIdx->tnum;
|
aRoot[++cnt] = pIdx->tnum;
|
||||||
@ -1624,6 +1647,7 @@ void sqlite3Pragma(
|
|||||||
int r1 = -1;
|
int r1 = -1;
|
||||||
|
|
||||||
if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
|
if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
|
||||||
|
if( pObjTab && pObjTab!=pTab ) continue;
|
||||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
||||||
1, 0, &iDataCur, &iIdxCur);
|
1, 0, &iDataCur, &iIdxCur);
|
||||||
|
@ -387,11 +387,15 @@ ifcapable attach {
|
|||||||
PRAGMA integrity_check=4
|
PRAGMA integrity_check=4
|
||||||
}
|
}
|
||||||
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2}}
|
||||||
do_test pragma-3.6 {
|
do_catchsql_test pragma-3.6 {
|
||||||
execsql {
|
PRAGMA integrity_check=xyz
|
||||||
PRAGMA integrity_check=xyz
|
} {1 {no such table: xyz}}
|
||||||
}
|
do_catchsql_test pragma-3.6b {
|
||||||
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
PRAGMA integrity_check=t2
|
||||||
|
} {0 {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}}
|
||||||
|
do_catchsql_test pragma-3.6c {
|
||||||
|
PRAGMA integrity_check=sqlite_schema
|
||||||
|
} {0 ok}
|
||||||
do_test pragma-3.7 {
|
do_test pragma-3.7 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=0
|
PRAGMA integrity_check=0
|
||||||
@ -423,7 +427,7 @@ ifcapable attach {
|
|||||||
do_test pragma-3.8.2 {
|
do_test pragma-3.8.2 {
|
||||||
execsql {PRAGMA QUICK_CHECK}
|
execsql {PRAGMA QUICK_CHECK}
|
||||||
} {ok}
|
} {ok}
|
||||||
do_test pragma-3.9 {
|
do_test pragma-3.9a {
|
||||||
execsql {
|
execsql {
|
||||||
ATTACH 'testerr.db' AS t2;
|
ATTACH 'testerr.db' AS t2;
|
||||||
PRAGMA integrity_check
|
PRAGMA integrity_check
|
||||||
@ -432,6 +436,12 @@ ifcapable attach {
|
|||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
|
do_execsql_test pragma-3.9b {
|
||||||
|
PRAGMA t2.integrity_check=t2;
|
||||||
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
|
do_execsql_test pragma-3.9c {
|
||||||
|
PRAGMA t2.integrity_check=sqlite_schema;
|
||||||
|
} {ok}
|
||||||
do_test pragma-3.10 {
|
do_test pragma-3.10 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=1
|
PRAGMA integrity_check=1
|
||||||
|
Reference in New Issue
Block a user