diff options
author | drh <> | 2022-08-17 18:07:52 +0000 |
---|---|---|
committer | drh <> | 2022-08-17 18:07:52 +0000 |
commit | 16b03c01965a6feae64ca5e202717f68df9415ad (patch) | |
tree | 176497accdcb8a214f836c4112bb12d9da7daac1 /src | |
parent | 0348fc722f83ebd2e0359b9a7388cd354a65f59c (diff) | |
download | sqlite-16b03c01965a6feae64ca5e202717f68df9415ad.tar.gz sqlite-16b03c01965a6feae64ca5e202717f68df9415ad.zip |
Enhance the "PRAGMA integrity_check" statement so that it verifies the rows of
a WITHOUT ROWID table are in the correct order.
FossilOrigin-Name: 62f934bff495850d0763e07ffa44a557f066ecba9d039363f32287213cba819f
Diffstat (limited to 'src')
-rw-r--r-- | src/pragma.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/src/pragma.c b/src/pragma.c index 37a73bdb6..2dd792f27 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1742,15 +1742,23 @@ void sqlite3Pragma( for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; - Index *pPrior = 0; + Index *pPrior = 0; /* Previous index */ int loopTop; int iDataCur, iIdxCur; int r1 = -1; int bStrict; + int r2; /* Previous key for WITHOUT ROWID tables */ if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + if( isQuick || HasRowid(pTab) ){ + pPk = 0; + r2 = 0; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); + sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); + } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. @@ -1769,6 +1777,24 @@ void sqlite3Pragma( sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); VdbeComment((v, "(right-most column)")); + if( pPk ){ + /* Verify WITHOUT ROWID keys are in ascending order */ + int a1; + char *zErr; + a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + zErr = sqlite3MPrintf(db, + "row not in PRIMARY KEY order for %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + sqlite3VdbeJumpHere(v, a1+1); + for(j=0; j<pPk->nKeyCol; j++){ + sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); + } + } } /* Verify that all NOT NULL columns really are NOT NULL. At the ** same time verify the type of the content of STRICT tables */ @@ -1895,6 +1921,9 @@ void sqlite3Pragma( integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, addr); } + if( pPk ){ + sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); + } } } } |