/ Check-in [8b12a15a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Reduce the amount of code used to implement OP_SeekGe and similar.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:8b12a15a2a8139d75f56a099f3f6af844da3ac9c
User & Date: dan 2013-11-26 18:22:59
Context
2013-11-26
21:18
Changing the CAST behavior of REAL values actually changed a documented requirement. So we also have to change the requirement evidence text to match. check-in: d84aa44e user: drh tags: trunk
18:22
Reduce the amount of code used to implement OP_SeekGe and similar. check-in: 8b12a15a user: dan tags: trunk
16:51
Fix a possible NULL pointer deference in the wordcount test program. check-in: 6f91dca0 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */
        pc = pOp->p2 - 1;
        break;
      }
      /* If we reach this point, then the P3 value must be a floating
      ** point number. */
      assert( (pIn3->flags & MEM_Real)!=0 );

      if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey)
       || (iKey==LARGEST_INT64 && pIn3->r>(double)iKey)
      ){
        /* The P3 value is too large in magnitude to be expressed as an
        ** integer. */
        res = 1;
        if( pIn3->r<0 ){
          if( oc>=OP_SeekGe ){  assert( oc==OP_SeekGe || oc==OP_SeekGt );
            rc = sqlite3BtreeFirst(pC->pCursor, &res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }else{
          if( oc<=OP_SeekLe ){  assert( oc==OP_SeekLt || oc==OP_SeekLe );
            rc = sqlite3BtreeLast(pC->pCursor, &res);
            if( rc!=SQLITE_OK ) goto abort_due_to_error;
          }
        }
        if( res ){
          pc = pOp->p2 - 1;
        }
        break;
      }else if( oc==OP_SeekLt || oc==OP_SeekGe ){
        /* Use the ceiling() function to convert real->int */
        if( pIn3->r > (double)iKey ) iKey++;
      }else{
        /* Use the floor() function to convert real->int */
        assert( oc==OP_SeekLe || oc==OP_SeekGt );
        if( pIn3->r < (double)iKey ) iKey--;
      }
    } 
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    if( res==0 ){







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<







3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534










3535
3536
3537
3538
3539
3540
3541
    if( (pIn3->flags & MEM_Int)==0 ){
      if( (pIn3->flags & MEM_Real)==0 ){
        /* If the P3 value cannot be converted into any kind of a number,
        ** then the seek is not possible, so jump to P2 */
        pc = pOp->p2 - 1;
        break;
      }

      /* If the approximation iKey is larger than the actual real search
      ** term, substitute >= for > and < for <=. e.g. if the search term
      ** is 4.9 and the integer approximation 5:
      **
      **        (x >  4.9)    ->     (x >= 5)
      **        (x <= 4.9)    ->     (x <  5)
      */
      if( pIn3->r<(double)iKey ){
        assert( OP_SeekGe==(OP_SeekGt-1) );
        assert( OP_SeekLt==(OP_SeekLe-1) );
        assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
        if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--;
      }

      /* If the approximation iKey is smaller than the actual real search
      ** term, substitute <= for < and > for >=.  */
      else if( pIn3->r>(double)iKey ){
        assert( OP_SeekLe==(OP_SeekLt+1) );
        assert( OP_SeekGt==(OP_SeekGe+1) );
        assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
        if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++;










      }
    } 
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    if( res==0 ){