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:
48
src/vdbe.c
48
src/vdbe.c
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user