From 7e84b377a911ae9fb882dcf9eba23f90b59a849c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Feb 2017 14:30:17 +0000 Subject: [PATCH 01/11] Small grammar simplification. FossilOrigin-Name: 0d8a868acd74fb1d076f23fda58b841bb7e6900b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 44763338e4..ab58b869fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_BUG_COMPATIBLE_20160819\scompile-time\soption\sto\somit\sthe\serror\nmessage\swhen\san\sunrecognized\sargument\sis\sprovided\sto\sthe\sVACUUM\scommand. -D 2017-02-18T13:47:11.181 +C Small\sgrammar\ssimplification. +D 2017-02-20T14:30:17.816 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -383,7 +383,7 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c +F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cc9d74c176a78aeebfbb39198c21b5dd547ff52 -R 57839b570efd132c834489fe34d93e5e +P 491814272dce7e937b4734fcbc2ad69e12377b56 +R b4cf79fa4c0fd30460236bc8c090e993 U drh -Z 38cfd439ab0cfeae01cbf1d291727475 +Z 32b02aa6638f1e40c7df4614e1f90d4a diff --git a/manifest.uuid b/manifest.uuid index 557d9a7e8b..c411ab59d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -491814272dce7e937b4734fcbc2ad69e12377b56 \ No newline at end of file +0d8a868acd74fb1d076f23fda58b841bb7e6900b \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 9cada2a1be..0949e97d16 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} %type likeop {Token} -likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/} +likeop(A) ::= LIKE_KW|MATCH(A). likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/} expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; From 5e6710ab6540e45cfb79d85609f28c496d5b6f25 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 20 Feb 2017 19:13:37 +0000 Subject: [PATCH 02/11] Avoid unsigned integer overflows for SQLITE_WIN32_HEAP_INIT_SIZE when the Win32 heap subsystem is used with very large values of SQLITE_DEFAULT_CACHE_SIZE and/or SQLITE_DEFAULT_PAGE_SIZE. FossilOrigin-Name: 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 52 ++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ab58b869fe..34aa979a22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sgrammar\ssimplification. -D 2017-02-20T14:30:17.816 +C Avoid\sunsigned\sinteger\soverflows\sfor\sSQLITE_WIN32_HEAP_INIT_SIZE\swhen\sthe\sWin32\sheap\ssubsystem\sis\sused\swith\svery\slarge\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sand/or\sSQLITE_DEFAULT_PAGE_SIZE. +D 2017-02-20T19:13:37.359 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -379,7 +379,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 -F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 +F src/os_win.c c97c79fe19dfb0a14c89b78280beabd9ac28acb1 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 491814272dce7e937b4734fcbc2ad69e12377b56 -R b4cf79fa4c0fd30460236bc8c090e993 -U drh -Z 32b02aa6638f1e40c7df4614e1f90d4a +P 0d8a868acd74fb1d076f23fda58b841bb7e6900b +R 42e490f947871a7f92e95baf4bc40d36 +U mistachkin +Z 144582bee7eff0d5ee39c945bf2670f2 diff --git a/manifest.uuid b/manifest.uuid index c411ab59d6..60aeb2563f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d8a868acd74fb1d076f23fda58b841bb7e6900b \ No newline at end of file +96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 2cb5f7b0c8..8d75d8bec5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -352,7 +352,34 @@ struct winVfsAppData { ****************************************************************************** */ #ifndef SQLITE_WIN32_HEAP_CREATE -# define SQLITE_WIN32_HEAP_CREATE (TRUE) +# define SQLITE_WIN32_HEAP_CREATE (TRUE) +#endif + +/* + * This is the maximum possible initial size of the Win32-specific heap, in + * bytes. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE +# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U) +#endif + +/* + * This is the extra space for the initial size of the Win32-specific heap, + * in bytes. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA +# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304) +#endif + +/* + * Calculate the maximum legal cache size, in pages, based on the maximum + * possible initial heap size and the default page size, setting aside the + * needed extra space. + */ +#ifndef SQLITE_WIN32_MAX_CACHE_SIZE +# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \ + (SQLITE_DEFAULT_PAGE_SIZE)) #endif /* @@ -361,25 +388,36 @@ struct winVfsAppData { */ #ifndef SQLITE_WIN32_CACHE_SIZE # if SQLITE_DEFAULT_CACHE_SIZE>=0 -# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) +# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) # else -# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) +# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) # endif #endif +/* + * Make sure that the calculated cache size, in pages, cannot cause the + * initial size of the Win32-specific heap to exceed the maximum amount + * of memory that can be specified in the call to HeapCreate. + */ +#if SQLITE_WIN32_CACHE_SIZE>=SQLITE_WIN32_MAX_CACHE_SIZE +# undef SQLITE_WIN32_CACHE_SIZE +# define SQLITE_WIN32_CACHE_SIZE (2000) +#endif + /* * The initial size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE -# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ - (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) #endif /* * The maximum size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_MAX_SIZE -# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) #endif /* @@ -387,7 +425,7 @@ struct winVfsAppData { * zero for the default behavior. */ #ifndef SQLITE_WIN32_HEAP_FLAGS -# define SQLITE_WIN32_HEAP_FLAGS (0) +# define SQLITE_WIN32_HEAP_FLAGS (0) #endif From 4689956b9e0dfad404a0b103d7903b8cbfddb48f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 20 Feb 2017 23:32:04 +0000 Subject: [PATCH 03/11] Correct a harmless typo in the previous check-in. FossilOrigin-Name: 1589db012ef1389bf84399fccf96d143b2ac4c0f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 34aa979a22..b9e136d680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunsigned\sinteger\soverflows\sfor\sSQLITE_WIN32_HEAP_INIT_SIZE\swhen\sthe\sWin32\sheap\ssubsystem\sis\sused\swith\svery\slarge\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sand/or\sSQLITE_DEFAULT_PAGE_SIZE. -D 2017-02-20T19:13:37.359 +C Correct\sa\sharmless\stypo\sin\sthe\sprevious\scheck-in. +D 2017-02-20T23:32:04.979 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -379,7 +379,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 -F src/os_win.c c97c79fe19dfb0a14c89b78280beabd9ac28acb1 +F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d8a868acd74fb1d076f23fda58b841bb7e6900b -R 42e490f947871a7f92e95baf4bc40d36 +P 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 +R a6d884232566cde130b9b77412776230 U mistachkin -Z 144582bee7eff0d5ee39c945bf2670f2 +Z c97450fc686b8c32bf5204625d8622fc diff --git a/manifest.uuid b/manifest.uuid index 60aeb2563f..a4b5b98287 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 \ No newline at end of file +1589db012ef1389bf84399fccf96d143b2ac4c0f \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 8d75d8bec5..a87d7d0925 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -399,7 +399,7 @@ struct winVfsAppData { * initial size of the Win32-specific heap to exceed the maximum amount * of memory that can be specified in the call to HeapCreate. */ -#if SQLITE_WIN32_CACHE_SIZE>=SQLITE_WIN32_MAX_CACHE_SIZE +#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE # undef SQLITE_WIN32_CACHE_SIZE # define SQLITE_WIN32_CACHE_SIZE (2000) #endif From e3247822549c6ef80b33baaffb0f4698ef9861bc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 Feb 2017 15:27:22 +0000 Subject: [PATCH 04/11] Very small enhancement to dispatch speed for SQL functions. FossilOrigin-Name: 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b9e136d680..ec707ac5ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sa\sharmless\stypo\sin\sthe\sprevious\scheck-in. -D 2017-02-20T23:32:04.979 +C Very\ssmall\senhancement\sto\sdispatch\sspeed\sfor\sSQL\sfunctions. +D 2017-02-21T15:27:22.044 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -461,7 +461,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b +F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 -R a6d884232566cde130b9b77412776230 -U mistachkin -Z c97450fc686b8c32bf5204625d8622fc +P 1589db012ef1389bf84399fccf96d143b2ac4c0f +R e3362d21e61dd042dd5284f17843c5d9 +U drh +Z 12602c247389d019265df8c626a67cf1 diff --git a/manifest.uuid b/manifest.uuid index a4b5b98287..451bfd624c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1589db012ef1389bf84399fccf96d143b2ac4c0f \ No newline at end of file +3c3228ed16ed8a72630bd56bb9192ee3c7f82093 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7f286b2c6d..97aa519df1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1669,21 +1669,21 @@ case OP_Function: { for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } - memAboutToChange(p, pCtx->pOut); + memAboutToChange(p, pOut); #ifdef SQLITE_DEBUG for(i=0; iargc; i++){ assert( memIsValid(pCtx->argv[i]) ); REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); } #endif - MemSetTypeFlag(pCtx->pOut, MEM_Null); + MemSetTypeFlag(pOut, MEM_Null); pCtx->fErrorOrAux = 0; (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ /* If the function returned an error, throw an exception */ if( pCtx->fErrorOrAux ){ if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); rc = pCtx->isError; } sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); @@ -1692,12 +1692,12 @@ case OP_Function: { /* Copy the result of the function into register P3 */ if( pOut->flags & (MEM_Str|MEM_Blob) ){ - sqlite3VdbeChangeEncoding(pCtx->pOut, encoding); - if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big; + sqlite3VdbeChangeEncoding(pOut, encoding); + if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; } - REGISTER_TRACE(pOp->p3, pCtx->pOut); - UPDATE_MAX_BLOBSIZE(pCtx->pOut); + REGISTER_TRACE(pOp->p3, pOut); + UPDATE_MAX_BLOBSIZE(pOut); break; } From f0e808c60b66cae45cbcf3c0fffb1e08776e879e Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Feb 2017 17:52:58 +0000 Subject: [PATCH 05/11] Fix an FTS5 problem that could cause a crash when certain queries were interrupted using sqlite3_interrupt(). FossilOrigin-Name: e400909f313c317b7b67be6eb867ed61df7383dc --- ext/fts5/fts5_expr.c | 15 +++++- ext/fts5/test/fts5faultD.test | 87 +++++++++++++++++++++++++++++++++++ manifest | 15 +++--- manifest.uuid | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 ext/fts5/test/fts5faultD.test diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 209748bbf5..e18691ad0b 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1110,7 +1110,10 @@ static int fts5ExprNodeNext_OR( || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0) ){ int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + pNode->bNomatch = 0; + return rc; + } } } } @@ -1141,7 +1144,10 @@ static int fts5ExprNodeTest_AND( if( cmp>0 ){ /* Advance pChild until it points to iLast or laster */ rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + pAnd->bNomatch = 0; + return rc; + } } /* If the child node is now at EOF, so is the parent AND node. Otherwise, @@ -1180,6 +1186,8 @@ static int fts5ExprNodeNext_AND( int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_AND(pExpr, pNode); + }else{ + pNode->bNomatch = 0; } return rc; } @@ -1222,6 +1230,9 @@ static int fts5ExprNodeNext_NOT( if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_NOT(pExpr, pNode); } + if( rc!=SQLITE_OK ){ + pNode->bNomatch = 0; + } return rc; } diff --git a/ext/fts5/test/fts5faultD.test b/ext/fts5/test/fts5faultD.test new file mode 100644 index 0000000000..e259cbf610 --- /dev/null +++ b/ext/fts5/test/fts5faultD.test @@ -0,0 +1,87 @@ +# 2016 February 2 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# This file is focused on OOM errors. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultA + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $testprefix { + if {"%DETAIL%"=="none"} continue + + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%); + INSERT INTO o1(o1, rank) VALUES('pgsz', 32); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s; + } + + do_faultsim_test 1 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT count(*) FROM o1('a') } + } -test { + faultsim_test_result {0 180} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 2 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 3 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 4 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('b:b OR a:a') } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 5 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT count(*) FROM o1('c:b') } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } +} + +finish_test diff --git a/manifest b/manifest index ec707ac5ad..c5dbc5dfad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\ssmall\senhancement\sto\sdispatch\sspeed\sfor\sSQL\sfunctions. -D 2017-02-21T15:27:22.044 +C Fix\san\sFTS5\sproblem\sthat\scould\scause\sa\scrash\swhen\scertain\squeries\swere\ninterrupted\susing\ssqlite3_interrupt(). +D 2017-02-21T17:52:58.643 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1 F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50 +F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -160,6 +160,7 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85 F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca +F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9 F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d @@ -1556,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1589db012ef1389bf84399fccf96d143b2ac4c0f -R e3362d21e61dd042dd5284f17843c5d9 -U drh -Z 12602c247389d019265df8c626a67cf1 +P 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 +R c2d6d6c70c7c0d8b681ef9ca8535c3a3 +U dan +Z 2a4ed498ce9ed73234b51fb6f9a899a9 diff --git a/manifest.uuid b/manifest.uuid index 451bfd624c..94de19d8f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c3228ed16ed8a72630bd56bb9192ee3c7f82093 \ No newline at end of file +e400909f313c317b7b67be6eb867ed61df7383dc \ No newline at end of file From 1325adf5e9d6745c9e00a85e294025ceda0691e9 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Feb 2017 21:24:05 +0000 Subject: [PATCH 06/11] In sqlite3VdbeHalt(), return as soon as possible if Vdbe.magic!=VDBE_MAGIC_RUN. This makes sqlite3_reset() slightly faster in some cases. FossilOrigin-Name: 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c5dbc5dfad..0c80aaffba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sFTS5\sproblem\sthat\scould\scause\sa\scrash\swhen\scertain\squeries\swere\ninterrupted\susing\ssqlite3_interrupt(). -D 2017-02-21T17:52:58.643 +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 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -466,7 +466,7 @@ F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 -F src/vdbeaux.c 4122458d33318ab039c4b5da1ca4e7c9221c38e4 +F src/vdbeaux.c 2f48204a0f2875b098ee046bba9265907297b0b5 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 -R c2d6d6c70c7c0d8b681ef9ca8535c3a3 +P e400909f313c317b7b67be6eb867ed61df7383dc +R 5434ea5a08220297aa4d56dd68f46447 U dan -Z 2a4ed498ce9ed73234b51fb6f9a899a9 +Z 68cf5c57f26344b5e30f88013a5c9e52 diff --git a/manifest.uuid b/manifest.uuid index 94de19d8f1..2ace79cb16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e400909f313c317b7b67be6eb867ed61df7383dc \ No newline at end of file +80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cf062cf01d..292ff2bdd2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2609,13 +2609,13 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ + if( p->magic!=VDBE_MAGIC_RUN ){ + return SQLITE_OK; + } if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; } closeAllCursors(p); - if( p->magic!=VDBE_MAGIC_RUN ){ - return SQLITE_OK; - } checkActiveVdbeCnt(db); /* No commit or rollback needed if the program never started or if the From 8a284dcefe85c88be8f07997931cb8b208087a9b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 14:15:37 +0000 Subject: [PATCH 07/11] Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. FossilOrigin-Name: 549bae0856004ff65b505175460abd598b30fe57 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/pragma.c | 27 ++++++++++++++++++++++++++- test/check.test | 8 ++++++-- 4 files changed, 44 insertions(+), 12 deletions(-) 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}} From 8b174f2916c16fc66c8b0248056011e2c5104e36 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 15:11:36 +0000 Subject: [PATCH 08/11] Fix integrity_check so that it verifies NOT NULL constraints even for tables that have no indexes. Enhance quick_check so that it verifies NOT NULL and CHECK constraints. FossilOrigin-Name: 5264844b069cdc20f456acee9f5b2b97c986120d --- manifest | 19 ++++++++---------- manifest.uuid | 2 +- src/build.c | 1 + src/pragma.c | 51 ++++++++++++++++++++++++++++++++----------------- src/sqliteInt.h | 17 +++++++++-------- 5 files changed, 52 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 7e7a9e3e8a..7776d07ac7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"PRAGMA\sintegrity_check"\sso\sthat\sit\sverifies\sCHECK\sconstraints. -D 2017-02-22T14:15:37.561 +C Fix\sintegrity_check\sso\sthat\sit\sverifies\sNOT\sNULL\sconstraints\seven\sfor\stables\nthat\shave\sno\sindexes.\s\sEnhance\squick_check\sso\sthat\sit\sverifies\sNOT\sNULL\sand\nCHECK\sconstraints. +D 2017-02-22T15:11:36.862 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -341,7 +341,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 -F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af +F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 @@ -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 aa4af3d8c4d9086cbceeafcbb8a5e75605a1207d +F src/pragma.c ec83a3cb496d6d6d24f9de78ccbb24369dcedf48 F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -400,7 +400,7 @@ F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7 +F src/sqliteInt.h a23e18aebdd0d851c2956a74a3a4f12ff202b472 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1557,10 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 -R b17279d0fcfdb924feca449c6ae8dc40 -T *branch * integrity-check-improvements -T *sym-integrity-check-improvements * -T -sym-trunk * +P 549bae0856004ff65b505175460abd598b30fe57 +R ca36fe65b7e723d2451bfac8ac59f0b7 U drh -Z 83b8ae4f812a6d4117d2cc9c8ae430b2 +Z 40e14a5b2e43e016c602364a556c9a0b diff --git a/manifest.uuid b/manifest.uuid index 8a2cc1e157..e0226c546a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -549bae0856004ff65b505175460abd598b30fe57 \ No newline at end of file +5264844b069cdc20f456acee9f5b2b97c986120d \ No newline at end of file diff --git a/src/build.c b/src/build.c index cd9c81be82..6e1e2177be 100644 --- a/src/build.c +++ b/src/build.c @@ -1115,6 +1115,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; p->aCol[p->nCol-1].notNull = (u8)onError; + p->tabFlags |= TF_HasNotNull; } /* diff --git a/src/pragma.c b/src/pragma.c index c7d092b30d..8a2b3de21e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1377,9 +1377,17 @@ void sqlite3Pragma( #endif #ifndef SQLITE_OMIT_INTEGRITY_CHECK - /* Pragma "quick_check" is reduced version of + /* PRAGMA integrity_check + ** PRAGMA integrity_check(N) + ** PRAGMA quick_check + ** PRAGMA quick_check(N) + ** + ** Verify the integrity of the database. + ** + ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption - ** without most of the overhead of a full integrity-check. + ** without the overhead of cross-checking indexes. Quick_check + ** is linear time wherease integrity_check is O(NlogN). */ case PragTyp_INTEGRITY_CHECK: { int i, j, addr, mxErr; @@ -1473,7 +1481,7 @@ void sqlite3Pragma( /* Make sure all the indices are constructed correctly. */ - for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; Index *pPrior = 0; @@ -1481,7 +1489,12 @@ void sqlite3Pragma( int iDataCur, iIdxCur; int r1 = -1; - if( pTab->pIndex==0 && pTab->pCheck==0 ) continue; + 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); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ VdbeCoverage(v); @@ -1543,7 +1556,7 @@ void sqlite3Pragma( sqlite3ExprCachePop(pParse); } /* Validate index entries for the current row */ - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + 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; @@ -1595,19 +1608,21 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); #ifndef SQLITE_OMIT_BTREECOUNT - sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( pPk==pIdx ) continue; - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeLoadString(v, 3, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + 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; + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); + sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeLoadString(v, 3, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); + sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + } } #endif /* SQLITE_OMIT_BTREECOUNT */ } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9a53d33626..d9ec8c5bc9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1879,14 +1879,15 @@ struct Table { ** the TF_OOOHidden attribute would apply in this case. Such tables require ** special handling during INSERT processing. */ -#define TF_Readonly 0x01 /* Read-only system table */ -#define TF_Ephemeral 0x02 /* An ephemeral table */ -#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ -#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -/* available for reuse: 0x10 */ -#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ -#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ +#define TF_Readonly 0x0001 /* Read-only system table */ +#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ +#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ +/* available for reuse: 0x0010 */ +#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ +#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x0100 /* Contains NOT NULL constraints */ /* From 66accfc56b51387b241ba2e27e7364ea1a01f37b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 18:04:42 +0000 Subject: [PATCH 09/11] Cleanup and simplification of the output row count limit control of PRAGMA integrity_check. FossilOrigin-Name: 5af7d72ed9ec758283d78ceb46627d72021c1c60 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/pragma.c | 60 +++++++++++++++++++++++---------------------------- src/vdbe.c | 6 +++--- 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 7776d07ac7..677bc6001d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sintegrity_check\sso\sthat\sit\sverifies\sNOT\sNULL\sconstraints\seven\sfor\stables\nthat\shave\sno\sindexes.\s\sEnhance\squick_check\sso\sthat\sit\sverifies\sNOT\sNULL\sand\nCHECK\sconstraints. -D 2017-02-22T15:11:36.862 +C Cleanup\sand\ssimplification\sof\sthe\soutput\srow\scount\slimit\scontrol\sof\nPRAGMA\sintegrity_check. +D 2017-02-22T18:04:42.473 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 ec83a3cb496d6d6d24f9de78ccbb24369dcedf48 +F src/pragma.c b127edeb54c744a101b371cfa2e221fd741bcd72 F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -462,7 +462,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 +F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 549bae0856004ff65b505175460abd598b30fe57 -R ca36fe65b7e723d2451bfac8ac59f0b7 +P 5264844b069cdc20f456acee9f5b2b97c986120d +R 46f90a15a015e3c65c6378dae6f8ff19 U drh -Z 40e14a5b2e43e016c602364a556c9a0b +Z ac3f9bd06db21fa3e22e700d592b007d diff --git a/manifest.uuid b/manifest.uuid index e0226c546a..de6e14387f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5264844b069cdc20f456acee9f5b2b97c986120d \ No newline at end of file +5af7d72ed9ec758283d78ceb46627d72021c1c60 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 8a2b3de21e..151a7a2e82 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -295,6 +295,22 @@ static const PragmaName *pragmaLocate(const char *zName){ return lwr>upr ? 0 : &aPragmaName[mid]; } +/* +** Helper subroutine for PRAGMA integrity_check: +** +** Generate code to output a single-column result row with the result +** held in register regResult. Decrement the result count and halt if +** the maximum number of result rows have been issued. +*/ +static int integrityCheckResultRow(Vdbe *v, int regResult){ + int addr; + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + return addr; +} + /* ** Process a pragma statement. ** @@ -1418,7 +1434,7 @@ void sqlite3Pragma( mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } - sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */ + sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ /* Do an integrity check on each database file */ for(i=0; inDb; i++){ @@ -1433,10 +1449,6 @@ void sqlite3Pragma( if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree ** @@ -1476,7 +1488,7 @@ void sqlite3Pragma( P4_DYNAMIC); sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); - sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); + integrityCheckResultRow(v, 2); sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. @@ -1496,10 +1508,6 @@ void sqlite3Pragma( continue; /* No additional checks needed for this table */ } pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); @@ -1514,21 +1522,17 @@ void sqlite3Pragma( /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ char *zErr; - int jmp2, jmp3; + int jmp2; if( j==pTab->iPKey ) continue; if( pTab->aCol[j].notNull==0 ) continue; sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pTab->aCol[j].zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); + integrityCheckResultRow(v, 3); sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeJumpHere(v, jmp3); } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ @@ -1545,13 +1549,10 @@ void sqlite3Pragma( 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); + integrityCheckResultRow(v, 3); sqlite3VdbeResolveLabel(v, addrCkOk); sqlite3ExprCachePop(pParse); } @@ -1567,16 +1568,13 @@ void sqlite3Pragma( /* Verify that an index entry exists for the current table row */ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, pIdx->nColumn); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ sqlite3VdbeLoadString(v, 3, "row "); sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); sqlite3VdbeLoadString(v, 4, " missing from index "); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); + jmp4 = integrityCheckResultRow(v, 3); sqlite3VdbeJumpHere(v, jmp2); /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL @@ -1597,7 +1595,6 @@ void sqlite3Pragma( sqlite3VdbeJumpHere(v, jmp6); sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, pIdx->nKeyCol); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); sqlite3VdbeGoto(v, jmp5); sqlite3VdbeResolveLabel(v, uniqOk); @@ -1612,16 +1609,13 @@ void sqlite3Pragma( sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ if( pPk==pIdx ) continue; - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeLoadString(v, 3, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + integrityCheckResultRow(v, 7); + sqlite3VdbeJumpHere(v, addr); } } #endif /* SQLITE_OMIT_BTREECOUNT */ @@ -1631,7 +1625,7 @@ void sqlite3Pragma( static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ - { OP_If, 1, 4, 0}, /* 1 */ + { OP_IfNotZero, 1, 4, 0}, /* 1 */ { OP_String8, 0, 3, 0}, /* 2 */ { OP_ResultRow, 3, 1, 0}, /* 3 */ }; @@ -1639,7 +1633,7 @@ void sqlite3Pragma( aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); if( aOp ){ - aOp[0].p2 = -mxErr; + aOp[0].p2 = 1-mxErr; aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; } diff --git a/src/vdbe.c b/src/vdbe.c index 97aa519df1..fabe98ae57 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5611,7 +5611,7 @@ case OP_DropTrigger: { ** register P1 the text of an error message describing any problems. ** If no problems are found, store a NULL in register P1. ** -** The register P3 contains the maximum number of allowed errors. +** The register P3 contains one less than the maximum number of allowed errors. ** At most reg(P3) errors will be reported. ** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. @@ -5644,14 +5644,14 @@ case OP_IntegrityCk: { assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, - (int)pnErr->u.i, &nErr); - pnErr->u.i -= nErr; + (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); }else if( z==0 ){ goto no_mem; }else{ + pnErr->u.i -= nErr-1; sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); From bd1d270ec9909d48c8e5b14ee03be6600877fa9c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Feb 2017 19:27:51 +0000 Subject: [PATCH 10/11] Improve the performance of ANALYZE when SQLITE_ENABLE_STAT4 is defined. FossilOrigin-Name: 737a82444065752785c643b1d29ca097c828effb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 24 +++++++++++++++++++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 061f9eb07e..5a5647725b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sPRAGMA\sintegrity_check.\nVerify\sCHECK\sconstraints.\nVerify\sNOT\sNULL\sconstraints\seven\son\stable\sthat\slack\sindexes.\nVerify\sCHECK\sand\sNOT\sNULL\sconstraints\swith\sPRAGMA\squick_check. -D 2017-02-22T18:53:13.913 +C Improve\sthe\sperformance\sof\sANALYZE\swhen\sSQLITE_ENABLE_STAT4\sis\sdefined. +D 2017-02-22T19:27:51.768 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -332,7 +332,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5 +F src/analyze.c 844359e720d1116592234f2f7938432bdc5b6238 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 5af7d72ed9ec758283d78ceb46627d72021c1c60 -R 46f90a15a015e3c65c6378dae6f8ff19 -U drh -Z 9fac49478b578adef606b235c8c223db +P aa02bd3c95e374008b930d296c88dfafaf11c65a +R 767bcf2e23bb391de45c0ed55772662f +U dan +Z 11a6abc8e262f46553fa08a6e318d405 diff --git a/manifest.uuid b/manifest.uuid index f457c0397d..cfc91dee69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa02bd3c95e374008b930d296c88dfafaf11c65a \ No newline at end of file +737a82444065752785c643b1d29ca097c828effb \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 890ae7c3b2..79c27d06ab 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -290,6 +290,7 @@ struct Stat4Accum { Stat4Sample *aBest; /* Array of nCol best samples */ int iMin; /* Index in a[] of entry with minimum score */ int nSample; /* Current number of samples */ + int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */ int iGet; /* Index of current sample accessed by stat_get() */ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ sqlite3 *db; /* Database connection, for malloc() */ @@ -551,7 +552,14 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ Stat4Sample *pSample = 0; int i; + /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0 + ** values in the anEq[] array of any sample in Stat4Accum.a[]. In + ** other words, if nMaxEqZero is n, then it is guaranteed that there + ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */ assert( IsStat4 || nEqZero==0 ); + if( nEqZero>p->nMaxEqZero ){ + p->nMaxEqZero = nEqZero; + } #ifdef SQLITE_ENABLE_STAT4 if( pNew->isPSample==0 ){ @@ -651,12 +659,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){ } } - /* Update the anEq[] fields of any samples already collected. */ + /* Check that no sample contains an anEq[] entry with an index of + ** p->nMaxEqZero or greater set to zero. */ for(i=p->nSample-1; i>=0; i--){ int j; - for(j=iChng; jnCol; j++){ - if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + for(j=p->nMaxEqZero; jnCol; j++) assert( p->a[i].anEq[j]>0 ); + } + + /* Update the anEq[] fields of any samples already collected. */ + if( iChngnMaxEqZero ){ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=iChng; jnCol; j++){ + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + } } + p->nMaxEqZero = iChng; } #endif From 24d772cc277cf831ef890495e72c2c9000137b5c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Feb 2017 19:41:16 +0000 Subject: [PATCH 11/11] Move a branch condition in analyze.c inside an #ifdef SQLITE_ENABLE_STAT4 block. FossilOrigin-Name: d6afd98de3ee8b714dfd6477ead955096f623972 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5a5647725b..7980c45c8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sANALYZE\swhen\sSQLITE_ENABLE_STAT4\sis\sdefined. -D 2017-02-22T19:27:51.768 +C Move\sa\sbranch\scondition\sin\sanalyze.c\sinside\san\s#ifdef\sSQLITE_ENABLE_STAT4\sblock. +D 2017-02-22T19:41:16.947 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -332,7 +332,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 844359e720d1116592234f2f7938432bdc5b6238 +F src/analyze.c 8a2af8a16e4d95ec2327d3f180cb0bab4b2074c1 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa02bd3c95e374008b930d296c88dfafaf11c65a -R 767bcf2e23bb391de45c0ed55772662f +P 737a82444065752785c643b1d29ca097c828effb +R 36d1036d6c004868a4b3899253e892b2 U dan -Z 11a6abc8e262f46553fa08a6e318d405 +Z b9298378d570f055da46d519ad41197c diff --git a/manifest.uuid b/manifest.uuid index cfc91dee69..69e4a7f8b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -737a82444065752785c643b1d29ca097c828effb \ No newline at end of file +d6afd98de3ee8b714dfd6477ead955096f623972 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 79c27d06ab..098b6c7e37 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -552,16 +552,16 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ Stat4Sample *pSample = 0; int i; + assert( IsStat4 || nEqZero==0 ); + +#ifdef SQLITE_ENABLE_STAT4 /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0 ** values in the anEq[] array of any sample in Stat4Accum.a[]. In ** other words, if nMaxEqZero is n, then it is guaranteed that there ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */ - assert( IsStat4 || nEqZero==0 ); if( nEqZero>p->nMaxEqZero ){ p->nMaxEqZero = nEqZero; } - -#ifdef SQLITE_ENABLE_STAT4 if( pNew->isPSample==0 ){ Stat4Sample *pUpgrade = 0; assert( pNew->anEq[pNew->iCol]>0 );