From a0368d9396ea3c8cb80f902cacb7594039909bb2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 May 2018 00:54:23 +0000 Subject: [PATCH 01/20] Demonstration code on a possible technique for optimizing the use of IN operator on columns to the right of multicolumn indexes. If the OP_Noop generated where were really a new opcode that checked to see if there existed any entries in the index with a matching prefix, it might prevent unnecessary iterations of the IN operator. FossilOrigin-Name: 92f0fe155d5546fc7f4a443d0630613dabe149061966308e5420fad652278f16 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/where.c | 4 ++++ src/whereInt.h | 2 ++ src/wherecode.c | 2 ++ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index fad5a45c93..2cfdac9d08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\snumber\sof\sdatabase\shandles\sopened\sby\stest\sscript\soserror.test\sto\nprovoke\san\s"out\sof\sfile-descriptors"\serror\sto\s20000\s(from\s2000). -D 2018-05-29T19:12:58.327 +C Demonstration\scode\son\sa\spossible\stechnique\sfor\soptimizing\sthe\suse\sof\sIN\noperator\son\scolumns\sto\sthe\sright\sof\smulticolumn\sindexes.\s\sIf\sthe\sOP_Noop\ngenerated\swhere\swere\sreally\sa\snew\sopcode\sthat\schecked\sto\ssee\sif\sthere\sexisted\nany\sentries\sin\sthe\sindex\swith\sa\smatching\sprefix,\sit\smight\sprevent\sunnecessary\niterations\sof\sthe\sIN\soperator. +D 2018-05-30T00:54:23.670 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -578,9 +578,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c 60ec752fcbe9f9e0271ac60548d159a540a1ee47a4f9fedc85e88a3d0e392dd1 -F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53 -F src/wherecode.c 728c7f70731430ccdac807a79969873e1af6968bf1c4745dff3f9dd35f636cc8 +F src/where.c a9a270991e5e526151d077959b868481b28db8707bc6d29b76badd536c48225a +F src/whereInt.h b6ab96d9c1e48d029eaaee8f9b6d05e6a2405af0ad68f684e75f21c46837ae11 +F src/wherecode.c 49256d67b95187f9b49777c0f526362f4eaaa46850700fe5020cf6b154a2fc52 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1729,7 +1729,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 89f56d6b0a6847b042a1556cdf79c598c9bfdbdd5f9529d508ca7b4d26a6ed38 -R d1b9772c07cea88c945a7c3a78ab0901 -U dan -Z caf1e7dfd24b3c90db5132889b4bf8f4 +P 3b00f73456c65dfc1827fdada9afb49245f9addfa684d5ae35e69a07f39164bf +R 150e6f6563a2a6ab67c600fc77f11cd6 +T *branch * multikey-opt-idea +T *sym-multikey-opt-idea * +T -sym-trunk * +U drh +Z 0e3a9a98888882656fe85b8d1be89ddd diff --git a/manifest.uuid b/manifest.uuid index 16cd4a0a40..60b47eade3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b00f73456c65dfc1827fdada9afb49245f9addfa684d5ae35e69a07f39164bf \ No newline at end of file +92f0fe155d5546fc7f4a443d0630613dabe149061966308e5420fad652278f16 \ No newline at end of file diff --git a/src/where.c b/src/where.c index b83915e264..b93e2260e6 100644 --- a/src/where.c +++ b/src/where.c @@ -5083,6 +5083,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + sqlite3VdbeAddOp3(v, OP_Noop, pLevel->iIdxCur, + pIn->iBase, pIn->nPrefix); + } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); diff --git a/src/whereInt.h b/src/whereInt.h index 4b6213af31..08159fe28e 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -82,6 +82,8 @@ struct WhereLevel { struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entires in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ diff --git a/src/wherecode.c b/src/wherecode.c index c9edab7b0c..1578122479 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,6 +592,8 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + pIn->iBase = iReg - i; + pIn->nPrefix = i; }else{ pIn->eEndLoopOp = OP_Noop; } From 00583291bd9ed02f795cc263e0e53c59f4081303 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 4 Jun 2018 19:24:41 +0000 Subject: [PATCH 02/20] Version 3.24.0 FossilOrigin-Name: c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca --- manifest | 12 +++++++----- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/manifest b/manifest index 9f8ea7f5b7..08282e8066 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sa\smisaligned\spointer. -D 2018-06-02T19:14:58.082 +C Version\s3.24.0 +D 2018-06-04T19:24:41.225 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -1730,8 +1730,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 ce2c3e7a875ede4366c48660ae8239d2b74e5f690ad5059844a45f1164f41e61 1b807b51cdf455b4f54216b73fd22bbc90f94e24222401e045f88cfd27f487e3 +P 1ecb3aa13de5c8dc611b814ff34010de0bd90aae73d88aa37a59c4627be4cc2d R 2db4b8b40a57a71d528932145db72c5a -T +closed 1b807b51cdf455b4f54216b73fd22bbc90f94e24222401e045f88cfd27f487e3 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.24.0 * U drh -Z 5a6c767d04a951cad28a5422f8a9694a +Z 1c60c6ad1e28023fcabbb88fe23d7708 diff --git a/manifest.uuid b/manifest.uuid index e0a78a25f6..3864d7913f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ecb3aa13de5c8dc611b814ff34010de0bd90aae73d88aa37a59c4627be4cc2d \ No newline at end of file +c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca \ No newline at end of file From 8e9deb61af6507e0dea5b51b472569c91cd39031 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Jun 2018 13:43:02 +0000 Subject: [PATCH 03/20] Update and correct the documentation on the OP_OpenRead, OP_OpenWrite, and OP_ReopenIdx opcodes. No code changes other than the addition of an assert(). FossilOrigin-Name: 8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 --- manifest | 15 ++++------ manifest.uuid | 2 +- src/vdbe.c | 82 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 08282e8066..66e6ec828d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.24.0 -D 2018-06-04T19:24:41.225 +C Update\sand\scorrect\sthe\sdocumentation\son\sthe\sOP_OpenRead,\sOP_OpenWrite,\nand\sOP_ReopenIdx\sopcodes.\s\sNo\scode\schanges\sother\sthan\sthe\saddition\sof\nan\sassert(). +D 2018-06-05T13:43:02.599 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -565,7 +565,7 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 37730af7540033135909ecaee3667dddec043293428d8718546d0d64ba4a5025 -F src/vdbe.c 71e5a72d89eabf7f88ef0ad4a429d3c3ee5d10de76af3818c47b275a6b3a9097 +F src/vdbe.c fcec6e9ad743f92f0a557f0b61728d001581ee96e18c3e5c7d09702afde79b38 F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d @@ -1730,10 +1730,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 1ecb3aa13de5c8dc611b814ff34010de0bd90aae73d88aa37a59c4627be4cc2d -R 2db4b8b40a57a71d528932145db72c5a -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.24.0 * +P c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca +R 0277d841a9ebaf3476d82cef8e2d4609 U drh -Z 1c60c6ad1e28023fcabbb88fe23d7708 +Z a41043871845bbfbe4b1d10a98baf884 diff --git a/manifest.uuid b/manifest.uuid index 3864d7913f..d25ed674b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca \ No newline at end of file +8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cab69b56b4..27bf56eb46 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3370,59 +3370,78 @@ case OP_SetCookie: { ** values need not be contiguous but all P1 values should be small integers. ** It is an error for P1 to be negative. ** -** If P5!=0 then use the content of register P2 as the root page, not -** the value of P2 itself. -** -** There will be a read lock on the database whenever there is an -** open cursor. If the database was unlocked prior to this instruction -** then a read lock is acquired as part of this instruction. A read -** lock allows other processes to read the database but prohibits -** any other process from modifying the database. The read lock is -** released when all cursors are closed. If this instruction attempts -** to get a read lock but fails, the script terminates with an -** SQLITE_BUSY error code. +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** ** See also: OpenWrite, ReopenIdx */ /* Opcode: ReopenIdx P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** -** The ReopenIdx opcode works exactly like ReadOpen except that it first -** checks to see if the cursor on P1 is already open with a root page -** number of P2 and if it is this opcode becomes a no-op. In other words, +** The ReopenIdx opcode works like OP_OpenRead except that it first +** checks to see if the cursor on P1 is already open on the same +** b-tree and if it is this opcode becomes a no-op. In other words, ** if the cursor is already open, do not reopen it. ** -** The ReopenIdx opcode may only be used with P5==0 and with P4 being -** a P4_KEYINFO object. Furthermore, the P3 value must be the same as -** every other ReopenIdx or OpenRead for the same cursor number. +** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ +** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must +** be the same as every other ReopenIdx or OpenRead for the same cursor +** number. ** -** See the OpenRead opcode documentation for additional information. +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
+** +** See also: OP_OpenRead, OP_OpenWrite */ /* Opcode: OpenWrite P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** ** Open a read/write cursor named P1 on the table or index whose root -** page is P2. Or if P5!=0 use the content of register P2 to find the -** root page. +** page is P2 (or whose root page is held in register P2 if the +** OPFLAG_P2ISREG bit is set in P5 - see below). ** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table, or to the -** largest index of any column of the table that is actually used. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** -** This instruction works just like OpenRead except that it opens the cursor -** in read/write mode. For a given table, there can be one or more read-only -** cursors or a single read/write cursor but not both. +** Allowed P5 bits: +**
    +**
  • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
  • 0x08 OPFLAG_FORDELETE: This cursor is used only to seek +** and subsequently delete entries in an index btree. This is a +** hint to the storage engine that the storage engine is allowed to +** ignore. The hint is not used by the official SQLite b*tree storage +** engine, but is used by COMDB2. +**
  • 0x10 OPFLAG_P2ISREG: Use the content of register P2 +** as the root page, not the value of P2 itself. +**
** -** See also OpenRead. +** This instruction works like OpenRead except that it opens the cursor +** in read/write mode. +** +** See also: OP_OpenRead, OP_ReopenIdx */ case OP_ReopenIdx: { int nField; @@ -3478,6 +3497,7 @@ case OP_OpenWrite: if( pOp->p5 & OPFLAG_P2ISREG ){ assert( p2>0 ); assert( p2<=(p->nMem+1 - p->nCursor) ); + assert( pOp->opcode==OP_OpenWrite ); pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); From 86d0ea755844cc3ace4800cfb1400d18bc067ccb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Jun 2018 15:16:25 +0000 Subject: [PATCH 04/20] Use an OP_NotFound opcode to cancel futile IN operators early. The current implementation is suboptimal because it always runs teh OP_NotFound. This still needs to be enhanced to only do the OP_NotFound if no results have been seen on the current loop. FossilOrigin-Name: 87a9fc504f9a78caf7a7949cc7ada0a19d61bfab51bb49a00a1607194c116212 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 4 +++- src/wherecode.c | 8 ++++++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index d53a07ddcf..ef0a40552a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges. -D 2018-06-05T13:54:06.962 +C Use\san\sOP_NotFound\sopcode\sto\scancel\sfutile\sIN\soperators\searly.\s\sThe\scurrent\nimplementation\sis\ssuboptimal\sbecause\sit\salways\sruns\steh\sOP_NotFound.\s\sThis\nstill\sneeds\sto\sbe\senhanced\sto\sonly\sdo\sthe\sOP_NotFound\sif\sno\sresults\shave\sbeen\nseen\son\sthe\scurrent\sloop. +D 2018-06-05T15:16:25.289 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -579,9 +579,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c a9a270991e5e526151d077959b868481b28db8707bc6d29b76badd536c48225a +F src/where.c a16f982d998e87067ea64d30602e008a24f767e6e502d7cdcddf0c858cdd9392 F src/whereInt.h b6ab96d9c1e48d029eaaee8f9b6d05e6a2405af0ad68f684e75f21c46837ae11 -F src/wherecode.c 49256d67b95187f9b49777c0f526362f4eaaa46850700fe5020cf6b154a2fc52 +F src/wherecode.c f941a484fd9f7a197099efe384be7a64c5588f27bbf92151705dae92eea7dbfc F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1730,7 +1730,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 f8df2a8e28acdd9573a9ffc18027553f35f769a989f5dfbf81f31b0656ee6065 8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 -R c016cdaa4deeb52d3fb41752c4ee7460 +P 047295c588e9fdf2ffa4e69e166f177fd193309531dc6a9ac755fb7a763adb72 +R 5115dc97bd8a224dc2a595e1eda36012 U drh -Z 7399c1ded5e7ae5c45a8362a80c02d78 +Z 3e5cea1662f3befc7bce81830cbd86be diff --git a/manifest.uuid b/manifest.uuid index d74be7579c..20f95cb085 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -047295c588e9fdf2ffa4e69e166f177fd193309531dc6a9ac755fb7a763adb72 \ No newline at end of file +87a9fc504f9a78caf7a7949cc7ada0a19d61bfab51bb49a00a1607194c116212 \ No newline at end of file diff --git a/src/where.c b/src/where.c index b93e2260e6..d31e0bb09d 100644 --- a/src/where.c +++ b/src/where.c @@ -5084,8 +5084,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ - sqlite3VdbeAddOp3(v, OP_Noop, pLevel->iIdxCur, + sqlite3VdbeAddOp4Int(v, OP_NotFound, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); diff --git a/src/wherecode.c b/src/wherecode.c index 1578122479..1c653c9f59 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,8 +592,12 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; - pIn->iBase = iReg - i; - pIn->nPrefix = i; + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + pIn->iBase = iReg - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } }else{ pIn->eEndLoopOp = OP_Noop; } From 280c894b74e7ab8756974596b9d58b3babc60681 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 5 Jun 2018 20:04:28 +0000 Subject: [PATCH 05/20] Calculate non-aggregate expressions in the SELECT list of an aggregate query that does not use min() or max() once per group, instead of once per row visited. FossilOrigin-Name: dce2dfbe1590deb3ef5661230ae2d232bd492441195defbf698ac56f9629211c --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/select.c | 37 ++++++++++++++++++++++++++++++++----- test/aggnested.test | 2 +- test/e_select.test | 26 +++++++++++++------------- test/select5.test | 2 +- 6 files changed, 61 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 66e6ec828d..01b910e6ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sand\scorrect\sthe\sdocumentation\son\sthe\sOP_OpenRead,\sOP_OpenWrite,\nand\sOP_ReopenIdx\sopcodes.\s\sNo\scode\schanges\sother\sthan\sthe\saddition\sof\nan\sassert(). -D 2018-06-05T13:43:02.599 +C Calculate\snon-aggregate\sexpressions\sin\sthe\sSELECT\slist\sof\san\saggregate\squery\nthat\sdoes\snot\suse\smin()\sor\smax()\sonce\sper\sgroup,\sinstead\sof\sonce\sper\srow\nvisited. +D 2018-06-05T20:04:28.586 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -495,7 +495,7 @@ F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 3291892add3a8f01dc3754e40ef9e30ad22c78e3404a388ae58f0390a1fb29eb +F src/select.c 8d3176c5258cc83942815ebe75b4c1f8dcf62b5e0f4d37373a14ebf23c046f9f F src/shell.c.in c29cb307d6275131e6f9874e0fa73f87acf40a22c4a82faba2059a93b4d294d1 F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -587,7 +587,7 @@ F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 +F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 F test/alter.test b820ab9dcf85f8e3a65bc8326accb2f0c7be64ef @@ -778,7 +778,7 @@ F test/e_fts3.test 8cf40550bb088a6aa187c818c00fabe26ef82900a4cd5c66b427ccafe28be F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test 6fd45fd4a59ec82b6dda7468699dcc0ec1a72538577750b4f90357a62c1d2723 +F test/e_select.test c5a669b4d63217aa10094ba737ba3ddd07bd439d4bc7a5b798f6ea32511cbe7c F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 @@ -1213,7 +1213,7 @@ F test/select1.test 2e760bab8f3658b3b97debcf52860d0d2e20aa6cbe8b40e678ddb99871a1 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 -F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 +F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d @@ -1730,7 +1730,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 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca -R 0277d841a9ebaf3476d82cef8e2d4609 -U drh -Z a41043871845bbfbe4b1d10a98baf884 +P 8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 +R 68f88270aa2c2118664b882e11dbe18f +T *branch * exp-agg-opt +T *sym-exp-agg-opt * +T -sym-trunk * +U dan +Z 491386dd047a3b3fa6ba9455da7a08ff diff --git a/manifest.uuid b/manifest.uuid index d25ed674b3..f655c090dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 \ No newline at end of file +dce2dfbe1590deb3ef5661230ae2d232bd492441195defbf698ac56f9629211c \ No newline at end of file diff --git a/src/select.c b/src/select.c index 529df0f949..a29d63273f 100644 --- a/src/select.c +++ b/src/select.c @@ -5100,11 +5100,17 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } } + /* ** Update the accumulator memory cells for an aggregate based on ** the current cursor position. +** +** If regAcc is non-zero and there are no min() or max() aggregates +** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator +** registers i register regAcc contains 0. The caller will take care +** of setting and clearing regAcc. */ -static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ +static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; int regHit = 0; @@ -5168,6 +5174,9 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ ** Another solution would be to change the OP_SCopy used to copy cached ** values to an OP_Copy. */ + if( regHit==0 && pAggInfo->nAccumulator ){ + regHit = regAcc; + } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } @@ -6021,8 +6030,6 @@ int sqlite3Select( pParse->nMem += pGroupBy->nExpr; sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); - sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); - VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. @@ -6155,7 +6162,7 @@ int sqlite3Select( ** the current row */ sqlite3VdbeJumpHere(v, addr1); - updateAccumulator(pParse, &sAggInfo); + updateAccumulator(pParse, iUseFlag, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); @@ -6207,6 +6214,8 @@ int sqlite3Select( */ sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ @@ -6272,6 +6281,23 @@ int sqlite3Select( }else #endif /* SQLITE_OMIT_BTREECOUNT */ { + int regAcc = 0; /* "populate accumulators" flag */ + + /* If there are accumulator registers but no min() or max() functions, + ** allocate register regAcc. Register regAcc will contain 0 the first + ** time the inner loop runs, and 1 thereafter. The code generated + ** by updateAccumulator() only updates the accumulator registers if + ** regAcc contains 0. */ + if( sAggInfo.nAccumulator ){ + for(i=0; ifuncFlags&SQLITE_FUNC_NEEDCOLL ) break; + } + if( i==sAggInfo.nFunc ){ + regAcc = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); + } + } + /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row ** of output. @@ -6293,7 +6319,8 @@ int sqlite3Select( if( pWInfo==0 ){ goto select_end; } - updateAccumulator(pParse, &sAggInfo); + updateAccumulator(pParse, regAcc, &sAggInfo); + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( sqlite3WhereIsOrdered(pWInfo)>0 ){ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); VdbeComment((v, "%s() by index", diff --git a/test/aggnested.test b/test/aggnested.test index a87c751eda..91de63b768 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -65,7 +65,7 @@ do_test aggnested-2.0 { t1.* FROM t1; } -} {A,B,B 3 33 333 3333} +} {A,B,B 1 11 111 1111} db2 close ##################### Test cases for ticket [bfbf38e5e9956ac69f] ############ diff --git a/test/e_select.test b/test/e_select.test index e88d63b54f..5916e94826 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -801,7 +801,7 @@ do_select_tests e_select-4.1 { 4 "SELECT z2.* FROM z1,z2 LIMIT 1" {{} 21} 5 "SELECT z2.*, z1.* FROM z1,z2 LIMIT 1" {{} 21 51.65 -59.58 belfries} - 6 "SELECT count(*), * FROM z1" {6 63 born -26} + 6 "SELECT count(*), * FROM z1" {6 51.65 -59.58 belfries} 7 "SELECT max(a), * FROM z1" {63 63 born -26} 8 "SELECT *, min(a) FROM z1" {-5 {} 75 -5} @@ -939,13 +939,13 @@ do_execsql_test e_select-4.6.0 { INSERT INTO a2 VALUES(10, 4); } {} do_select_tests e_select-4.6 { - 1 "SELECT one, two, count(*) FROM a1" {4 10 4} - 2 "SELECT one, two, count(*) FROM a1 WHERE one<3" {2 3 2} + 1 "SELECT one, two, count(*) FROM a1" {1 1 4} + 2 "SELECT one, two, count(*) FROM a1 WHERE one<3" {1 1 2} 3 "SELECT one, two, count(*) FROM a1 WHERE one>3" {4 10 1} - 4 "SELECT *, count(*) FROM a1 JOIN a2" {4 10 10 4 16} - 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {3 6 2 3} - 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {3 6 2 3} - 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 3 6} + 4 "SELECT *, count(*) FROM a1 JOIN a2" {1 1 1 1 16} + 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} + 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} + 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} } # EVIDENCE-OF: R-04486-07266 Or, if the dataset contains zero rows, then @@ -1128,7 +1128,7 @@ do_select_tests e_select-4.13 { 2.1 "SELECT up FROM c1 GROUP BY up HAVING down>10" {y} 2.2 "SELECT up FROM c1 GROUP BY up HAVING up='y'" {y} - 2.3 "SELECT i, j FROM c2 GROUP BY i>4 HAVING i>6" {9 36} + 2.3 "SELECT i, j FROM c2 GROUP BY i>4 HAVING j>6" {5 10} } # EVIDENCE-OF: R-23927-54081 Each expression in the result-set is then @@ -1154,12 +1154,12 @@ do_select_tests e_select-4.15 { # for the same row. # do_select_tests e_select-4.15 { - 1 "SELECT i, j FROM c2 GROUP BY i%2" {8 28 9 36} - 2 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j<30" {8 28} - 3 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {9 36} - 4 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {9 36} + 1 "SELECT i, j FROM c2 GROUP BY i%2" {2 1 1 0} + 2 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j<30" {2 1 1 0} + 3 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {} + 4 "SELECT i, j FROM c2 GROUP BY i%2 HAVING j>30" {} 5 "SELECT count(*), i, k FROM c2 NATURAL JOIN c3 GROUP BY substr(k, 1, 1)" - {2 5 boron 2 2 helium 1 3 lithium} + {2 4 beryllium 2 1 hydrogen 1 3 lithium} } # EVIDENCE-OF: R-19334-12811 Each group of input dataset rows diff --git a/test/select5.test b/test/select5.test index 3a787fc767..8f451eacbb 100644 --- a/test/select5.test +++ b/test/select5.test @@ -154,7 +154,7 @@ do_test select5-5.5 { execsql { SELECT a, b FROM t2 GROUP BY a; } -} {1 4 6 4} +} {1 2 6 4} # Test rendering of columns for the GROUP BY clause. # From 8c2b6d784b44c601ea600e8cfca9a222ce66b54b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Jun 2018 20:45:20 +0000 Subject: [PATCH 06/20] Add the OP_IfNoHope and OP_SeekHit opcodes used to reduce the number of unnecessary sqlite3BtreeMovetoUnpacked() calls when checking for an early exit on IN-operator loops. Futher optimizations are likely possible here. FossilOrigin-Name: 6bf251af4347165a470d39457d61ab6d2a06c206db8f30bd8be5dbb388ae8a5b --- manifest | 18 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- src/vdbeInt.h | 1 + src/where.c | 2 +- src/wherecode.c | 7 +++++++ 6 files changed, 74 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ef0a40552a..f16c3e72be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\san\sOP_NotFound\sopcode\sto\scancel\sfutile\sIN\soperators\searly.\s\sThe\scurrent\nimplementation\sis\ssuboptimal\sbecause\sit\salways\sruns\steh\sOP_NotFound.\s\sThis\nstill\sneeds\sto\sbe\senhanced\sto\sonly\sdo\sthe\sOP_NotFound\sif\sno\sresults\shave\sbeen\nseen\son\sthe\scurrent\sloop. -D 2018-06-05T15:16:25.289 +C Add\sthe\sOP_IfNoHope\sand\sOP_SeekHit\sopcodes\sused\sto\sreduce\sthe\snumber\sof\nunnecessary\ssqlite3BtreeMovetoUnpacked()\scalls\swhen\schecking\sfor\san\searly\nexit\son\sIN-operator\sloops.\s\sFuther\soptimizations\sare\slikely\spossible\shere. +D 2018-06-05T20:45:20.959 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -565,9 +565,9 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 37730af7540033135909ecaee3667dddec043293428d8718546d0d64ba4a5025 -F src/vdbe.c fcec6e9ad743f92f0a557f0b61728d001581ee96e18c3e5c7d09702afde79b38 +F src/vdbe.c 1c429876d32a96fdebd8f8b31f735c6236a8fb04395e8f731784767b909d2504 F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 -F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 +F src/vdbeInt.h d299d7a19853463dac418de0d97f2dd9cb4ddb495a45c93364e2daee109ba0ef F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d F src/vdbeaux.c b00d35805a2b326d1371ab7ce8f3a95c8af35b1431367ffe482fc2c735d69fb1 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 @@ -579,9 +579,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c a16f982d998e87067ea64d30602e008a24f767e6e502d7cdcddf0c858cdd9392 +F src/where.c 83b6cf94d98ff9a2185071aeed664a57922999a6dd58a03dbb379d472314e4b2 F src/whereInt.h b6ab96d9c1e48d029eaaee8f9b6d05e6a2405af0ad68f684e75f21c46837ae11 -F src/wherecode.c f941a484fd9f7a197099efe384be7a64c5588f27bbf92151705dae92eea7dbfc +F src/wherecode.c 12d88d0195a50b456c5dbeb3c44cb7d7087f591526968e8bde7a38b5534cd0ee F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1730,7 +1730,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 047295c588e9fdf2ffa4e69e166f177fd193309531dc6a9ac755fb7a763adb72 -R 5115dc97bd8a224dc2a595e1eda36012 +P 87a9fc504f9a78caf7a7949cc7ada0a19d61bfab51bb49a00a1607194c116212 +R 06e6068952816b400d67d388d7704be4 U drh -Z 3e5cea1662f3befc7bce81830cbd86be +Z 5b6bba2950cd0e23a4c3733c8955eb63 diff --git a/manifest.uuid b/manifest.uuid index 20f95cb085..9568d071fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87a9fc504f9a78caf7a7949cc7ada0a19d61bfab51bb49a00a1607194c116212 \ No newline at end of file +6bf251af4347165a470d39457d61ab6d2a06c206db8f30bd8be5dbb388ae8a5b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 27bf56eb46..4a325b207b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4034,6 +4034,25 @@ seek_not_found: break; } +/* Opcode: SeekHit P1 P2 * * * +** Synopsis: seekHit=P2 +** +** Set the seekHit flag on cursor P1 to the value in P2. +** The seekHit flag is used by the IfNoHope opcode. +** +** P1 must be a valid b-tree cursor. P2 must be a boolean value, +** either 0 or 1. +*/ +case OP_SeekHit: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p2==0 || pOp->p2==1 ); + pC->seekHit = pOp->p2 & 1; + break; +} + /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -4068,7 +4087,34 @@ seek_not_found: ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** -** See also: Found, NotExists, NoConflict +** See also: Found, NotExists, NoConflict, IfNoHope +*/ +/* Opcode: IfNoHope P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** Register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then +** this opcode is a no-op. But if the seekHit flag of P1 is clear, then +** check to see if there is any entry in P1 that matches the +** prefix identified by P3 and P4. If no entry matches the prefix, +** jump to P2. Otherwise fall through. +** +** This opcode behaves like OP_NotFound if the seekHit +** flag is clear and it behaves like OP_Noop if the seekHit flag is set. +** +** This opcode is used in IN clause processing for a multi-column key. +** If an IN clause is attached to an element of the key other than the +** left-most element, and if there are no matches on the most recent +** seek over the whole key, then it might be that one of the key element +** to the left is prohibiting a match, and hence there is "no hope" of +** any match regardless of how many IN clause elements are checked. +** In such a case, we abandon the IN clause search early, using this +** opcode. The opcode name comes from the fact that the +** jump is taken if there is "no hope" of achieving a match. +** +** See also: NotFound, SeekHit */ /* Opcode: NoConflict P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] @@ -4093,6 +4139,14 @@ seek_not_found: ** ** See also: NotFound, Found, NotExists */ +case OP_IfNoHope: { /* jump, in3 */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( pC->seekHit ) break; + /* Fall through into OP_NotFound */ +} case OP_NoConflict: /* jump, in3 */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 0f10e3759d..dd8e29108a 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -85,6 +85,7 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ int *aAltMap; /* Mapping from table to index column numbers */ diff --git a/src/where.c b/src/where.c index d31e0bb09d..bfb848f426 100644 --- a/src/where.c +++ b/src/where.c @@ -5084,7 +5084,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ - sqlite3VdbeAddOp4Int(v, OP_NotFound, pLevel->iIdxCur, + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); VdbeCoverage(v); diff --git a/src/wherecode.c b/src/wherecode.c index 1c653c9f59..a20a9808e1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1664,6 +1664,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ + if( pLoop->wsFlags & WHERE_IN_ABLE ){ + sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); + } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); @@ -1727,6 +1730,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } + if( pLoop->wsFlags & WHERE_IN_ABLE ){ + sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + } + /* Seek the table cursor, if required */ if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ From bb777d517d79df02320e2c49e15b75b14441c452 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Jun 2018 23:51:52 +0000 Subject: [PATCH 07/20] Update the version number to 3.25.0 for the next development cycle. FossilOrigin-Name: 7598236c356cdb548c6188d69dfef99f7a08b89e512a3addfe1433ccd85e7b68 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 954e228821..0914443131 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.24.0 +3.25.0 diff --git a/configure b/configure index ea1160120f..aa18ccb622 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.24.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.25.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.24.0' -PACKAGE_STRING='sqlite 3.24.0' +PACKAGE_VERSION='3.25.0' +PACKAGE_STRING='sqlite 3.25.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1465,7 +1465,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.24.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.25.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1530,7 +1530,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.24.0:";; + short | recursive ) echo "Configuration of sqlite 3.25.0:";; esac cat <<\_ACEOF @@ -1655,7 +1655,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.24.0 +sqlite configure 3.25.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2074,7 +2074,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.24.0, which was +It was created by sqlite $as_me 3.25.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12242,7 +12242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.24.0, which was +This file was extended by sqlite $as_me 3.25.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12308,7 +12308,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.24.0 +sqlite config.status 3.25.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 4c99f93e8e..764a87d140 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Avoid\sunnecessary\sloads\sof\scolumns\sin\san\saggregate\squery\sthat\sare\snot\nwithin\san\saggregate\sfunction\sand\sthat\sare\snot\spart\sof\sthe\sGROUP\sBY\sclause. -D 2018-06-05T23:21:11.926 +C Update\sthe\sversion\snumber\sto\s3.25.0\sfor\sthe\snext\sdevelopment\scycle. +D 2018-06-05T23:51:52.463 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 681fb88cccf1fd58c0b9648f6a09b75332206ef72ca76012ad11699c320cec5f F README.md 7764d56778d567913ef11c82da9ab94aefa0826f7c243351e4e2d7adaef6f373 -F VERSION b7c9d1d11cb70ef8e90cfcf3c944aa58a9f801cc2ad487eebb0a110c16dfc2df +F VERSION d3e3afdec1165a5e593dcdfffd8e0f33a2b0186067eb51a073ef6c4aec34923d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -33,7 +33,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 80e2dcad8ab88aacc58b55eb0e395f79184b45fcfaa3f36fc20d2e71cfa0a7e4 x +F configure 481df2c668b5c8cd5723dbcda88df8e6796a23884877109d1fe558667a0474bf x F configure.ac d4529ebb26ae046269334f1dac65f2b1d6927c2efe22b2ec24dce24dfe4f83dd F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html ac63db056bce24b7368e29319cd1a7eb5f1798cc85922d96a80b6c3a4ff9f51b @@ -1730,8 +1730,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 8a0b730d0ea640d5cf75febe39b2162411a12eb5275765a85882158b5a085681 dce2dfbe1590deb3ef5661230ae2d232bd492441195defbf698ac56f9629211c -R 68f88270aa2c2118664b882e11dbe18f -T +closed dce2dfbe1590deb3ef5661230ae2d232bd492441195defbf698ac56f9629211c +P e15e100660d290249ef235e7a8927b88296e56ec0f80ec626eecbd542adc7633 +R 9c79e6d517db97b3d75f12832208568b U drh -Z 74586da5649e70ef849c88cf2deb0eea +Z 33fc71c9e82a78478fc654d7337f409f diff --git a/manifest.uuid b/manifest.uuid index 27c51103b3..c55e06ffc4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e15e100660d290249ef235e7a8927b88296e56ec0f80ec626eecbd542adc7633 \ No newline at end of file +7598236c356cdb548c6188d69dfef99f7a08b89e512a3addfe1433ccd85e7b68 \ No newline at end of file From 0cfd46a1ad5ef1c2bb0d7a56d1a8560998619b42 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 01:18:01 +0000 Subject: [PATCH 08/20] Fix the ".archive" command in the CLI (and the corresponding -A command-line option) so that it silently ignores filenames that contain "../" in their names. This prevents the "Zip Slip" attack. FossilOrigin-Name: 27291f2d7fd4dadf2ee9b9a7d1373158cadfbaf83c3654b00d7030dc921770c6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 764a87d140..2269e8f309 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sversion\snumber\sto\s3.25.0\sfor\sthe\snext\sdevelopment\scycle. -D 2018-06-05T23:51:52.463 +C Fix\sthe\s".archive"\scommand\sin\sthe\sCLI\s(and\sthe\scorresponding\s-A\scommand-line\noption)\sso\sthat\sit\ssilently\signores\sfilenames\sthat\scontain\s"../"\sin\stheir\nnames.\s\sThis\sprevents\sthe\s"Zip\sSlip"\sattack. +D 2018-06-06T01:18:01.520 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -496,7 +496,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 8d3176c5258cc83942815ebe75b4c1f8dcf62b5e0f4d37373a14ebf23c046f9f -F src/shell.c.in c29cb307d6275131e6f9874e0fa73f87acf40a22c4a82faba2059a93b4d294d1 +F src/shell.c.in 099edadacd82abbe38472e2995b140560bb9826cd4af611e6bab662cfba8fbda F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 @@ -1730,7 +1730,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 e15e100660d290249ef235e7a8927b88296e56ec0f80ec626eecbd542adc7633 -R 9c79e6d517db97b3d75f12832208568b +P 7598236c356cdb548c6188d69dfef99f7a08b89e512a3addfe1433ccd85e7b68 +R e18f63662d0afb8275af32300ec3f6c3 U drh -Z 33fc71c9e82a78478fc654d7337f409f +Z 67410ec210186d8a0784f53b2ab9e4b9 diff --git a/manifest.uuid b/manifest.uuid index c55e06ffc4..9d4b32fa4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7598236c356cdb548c6188d69dfef99f7a08b89e512a3addfe1433ccd85e7b68 \ No newline at end of file +27291f2d7fd4dadf2ee9b9a7d1373158cadfbaf83c3654b00d7030dc921770c6 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index b9d7cecbc7..adc7ce7002 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -5284,7 +5284,8 @@ static int arExtractCommand(ArCommand *pAr){ "SELECT " " ($dir || name)," " writefile(($dir || name), %s, mode, mtime) " - "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"; + "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" + " AND name NOT GLOB '*..[/\\]*'"; const char *azExtraArg[] = { "sqlar_uncompress(data, sz)", From bb2d9b1bf167b05a25cc67cd2be7a6a8cb37a142 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 16:28:40 +0000 Subject: [PATCH 09/20] Change sqlite3BtreeBeginTrans() to return the BTREE_SCHEMA_COOKIE, for a small speed improvement when starting new transactions. FossilOrigin-Name: a10662aa915ae2b5a78b3e10920350d32255b2d6b1a8aac0aba1ad173b07ed2b --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/backup.c | 6 +++--- src/btree.c | 23 ++++++++++++++--------- src/btree.h | 2 +- src/dbpage.c | 2 +- src/prepare.c | 4 ++-- src/test3.c | 2 +- src/vacuum.c | 2 +- src/vdbe.c | 11 ++++------- 10 files changed, 41 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index 2269e8f309..9698adcb8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".archive"\scommand\sin\sthe\sCLI\s(and\sthe\scorresponding\s-A\scommand-line\noption)\sso\sthat\sit\ssilently\signores\sfilenames\sthat\scontain\s"../"\sin\stheir\nnames.\s\sThis\sprevents\sthe\s"Zip\sSlip"\sattack. -D 2018-06-06T01:18:01.520 +C Change\ssqlite3BtreeBeginTrans()\sto\sreturn\sthe\sBTREE_SCHEMA_COOKIE,\sfor\sa\nsmall\sspeed\simprovement\swhen\sstarting\snew\stransactions. +D 2018-06-06T16:28:40.777 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -433,18 +433,18 @@ F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594 F src/analyze.c 71fbbeb7b25417592f54d869fe90c28b48e4cecb9926ef9b06d90fb0aec48941 F src/attach.c 4a3138bd771d5426ae4344d8d5e900440af29fabc5ec2f39f69a45010dfbccd7 F src/auth.c a38f3c63c974787ecf75e3213f8cac6568b9a7af7591fb0372ec0517dd16dca8 -F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b +F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 44405d03a05496e13b40b3a208bcf941c42c815da90d6ff4b04267a6985e5eb7 -F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598 +F src/btree.c ae7687faa330562d36cede3375fdc316bff068e9216322d0dfbb3749333e5d3d +F src/btree.h ab639c4b9b210b8f4cd7a3a922af73df9a3f27c1d124267339fd73ef8619f488 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/build.c 5fc41458505331bfb0c175f40b9a13cb335f826bed3ae311aaae000c132d7b16 F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48 F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 -F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6 +F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91 F src/delete.c 4c8c7604277a2041647f96b78f4b9a47858e9217e4fb333d35e7b5ab32c5b57f F src/expr.c 16f90ae2af2a100bc430a89184afde54878d82f18267e8d00bc4f33e695a7c57 @@ -490,7 +490,7 @@ F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 F src/pragma.c c0d13c0e82a9197aef5533d63300c5b0c8a216ae1fd14ada64e1f12f398d7e82 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 -F src/prepare.c 95a9dba7a5d032039a77775188cb3b6fb17f2fa1a0b7cd915b30b4b823383ffa +F src/prepare.c e966ecc97c3671ff0e96227c8c877b83f2d33ea371ee190bbf1698b36b5605c0 F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e @@ -507,7 +507,7 @@ F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 916a92de77ec5cbe27818ca194d8cf0c58aa7ad5b87527098f6aa5a6068800ce F src/test1.c 51aa5f3030217ca45eb62e90944838794d4faaae7a8f60e0330ae01f30bc997b F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 -F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b +F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d F src/test6.c e8d839fbc552ce044bec8234561a2d5b8819b48e29548ad0ba400471697946a8 @@ -564,8 +564,8 @@ F src/update.c 46dc24c6158446aaab45caee09b6d99327cb479268b83ffeb5b701823da3b67b F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 -F src/vacuum.c 37730af7540033135909ecaee3667dddec043293428d8718546d0d64ba4a5025 -F src/vdbe.c fcec6e9ad743f92f0a557f0b61728d001581ee96e18c3e5c7d09702afde79b38 +F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855 +F src/vdbe.c 6d399cc8e10a7c1b2103e5bc21874cbbb645bab39ae5839a124547de9c67281d F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d @@ -1730,7 +1730,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 7598236c356cdb548c6188d69dfef99f7a08b89e512a3addfe1433ccd85e7b68 -R e18f63662d0afb8275af32300ec3f6c3 +P 27291f2d7fd4dadf2ee9b9a7d1373158cadfbaf83c3654b00d7030dc921770c6 +R 16b62aa5de77d5bb1612bf4110bec5fd U drh -Z 67410ec210186d8a0784f53b2ab9e4b9 +Z 863a8fc1288d57d76620b26ae04bd21c diff --git a/manifest.uuid b/manifest.uuid index 9d4b32fa4f..041e5a4660 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27291f2d7fd4dadf2ee9b9a7d1373158cadfbaf83c3654b00d7030dc921770c6 \ No newline at end of file +a10662aa915ae2b5a78b3e10920350d32255b2d6b1a8aac0aba1ad173b07ed2b \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 165144d965..4200940b24 100644 --- a/src/backup.c +++ b/src/backup.c @@ -382,7 +382,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** before this function exits. */ if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ - rc = sqlite3BtreeBeginTrans(p->pSrc, 0); + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -398,10 +398,10 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, + (int*)&p->iDestSchema)) ){ p->bDestLocked = 1; - sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); } /* Do not allow backup if the destination database is in WAL mode diff --git a/src/btree.c b/src/btree.c index fb3b89fe13..80b05d36cd 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3300,7 +3300,7 @@ int sqlite3BtreeNewDb(Btree *p){ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ +int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ BtShared *pBt = p->pBt; int rc = SQLITE_OK; @@ -3428,12 +3428,17 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ trans_begun: - if( rc==SQLITE_OK && wrflag ){ - /* This call makes sure that the pager has the correct number of - ** open savepoints. If the second parameter is greater than 0 and - ** the sub-journal is not already open, then it will be opened here. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + if( rc==SQLITE_OK ){ + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } } btreeIntegrity(p); @@ -10084,11 +10089,11 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ pBt->btsFlags &= ~BTS_NO_WAL; if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - rc = sqlite3BtreeBeginTrans(pBtree, 0); + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); if( rc==SQLITE_OK ){ u8 *aData = pBt->pPage1->aData; if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ - rc = sqlite3BtreeBeginTrans(pBtree, 2); + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ diff --git a/src/btree.h b/src/btree.h index b5bf9f7564..32d1b78f98 100644 --- a/src/btree.h +++ b/src/btree.h @@ -78,7 +78,7 @@ int sqlite3BtreeGetOptimalReserve(Btree*); int sqlite3BtreeGetReserveNoMutex(Btree *p); int sqlite3BtreeSetAutoVacuum(Btree *, int); int sqlite3BtreeGetAutoVacuum(Btree *); -int sqlite3BtreeBeginTrans(Btree*,int); +int sqlite3BtreeBeginTrans(Btree*,int,int*); int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); int sqlite3BtreeCommitPhaseTwo(Btree*, int); int sqlite3BtreeCommit(Btree*); diff --git a/src/dbpage.c b/src/dbpage.c index c38de3b39f..5b19abd356 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -369,7 +369,7 @@ static int dbpageBegin(sqlite3_vtab *pVtab){ int i; for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt ) sqlite3BtreeBeginTrans(pBt, 1); + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } diff --git a/src/prepare.c b/src/prepare.c index c745f45a5a..92902ca70b 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -188,7 +188,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ - rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; @@ -433,7 +433,7 @@ static void schemaIsValid(Parse *pParse){ ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } diff --git a/src/test3.c b/src/test3.c index 0de19469a4..d1626b6ef4 100644 --- a/src/test3.c +++ b/src/test3.c @@ -133,7 +133,7 @@ static int SQLITE_TCLAPI btree_begin_transaction( } pBt = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); - rc = sqlite3BtreeBeginTrans(pBt, 1); + rc = sqlite3BtreeBeginTrans(pBt, 1, 0); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); diff --git a/src/vacuum.c b/src/vacuum.c index fe295147c5..04ad5e7a3a 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -224,7 +224,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ */ rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeBeginTrans(pMain, 2); + rc = sqlite3BtreeBeginTrans(pMain, 2, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ diff --git a/src/vdbe.c b/src/vdbe.c index 27bf56eb46..3627e5aa37 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3202,8 +3202,8 @@ case OP_AutoCommit: { */ case OP_Transaction: { Btree *pBt; - int iMeta; - int iGen; + int iMeta = 0; + int iGen = 0; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); @@ -3216,7 +3216,7 @@ case OP_Transaction: { pBt = db->aDb[pOp->p1].pBt; if( pBt ){ - rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); if( rc!=SQLITE_OK ){ @@ -3255,10 +3255,7 @@ case OP_Transaction: { ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. */ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); iGen = db->aDb[pOp->p1].pSchema->iGeneration; - }else{ - iGen = iMeta = 0; } assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ @@ -3626,7 +3623,7 @@ case OP_OpenEphemeral: { rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling From 397776a8235cc443bc8158f2f7c27932612c31d9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 17:45:51 +0000 Subject: [PATCH 10/20] Another minor optimization to OP_Transaction. FossilOrigin-Name: d80077aee3904e5d93164b342cae14d813de8e84e567462412751e06c7487d41 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 9698adcb8a..f37a81d248 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\ssqlite3BtreeBeginTrans()\sto\sreturn\sthe\sBTREE_SCHEMA_COOKIE,\sfor\sa\nsmall\sspeed\simprovement\swhen\sstarting\snew\stransactions. -D 2018-06-06T16:28:40.777 +C Another\sminor\soptimization\sto\sOP_Transaction. +D 2018-06-06T17:45:51.934 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -565,7 +565,7 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855 -F src/vdbe.c 6d399cc8e10a7c1b2103e5bc21874cbbb645bab39ae5839a124547de9c67281d +F src/vdbe.c ffa02701cda500e0770abf139d860447e546949c5d55acab58ad8239ad92daf0 F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d @@ -1730,7 +1730,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 27291f2d7fd4dadf2ee9b9a7d1373158cadfbaf83c3654b00d7030dc921770c6 -R 16b62aa5de77d5bb1612bf4110bec5fd +P a10662aa915ae2b5a78b3e10920350d32255b2d6b1a8aac0aba1ad173b07ed2b +R 0414460bef03f5574242d45104db8a7b U drh -Z 863a8fc1288d57d76620b26ae04bd21c +Z 426a1576c4740e63608a04eef5bea89e diff --git a/manifest.uuid b/manifest.uuid index 041e5a4660..60bbc07de5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a10662aa915ae2b5a78b3e10920350d32255b2d6b1a8aac0aba1ad173b07ed2b \ No newline at end of file +d80077aee3904e5d93164b342cae14d813de8e84e567462412751e06c7487d41 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 3627e5aa37..ba917e1c85 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3203,7 +3203,6 @@ case OP_AutoCommit: { case OP_Transaction: { Btree *pBt; int iMeta = 0; - int iGen = 0; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); @@ -3249,16 +3248,17 @@ case OP_Transaction: { p->nStmtDefCons = db->nDeferredCons; p->nStmtDefImmCons = db->nDeferredImmCons; } - - /* Gather the schema version number for checking: + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( pOp->p5 + && (iMeta!=pOp->p3 + || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) + ){ + /* ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. */ - iGen = db->aDb[pOp->p1].pSchema->iGeneration; - } - assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); - if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie From 685a50ad74167413a4a716d318051b57e72e277d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 18:50:50 +0000 Subject: [PATCH 11/20] Fix the sqlite3BeginTrans() calls within the snapshot extension. FossilOrigin-Name: 1fef7ad25b6a8e59163ac57f5cf0412bfc5b0e9446fd782f5f0a7d7ee11741fc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f37a81d248..26f68548e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sminor\soptimization\sto\sOP_Transaction. -D 2018-06-06T17:45:51.934 +C Fix\sthe\ssqlite3BeginTrans()\scalls\swithin\sthe\ssnapshot\sextension. +D 2018-06-06T18:50:50.582 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -459,7 +459,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 76b1dc902e4c3930d9a17a40cd8ee2e94b1fd8cce766672caef164a6d5d4df1d F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b -F src/main.c 0402e234155e0aad75fe6cd204864f492495be8605a50b4b3d4d72895cced3ce +F src/main.c a086ab7d6e4e3f07bd5789d16f977d425f9482e7b3baeeb2f17bde0e6bfb2bc1 F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1730,7 +1730,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 a10662aa915ae2b5a78b3e10920350d32255b2d6b1a8aac0aba1ad173b07ed2b -R 0414460bef03f5574242d45104db8a7b +P d80077aee3904e5d93164b342cae14d813de8e84e567462412751e06c7487d41 +R 171a49b9aa8a65c0e7fed5c4fb894ba2 U drh -Z 426a1576c4740e63608a04eef5bea89e +Z a4c79e357ad5b38e16700f26935c42bb diff --git a/manifest.uuid b/manifest.uuid index 60bbc07de5..791697ea26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d80077aee3904e5d93164b342cae14d813de8e84e567462412751e06c7487d41 \ No newline at end of file +1fef7ad25b6a8e59163ac57f5cf0412bfc5b0e9446fd782f5f0a7d7ee11741fc \ No newline at end of file diff --git a/src/main.c b/src/main.c index 8e89cc553a..a2b994f9be 100644 --- a/src/main.c +++ b/src/main.c @@ -4115,7 +4115,7 @@ int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -4153,7 +4153,7 @@ int sqlite3_snapshot_open( if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); } } @@ -4185,7 +4185,7 @@ int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); sqlite3BtreeCommit(pBt); From 4011c44322f6e7c3a81161501036053d31dc6692 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 19:48:19 +0000 Subject: [PATCH 12/20] Rearrange the order of some checks in the integrity_check pragma for a very slight performance gain. FossilOrigin-Name: 4b853f020570bf4af1b14e03f35764c7d7a03a40af58efc783e06f2b883cef78 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 26f68548e3..e9d21e6725 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3BeginTrans()\scalls\swithin\sthe\ssnapshot\sextension. -D 2018-06-06T18:50:50.582 +C Rearrange\sthe\sorder\sof\ssome\schecks\sin\sthe\sintegrity_check\spragma\sfor\sa\svery\nslight\sperformance\sgain. +D 2018-06-06T19:48:19.360 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -488,7 +488,7 @@ F src/parse.y 0b81472496809693a139067fea1fe3f14a7be8aa26c8f18bb327034d1252a06a F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 -F src/pragma.c c0d13c0e82a9197aef5533d63300c5b0c8a216ae1fd14ada64e1f12f398d7e82 +F src/pragma.c 71c585f1d26e14b931fa4573f587933d6dfddecd9d9001b0f126f74f7306bf87 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c e966ecc97c3671ff0e96227c8c877b83f2d33ea371ee190bbf1698b36b5605c0 F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365 @@ -1730,7 +1730,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 d80077aee3904e5d93164b342cae14d813de8e84e567462412751e06c7487d41 -R 171a49b9aa8a65c0e7fed5c4fb894ba2 +P 1fef7ad25b6a8e59163ac57f5cf0412bfc5b0e9446fd782f5f0a7d7ee11741fc +R 93609cd66c5b427e1d6471bfc6fce490 U drh -Z a4c79e357ad5b38e16700f26935c42bb +Z f75a4ef6d01483c8588f9c5a8cdbf911 diff --git a/manifest.uuid b/manifest.uuid index 791697ea26..2ac47cefb3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1fef7ad25b6a8e59163ac57f5cf0412bfc5b0e9446fd782f5f0a7d7ee11741fc \ No newline at end of file +4b853f020570bf4af1b14e03f35764c7d7a03a40af58efc783e06f2b883cef78 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 4699c96a1e..02510188f3 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1564,6 +1564,11 @@ void sqlite3Pragma( assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + if( !isQuick ){ + /* Sanity check on record header decoding */ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ char *zErr; @@ -1606,9 +1611,6 @@ void sqlite3Pragma( sqlite3ExprListDelete(db, pCheck); } if( !isQuick ){ /* Omit the remaining tests for quick_check */ - /* Sanity check on record header decoding */ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); - sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; From d882108a01c709a03407d31c215c6878d99f6c36 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 20:29:19 +0000 Subject: [PATCH 13/20] Small performance optimization in sqlite3VdbeRecordCompareWithSkip() for the common case where the comparison is equal. FossilOrigin-Name: 1e616e256a4fb1b64271706fdfa77dc5790eba0a2f0e619544e169bc61d7c805 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e9d21e6725..3485cebcc1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\sthe\sorder\sof\ssome\schecks\sin\sthe\sintegrity_check\spragma\sfor\sa\svery\nslight\sperformance\sgain. -D 2018-06-06T19:48:19.360 +C Small\sperformance\soptimization\sin\ssqlite3VdbeRecordCompareWithSkip()\sfor\nthe\scommon\scase\swhere\sthe\scomparison\sis\sequal. +D 2018-06-06T20:29:19.541 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -569,7 +569,7 @@ F src/vdbe.c ffa02701cda500e0770abf139d860447e546949c5d55acab58ad8239ad92daf0 F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d -F src/vdbeaux.c b00d35805a2b326d1371ab7ce8f3a95c8af35b1431367ffe482fc2c735d69fb1 +F src/vdbeaux.c 20c12c6911e5cf0a3e013f3e6b364a2cdc6e9facd2b41cec39ef37d4b4c0c759 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 803323406d8623a7619ea5d5f74016697eeaed19c02b98ce9c3013e77dbe1c38 F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f @@ -1730,7 +1730,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 1fef7ad25b6a8e59163ac57f5cf0412bfc5b0e9446fd782f5f0a7d7ee11741fc -R 93609cd66c5b427e1d6471bfc6fce490 +P 4b853f020570bf4af1b14e03f35764c7d7a03a40af58efc783e06f2b883cef78 +R 7344c5deda24a0cfa9adaed6fbe1c4f5 U drh -Z f75a4ef6d01483c8588f9c5a8cdbf911 +Z 8ab3115bce5174cc71ba7755437d5270 diff --git a/manifest.uuid b/manifest.uuid index 2ac47cefb3..a7ffb0a3f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b853f020570bf4af1b14e03f35764c7d7a03a40af58efc783e06f2b883cef78 \ No newline at end of file +1e616e256a4fb1b64271706fdfa77dc5790eba0a2f0e619544e169bc61d7c805 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 38ef85f0ec..395e700d17 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4284,10 +4284,11 @@ int sqlite3VdbeRecordCompareWithSkip( } i++; + if( i==pPKey2->nField ) break; pRhs++; d1 += sqlite3VdbeSerialTypeLen(serial_type); idx1 += sqlite3VarintLen(serial_type); - }while( idx1<(unsigned)szHdr1 && inField && d1<=(unsigned)nKey1 ); + }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a From 6eb3480bd7344ba8f918ba42733dcd77a4159fbf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 20:55:10 +0000 Subject: [PATCH 14/20] More space and performance enhancements to sqlite3VdbeRecordCompare(). FossilOrigin-Name: 83a60ff056a63f18479030e9dfb10926fbb0d906d51f2cf88233098e15c75534 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 3485cebcc1..5908003a12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\ssqlite3VdbeRecordCompareWithSkip()\sfor\nthe\scommon\scase\swhere\sthe\scomparison\sis\sequal. -D 2018-06-06T20:29:19.541 +C More\sspace\sand\sperformance\senhancements\sto\ssqlite3VdbeRecordCompare(). +D 2018-06-06T20:55:10.915 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -569,7 +569,7 @@ F src/vdbe.c ffa02701cda500e0770abf139d860447e546949c5d55acab58ad8239ad92daf0 F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h 42d3e65ea0c664f6d9bc9a53de645c0baf8566ff0188409ff3b8d2abc327bc17 F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d -F src/vdbeaux.c 20c12c6911e5cf0a3e013f3e6b364a2cdc6e9facd2b41cec39ef37d4b4c0c759 +F src/vdbeaux.c adbd21d93209c98c792e4ed03915b541f2c8bce1f672d64c2b023a3fd274352b F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 803323406d8623a7619ea5d5f74016697eeaed19c02b98ce9c3013e77dbe1c38 F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f @@ -1730,7 +1730,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 4b853f020570bf4af1b14e03f35764c7d7a03a40af58efc783e06f2b883cef78 -R 7344c5deda24a0cfa9adaed6fbe1c4f5 +P 1e616e256a4fb1b64271706fdfa77dc5790eba0a2f0e619544e169bc61d7c805 +R 190026d18cdaeea82d1546f8bc38f07e U drh -Z 8ab3115bce5174cc71ba7755437d5270 +Z d6071b0218e4b21faa51db68b4c17551 diff --git a/manifest.uuid b/manifest.uuid index a7ffb0a3f3..e7fcfe2c3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e616e256a4fb1b64271706fdfa77dc5790eba0a2f0e619544e169bc61d7c805 \ No newline at end of file +83a60ff056a63f18479030e9dfb10926fbb0d906d51f2cf88233098e15c75534 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 395e700d17..0669b6820d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4129,7 +4129,7 @@ int sqlite3VdbeRecordCompareWithSkip( u32 idx1; /* Offset of first type in header */ int rc = 0; /* Return value */ Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ - KeyInfo *pKeyInfo = pPKey2->pKeyInfo; + KeyInfo *pKeyInfo; const unsigned char *aKey1 = (const unsigned char *)pKey1; Mem mem1; @@ -4224,7 +4224,7 @@ int sqlite3VdbeRecordCompareWithSkip( if( (d1+mem1.n) > (unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ - }else if( pKeyInfo->aColl[i] ){ + }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){ mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = MEM_Str; @@ -4275,7 +4275,7 @@ int sqlite3VdbeRecordCompareWithSkip( } if( rc!=0 ){ - if( pKeyInfo->aSortOrder[i] ){ + if( pPKey2->pKeyInfo->aSortOrder[i] ){ rc = -rc; } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); @@ -4300,7 +4300,7 @@ int sqlite3VdbeRecordCompareWithSkip( ** value. */ assert( CORRUPT_DB || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) - || pKeyInfo->db->mallocFailed + || pPKey2->pKeyInfo->db->mallocFailed ); pPKey2->eqSeen = 1; return pPKey2->default_rc; @@ -4626,7 +4626,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } From df12595c097e34143697d96cdd56dd36278416ff Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Jun 2018 23:31:26 +0000 Subject: [PATCH 15/20] Change a comma into a logically equivalent but semantically clearer semicolon. FossilOrigin-Name: 71f97f0f82b3abfb07feb78d64a182fc50ff396e85d6f5aac479dbf58ba4d00a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5908003a12..28afcd291a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sspace\sand\sperformance\senhancements\sto\ssqlite3VdbeRecordCompare(). -D 2018-06-06T20:55:10.915 +C Change\sa\scomma\sinto\sa\slogically\sequivalent\sbut\ssemantically\sclearer\ssemicolon. +D 2018-06-06T23:31:26.651 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -429,7 +429,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594 +F src/alter.c 819b14b58e71565f8da505a9c1d5d9d904605f85cd64179cf9c7d1edcdad6c25 F src/analyze.c 71fbbeb7b25417592f54d869fe90c28b48e4cecb9926ef9b06d90fb0aec48941 F src/attach.c 4a3138bd771d5426ae4344d8d5e900440af29fabc5ec2f39f69a45010dfbccd7 F src/auth.c a38f3c63c974787ecf75e3213f8cac6568b9a7af7591fb0372ec0517dd16dca8 @@ -1730,7 +1730,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 1e616e256a4fb1b64271706fdfa77dc5790eba0a2f0e619544e169bc61d7c805 -R 190026d18cdaeea82d1546f8bc38f07e +P 83a60ff056a63f18479030e9dfb10926fbb0d906d51f2cf88233098e15c75534 +R 5d16f56d3b58167452434c091fea89d0 U drh -Z d6071b0218e4b21faa51db68b4c17551 +Z 444c916353093e35122e938c5f56cdda diff --git a/manifest.uuid b/manifest.uuid index e7fcfe2c3d..d349aaf719 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83a60ff056a63f18479030e9dfb10926fbb0d906d51f2cf88233098e15c75534 \ No newline at end of file +71f97f0f82b3abfb07feb78d64a182fc50ff396e85d6f5aac479dbf58ba4d00a \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 51d4a40067..f338e8bf44 100644 --- a/src/alter.c +++ b/src/alter.c @@ -142,7 +142,7 @@ static void renameParentFunc( } } - zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), + zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput); sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); sqlite3DbFree(db, zOutput); } From f7b0a5f3c369d2e2d3d3c51a1f45203fe7841eb6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jun 2018 14:59:22 +0000 Subject: [PATCH 16/20] Add the WHERE_IN_EARLYOUT flag and use it to clarify the logic of this optimization. FossilOrigin-Name: 522f1eacc20f11002cad58232a7c2610f369568653510e54f46088f579f778dc --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 1 + src/whereInt.h | 1 + src/wherecode.c | 5 +++-- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c553e9b56e..f93277565d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\strunk\senhancements. -D 2018-06-07T14:32:16.906 +C Add\sthe\sWHERE_IN_EARLYOUT\sflag\sand\suse\sit\sto\sclarify\sthe\slogic\sof\sthis\noptimization. +D 2018-06-07T14:59:22.505 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -579,9 +579,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c 83b6cf94d98ff9a2185071aeed664a57922999a6dd58a03dbb379d472314e4b2 -F src/whereInt.h b6ab96d9c1e48d029eaaee8f9b6d05e6a2405af0ad68f684e75f21c46837ae11 -F src/wherecode.c 12d88d0195a50b456c5dbeb3c44cb7d7087f591526968e8bde7a38b5534cd0ee +F src/where.c 6011e6a78efbe9c767eb5316c23f59ea52481be66d5a8e219dda8f657f494e5d +F src/whereInt.h b09753e74bf92a8b17cf0e41ca94c44432c454544be6699b5311dcc57bf229c6 +F src/wherecode.c 5f005bbdb4d1c27f1ff68e91d92766b15e0f9d0c5d00603538eec7711421c3c4 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1730,7 +1730,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 6bf251af4347165a470d39457d61ab6d2a06c206db8f30bd8be5dbb388ae8a5b 71f97f0f82b3abfb07feb78d64a182fc50ff396e85d6f5aac479dbf58ba4d00a -R e30bf4f9e62dead29f35aa7c5dd3eb87 +P e9d7bf4f7b9d6f8dabc4c95d43ebf12f2149bed1c5e750048b1b684128073c38 +R 6d4277fa9b6622056a87cf8567cfc5ae U drh -Z 4167bce53a1d321bedb2c1528b36a7a2 +Z c9c3d95e2b08432c3b21f5302501cc1d diff --git a/manifest.uuid b/manifest.uuid index dfaafebd34..a179c92a9c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9d7bf4f7b9d6f8dabc4c95d43ebf12f2149bed1c5e750048b1b684128073c38 \ No newline at end of file +522f1eacc20f11002cad58232a7c2610f369568653510e54f46088f579f778dc \ No newline at end of file diff --git a/src/where.c b/src/where.c index bfb848f426..8499d16e72 100644 --- a/src/where.c +++ b/src/where.c @@ -5084,6 +5084,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ + assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); diff --git a/src/whereInt.h b/src/whereInt.h index 08159fe28e..5028793bb8 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -557,3 +557,4 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ +#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ diff --git a/src/wherecode.c b/src/wherecode.c index a20a9808e1..03c3b78aeb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -595,6 +595,7 @@ static int codeEqualityTerm( if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; + pLoop->wsFlags |= WHERE_IN_EARLYOUT; }else{ pIn->nPrefix = 0; } @@ -1664,7 +1665,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ - if( pLoop->wsFlags & WHERE_IN_ABLE ){ + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; @@ -1730,7 +1731,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } - if( pLoop->wsFlags & WHERE_IN_ABLE ){ + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); } From 3c49eaf4be865f4f9a092073b7609bb69a06ee51 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jun 2018 15:23:43 +0000 Subject: [PATCH 17/20] Avoid using a prepared statement for ".stats on" after it has been closed by the ".eqp full" logic. Fix for ticket [7be932dfa60a8a6b3b26bcf76]. FossilOrigin-Name: bb87c054b1b76959e46258ac66b24027f468b390a4148ac67f208a1fbeda4060 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 1 + test/shell1.test | 13 +++++++++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 28afcd291a..ae7fdac937 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sa\scomma\sinto\sa\slogically\sequivalent\sbut\ssemantically\sclearer\ssemicolon. -D 2018-06-06T23:31:26.651 +C Avoid\susing\sa\sprepared\sstatement\sfor\s".stats\son"\safter\sit\shas\sbeen\sclosed\nby\sthe\s".eqp\sfull"\slogic.\s\sFix\sfor\sticket\s[7be932dfa60a8a6b3b26bcf76]. +D 2018-06-07T15:23:43.571 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -496,7 +496,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 8d3176c5258cc83942815ebe75b4c1f8dcf62b5e0f4d37373a14ebf23c046f9f -F src/shell.c.in 099edadacd82abbe38472e2995b140560bb9826cd4af611e6bab662cfba8fbda +F src/shell.c.in 3151c40b2f23857d6af032d535bcc8c432926c11ceb14803213cbb45552b957a F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 @@ -1241,7 +1241,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 50154b0c4779df435b9e60ca60104b05f1cc217eab1aa383131359329e73d939 +F test/shell1.test 707c03fbd07ac506cfb6fa09da4ee22e2b50453c3db2f404694116eb990168f3 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1730,7 +1730,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 83a60ff056a63f18479030e9dfb10926fbb0d906d51f2cf88233098e15c75534 -R 5d16f56d3b58167452434c091fea89d0 +P 71f97f0f82b3abfb07feb78d64a182fc50ff396e85d6f5aac479dbf58ba4d00a +R 88b349f4995942bbb83ef8407ed20dc3 U drh -Z 444c916353093e35122e938c5f56cdda +Z 107f8808affc9ffe8154c296896c4113 diff --git a/manifest.uuid b/manifest.uuid index d349aaf719..c4bf873456 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71f97f0f82b3abfb07feb78d64a182fc50ff396e85d6f5aac479dbf58ba4d00a \ No newline at end of file +bb87c054b1b76959e46258ac66b24027f468b390a4148ac67f208a1fbeda4060 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index adc7ce7002..9032e44d69 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2972,6 +2972,7 @@ static int shell_exec( /* Reprepare pStmt before reactiving trace modes */ sqlite3_finalize(pStmt); sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( pArg ) pArg->pStmt = pStmt; } restore_debug_trace_modes(); } diff --git a/test/shell1.test b/test/shell1.test index 922446f528..1bd7fbea76 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -637,6 +637,19 @@ do_test shell1-3.23b.4 { catchcmd "test.db" ".stats OFF BAD" } {1 {Usage: .stats ?on|off?}} +# Ticket 7be932dfa60a8a6b3b26bcf7623ec46e0a403ddb 2018-06-07 +# Adverse interaction between .stats and .eqp +# +do_test shell1-3.23b.5 { + catchcmd "test.db" [string map {"\n " "\n"} { + CREATE TEMP TABLE t1(x); + INSERT INTO t1 VALUES(1),(2); + .stats on + .eqp full + SELECT * FROM t1; + }] +} {/1\n2\n/} + # .tables ?TABLE? List names of tables # If TABLE specified, only list tables matching # LIKE pattern TABLE. From 056f5396fef186c23f654b06872c9f478d530016 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jun 2018 16:07:00 +0000 Subject: [PATCH 18/20] Test cases. FossilOrigin-Name: 085e863713a3f2d420c0076b275a6ac445a59d4d93f9eb0e8503b4e3f5589249 --- manifest | 15 +++++----- manifest.uuid | 2 +- src/wherecode.c | 2 +- test/in6.test | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ test/where.test | 4 +-- 5 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 test/in6.test diff --git a/manifest b/manifest index cc162b66ab..19feb3d166 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\s".stat/.eqp"\sCLI\sfix\sfrom\strunk. -D 2018-06-07T15:28:40.178 +C Test\scases. +D 2018-06-07T16:07:00.142 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -581,7 +581,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f F src/where.c 6011e6a78efbe9c767eb5316c23f59ea52481be66d5a8e219dda8f657f494e5d F src/whereInt.h b09753e74bf92a8b17cf0e41ca94c44432c454544be6699b5311dcc57bf229c6 -F src/wherecode.c 5f005bbdb4d1c27f1ff68e91d92766b15e0f9d0c5d00603538eec7711421c3c4 +F src/wherecode.c 06950dc0ede5588ce02158a3d356cf1cd30c75c23d59b6c00f76b116c2094956 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -967,6 +967,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08 +F test/in6.test 77c3e1d356d8aeb0864051f0677d3c0a032cf97b7f33a0ba8fa2b04a663f6b7b F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 @@ -1585,7 +1586,7 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 -F test/where.test f19ea3fa31c425b04af42c8b192a5b595ee84498df8d27dcd79ec043b25fbbfb +F test/where.test 6bfcd29db193b814e5736832ffa899b4ff2969a106b718a79375063d5eb02b29 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -1730,7 +1731,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 522f1eacc20f11002cad58232a7c2610f369568653510e54f46088f579f778dc bb87c054b1b76959e46258ac66b24027f468b390a4148ac67f208a1fbeda4060 -R ab39df9e13ae287891b82fbbff6e201a +P a91cad3381bb843d6f58975251bf99f0fa1a1398fae53d97a98a6c8ee65e718e +R 5a4c78a05981b673cdf266d134735cc4 U drh -Z 011ea25541aef6f0f28ebbe3afa79009 +Z 76c1f474368dc618d1f0cb11de44e0a8 diff --git a/manifest.uuid b/manifest.uuid index 5b41398eef..3684822a16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a91cad3381bb843d6f58975251bf99f0fa1a1398fae53d97a98a6c8ee65e718e \ No newline at end of file +085e863713a3f2d420c0076b275a6ac445a59d4d93f9eb0e8503b4e3f5589249 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 03c3b78aeb..32378381e1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,7 +592,7 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; pLoop->wsFlags |= WHERE_IN_EARLYOUT; diff --git a/test/in6.test b/test/in6.test new file mode 100644 index 0000000000..ad16c4e8a8 --- /dev/null +++ b/test/in6.test @@ -0,0 +1,77 @@ +# 2018-06-07 +# +# 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. +# +#*********************************************************************** +# +# A multi-key index that uses an IN operator on one of the keys other +# than the left-most key is able to abort the IN-operator loop early +# if key terms further to the left do not match. +# +# Call this the "multikey-IN-operator early-out optimization" or +# just "IN-early-out" optimization for short. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix in6 + +do_test in6-1.1 { + db eval { + CREATE TABLE t1(a,b,c,d); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) + SELECT 100, 200+x/2, 300+x/5, x FROM c; + CREATE INDEX t1abc ON t1(a,b,c); + } + set ::sqlite_search_count 0 + db eval { + SELECT d FROM t1 + WHERE a=99 + AND b IN (200,205,201,204) + AND c IN (304,302,309,308); + } +} {} +do_test in6-1.2 { + set ::sqlite_search_count +} {0} ;# Without the IN-early-out optimization, this value would be 15 + +# The multikey-IN-operator early-out optimization does not apply +# when the IN operator is on the left-most column of the index. +# +do_test in6-1.3 { + db eval { + EXPLAIN + SELECT d FROM t1 + WHERE a IN (98,99,100,101) + AND b=200 AND c=300; + } +} {~/(IfNoHope|SeekHit)/} + +set sqlite_search_count 0 +do_execsql_test in6-1.4 { + SELECT d FROM t1 + WHERE a=100 + AND b IN (200,201,202,204) + AND c IN (300,302,301,305) + ORDER BY +d; +} {1 2 3 4 5 8 9} +do_test in6-1.5 { + set ::sqlite_search_count +} {39} + +do_execsql_test in6-2.1 { + CREATE TABLE t2(e INT UNIQUE, f TEXT); + SELECT d, f FROM t1 LEFT JOIN t2 ON (e=d) + WHERE a=100 + AND b IN (200,201,202,204) + AND c IN (300,302,301,305) + ORDER BY +d; +} {1 {} 2 {} 3 {} 4 {} 5 {} 8 {} 9 {}} + +finish_test diff --git a/test/where.test b/test/where.test index 7ac1738028..216325d03b 100644 --- a/test/where.test +++ b/test/where.test @@ -490,12 +490,12 @@ ifcapable subquery { count { SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1; } - } {2 1 9 5} + } {2 1 9 4} do_test where-5.15 { count { SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1; } - } {2 1 9 3 1 16 9} + } {2 1 9 3 1 16 8} do_test where-5.100 { db eval { SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) From f1949b6634bb7bdf836cc0371917dec25edc9c85 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jun 2018 17:32:59 +0000 Subject: [PATCH 19/20] Remove the NextIfOpen and PrevIfOpen opcodes which are no longer needed when the IN-early-out optimization is working. FossilOrigin-Name: 439c8162272795b422a0e01b01b832fbc12b39914c9632a674162af8bdecff98 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/shell.c.in | 3 +-- src/vdbe.c | 24 +++++------------------- src/vdbeaux.c | 4 +--- src/where.c | 4 ++-- src/wherecode.c | 2 +- 7 files changed, 21 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 19feb3d166..4757702e64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases. -D 2018-06-07T16:07:00.142 +C Remove\sthe\sNextIfOpen\sand\sPrevIfOpen\sopcodes\swhich\sare\sno\slonger\sneeded\nwhen\sthe\sIN-early-out\soptimization\sis\sworking. +D 2018-06-07T17:32:59.729 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -496,7 +496,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 8d3176c5258cc83942815ebe75b4c1f8dcf62b5e0f4d37373a14ebf23c046f9f -F src/shell.c.in 3151c40b2f23857d6af032d535bcc8c432926c11ceb14803213cbb45552b957a +F src/shell.c.in 4d0ddf10c403710d241bf920163dcf032c21119aebb61e70840942c0eafecdf9 F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 @@ -565,11 +565,11 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855 -F src/vdbe.c ed88889ca2b71dd27770312b0ebfe06dca85c34ca418d368619a683cdaefe744 +F src/vdbe.c 3b8517d41c514a6e892f20a74c69d9c04849fe45fb676703f5c6672f11fca97f F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h d299d7a19853463dac418de0d97f2dd9cb4ddb495a45c93364e2daee109ba0ef F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d -F src/vdbeaux.c adbd21d93209c98c792e4ed03915b541f2c8bce1f672d64c2b023a3fd274352b +F src/vdbeaux.c daecbbefaf0adfc428cddbfa5164c1d744496ba5dd19f840845ecac652913802 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 803323406d8623a7619ea5d5f74016697eeaed19c02b98ce9c3013e77dbe1c38 F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f @@ -579,9 +579,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c 6011e6a78efbe9c767eb5316c23f59ea52481be66d5a8e219dda8f657f494e5d +F src/where.c 7dcb13bbcfd8c926546946556014c8f5aa0829eb8b65a6c18f8d187d265200a5 F src/whereInt.h b09753e74bf92a8b17cf0e41ca94c44432c454544be6699b5311dcc57bf229c6 -F src/wherecode.c 06950dc0ede5588ce02158a3d356cf1cd30c75c23d59b6c00f76b116c2094956 +F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1731,7 +1731,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 a91cad3381bb843d6f58975251bf99f0fa1a1398fae53d97a98a6c8ee65e718e -R 5a4c78a05981b673cdf266d134735cc4 +P 085e863713a3f2d420c0076b275a6ac445a59d4d93f9eb0e8503b4e3f5589249 +R 2dde483ff37edacba64e59586d1522f4 U drh -Z 76c1f474368dc618d1f0cb11de44e0a8 +Z b644b027a94a428792d2674b80d687cf diff --git a/manifest.uuid b/manifest.uuid index 3684822a16..2495bdfd74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -085e863713a3f2d420c0076b275a6ac445a59d4d93f9eb0e8503b4e3f5589249 \ No newline at end of file +439c8162272795b422a0e01b01b832fbc12b39914c9632a674162af8bdecff98 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 9032e44d69..392580733f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2567,8 +2567,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; /* Index of operation in p->aiIndent[] */ - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", - "NextIfOpen", "PrevIfOpen", 0 }; + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 }; const char *azGoto[] = { "Goto", 0 }; diff --git a/src/vdbe.c b/src/vdbe.c index 5054d4f2e0..7a25eea0e6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5132,12 +5132,7 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** -** See also: Prev, NextIfOpen -*/ -/* Opcode: NextIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Next except that if cursor P1 is not -** open it behaves a no-op. +** See also: Prev */ /* Opcode: Prev P1 P2 P3 P4 P5 ** @@ -5165,11 +5160,6 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Prev except that if cursor P1 is not -** open it behaves a no-op. -*/ /* Opcode: SorterNext P1 P2 * * P5 ** ** This opcode works just like OP_Next except that P1 must be a @@ -5184,10 +5174,6 @@ case OP_SorterNext: { /* jump */ assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; -case OP_PrevIfOpen: /* jump */ -case OP_NextIfOpen: /* jump */ - if( p->apCsr[pOp->p1]==0 ) break; - /* Fall through */ case OP_Prev: /* jump */ case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -5198,17 +5184,17 @@ case OP_Next: /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); - assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); +#if 0 /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ - assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen + assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); - assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen + assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE || pC->seekOp==OP_Last ); +#endif rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0669b6820d..7f0448ec1f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -689,7 +689,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ break; } case OP_Next: - case OP_NextIfOpen: case OP_SorterNext: { pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; @@ -699,8 +698,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( pOp->p2>=0 ); break; } - case OP_Prev: - case OP_PrevIfOpen: { + case OP_Prev: { pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; /* The code generator never codes any of these opcodes as a jump diff --git a/src/where.c b/src/where.c index 8499d16e72..10cb138143 100644 --- a/src/where.c +++ b/src/where.c @@ -5092,8 +5092,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); } sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } diff --git a/src/wherecode.c b/src/wherecode.c index 32378381e1..67f5e30738 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -591,7 +591,7 @@ static int codeEqualityTerm( sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; From cf025a8c18590ea3b11a160cc9d2a1ba53631efe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Jun 2018 18:01:21 +0000 Subject: [PATCH 20/20] Fix the assert()s in the byte-code engine that prove that cursors are unidirectional. FossilOrigin-Name: 4b0b4e14039469b656662312a5f80f086ede293e9ad04c7bc99a202b683a1e55 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 15 +++++++++------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 4757702e64..660acafd9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sNextIfOpen\sand\sPrevIfOpen\sopcodes\swhich\sare\sno\slonger\sneeded\nwhen\sthe\sIN-early-out\soptimization\sis\sworking. -D 2018-06-07T17:32:59.729 +C Fix\sthe\sassert()s\sin\sthe\sbyte-code\sengine\sthat\sprove\sthat\scursors\nare\sunidirectional. +D 2018-06-07T18:01:21.263 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -565,7 +565,7 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855 -F src/vdbe.c 3b8517d41c514a6e892f20a74c69d9c04849fe45fb676703f5c6672f11fca97f +F src/vdbe.c d7a475cec51c83daf0d348301a1aec77f535832ea946632b5738ff9f087c0edb F src/vdbe.h e3f43bcc27ff30b0f25a6104d0cb5657e1c4b5e1b5cd2dd2216d5bcc2156a746 F src/vdbeInt.h d299d7a19853463dac418de0d97f2dd9cb4ddb495a45c93364e2daee109ba0ef F src/vdbeapi.c 765a0bbe01311626417de6cb743f7f25f9f98435c98a9df4bb0714d11014633d @@ -1731,7 +1731,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 085e863713a3f2d420c0076b275a6ac445a59d4d93f9eb0e8503b4e3f5589249 -R 2dde483ff37edacba64e59586d1522f4 +P 439c8162272795b422a0e01b01b832fbc12b39914c9632a674162af8bdecff98 +R fe7d026f8be3134e2723fc39eeec5ed5 U drh -Z b644b027a94a428792d2674b80d687cf +Z 8c642b57392b756fd19e94b953870085 diff --git a/manifest.uuid b/manifest.uuid index 2495bdfd74..9c15183170 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -439c8162272795b422a0e01b01b832fbc12b39914c9632a674162af8bdecff98 \ No newline at end of file +4b0b4e14039469b656662312a5f80f086ede293e9ad04c7bc99a202b683a1e55 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7a25eea0e6..243e4fe70a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4292,7 +4292,7 @@ case OP_NotExists: /* jump, in3 */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG - pC->seekOp = 0; + pC->seekOp = OP_SeekRowid; #endif assert( pC->isTable ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -4946,6 +4946,9 @@ case OP_NullRow: { assert( pC->uc.pCursor!=0 ); sqlite3BtreeClearCursor(pC->uc.pCursor); } +#ifdef SQLITE_DEBUG + if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; +#endif break; } @@ -5185,16 +5188,16 @@ case OP_Next: /* jump */ assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); -#if 0 - /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. + /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow); assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last ); -#endif + || pC->seekOp==OP_Last + || pC->seekOp==OP_NullRow); rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: