From: drh Date: Wed, 22 Feb 2017 14:15:37 +0000 (+0000) Subject: Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. X-Git-Tag: version-3.18.0~101^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a284dcefe85c88be8f07997931cb8b208087a9b;p=thirdparty%2Fsqlite.git Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. FossilOrigin-Name: 549bae0856004ff65b505175460abd598b30fe57 --- diff --git a/manifest b/manifest index 0c80aaffba..7e7a9e3e8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3VdbeHalt(),\sreturn\sas\ssoon\sas\spossible\sif\nVdbe.magic!=VDBE_MAGIC_RUN.\sThis\smakes\ssqlite3_reset()\sslightly\sfaster\sin\ssome\ncases. -D 2017-02-21T21:24:05.029 +C Enhance\s"PRAGMA\sintegrity_check"\sso\sthat\sit\sverifies\sCHECK\sconstraints. +D 2017-02-22T14:15:37.561 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -388,7 +388,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d +F src/pragma.c aa4af3d8c4d9086cbceeafcbb8a5e75605a1207d F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -576,7 +576,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485 +F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -1557,7 +1557,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e400909f313c317b7b67be6eb867ed61df7383dc -R 5434ea5a08220297aa4d56dd68f46447 -U dan -Z 68cf5c57f26344b5e30f88013a5c9e52 +P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 +R b17279d0fcfdb924feca449c6ae8dc40 +T *branch * integrity-check-improvements +T *sym-integrity-check-improvements * +T -sym-trunk * +U drh +Z 83b8ae4f812a6d4117d2cc9c8ae430b2 diff --git a/manifest.uuid b/manifest.uuid index 2ace79cb16..8a2cc1e157 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 \ No newline at end of file +549bae0856004ff65b505175460abd598b30fe57 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index b1775a4082..c7d092b30d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1481,7 +1481,7 @@ void sqlite3Pragma( int iDataCur, iIdxCur; int r1 = -1; - if( pTab->pIndex==0 ) continue; + 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); @@ -1517,6 +1517,31 @@ void sqlite3Pragma( 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; diff --git a/test/check.test b/test/check.test index 43e447f70d..19f252677c 100644 --- a/test/check.test +++ b/test/check.test @@ -309,11 +309,15 @@ do_test check-4.8 { PRAGMA ignore_check_constraints=ON; UPDATE t4 SET x=0, y=1; SELECT * FROM t4; + PRAGMA integrity_check; } -} {0 1} +} {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 { - PRAGMA ignore_check_constraints=OFF; UPDATE t4 SET x=0, y=2; } } {1 {CHECK constraint failed: t4}}