mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Fix the OP_SeekRowid opcode so that it works correctly with a Real argument
without damaging the value in the register that is the argument. Ticket [b2d4edaffdc156cc]. Test cases in TH3. FossilOrigin-Name: 3cde82c86b963fa75192907d548febd3882c7d8fc7daf1903fadd5ca46623be1
This commit is contained in:
25
src/vdbe.c
25
src/vdbe.c
@@ -4539,23 +4539,27 @@ case OP_SeekRowid: { /* jump, in3 */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
testcase( pIn3->flags & MEM_Int );
|
||||
testcase( pIn3->flags & MEM_IntReal );
|
||||
testcase( pIn3->flags & MEM_Real );
|
||||
testcase( (pIn3->flags & (MEM_Str|MEM_Int))==MEM_Str );
|
||||
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
|
||||
/* Make sure pIn3->u.i contains a valid integer representation of
|
||||
** the key value, but do not change the datatype of the register, as
|
||||
** other parts of the perpared statement might be depending on the
|
||||
** current datatype. */
|
||||
u16 origFlags = pIn3->flags;
|
||||
int isNotInt;
|
||||
applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
|
||||
isNotInt = (pIn3->flags & MEM_Int)==0;
|
||||
pIn3->flags = origFlags;
|
||||
if( isNotInt ) goto jump_to_p2;
|
||||
/* If pIn3->u.i does not contain an integer, compute iKey as the
|
||||
** integer value of pIn3. Jump to P2 if pIn3 cannot be converted
|
||||
** into an integer without loss of information. Take care to avoid
|
||||
** changing the datatype of pIn3, however, as it is used by other
|
||||
** parts of the prepared statement. */
|
||||
Mem x = pIn3[0];
|
||||
applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding);
|
||||
if( (x.flags & MEM_Int)==0 ) goto jump_to_p2;
|
||||
iKey = x.u.i;
|
||||
goto notExistsWithKey;
|
||||
}
|
||||
/* Fall through into OP_NotExists */
|
||||
case OP_NotExists: /* jump, in3 */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
iKey = pIn3->u.i;
|
||||
notExistsWithKey:
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -4566,7 +4570,6 @@ case OP_NotExists: /* jump, in3 */
|
||||
pCrsr = pC->uc.pCursor;
|
||||
assert( pCrsr!=0 );
|
||||
res = 0;
|
||||
iKey = pIn3->u.i;
|
||||
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
|
||||
assert( rc==SQLITE_OK || res==0 );
|
||||
pC->movetoTarget = iKey; /* Used by OP_Delete */
|
||||
|
Reference in New Issue
Block a user