1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Split the OP_Last opcode into OP_Last and OP_SeekEnd. Use OP_SeekEnd to

position a cursor prior to appending.  Ticket [cb91bf4290c211d].

FossilOrigin-Name: 3e02474c7bbe16891a7cfc8771cf72f64cd2c0692779037982d7d307512a4f23
This commit is contained in:
drh
2017-08-01 19:53:43 +00:00
parent b7673ede37
commit 86b40dfd33
6 changed files with 53 additions and 35 deletions

View File

@@ -4776,7 +4776,17 @@ case OP_NullRow: {
break;
}
/* Opcode: Last P1 P2 P3 * *
/* Opcode: SeekEnd P1 * * * *
**
** Position cursor P1 at the end of the btree for the purpose of
** appending a new entry onto the btree.
**
** 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.
*/
/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
@@ -4787,14 +4797,8 @@ 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_SeekEnd:
case OP_Last: { /* jump */
VdbeCursor *pC;
BtCursor *pCrsr;
@@ -4807,22 +4811,24 @@ case OP_Last: { /* jump */
pCrsr = pC->uc.pCursor;
res = 0;
assert( pCrsr!=0 );
pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
pC->seekOp = pOp->opcode;
#endif
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{
if( pOp->opcode==OP_SeekEnd ){
assert( pOp->p2==0 );
pC->seekResult = -1;
if( sqlite3BtreeCursorIsValidNN(pCrsr) ){
break;
}
}
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;
}
break;
}