aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-08-17 18:07:52 +0000
committerdrh <>2022-08-17 18:07:52 +0000
commit16b03c01965a6feae64ca5e202717f68df9415ad (patch)
tree176497accdcb8a214f836c4112bb12d9da7daac1 /src
parent0348fc722f83ebd2e0359b9a7388cd354a65f59c (diff)
downloadsqlite-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.c33
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);
+ }
}
}
}