From: drh Date: Tue, 15 Nov 2016 04:00:24 +0000 (+0000) Subject: Change the OP_Last opcode so that it is a no-op if the cursor is already X-Git-Tag: version-3.16.0~118 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d6ef5afe3f905596571041926a4dae18322e58f9;p=thirdparty%2Fsqlite.git Change the OP_Last opcode so that it is a no-op if the cursor is already pointing at the end of the b-tree. FossilOrigin-Name: 663473850c4274270445b3771911fa773a8c405f --- diff --git a/manifest b/manifest index 59906c5d78..ebd7485bf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sVACUUM\scommand\sabout\s9%\sfaster\sby\savoiding\sunnecessary\scalls\nto\ssqlite3BtreeMovetoUnpacked()\swhile\scopying\srowid\stables. -D 2016-11-15T02:46:39.239 +C Change\sthe\sOP_Last\sopcode\sso\sthat\sit\sis\sa\sno-op\sif\sthe\scursor\sis\salready\npointing\sat\sthe\send\sof\sthe\sb-tree. +D 2016-11-15T04:00:24.244 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -330,8 +330,8 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c cfe038d1844420caddfa0238d52b7b2102dda98b -F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 +F src/btree.c a7ed407f879be72c94b81f965d552e51b54a971f +F src/btree.h 01ec45846fa177e929f01ee36a8e34337d653544 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -454,7 +454,7 @@ F src/update.c bb9854778bdbbbca55d7533e55058733bd3fefe3 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c f1a8e5bf7747f2e731812804cb65d4d07d86862e +F src/vdbe.c e76ee960a2e6d099838173599ae2d0999dc3aa63 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1534,7 +1534,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 03f75a67c320f21192d721a8c34d49dea48ffdbb -R 8e81a23a0b0c79dacc7554a88cc14173 +P 5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 +R 666875522a5a69f5f9bb179805474981 U drh -Z deb6f2821ede2b99520e7ac64aa770e4 +Z 3c6d6cf804e5301c81a1f9af34f5b4ed diff --git a/manifest.uuid b/manifest.uuid index 8dcb1cf916..53cf085748 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 \ No newline at end of file +663473850c4274270445b3771911fa773a8c405f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 283f37b797..895e8009ed 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4278,6 +4278,10 @@ int sqlite3BtreeCursorIsValid(BtCursor *pCur){ return pCur && pCur->eState==CURSOR_VALID; } #endif /* NDEBUG */ +int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ + assert( pCur!=0 ); + return pCur->eState==CURSOR_VALID; +} /* ** Return the value of the integer key or "rowid" for a table btree. diff --git a/src/btree.h b/src/btree.h index 8b421e4201..92cf443b21 100644 --- a/src/btree.h +++ b/src/btree.h @@ -310,6 +310,7 @@ int sqlite3HeaderSizeBtree(void); #ifndef NDEBUG int sqlite3BtreeCursorIsValid(BtCursor*); #endif +int sqlite3BtreeCursorIsValidNN(BtCursor*); #ifndef SQLITE_OMIT_BTREECOUNT int sqlite3BtreeCount(BtCursor *, i64 *); diff --git a/src/vdbe.c b/src/vdbe.c index 740e52fc90..9cf62f33bf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4799,6 +4799,13 @@ case OP_NullRow: { ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is ** configured to use Prev, not Next. +** +** If P3 is -1, then the cursor is positioned at the end of the btree +** for the purpose of appending a new entry onto the btree. In that +** case P2 must be 0. It is assumed that the cursor is used only for +** appending and so if the cursor is valid, then the cursor must already +** be pointing at the end of the btree and so no changes are made to +** the cursor. */ case OP_Last: { /* jump */ VdbeCursor *pC; @@ -4812,18 +4819,22 @@ case OP_Last: { /* jump */ pCrsr = pC->uc.pCursor; res = 0; assert( pCrsr!=0 ); - rc = sqlite3BtreeLast(pCrsr, &res); - pC->nullRow = (u8)res; - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; pC->seekResult = pOp->p3; #ifdef SQLITE_DEBUG pC->seekOp = OP_Last; #endif - if( rc ) goto abort_due_to_error; - if( pOp->p2>0 ){ - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; + if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){ + rc = sqlite3BtreeLast(pCrsr, &res); + pC->nullRow = (u8)res; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( rc ) goto abort_due_to_error; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + }else{ + assert( pOp->p2==0 ); } break; }